]> rtime.felk.cvut.cz Git - fpga/uart.git/blob - fifo.vhd
Resets changed from asynchronous to synchronous.
[fpga/uart.git] / fifo.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5
6 --------------------------------------------------------------------------------
7 -- This is a behavioral model of FIFO (Fisrt In First Out) memory.
8 --
9 -- All operations (except for reset) are synchronous to 'clk' rising edges.
10 -- Reset makes fifo empty but actually does not change the content of memory.
11 --
12 -- The generic parameter 'width' determines the width of address vector used to
13 -- access memory and so the size of memory.
14 --
15 -- When overflow occurs, the 'overflow' flag is set to 1 and the least recent
16 -- data is rewritten by new data.
17 --
18 -- Underflow is not handled currently and causes misfunction.
19 --------------------------------------------------------------------------------
20
21 entity fifo is
22   generic (
23     width : integer := 2
24   );
25   port (
26     clk      : in  std_logic;
27     reset    : in  std_logic;
28     we       : in  std_logic;  -- write enable
29     re       : in  std_logic;  -- read enable
30     clear_ow : in  std_logic;  -- clear overflow flag
31     d_in     : in  std_logic_vector (7 downto 0);
32     d_out    : out std_logic_vector (7 downto 0);
33     full     : out std_logic;  -- fifo is full
34     hfull    : out std_logic;  -- fifo is half full
35     empty    : out std_logic;  -- fifo is empty
36     overflow : out std_logic := '0'
37   );
38 end fifo;
39
40 --------------------------------------------------------------------------------
41
42 architecture behavioral of fifo is
43
44   subtype mem_addr_t is std_logic_vector (width-1 downto 0);
45   type mem_t is array (3 downto 0) of std_logic_vector (7 downto 0);
46
47   signal memory : mem_t;
48   
49   signal read_addr : mem_addr_t := (others => '0');
50   signal write_addr : mem_addr_t := (others => '0');
51
52   signal length : std_logic_vector (width downto 0) := (others => '0');
53
54   signal full_s : std_logic;
55
56 --------------------------------------------------------------------------------
57
58 begin
59   
60   -- Handling of overflow output signal and internal length signal, storing
61   --   the number of occupied memory positions.
62   process (clk, reset)
63   begin
64     if (rising_edge(clk)) then
65       if (reset = '1') then
66         length <= (others => '0');
67         overflow <= '0';
68
69       else
70         if ((re = '1') and (we = '0')) then
71           length <= length - 1;
72         elsif ((re = '0') and (we = '1')) then
73           if (full_s = '1') then
74             overflow <= '1';
75           else
76             length <= length + 1;
77           end if;
78         end if;
79         
80         if (clear_ow = '1') then
81           overflow <= '0';
82         end if;
83       end if;
84     end if;
85   end process;
86
87
88   -- Handling of address registers and writing to memory.
89   process (clk, reset)
90   begin
91     if (reset = '1') then
92       read_addr <= (others => '0');
93       write_addr <= (others => '0');
94     
95     elsif (rising_edge(clk)) then
96       if (re = '1') then
97         read_addr <= read_addr + 1;
98       end if;
99       
100       if (we = '1') then
101         write_addr <= write_addr + 1;
102         memory (conv_integer(write_addr)) <= d_in;
103         
104         if (full_s = '1') then
105           read_addr <= read_addr + 1;
106         end if;
107       end if;
108     end if;
109   end process;
110   
111 --------------------------------------------------------------------------------
112   
113   d_out <= memory (conv_integer(read_addr));
114   
115   full_s  <= '1' when (length >= 2**width) else '0';
116
117   full  <= full_s;
118   hfull <= '1' when (length >= 2**(width-1)) else '0';
119   empty <= '1' when (length = 0) else '0';
120   
121 end behavioral;
122