====== FIFOs library ======
The FIFOs library consists of the following 2 generic components:
* [[.:fifos#ff_N_W]]: single clocked fifo with N words of W bits each
* [[.:fifos#dff_N_W]]: dual clocked fifo with N words of W bits each
The FIFOs library can be verified with this testbench: [[.:fifos#testbench|test_fifos]]
===== ff_N_W =====
-- ############################################################################
-- # Project : Leonardo CBT-Kernel #
-- # #
-- # Filename : fifos.vhd #
-- # #
-- # Component : ff_N_W : single clocked fifo with N words of W bits #
-- # #
-- # Model : rtl #
-- # #
-- # Designer : S. Theoharis,N. Zervas #
-- # Institute : VLSI Design Lab., University of Patras #
-- # Date : 01.05.1999 #
-- ############################################################################
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.useful_functions.all;
-- ff_N_W Entity Description
entity ff_N_W is
generic(W: INTEGER := 1; --width of FIFO
N: INTEGER := 8; --length of FIFO
K: INTEGER := 2); --threshold for AEF
port(
D: in unsigned(W-1 downto 0);
Q: out unsigned(W-1 downto 0);
RES, CLK, RDEN, WREN: in std_ulogic;
F: buffer std_ulogic :='0';
E: buffer std_ulogic :='1';
HF, AEF: out std_ulogic
);
end ff_N_W;
-- ff_N_W Architecture Description
architecture rtl of ff_N_W is
constant N_2: integer:= N / 2; --N/2
constant L: integer:=log2(N); --ceiling log2(N)
subtype ramword is unsigned (W-1 downto 0);
type rammemory is array (N-1 downto 0) of ramword;
signal ram: rammemory;
signal rcount, wcount: integer range 0 to N-1 :=0;
signal T, S, R: std_ulogic :='0';
begin
Read_Process: process(RES, CLK)
begin
if (RES='0') then
rcount<=0;
Q<=(OTHERS=>'0');
elsif (rising_edge(CLK)) then
if (RDEN='1' and E/='1') then
Q<=ram(rcount);
if(rcount=N-1) then
rcount<=0;
R<='1';
else
rcount<=rcount+1;
R<='0';
end if;
else
R<='0';
end if;
end if;
end process Read_Process;
Write_Process: process(RES, CLK)
begin
if (RES='0') then
wcount<=0;
ram<=(OTHERS=>(OTHERS=>'0'));
elsif (rising_edge(CLK)) then
if (WREN='1' and F/='1') then
ram(wcount)<=D;
if(wcount=N-1) then
wcount<=0;
S<='1';
else
wcount<=wcount+1;
S<='0';
end if;
else
S<='0';
end if;
end if;
end process Write_Process;
Toggle_Process:process(RES, S, R)
begin
if (RES='0') then
T<='0';
elsif (S='1') then
T<='1';
elsif (R='1') then
T<='0';
end if;
end process Toggle_Process;
Flag_Process: process(RES, rcount, wcount, T)
variable rcount_ext, wcount_ext, diff: unsigned(L downto 0);
begin
wcount_ext:='0' & Conv_Unsigned(wcount,L);
rcount_ext:='0' & Conv_Unsigned(rcount,L);
if T='0' then
diff:=wcount_ext-rcount_ext;
else
diff:=Conv_Unsigned(N,L+1)-rcount_ext+wcount_ext;
end if;
if (RES='0') then
E<='1';
F<='0';
elsif diff=Conv_Unsigned(0,L+1) then
E<='1';
F<='0';
elsif diff=Conv_Unsigned(N,L+1) then
E<='0';
F<='1';
else
E<='0';
F<='0';
end if;
if (RES='0') then
HF<='0';
AEF<='1';
else
if (diff>Conv_Unsigned(N_2-1,L+1)) then
HF <= '1';
else
HF <= '0';
end if;
if (diffConv_Unsigned(N-K,L+1)) then
AEF <= '1';
else
AEF <= '0';
end if;
end if;
end process Flag_Process;
end rtl;
===== dff_N_W =====
-- ############################################################################
-- # Project : Leonardo CBT-Kernel #
-- # #
-- # Filename : fifos.vhd #
-- # #
-- # Component : dff_N_W : dual clocked fifo with N words of W bits #
-- # #
-- # Model : rtl #
-- # #
-- # Designer : S. Theoharis,N. Zervas #
-- # Institute : VLSI Design Lab., University of Patras #
-- # Date : 01.05.1999 #
-- ############################################################################
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.useful_functions.all;
-- dff_N_W Entity Description
entity dff_N_W is
generic(W: INTEGER := 1; --width of FIFO
N: INTEGER := 8; --length of FIFO
K: INTEGER := 2); --threshold for AEF
port(
D: in unsigned(W-1 downto 0);
Q: out unsigned(W-1 downto 0);
RES, RDCLK, WRCLK, RDEN, WREN: in std_ulogic;
F: buffer std_ulogic :='0';
E: buffer std_ulogic :='1';
HF, AEF: out std_ulogic
);
end dff_N_W;
-- dff_N_W Architecture Description
architecture rtl of dff_N_W is
constant N_2: integer:=N / 2; --N/2
constant L: integer:=log2(N); --ceiling log2(N)
subtype ramword is unsigned (W-1 downto 0);
type rammemory is array (N-1 downto 0) of ramword;
signal ram: rammemory;
signal rcount, wcount: integer range 0 to N-1 :=0;
signal T, S, R: std_ulogic :='0';
begin
Read_Process: process(RES, RDCLK)
begin
if (RES='0') then
rcount<=0;
Q<=(OTHERS=>'0');
elsif (rising_edge(RDCLK)) then
if (RDEN='1' and E/='1') then
Q<=ram(rcount);
if(rcount=N-1) then
rcount<=0;
R<='1';
else
rcount<=rcount+1;
R<='0';
end if;
else
R<='0';
end if;
end if;
end process Read_Process;
Write_Process: process(RES, WRCLK)
begin
if (RES='0') then
wcount<=0;
ram<=(OTHERS=>(OTHERS=>'0'));
elsif (rising_edge(WRCLK)) then
if (WREN='1' and F/='1') then
ram(wcount)<=D;
if(wcount=N-1) then
wcount<=0;
S<='1';
else
wcount<=wcount+1;
S<='0';
end if;
else
S<='0';
end if;
end if;
end process Write_Process;
Toggle_Process:process(RES, S, R)
begin
if (RES='0') then
T<='0';
elsif (S='1') then
T<='1';
elsif (R='1') then
T<='0';
end if;
end process Toggle_Process;
Flag_Process: process(RES, rcount, wcount, T)
variable rcount_ext, wcount_ext, diff: unsigned(L downto 0);
begin
wcount_ext:='0' & Conv_Unsigned(wcount,L);
rcount_ext:='0' & Conv_Unsigned(rcount,L);
if T='0' then
diff:=wcount_ext-rcount_ext;
else
diff:=Conv_Unsigned(N,L+1)-rcount_ext+wcount_ext;
end if;
if (RES='0') then
E<='1';
F<='0';
elsif diff=Conv_Unsigned(0,L+1) then
E<='1';
F<='0';
elsif diff=Conv_Unsigned(N,L+1) then
E<='0';
F<='1';
else
E<='0';
F<='0';
end if;
if (RES='0') then
HF<='0';
AEF<='1';
else
if (diff>Conv_Unsigned(N_2-1,L+1)) then
HF <= '1';
else
HF <= '0';
end if;
if (diffConv_Unsigned(N-K,L+1)) then
AEF <= '1';
else
AEF <= '0';
end if;
end if;
end process Flag_Process;
end rtl;
===== Testbench =====
-- ############################################################################
-- # Project : Leonardo CBT-Kernel #
-- # #
-- # Filename : test_fifos.vhd #
-- # #
-- # Component : test_fifos : Test Bench for various FIFOs #
-- # #
-- # Model : rtl #
-- # #
-- # Designer : S. Theoharis,N. Zervas #
-- # Institute : VLSI Design Lab., University of Patras #
-- # Date : 01.05.1999 #
-- ############################################################################
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity test_fifos IS
END test_fifos;
ARCHITECTURE rtl OF test_fifos IS
COMPONENT ff_N_W is
generic(W: INTEGER := 1; --width of FIFO
N: INTEGER := 8; --length of FIFO
K: INTEGER := 2); --threshold for AEF
port(
D: in unsigned(W-1 downto 0);
Q: out unsigned(W-1 downto 0);
RES, CLK, RDEN, WREN: in std_ulogic;
F: buffer std_ulogic :='0';
E: buffer std_ulogic :='1';
HF, AEF: out std_ulogic
);
end COMPONENT;
COMPONENT dff_N_W is
generic(W: INTEGER := 1; --width of FIFO
N: INTEGER := 8; --length of FIFO
K: INTEGER := 2); --threshold for AEF
port(
D: in unsigned(W-1 downto 0);
Q: out unsigned(W-1 downto 0);
RES, RDCLK, WRCLK, RDEN, WREN: in std_ulogic;
F: buffer std_ulogic :='0';
E: buffer std_ulogic :='1';
HF, AEF: out std_ulogic
);
end COMPONENT;
FOR ALL : ff_N_W USE ENTITY WORK.ff_N_W(rtl);
FOR ALL : dff_N_W USE ENTITY WORK.dff_N_W(rtl);
CONSTANT N : integer := 16;
CONSTANT W : integer := 8;
CONSTANT K : integer := 12;
SIGNAL DIN1,DIN2,DOUT1,DOUT2 : unsigned(W-1 downto 0);
SIGNAL RESET,CLK,RDEN,WREN,F1,E1,HF1,AEF1,F2,E2,HF2,AEF2 : std_ulogic := '0';
BEGIN
Single_Fifo : ff_N_W
GENERIC MAP (
W=>W,
N=>N,
K=>K
)
PORT MAP (
D=>DIN1,
Q=>DOUT1,
RES=>RESET,
CLK=>CLK,
RDEN=>RDEN,
WREN=>WREN,
F=>F1,
E=>E1,
HF=>HF1,
AEF=>AEF1
);
Dual_Fifo : dff_N_W
GENERIC MAP (
W=>W,
N=>N,
K=>K
)
PORT MAP (
D=>DIN2,
Q=>DOUT2,
RES=>RESET,
RDCLK=>CLK,
WRCLK=>CLK,
RDEN=>RDEN,
WREN=>WREN,
F=>F2,
E=>E2,
HF=>HF2,
AEF=>AEF2
);
CLK <= not CLK AFTER 50 ns;
RESET <= '0', '1' AFTER 120 ns;
RDEN <= '0', '1' AFTER 1500 ns;
WREN <= '1', '0' AFTER 1500 ns;
PROCESS(RESET,CLK)
BEGIN
IF (RESET='0') THEN
DIN1 <= (OTHERS=>'0');
DIN2 <= (OTHERS=>'1');
ELSIF (rising_edge(CLK)) THEN
DIN1 <= DIN1 + "1";
DIN2 <= DIN2 - "1";
END IF;
END PROCESS;
END rtl;