Reputation: 109
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
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