Here we present a simple RAM model, written in a style that maximises its usefulness.
To achieve this, no signal sizes are fixed in the description; unconstrained ports and use of array attribute allow the easy re-use of this memory.
Conceptually, the RAM's address is used as an index into the memory array. The array is declared as an integer-indexed array, but the address port is modelled as a std_logic_vector signal. Type mismatch! To get round this we use the to_integer function from IEEE package numeric_std. But this requires an argument of either signed or unsigned type, so we first convert the std_logic_vector value to unsigned.
This memory also displays write-before-read behaviour, common in static memories. What is that? It means that during a write-cycle the data being returned is the same as that being written. Without this, the data returned through the dataout port would be the data just being overwritten. Not ideal.
This model synthesises into internal block memories in the majority of FPGA architectures.
To summarise the key code points from this RAM model, we have:
You are welcome to use the source code we provide but you must keep the copyright notice with the code (see the Notices page for details).
-- Simple generic RAM Model -- -- +-----------------------------+ -- | Copyright 2008 DOULOS | -- | designer : JK | -- +-----------------------------+ library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.Numeric_Std.all; entity sync_ram is port ( clock : in std_logic; we : in std_logic; address : in std_logic_vector; datain : in std_logic_vector; dataout : out std_logic_vector ); end entity sync_ram; architecture RTL of sync_ram is type ram_type is array (0 to (2**address'length)-1) of std_logic_vector(datain'range); signal ram : ram_type; signal read_address : std_logic_vector(address'range); begin RamProc: process(clock) is begin if rising_edge(clock) then if we = '1' then ram(to_integer(unsigned(address))) <= datain; end if; read_address <= address; end if; end process RamProc; dataout <= ram(to_integer(unsigned(read_address))); end architecture RTL;
To download the VHDL source code for this model, click here.