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;