library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY sc_fifo is
generic (Na : Integer := 4; Nd : Integer := 8);
PORT
(
din : in std_logic_vector(Nd-1 downto 0);
wrreq : in std_logic;
rdreq : in std_logic;
clk : in std_logic;
sclr : in std_logic;
dout : out std_logic_vector(Nd-1 downto 0);
full : out std_logic;
empty : out std_logic
);
end sc_fifo;
architecture a of sc_fifo is
component dp_sram is
generic (Na : Positive := 8;
Nd : positive := 16);
port(
clk : in std_logic;
we : in std_logic;
waddr : in std_logic_vector(Na-1 downto 0);
raddr : in std_logic_vector(Na-1 downto 0);
din : in std_logic_vector(Nd-1 downto 0);
dout : out std_logic_vector(Nd-1 downto 0) );
end component;
signal almost_full : std_logic_vector(Na downto 0);
signal almost_empty : std_logic_vector(Na downto 0);
signal wpointer : std_logic_vector(Na-1 downto 0);
signal rpointer : std_logic_vector(Na-1 downto 0);
signal nwords : std_logic_vector(Na downto 0);
signal fifo_cmd : std_logic_vector( 1 downto 0);
signal fifo_status : std_logic_vector( 1 downto 0);
signal fifo_full : std_logic;
signal fifo_empty : std_logic;
begin
almost_full <= (Na => '0', others => '1');
almost_empty <= (0 => '1', others => '0');
fifo_cmd <= wrreq & rdreq;
fifo_status <= fifo_full & fifo_empty;
process(clk)
begin
if clk'event and clk='1' then
if sclr = '1' then
wpointer <= (others => '0');
rpointer <= (others => '0');
nwords <= (others => '0');
fifo_full <= '0';
fifo_empty <= '1';
else
case fifo_cmd is
when "10" => -- write
if fifo_full='0' then
wpointer <= wpointer+1;
if nwords = almost_full then fifo_full <= '1'; end if;
nwords <= nwords +1;
fifo_empty <= '0';
end if;
when "01" => -- read
if fifo_empty='0' then
rpointer <= rpointer+1;
if nwords = almost_empty then fifo_empty <= '1'; end if;
nwords <= nwords -1;
fifo_full <= '0';
end if;
when "11" => -- read & write
case fifo_status is
when "00" => -- not full, not empty
wpointer <= wpointer+1;
rpointer <= rpointer+1;
when "10" => -- full, not empty
nwords <= nwords -1;
fifo_full <= '0';
when "01" => -- not full, empty
nwords <= nwords +1;
fifo_empty <= '0';
when others => NULL; -- should not happen!!!
end case;
when "00" => NULL;
when others => wpointer <= (others => '-');
rpointer <= (others => '-');
nwords <= (others => '-');
fifo_full <= '-';
fifo_empty <= '-';
end case;
end if;
end if;
end process;
dpr: dp_sram
generic map(
Na => Na,
Nd => Nd)
PORT map(
din => din,
waddr => wpointer,
raddr => rpointer,
we => wrreq,
clk => clk,
dout => dout);
empty <= fifo_empty;
full <= fifo_full;
end;