------------------------------------------------------------------------------------------
-- Designer : Jerry Wang
-- Date : 2009-3-5
-- Description : Synchronous FIFO created by VHDL
-----------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity SFIFO is
generic(
FIFOwidth : positive :=16;
depth : positive :=45;
almost_empty_value: positive :=5;
almost_full_value: positive :=40
);
port
(
clk : in std_logic;
rst : in std_logic;
wq : in std_logic;
rq : in std_logic;
datain : in std_logic_vector(FIFOwidth - 1 downto 0);
qout : out std_logic_vector(FIFOwidth - 1 downto 0);
almost_empty: out std_logic;
almost_full: out std_logic;
empty : out std_logic;
full : out std_logic
);
end SFIFO;
architecture Behavioral of SFIFO is
------------------------------------
--signal wr_pt: std_logic_vector(15 downto 0); -- writer pointer counter
signal wr_pt: integer range depth-1 downto 0;
-------------------------------------
--signal rd_pt: std_logic_vector(15 downto 0); -- read pointer counter
signal rd_pt: integer range depth-1 downto 0;
--------------------------------------
signal empty_t: std_logic;
signal full_t: std_logic;
--------------------------------------
type ram is array(depth - 1 downto 0) of std_logic_vector(FIFOwidth - 1 downto 0);
signal dualram: ram;
signal addra: integer range depth-1 downto 0;--std_logic_vector(15 downto 0);
signal addrb: integer range depth-1 downto 0;--std_logic_vector(15 downto 0);
signal dataout: std_logic_vector(FIFOwidth - 1 downto 0);
---------------------------------------
signal usedw: integer range depth-1 downto 0;--The number of words that are currently in the FIFO
--signal usedw:std_logic_vector(depth - 1 downto 0);
signal almost_empty_t: std_logic;
signal almost_full_t: std_logic;
begin
-- write_pointer is created----------------------------------
process(rst, clk)
begin
if rst = '1' then
wr_pt <= 0;--(others => '0');
elsif clk'event and clk = '1' then
if wq = '1' and full_t = '0' then
if rd_pt > wr_pt then
if rd_pt - wr_pt >1 then
if wr_pt < depth - 1 then
wr_pt <= wr_pt + 1;
else wr_pt <= 0;
end if;
end if;
--end if;
else
if wr_pt - rd_pt /= depth - 1 then
if wr_pt < depth - 1 then
wr_pt <= wr_pt + 1;
else wr_pt <= 0;
end if;
end if;
end if;
end if;
end if;
end process;
addra <= wr_pt;
---- read_pointer is created -------------------------------------------------------------
process(rst, clk)
begin
if rst = '1' then
rd_pt <= 0;--(others => '0');
elsif clk'event and clk = '1' then
if rq = '1' and empty_t = '0' and rd_pt /= wr_pt then --必须要加最后一个条件,否则读指针不会停止累加。
if rd_pt < depth-1 then
rd_pt <= rd_pt +1;
else rd_pt <= 0;
end if;
end if;
end if;
end process;
addrb <= rd_pt;
-----Calculate the usedw and Generate almost empty and full flag------------------------
process(rst,clk)
begin
if rst = '1' then
usedw <= 0;
elsif clk'event and clk = '1' then
if wq ='1' and rq ='0' and full_t = '0' and usedw < (depth-1) then
usedw <= usedw + 1;
elsif wq = '0' and rq = '1' and empty_t = '0' and usedw >0 then
usedw <= usedw - 1;
else
usedw <= usedw;
end if;
end if;
end process;
process(rst,clk)
begin
if rst = '1' then
almost_empty_t <= '1';
almost_full_t <= '0';
elsif clk'event and clk = '1' then
if usedw <= almost_empty_value then
almost_empty_t <= '1';
else
almost_empty_t <= '0';
end if;
if usedw >= almost_full_value then
almost_full_t <= '1';
else
almost_full_t <= '0';
end if;
end if;
end process;
almost_full <= almost_full_t;
almost_empty <= almost_empty_t;
--FIFO status judge-------------------------------------
process(rst, clk)
begin
if rst = '1' then
empty_t <= '1';
elsif clk'event and clk = '1' then
if wr_pt = rd_pt then
empty_t <= '1';
else
empty_t <= '0';
end if;
end if;
end process;
empty <= empty_t;
process(rst, clk)
begin
if rst = '1' then
full_t <= '0';
elsif clk'event and clk = '1' then
if wr_pt > rd_pt then
if (wr_pt - rd_pt) = depth - 1 then
full_t <= '1';
else
full_t <= '0';
end if;
else
if (wr_pt + 1 ) = rd_pt then
full_t <= '1';
else
full_t <= '0';
end if;
end if;
end if;
end process;
full <= full_t;
-- generate a dual port ram -----------------------------------------------------------------
process(clk)
begin
if clk'event and clk = '1' then
if wq = '1' then
--dualram(conv_integer(addra)) <= datain;
dualram(addra) <= datain;
end if;
--end if;
--end process;
--process(clkb)
--begin
--if clkb'event and clkb = '1' then
if rq = '1' then
--dataout <= dualram(conv_integer(addrb));
dataout <= dualram(addrb);
end if;
end if;
end process;
qout <= dataout;
end Behavioral;
---------------------------------------end of file----------------------------------------------
用户313253 2010-12-27 14:58