Introduction
The ram_dp2 component is a full dual port RAM. Unlike the original ram_dp component, ram_dp2 has two ports which are capable of both reads and writes (ram_dp has one write-only port and another read-only port). Of course, this ability comes at a price-- portability and flexability. The ram_dp2 component is not as portable as the basic ram_dp, and it does not offer as many options.
Component Declaration
The basic component declaration of the Free-RAM dual port module is:
Generic Map
The generic portion of the component has parameters for the number of address and data bits, plus flags to specify read modes and optimization hints. The parameters are:
addr_bits -- The number of bits on the address bus (same for reads and writes).
data_bits -- The number of bits on the data bus (same for reads and writes).
block_type -- Signals to the RAM core what type of RAM should be used.
0 = Automatic, the RAM core decides what is most appropriate.
Note that the ram_dp2 component doesn't have a register_out_flag. The ram_dp2 operates only with synchronous reads.
Also note that while the block_type is defined, it is not currently used. The Free-RAM core will always use the most appropriate RAM type.
Port Map
Aside from the common reset signal, the ram_dp2's two ports are identical so we'll only describe one:
reset -- An asynchronous reset signal.
clk -- The clock used for reads and writes of the port.
we -- The write enable signal (1=enabled).
addr -- The port address bus.
din -- Input data for the port.
dout -- Output data for the port.
Read and Write Timing
The read and write timing is identical to the ram_dp component (assuming that register_out_flag=1).
entity FIFOMXN is
generic(m, n : Positive := 8); --m is fifo depth, n is fifo width
port(RESET, WRREQ, RDREQ, CLOCK : in Std_logic;
DATAIN : in Std_logic_vector((n-1) downto 0);
DATAOUT : out Std_logic_vector((n-1) downto 0);
FULL, EMPTY : inout Std_logic);
end FIFOMXN;
architecture V2 of FIFOMXN is
type Fifo_array is array(0 to (m-1)) of Bit_vector((n-1) downto 0);
signal Fifo_memory : Fifo_array;
signal Wraddr, Rdaddr, Offset : Natural range 0 to (m-1);
signal Rdpulse, Wrpulse, Q1, Q2, Q3, Q4 : Std_logic;
signal Databuffer : Bit_vector((n-1) downto 0);
begin
--pulse synchronisers for WRREQ and RDREQ
--modified for Synplify to a process
sync_ffs : process
begin
wait until rising_edge(CLOCK);
Q1 <= WRREQ;
Q2 <= Q1;
Q3 <= RDREQ;
Q4 <= Q3;
end process;
--concurrent logic to generate pulses
Wrpulse <= Q2 and not(Q1);
Rdpulse <= Q4 and not(Q3);
Fifo_read : process
begin
wait until rising_edge(CLOCK);
if RESET = '1' then
Rdaddr <= 0;
Databuffer <= (others => '0');
elsif (Rdpulse = '1' and EMPTY = '0') then
Databuffer <= Fifo_memory(Rdaddr);
Rdaddr <= (Rdaddr + 1) mod m;
end if;
end process;
Fifo_write : process
begin
wait until rising_edge(CLOCK);
if RESET = '1' then
Wraddr <= 0;
elsif (Wrpulse = '1' and FULL = '0') then
Fifo_memory(Wraddr) <= To_Bitvector(DATAIN);
Wraddr <= (Wraddr + 1) mod m;
end if;
end process;