Ivan I. Ovchinnikov
Ivan I. Ovchinnikov

Reputation: 109

VHDL: error while working with two dimensional array

I have a two dimensional array, I call it Memory.

type mem is array (0 to 79) of integer range 0 to 255;      -- 80 times by 8 bit 
type dataArray is array (0 to 7) of mem;                    -- 8 arrays of 640bit 
variable Memory: dataArray;                                 -- Here they are

And I have a SLV, answering on some requests, and is represented by integers in that array

inAnsw  :   in STD_LOGIC_VECTOR(7 downto 0);        -- the incoming bus
inVALID :   in STD_LOGIC                            -- the signal

on some incoming signal, that indicates that I have 14 new bytes of data, i have to collect the incoming 12 bytes of that data in my array in a special order. The code looks like this:

    if falling_edge(inVALID) then   -- 14 signals will come         
        bytenum := bytenum + 1;     -- count them to know we 
        if (bytenum = 14) then      -- start every new session with
            bytenum := 0;           -- a zero position
            answmem := answmem + 1; -- increment the array position for  
            if (answmem = 8) then answmem := 0; end if;     -- the next answer
        end if;

-- And here comes the huge problem. i am working with this 
-- huge CASE, that puts a significant answer to the needed place 
-- of my array. it works fine, but it takes more than 1500 logic 
-- cells of my FPGA. 

        case bytenum is
            when 0 => Memory(answmem)(0) := TO_INTEGER(unsigned(inAnsw));               
            when 1 => Memory(answmem)(7) := TO_INTEGER(unsigned(inAnsw));
            when 2 => Memory(answmem)(9) := TO_INTEGER(unsigned(inAnsw));
            when 3 => Memory(answmem)(10) := TO_INTEGER(unsigned(inAnsw));
            when 4 => Memory(answmem)(17) := TO_INTEGER(unsigned(inAnsw));
            when 5 => Memory(answmem)(19) := TO_INTEGER(unsigned(inAnsw));
            when 6 => Memory(answmem)(20) := TO_INTEGER(unsigned(inAnsw));
            when 7 => Memory(answmem)(27) := TO_INTEGER(unsigned(inAnsw));
            when 8 => Memory(answmem)(30) := TO_INTEGER(unsigned(inAnsw));
            when 9 => Memory(answmem)(37) := TO_INTEGER(unsigned(inAnsw));
            when 10 => Memory(answmem)(40) := TO_INTEGER(unsigned(inAnsw));
            when 11 => Memory(answmem)(47) := TO_INTEGER(unsigned(inAnsw));
            when others => Memory(answmem)(67) := TO_INTEGER(unsigned(inAnsw));
        end case;
    end if; 

So if i try to replace the code that writes data with some other constructs, like the following or any other, using IF/ELSIF statements

if (bytenum <12) then
    Memory (answmem)(bytenum+whatever) := TO_INTEGER(UNSIGNED(inAnsw));
end if;

The symbol compilation works fine, and it takes about 100-200 logic cells, but when i start to compile a full project, I have a huge list of compilation errors

Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][0]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][0]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][1]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][1]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][2]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][2]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][3]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][3]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][4]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][4]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][5]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][5]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][6]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][6]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(217): can't infer register for "Memory[7][25][7]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(199): can't infer register for "Memory[7][25][7]" because its behavior does not match any supported register model
Error (10821): HDL error at MyModule.vhd(203): can't infer register for "Memory[7][18][0]" because its behavior does not match any supported register model
Error (10820): Netlist error at MyModule.vhd(199): can't infer register for Memory[7][18][0] because its behavior depends on the edges of multiple distinct clocks
Error (10821): HDL error at MyModule.vhd(203): can't infer register for "Memory[7][18][1]" because its behavior does not match any supported register model

and the list is always the same, a couple of errors about behavior, and one about distinct clock edges

Upvotes: 0

Views: 181

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 28945

All these errors indicate that the behaviour you describe with your code cannot be implemented with hardware resources of your target.

...because its behavior does not match any supported register model

says that the synthesis tool recognized a kind of register but not the kind it can implement.

...because its behavior depends on the edges of multiple distinct clocks

tells you a bit more: you described a multi-clocks register and this is not supported. As Memory is a local variable of your process, your problem comes from lines of the same process that you did not post. For example, if your code is surrounded by:

process(clk,inVALID)
begin
  if rising_edge(clk) then
    if falling_edge(inVALID) then   -- 14 signals will come
      ... your code ...
    end if;
  end if;
end process;

then you have two clocks for your Memory register bank: clk and inVALID and each bit of Memory is supposed to be updated when there is a rising edge of clk and, simultaneously, a falling edge of inVALID.

It can also be some code before or after your code, still in the same process. For example, if your code is preceded or by something like:

  if rising_edge(another_signal) then
    ...
    Memory(x)(y) := value;
    ...
  end if;
  if falling_edge(inVALID) then   -- 14 signals will come
    ... your code ...
  end if;

then, you also have two clocks for your Memory register bank: another_signal and inVALID and each bit of Memory is supposed to be updated either when there is a rising edge of another_signal or/and a falling edge of inVALID, with highest priority to inVALID.

This is too much for all synthesizers I know.

Upvotes: 2

Related Questions