0

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

11
  • What is the name of your tool chain? What is your target device? By the way: You aren't using a true n-dimmensional array. It's a 1 dimmensional arrary nested in another 1 dimmensional array, nested in another 1 dimmensional array. So actually you are addressing 3 dimmensions. (Integer is already 1 dimmension) Does your target device support falling edge clocks? Commented Aug 24, 2015 at 6:46
  • @Paebbels Quartus II, Altera FLEX10K, yes this is a 1dim of 1 dim of 1 dim array, but still it doesnt' work without that monstrous case. Yes, my device supports falling edge, i do a lot of things on falling edges of other clocks Commented Aug 24, 2015 at 10:26
  • Have you tried to use powers of to for your dimensional sizes: type mem is array (0 to 127) of integer range 0 to 255;? Maybe Quartus has some problems recognizing memory address calculations if it's not a power of 2. Commented Aug 24, 2015 at 12:22
  • @Paebbels Thanks for your answer, but it didn't work, and i have an other array of 0 to 159 of integer range 0 to 255; that actually works fine in other thread Commented Aug 24, 2015 at 12:33
  • Ok, it was just a thought ... Have you tried to reduce the dimensions to only 2 (just for testing) -> do manual address calculation to emulate the third dimension. Another way could be to setup a little example project just with your 3D array and test the synthesis results until you find a way to convince Quartus :). Commented Aug 24, 2015 at 12:48

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.