RAM is a useful thing to have when you need to store bits of information for later, the code below is for a simple, single port write first, RAM module and test bench. This may seem like a great bit of code to have lying around, but in reality it’s more for educational purposes. If you were actually going to use a RAM module like the one below you should really use a RAM generator from the manufacture of what ever device you are using ie: Xilinx, Altera, Lattice… These generated module are designed to take advantage of special RAM blocks built into the FPGA which allows them to be fast and efficient.
The function of this module is simple, by changing the address bits Address you can then read, on the next clock cycle, the data that is present at that memory location on the DataOut pins. In order to write data to a specific memory location you simply supply the data and address to the DataIn and Address lines respectively and then toggle the write enable WriteEn high for one clock cycle. The Enable bit is a global enable that prevents any actions from happening if the pin is low.
To change the width and depth of this module you only need to change the two generics at the top of the module. The DATA_WIDTH controls how many bits are in the input and out data. To adjust how many memory locations are in the RAM module you need to adjust the address width ADDRESS_WIDTH, this controls how many bits are in the address input and the number of RAM location will be spots. For example if you have an address width of 8, like below, you would be able to read 256 different memory locations.
Code
VHDL
Test Bench
Change Log
7/6/2013: Removed need for ADDR_COUNT generic. Updated port and generic names for consistency.
thanks sir……………………..
Wow, thank you for sharing this.
Thank you sir,
Can you share DDS operation with Example Design?
Hello
when I describe a RAM with reset pin to clear whole the ram, synthesis tool (xilinx ISE) doesn’t accept my describe as a Block RAM. It uses a lot of FF/Latch (flip flop) and warns me.
when I remove this part of code:
if Reset = ‘1’ then
— Clear Memory on Reset
for i in Memory’Range loop
Memory(i) ‘0’);
end loop;
rest of the code will be accepted as a Block RAM, but not useful for my usage.
Can U help me?
Thanks a lot!!!!
is this the code for “ram 8 locations each of 6 bits???
The default for this RAM is 256 locations each of 8 bits. It can be adjusted to 8 locations each of 6 bits by changing ADDRESS_WIDTH to 3 and DATA_WIDTH to 6.
sir please can share me true dual port RAM WITH SINGLE clcok its urgent
If it’s urgent I would suggest using a pre-made core from someplace like http://opencores.org. I would not have the time to quickly write and verify a new module for you.
Query 1
Is it possible to use my generic variables DIN_WIDTH and ADDR_WIDTH in the signal declaration lines below?
signal Din : std_logic_vector(DIN_WIDTH downto 0) := (others => ‘0’);
signal Addr : std_logic_vector(ADDR_WIDTH downto 0) := (others => ‘0’);
instead of
signal Din : std_logic_vector(7 downto 0) := (others => ‘0’);
signal Addr : std_logic_vector(4 downto 0) := (others => ‘0’);
In this case, do I need to declare these generics again as constants before my signal declarations? i.e.,
constant DIN_WIDTH : integer := 8;
constant ADDR_WIDTH : integer := 5;
constant ADDR_COUNT : integer := 32;
followed by signal declarations, generic map and port map?
Query 2
Is it possible to do the generic mapping without giving value to the constants declared? i.e.,
COMPONENT RAM
GENERIC (
DIN_WIDTH : integer := 8;
ADDR_WIDTH : integer := 5;
ADDR_COUNT : integer := 32
);
……………….
END COMPONENT;
***generic constant declaration before signal declaration but without giving value to the constant variable***.
constant DIN_WIDTH: integer ;
constant ADDR_WIDTH: integer ;
constant ADDR_COUNT: integer ;
–Inputs
signal CLK : std_logic := ‘0’;
…………….
BEGIN
— Instantiate the Unit Under Test (UUT)
uut: RAM
generic map (DIN_WIDTH => DIN_WIDTH;
ADDR_WIDTH => ADDR_WIDTH ;
ADDR_COUNT => ADDR_COUNT);
something like this?
I want to change DIN_WIDTH, ADDR_WIDTH, ADDR_COUNT only in the generics not in the constant declaration. Is it possible?
If you declare a constant (or a generic for the module your in) before the signal declaration you can use it in the signal declaration, component declaration and instantiation.
Entity test_bench is
Generic (
constant DIN_WIDTH : integer := 8;
…
End test_bench;
Architecture behavior of test_bench is
Constant ADDR_WIDTH : integer := 5;
Component RAM is…
End component;
Begin
uut : RAM
generic map (
DIN_WIDTH := DIN_WIDTH,
ADDR_WIDTH := ADDR_WIDTH);
port map (
….