# FPGA RAM / SRAM in VHDL

Today I ran out of gates on my Xylinx Spartan 3 (Basys2 by Digilent) FPGA.

This was not a surprise to me as I had implemented an 8 bit x 2048 array for use as an FIFO buffer.

Code: type MEMORY is array(0 to (MEM_L - 1)) of std_logic_vector(7 downto 0);

where MEM_L is an integer, value 2048.

I read through the product brief, and as I understand it there is 72 kB of bi-directional RAM on Spartan 3E series FPGA's.

However I do not know how to use it (program it) using VHDL. How would I go about declaring that I want some data to be stored in RAM memory?

Initially I assumed the use of RAM was up to the compiler (synthesizer and implementer tools) and that I was not able to control how it was used directly, however I suspect that I was wrong in this assumption, because the implementation process failed due to my FIFO being too large for the number of gates supported. (Approx 100 k gates.)

I should add that I wasn't able to find an answer through google, perhaps I didn't know quite what to search for?

EDIT: That should have said 78 kb of ram, 78000 bits.

The most straightforward thing to do (IMO) is to directly instantiate the device primitive in your VHDL. This way you are not relying on the tools to infer block RAM. In ISE, go to Edit -> Language Templates, and you will be able to bring up the template. (You will want to choose Spartan-3E, of course, although I think the primitive is the same in this case.)

The disadvantage of using the primitive, of course, is that your code is not trivially portable outside of the device family. (For block RAMs, this is not such a big deal since they are very similar across vendors and families.)

Another option is to use the Core Generator, which is perhaps more 'user friendly' to set up, but slow during initial synthesis. You can also generate an entire FIFO this way.

Perhaps someone can speak to methods of inferring block RAM.

• Ah I see, where can I find the information on how to use these devices? I'm guessing I initially create a RAM type by doing something like signal my_ram: RAMB16_S9_S9? Aug 14, 2014 at 18:36
• You will have to reorient your thinking, because this is a module and not a signal entity. The template has instructions for use. Also take a look at XAPP463.
– mng
Aug 14, 2014 at 19:29
• I followed the instructions - I copied the code below the "copy below here" line and pasted it inside the architecture section. The error appears on synthesis: ERROR:HDLParsers:164 - Line 83. parse error, unexpected IDENTIFIER This is due to the line: RAMB16_S9_S9_inst : RAMB16_S9_S9 which is followed by generic map ( ... Any ideas? Aug 21, 2014 at 14:10
• @user3728501, that sounds like a syntax error. But make sure you've put in the UNISIM library lines too.
– mng
Aug 21, 2014 at 18:26
• Yeah I did that, literally just copied it but Ill try again Aug 21, 2014 at 19:01

XST can automatically infer RAM blocks.

Read Xilinx's "XST User Guide" ref. UG627

"Dual-Port RAM With Synchronous Read (Read Through)"

architecture syn of rams_11 is
type ram_type is array (63 downto 0) of std_logic_vector (15 downto 0);
signal RAM : ram_type;
signal read_a : std_logic_vector(5 downto 0);
signal read_dpra : std_logic_vector(5 downto 0);
begin
process (clk)
begin
if (clk’event and clk = ’1’) then
if (we = ’1’) then
RAM(conv_integer(a)) <= di;
end if;