-- ############################################################################ -- # 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;