Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16597 Discussions

Automatic use of internal block RAMs

PElm
Beginner
1,802 Views

I'm translating code from Xilinx devices to Intel to see if we could switch to Altera FPGAs.

Xilinx tools automatically translate VHDL memory operations to block-ram without need to use macros or components.

This make it very simple to have a common code base for different FPGA-families.

 

The following code works for all xilinx devices. The result is 1 block ram.

However when I do this in Quartus the result is a lot of logic. 

 

Can I force it somehow to use block ram or can I write different. I do not want to use megafunctions or device specific component etc if not necessary.

 

 

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;   entity MemStd is port ( Clk : in std_logic; Reset : in std_logic; DOA : out std_logic_vector( 8 downto 0); ADDRA : in std_logic_vector(10 downto 0); ADDRB : in std_logic_vector(10 downto 0); DIB : in std_logic_vector( 8 downto 0); WEB : in std_logic ); end entity;   architecture IMPL of MemStd is -- Shared memory type mem_t is array ( 0 to (2**11)-1 ) of std_logic_vector(9-1 downto 0); shared variable mem : mem_t := ( '0'&x"12",'0'&x"12",'0'&x"13",'0'&x"14",'0'&x"55",'0'&x"66 ",'1'&x"77",'1'&x"88", '1'&x"FF",'1'&x"88",'1'&x"12",'1'&x"11",'0'&x"11",'0'&x"00",'0'&x"12",'0'&x"15", '0'&x"12",'0'&x"12",'0'&x"13",'0'&x"14",'0'&x"55",'0'&x"66 ",'1'&x"77",'1'&x"88", '1'&x"FF",'1'&x"88",'1'&x"12",'1'&x"11",'1'&x"11",'1'&x"00",'1'&x"12",'1'&x"15", '0'&x"12",'0'&x"12",'0'&x"13",'0'&x"14",'0'&x"55",'0'&x"66 ",'0'&x"77",'0'&x"88", -- Rest of memory init... ,others=>"000000000"); begin -- Port A Write WRP : process(Clk) begin if rising_edge(Clk) then if(WEB='1') then mem(conv_integer(ADDRB)) := DIB; end if; end if; end process; -- Port B Read process(Clk) begin if rising_edge(Clk) then DOA <= mem(conv_integer(ADDRA)); end if; end process; end IMPL;

 

0 Kudos
8 Replies
Daixiwen
New Contributor I
832 Views

You will find recommended ways of describing memory in hdl in this document: https://www.intel.com/content/www/us/en/programmable/documentation/sbc1513987577203.html#mwh1409959579089

If you don't stick to the guide, sometimes it works and sometimes it doesn't. AFAIK shared variables are only used in Quartus to describe memories with dual clocks.

Tricky
New Contributor II
832 Views

Using a shared variable implies write-before-read behaviour. Historically Altera could only infer read-before-write behaviour and if you needed write-before-read it had to be done using an altsyncram with the appropriate generic.

 

It now appears that write-before-read can be infered, but using a variable in a single process, rather than a shared variable over 2 processes.

 

To be safe, Both Xilinx and Altera will always infer a ram using a signal rather than shared variable.

PElm
Beginner
832 Views

@Daixiwen​ @Tricky​ 

I changed to using signals instead and read/write in the same process.

It works fine and one memory is created. However this only works when I'm not initializing the memory content. Then everything becomes logic again.

I don't understand how Altera want me to write the initialization of the memory content in VHDL.

0 Kudos
Tricky
New Contributor II
832 Views

Intel should accept initialisation just like Xilinx. What family are you targetting?

0 Kudos
Daixiwen
New Contributor I
832 Views

According to the "Specifying Initial Memory Contents at Power-Up

" chapter in the document https://www.intel.com/content/www/us/en/programmable/documentation/sbc1513987577203.html#mwh1409959590153 , the recommended way to initialize the memory is to give a default value to the signal. Check if there is any sublte difference between your code and the example given by altera that could confuse the synthesizer.

0 Kudos
PElm
Beginner
832 Views

@Tricky​ I use Max10

0 Kudos
corestar
New Contributor I
832 Views

If you right-click in a VHDL windows, there is an "Insert Template" option that can be useful. There is a ROM example.

 

I've used the memory initialization and it works within limits. The templates use functions.

 

 

Just a side note, for VHDL 2008, instead of:

'1'&x"12"

you could use:

9x"112"   or   9x"1_12"

 

0 Kudos
corestar
New Contributor I
832 Views

Dear Intel, some of us are really really trying to use the forums you made a mess of, but I'm awfully tired of hitting "Show More" and "Latest Posts" instead of "Top Posts".

0 Kudos
Reply