Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
2,037 Views

How to use M9K Memory Blocks for a large array

Hi everyone, 

 

I have a Problem with implementing a big Array in my design. Quartus always want to use Logic Elements for my array and I don't have a clue how to use Memory Blocks instead. I have a Cyclone IV so I want to use M9K. 

I'm using Quartus II 12.1. 

I'm coding in VHDL and this is the code for my arrays: 

 

type My_Big_Array is array (1631 downto 0) of std_logic_vector (7 downto 0); signal sig_big_array_0 : My_Big_Array := ( others => X"00" ); signal sig_big_array_1 : PMy_Big_Array:= ( others => X"00" ); attribute ramstyle : string; attribute ramstyle of sig_big_array_0 : signal is "M9K"; attribute ramstyle of sig_big_array_1 : signal is "M9K";  

 

I got the attribute-code from here: 

http://quartushelp.altera.com/12.0/mergedprojects/hdl/vhdl/vhdl_file_dir_ram.htm 

 

But the Analysis & Synthesis always tells me: 

Warning (11000): Verilog HDL warning at SomeBigArrays.vhd(92): can't infer memory for variable 'sig_big_array_0' with attribute '"M9K"'. 

Warning (11000): Verilog HDL warning at SomeBigArrays.vhd(92): can't infer memory for variable 'sig_big_array_1' with attribute '"M9K"'. 

 

What am I doing wrong? 

Do I have to enable M9K somewhere else too?
0 Kudos
9 Replies
Highlighted
Valued Contributor III
35 Views

 

--- Quote Start ---  

I guess, you array is too big to be packed in one M9K block. According given example 8x64 bits are packed to one M512 block. And you are trying to put 8x1632 bits to M9K block. But that's just a guess. 

--- Quote End ---  

 

 

You guessed wrong. Quartus is good at deciding how many ram blocks are needed. An array does not infer M9Ks, it infers the altsyncram megafunction block, which can use as many M9Ks as required. The OPs attributes just pass the ramstyle parameter to the altsyncram megafunction, telling it what type of base memory types to use (eg. M9K, MLAB, LUTRAM etc). 

 

To OP: Memories can only be infered if the signal assignments and addressing follow the correct template. Have you read the altera coding guidelines? http://www.altera.co.uk/literature/hb/qts/qts_qii51007.pdf 

You havent posted the whole code, just the type and signal declarations. This tells us nothing about your code. It is likely that the code you have written is not suitable for rams.
0 Kudos
Highlighted
Valued Contributor III
35 Views

 

--- Quote Start ---  

I guess, you array is too big to be packed in one M9K block. According given example 8x64 bits are packed to one M512 block. And you are trying to put 8x1632 bits to M9K block. But that's just a guess. 

--- Quote End ---  

 

 

I played with the size a bit and reduced it down to 8x128 bits. But this didn't solve the problem.
0 Kudos
Highlighted
Valued Contributor III
35 Views

 

--- Quote Start ---  

I played with the size a bit and reduced it down to 8x128 bits. But this didn't solve the problem. 

--- Quote End ---  

 

 

I told you the answer - linas posted wrong information. It's your code, not the declarations, that are the problem.
0 Kudos
Highlighted
Valued Contributor III
35 Views

 

--- Quote Start ---  

You guessed wrong. Quartus is good at deciding how many ram blocks are needed. An array does not infer M9Ks, it infers the altsyncram megafunction block, which can use as many M9Ks as required. The OPs attributes just pass the ramstyle parameter to the altsyncram megafunction, telling it what type of base memory types to use (eg. M9K, MLAB, LUTRAM etc). 

 

To OP: Memories can only be infered if the signal assignments and addressing follow the correct template. Have you read the altera coding guidelines? http://www.altera.co.uk/literature/hb/qts/qts_qii51007.pdf 

--- Quote End ---  

 

 

Well, Altera documents are not very easy to read. And there are only few examples. I try my best to get information out of it, but at the moment I haven't found more on how I should handle my arrays to infer them as Memory Blocks. Any Hints? 

 

 

--- Quote Start ---  

You havent posted the whole code, just the type and signal declarations. This tells us nothing about your code. It is likely that the code you have written is not suitable for rams. 

--- Quote End ---  

 

Too bad I can't give you the whole code. Kind of secret stuff. But I can tell you something about it: 

I have three processes which are using the arrays. 

One process loads the Arrays with data and the other two are reading from them. 

All three Processes have different clocks. 

The two reading processes are accessing one of the two arrays at the same time while the other array is loaded with data.
0 Kudos
Highlighted
Valued Contributor III
35 Views

 

--- Quote Start ---  

Well, Altera documents are not very easy to read. And there are only few examples. I try my best to get information out of it, but at the moment I haven't found more on how I should handle my arrays to infer them as Memory Blocks. Any Hints? 

 

--- Quote End ---  

 

 

Read page 13-13 - "Inferring memory functions from HDL code". I find it rather helpful. But it also helps a lot if you understand the underlying architecture. 

 

 

--- Quote Start ---  

 

Too bad I can't give you the whole code. Kind of secret stuff. But I can tell you something about it: 

I have three processes which are using the arrays. 

One process loads the Arrays with data and the other two are reading from them. 

All three Processes have different clocks. 

The two reading processes are accessing one of the two arrays at the same time while the other array is loaded with data. 

--- Quote End ---  

 

 

 

Theres the problem. The memories on the board are dual ported - hence only 2 clocks allowed. And 3 processes does not follow the guidlines (2 processes, 1 for each port if they are separate clocks).  

If you could post the code, then we could help further. Why not just make a new file with just the ram in it thats causing the problem and post that. I promise you, ram inference is not that secret and what you are doing has probably been done many times before.
0 Kudos
Highlighted
Valued Contributor III
35 Views

OK, in that case I try to double my arrays. The writing process must then write two arrays with the same data and then I use one Array for reading process 1 and the other array for reading process 2. 

This will double the needed size of M9K, but that is not my problem. My Problem are the Logic Elements. And when I get the arrays by this way into the Memory, well, problem fixed. 

Thank you, I will post the result.
0 Kudos
Highlighted
Valued Contributor III
35 Views

Its very difficult to understand what you're doing without code. Why have you got 3 clocks? are you using the memories as a clock domain crossing (good thing)? 

If you dont understand the architecure properly, instead of infering rams, you may be better off using the megawizard altsyncram components.
0 Kudos
Highlighted
Valued Contributor III
35 Views

It's all about clock crossing. The arrays are loaded with the pcie clock. 

One Output is fed by a transmit clock and the other by a receive clock. The datas must be repeated by another device and checked bit-wise to ensure they are received properly.
0 Kudos
Highlighted
Valued Contributor III
35 Views

Yes, I made it!!!!! 

 

I had to solve some issues in my Design, but now the Arrays are in M9K Memory: 

- In my Write-Process I had an asynchronous Reset which set the whole Arrays to "00" --> Reset for Arrays removed 

- Also in the Write-Process I loaded the Array with 64Bit --> Reduced to 8Bit at a higher loading clock 

- I read from one array with two processes --> I doubled every array and now I write the same data to two arrays. Every read-process now has its own array to read from. 

 

Well thats it. By this way I reduced the needed amount of LEs by 20.000!!!! 

 

Thank you Tricky for the hints! Although you didn't see my Code.
0 Kudos