1 library ieee; 2 use ieee.std_logic_1164.all; 3 use ieee.std_logic_unsigned.all; 4 5 entity fifo is 6 port ( 7 reset, clk, r, w : in std_logic; 8 empty, full : out std_logic; 9 d : in std_logic_vector(7 downto 0); 10 q : out std_logic_vector(7 downto 0)); 11 end fifo; 12 13 architecture rtl of fifo is 14 constant m : integer := 8; 15 constant n : integer := 8; 16 signal rcntr, wcntr : std_logic_vector(2 downto 0); 17 subtype wrdtype is std_logic_vector(n - 1 downto 0); 18 type regtype is array(0 to m - 1) of wrdtype; 19 signal reg : regtype; 20 signal rw : std_logic_vector(1 downto 0); 21 signal full_buf, empty_buf : std_logic; 22 begin 23 rw <= r & w; 24 seq : process(reset, clk) 25 begin 26 if reset = '1' then 27 rcntr <= (others => '0'); 28 wcntr <= (others => '0'); 29 empty_buf <= '1'; 30 full_buf <= '0'; 31 for j in 0 to m - 1 loop 32 reg(j) <= (others => '0'); 33 end loop; 34 elsif falling_edge(clk) then 35 case rw is 36 when "11" => 37 -- read and write at the same time 38 rcntr <= rcntr + 1; 39 wcntr <= wcntr + 1; 40 reg(conv_integer(wcntr)) <= d; 41 when "10" => 42 -- only read 43 if empty_buf = '0' then 44 -- not empty 45 if (rcntr + 1) = wcntr then 46 empty_buf <= '1'; 47 end if; 48 rcntr <= rcntr + 1; 49 end if; 50 full_buf <= '0'; 51 when "01" => 52 -- only write 53 empty_buf <= '0'; 54 if full_buf = '0' then 55 -- not full 56 reg(conv_integer(wcntr)) <= d; 57 if (wcntr + 1) = rcntr then 58 full_buf <= '1'; 59 end if; 60 wcntr <= wcntr + 1; 61 end if; 62 when others => 63 null; 64 end case; 65 end if; 66 end process; 67 68 q <= reg(conv_integer(rcntr)); 69 full <= full_buf; 70 empty <= empty_buf; 71 end rtl;