Forum Discussion
RAM inference not working for initialized RAM
According to documentation RAM initialization should work in VHDL by simply adding an initialization value to the memory array.
However, In my code (see attached), this is not the case. Without initialization value (resp. with initializing all content to zero) the code infers 8kb RAM - so the syntax seems fine for RAM inference. As soon as I add any other initialization content than zeros, registers are inferred (not RAM).
I have attached my code containing both cases.
With line 109 uncommented, RAM inferrence works:
With line 108 uncommented, RAM inferrence fails:
signal Mem_v : Data_t(Depth_g - 1 downto 0) := (0 => x"1234", 1 => x"5678", others => (others => '0'));
Why is RAM inference not working? What can I do to make it work?
18 Replies
- FvM
Super Contributor
Hi,
there should be a message telling reason for RAM inference failure.
I can tell that initialization of inferred RAM works for me with init functions.
Are you using MAX10 without RAM initialization feature?- obruendl
New Contributor
@FvM
I couldn't find any message about failed RAM inference in the report. You can find the report here, so you can check yourself.
https://drive.google.com/file/d/1UBp4T_LOryi9wlOndzk2sym02u92Ym-4/view?usp=drive_link
- ShengN_altera
Super Contributor
Hi,
May I know does the code being attached?
Thanks,
Regards,
Sheng
- obruendl
New Contributor
@ShengN_Intel
I attached a ZIP to the forum post - seems like it was dropped silently...
You can get the ZIP with the code from my google-drive: https://drive.google.com/file/d/1RN4Dxybv4DdVjD169ncRZsm_r1JkagAj/view?usp=drive_link - obruendl
New Contributor
I ran some more tests of the same code. It seems like Quartus is pretty much alone in terms of struggling with my code.
Efinity (Efinix), Gowin EDA (Gowin), Vivado (AMD) and Libero (Microchip) all handle the code well. - FvM
Super Contributor
Hi,
I can't recognize/reproduce the issue with given information:
- According to report, block memory is inferred
- Top level entity RamWrp.vhd is missing, thus we can't reproduce actual design implementation with all parameters
Preferably we'll have a .qar project archive availableRegards
Frank - obruendl
New Contributor
The code describes a simple-dual-port memory of 4kbit in size. Yes, some RAM is inferred but in addition to that RAM I see > 7000 registers which I would not be expected. The code really only describes a RAM.
In the meantime a contributor of Open Logic identified that RAM inference works correctly when commenting out the Byte-Enable Logic. See GitHub issue for details: https://github.com/open-logic/open-logic/issues/122
The strange thing is that the configuration of the RAM I use here does not even make use of Byte Enables. Generics are set to not use Byte-Enables - so the logic that breaks inference is unused.
I agree that the files I provided are inconsistent because I tried out a few things. I now archived the project in Quartus (QAR) in two ways:
- The failing version (including byte-enable logic): https://drive.google.com/file/d/13sTr6c7nqkbVoqz2a4C808FaXzsyirUN/view?usp=drive_link- A version with byte-enable logic commented (which does infer RAMs correctly): https://drive.google.com/file/d/10Wbemcy09Xk6Y99eESxcZIhgwJy5aTuf/view?usp=drive_link
- obruendl
New Contributor
I have even more interesting news. I fixed my memory to 16 bits and played with the exact formulations in VHDL.
Below code fails to infer RAM:
for byte in 0 to 1 loop if Wr_Be(byte) = '1' then Mem_v(to_integer(unsigned(Wr_Addr)))(byte * 8 + 7 downto byte *:= Wr_Data(byte * 8 + 7 downto byte * 8); end if; end loop; If I just unroll the loop, RAM is inferred correctly:
if Wr_Be(0) = '1' then Mem_v(to_integer(unsigned(Wr_Addr)))(7 downto 0) := Wr_Data(7 downto 0); end if; if Wr_Be(1) = '1' then Mem_v(to_integer(unsigned(Wr_Addr)))(15 downto:= Wr_Data(15 downto 8); end if; I feel like formulating the very same thing in a loop or unrolled should lead to the same results and if it does not, I'd call this a bug.
Unfortunately I still didn't find a language construct to cleanly work around this bug for parametrizable code - without understanding the root-cause making Quartus to behave different for the two snippets above it is difficult to find one because this (to my understanding) is not a logical issue.
Please provide suggestions how this issue can be worked around. Alternatively I could accept a confirmation of this being a bug that will be fixed in the next release of Quartus. If I know its getting fixed it'd be fine for me to just document that RAM inference for Altera works correctly starting from 25.1. - ShengN_altera
Super Contributor
Hi,
It's not a bug. Just the pro and standard version support different format for RAM byteenable.
The format provided by you is only supported in pro version check this link https://www.intel.com/content/www/us/en/docs/programmable/683082/24-2/ram-with-byte-enable-signals.html
For Standard version link https://www.intel.com/content/www/us/en/docs/programmable/683323/18-1/ram-with-byte-enable-signals.html, have to change to something like below:
if Wr_Be(0) = '1' then
Mem_v(to_integer(unsigned(Wr_Addr)))(7 downto 0) := unsigned(Wr_Data(7 downto 0));
end if;
if Wr_Be(1) = '1' then
Mem_v(to_integer(unsigned(Wr_Addr)))(15 downto
:= unsigned(Wr_Data(15 downto 8)); end if;
Then the ram will be inferred check attached screenshot.
- obruendl
New Contributor
I am - let's say surprised - by the fact that such slight details like supporting loops for BE in memory inference differing between the paid and the free version of Quartus. It's impossible for users to keep track of this...
However, technically you answered the question why inference does not work. The question now is how I shall proceed from here.I am maintaining an Open Source FPGA Standard library - which according to GitHub stars belongs to the most popular ones around (see https://github.com/open-logic/open-logic). Of course I will document that RAM inference might not work for Quartus Standard. However, I would want to verify it to work with Quartus Pro. Would Altera be open to donate a Pro License to the Open Logic project for this purpose?
IMO this would be in the mutual interest of both sides: I'd like to verify RAM inference for Altera devices at least with Quartus Pro. If I do so, users probably are motivated to buy Quartus Pro which is in the interest of Altera.BTW: I ran into other errors with True-Dual-Port RAM inference - but I guess I should try this one with Quartus Pro as well.
- ShengN_altera
Super Contributor
Hi,
You may try with the pro version. The pro version has 30-day evaluation license.
Btw, I had done the testing in pro version and it works well.
Thanks,
Regards,
Sheng
- FvM
Super Contributor
Hi,
despite of license requirements, Pro version is not a solution because you don't have a choice to use either Std/Lite or Pro version for a specific FPGA series.
Although I'm frequently using RAM inference in my code, with both Quartus versions, I must confess that I'm surprised about the observed behaviour. Curiously Quartus infers RAM for 1 bit and registers for the other 15 bits of 16 Bit word in the present example. In fact the problem doesn't occur with Altera suggested RAM coding style.- ShengN_altera
Super Contributor
Hi FvM,
The format supported for Standard and Pro version had been stated in these two documents https://www.intel.com/content/www/us/en/docs/programmable/683082/24-2/ram-with-byte-enable-signals.html (pro) and https://www.intel.com/content/www/us/en/docs/programmable/683323/18-1/ram-with-byte-enable-signals.html (standard)