Can't infer register because its behavior doesn't match any supported model in Quartus II

StackOverflow https://stackoverflow.com/questions/10390497

  •  04-06-2021
  •  | 
  •  

Question

The code:

        library IEEE;
        use IEEE.std_logic_1164.all;
        use ieee.numeric_std.all;
        use ieee.std_logic_unsigned.all;
        entity decoder10 is 
        port( in_data:  in STD_LOGIC_VECTOR (7 downto 0);
                clk : in STD_LOGIC;
                out_data:  out STD_LOGIC_VECTOR (7 downto 0));
        end decoder10;

        architecture behavioral of decoder10 is
        signal int_bus1 : STD_LOGIC_VECTOR (63 downto 0);
        signal int_bus2 : STD_LOGIC_VECTOR (63 downto 0);
        signal int_bus3 : STD_LOGIC_VECTOR (31 downto 0);
        signal lower : STD_LOGIC_VECTOR (31 downto 0);
        signal higher : STD_LOGIC_VECTOR (31 downto 0);
        signal intermid : STD_LOGIC_VECTOR (31 downto 0);
        signal curr_key : STD_LOGIC_VECTOR (31 downto 0);
        signal got_data: std_logic;      --data written in    
        signal variable_test: std_logic:= '0';      
        signal n_ready: std_logic; --code assembled
        signal k_ready: std_logic; --key selected
        signal k_added: std_logic; --key added
        signal sub_ready: std_logic; --blocks substituted
        signal sh_ready: std_logic; --shift done
        signal xor_ready: std_logic; --xor done
        signal out_ready: std_logic; --ready for output
        signal sent_data: std_logic; --data written out  
        signal start_again: std_logic; --start the main step again
        type arr is array (0 to 15) of std_logic_vector(31 downto 0);
        type key is array (0 to 7) of std_logic_vector(31 downto 0);
        type key_num is array (0 to 31) of integer;
        signal key_it : key_num := (0,1,2,3,4,5,6,7,
                                             7,6,5,4,3,2,1,0,
                                             7,6,5,4,3,2,1,0,
                                             7,6,5,4,3,2,1,0);

        signal tab : arr := (X"00000001",
                                    X"00000002",
                                    X"00000003",
                                    X"00000004",
                                    X"00000005",
                                    X"00000006",
                                    X"00000007",
                                    X"00000008",
                                    X"00000009",
                                    X"0000000a",
                                    X"0000000b",
                                    X"0000000c",
                                    X"0000000d",
                                    X"0000000e",
                                    X"0000000f",
                                    X"00000000");  

        signal tab_key : key := (X"00000007",
                                         X"00000006",
                                         X"00000005",
                                         X"00000004",
                                         X"00000003",
                                         X"00000002",
                                         X"00000001",
                                         X"00000000");

        component adder is 
        port(   dataa       : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
                datab       : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
                result      : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
        END component;

        begin

        add1: adder
            port map (lower, curr_key, int_bus3);

        process (clk, in_data)
        variable i: INTEGER := 0;
        variable j: INTEGER := 0;
        variable k: INTEGER := 0;


        begin
          -- assembling input code into one piece
          if (rising_edge(clk)) then
              if (i<8) then
                 int_bus1(63 downto 56)<=in_data;
                got_data <= '1';
                n_ready <= '0';
                 if (got_data = '1') then 
                     --shift right 8 bits 
                     int_bus1(55 downto 0) <= int_bus1(63 downto 8);
                     i := i + 1;
                     got_data <= '0';
                 end if;
              end if;

                 if (i = 8 and n_ready = '0' and out_ready = '0') then
                     lower<=int_bus1(31 downto 0);
                     higher<=int_bus1(63 downto 32);
                     n_ready <= '1';
                     start_again <= '1';
                 end if;
          end if; 



          if (n_ready ='1') then
          -- base encryption step
             if (rising_edge(clk)) then
             if (j <32 and start_again = '1') then
             -- key/step dependence
                 curr_key <= tab_key(key_it(j));
                k_ready <= '1';
                start_again <= '0';
             end if;   

             if (k_ready = '1') then 
                    lower <= curr_key + lower;
                    k_added <= '1';
                    k_ready <='0';
             end if;

             if (k_added = '1') then
                    --block substitution
                    lower(3 downto 0) <= tab(CONV_INTEGER(lower(3 downto 0)))(3 downto 0);
                    lower(7 downto 4) <= tab(CONV_INTEGER(lower(7 downto 4)))(7 downto 4);
                    lower(11 downto 8) <= tab(CONV_INTEGER(lower(11 downto 8)))(11 downto 8);
                    lower(15 downto 12) <= tab(CONV_INTEGER(lower(15 downto 12)))(15 downto 12);
                    lower(19 downto 16) <= tab(CONV_INTEGER(lower(19 downto 16)))(19 downto 16);
                    lower(23 downto 20) <= tab(CONV_INTEGER(lower(23 downto 20)))(23 downto 20);
                    lower(27 downto 24) <= tab(CONV_INTEGER(lower(27 downto 24)))(27 downto 24);
                    lower(31 downto 28) <= tab(CONV_INTEGER(lower(31 downto 28)))(31 downto 28);
                    sub_ready <= '1';
                    k_added <= '0';
             end if;    

             if (sub_ready = '1') then
                  --shift 11 bits right cyclically
                    lower(31 downto 21) <= lower(10 downto 0);
                    lower(20 downto 0) <= lower(31 downto 11);
                    sh_ready<= '1';
                    sub_ready <= '0';
             end if;

             if (sh_ready = '1') then
                    higher <= lower xor higher;
                    lower <= higher;
                    sh_ready<= '0';
                    j:=j+1;
                    start_again <= '1';
                    out_ready <= '0'; 
              end if;
              end if; 
             end if;     

         if (rising_edge(clk)) then
              if (j = 32 and out_ready = '0') then
                j:=j+1;
                variable_test <= '1'; --artifact of testing the behavior of variables
              end if;   


         end if;
          -- assembling output code into one piece
          if (rising_edge(clk)) then  
            if (out_ready = '0' and variable_test = '1') then
                 int_bus2 (63 downto 32) <= higher;
                 int_bus2 (31 downto 0) <= lower;
                 out_ready <= '1';
                 n_ready <= '0';
            end if;

             if (out_ready = '1' and k<8) then
                 out_data<=int_bus2(7 downto 0);
                 sent_data <= '1';
                 if (sent_data ='1') then 
                    --shift right 8 bits 
                     int_bus2(55 downto 0) <= int_bus2(63 downto 8);
                     k := k + 1;
                     sent_data <= '0';
                 end if;
            end if;
         end if;
        end process; 
        end behavioral;

And I'm getting the following errors:

Error (10821): HDL error at decoder10.vhd(106): can't infer register for start_again because its behavior does not match any supported register model
Info (10041): Inferred latch for start_again at decoder10.vhd(75)
Error (10821): HDL error at decoder10.vhd(106): can't infer register for higher[0] because its behavior does not match any supported register model
Info (10041): Inferred latch for higher[0] at decoder10.vhd(75)
(this continues for the first 18 bits of "higher")

Why won't it synthesize? And why can't only first 18 bits of higher be inferred?

Was it helpful?

Solution

It's most probably because your clock enable has higher priority than your clock, and that no FPGA hardware exists that allows this. Whenever you write code for synthesis you need to think about if this can actually map to the underlying hardware. So instead of

if (n_ready ='1') then
  -- base encryption step
  if (rising_edge(clk)) then
    (...)

Try:

if(rising_edge(clk)) then
  if(n_ready = '1') then
    (...)

And have a look at Get your priorities right - it's written for Xilinx FPGAs, but I'd guess that something similar applies to other makes also.

OTHER TIPS

The first answer, by sonicwave is not strictly true in all architectures, though I think it is true in this case.
An if followed by an edge could be implemented by a gated clock, not that doing this is a good idea or is it supported in all types of FPGA or CPLD architecture.

Some tips: change tab and tab_key to constant. They are never assigned so no need for signal. Making them a signal might mean they are unitalised in some architectures.

The entire thing should use processes, instead it is using sequential logic. This is causing the 'inferred latch' error as depending on the path through the code start_again may or may not be written. To avoid inferred latches ensure a signal is written through all paths or clocked inside a process.

You need to remember that VHDL is not a programming language, it is a description language. Unless a system is synchronous all the lines are executed at the same time. e.g. at line 147, you have two lines that manipulate higher and lower at the same time.

If you tell me what you are trying to achieve I can re-write it for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top