Add Tercel PHY reset synchronization
[microwatt.git] / fpga / pp_fifo.vhd
1 -- The Potato Processor - A simple processor for FPGAs
2 -- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
3
4 library ieee;
5 use ieee.std_logic_1164.all;
6
7 --! @brief A generic FIFO module.
8 --! Adopted from the FIFO module in <https://github.com/skordal/smallthings>.
9 entity pp_fifo is
10 generic(
11 DEPTH : natural := 64;
12 WIDTH : natural := 32
13 );
14 port(
15 -- Control lines:
16 clk : in std_logic;
17 reset : in std_logic;
18
19 -- Status lines:
20 full : out std_logic;
21 empty : out std_logic;
22
23 -- Data in:
24 data_in : in std_logic_vector(WIDTH - 1 downto 0);
25 data_out : out std_logic_vector(WIDTH - 1 downto 0);
26 push, pop : in std_logic
27 );
28 end entity pp_fifo;
29
30 architecture behaviour of pp_fifo is
31
32 type memory_array is array(0 to DEPTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
33 signal memory : memory_array := (others => (others => '0'));
34
35 subtype index_type is integer range 0 to DEPTH - 1;
36 signal top, bottom : index_type;
37
38 type fifo_op is (FIFO_POP, FIFO_PUSH);
39 signal prev_op : fifo_op := FIFO_POP;
40
41 begin
42
43 empty <= '1' when top = bottom and prev_op = FIFO_POP else '0';
44 full <= '1' when top = bottom and prev_op = FIFO_PUSH else '0';
45
46 read: process(clk)
47 begin
48 if rising_edge(clk) then
49 if reset = '1' then
50 bottom <= 0;
51 else
52 if pop = '1' then
53 data_out <= memory(bottom);
54 bottom <= (bottom + 1) mod DEPTH;
55 end if;
56 end if;
57 end if;
58 end process read;
59
60 write: process(clk)
61 begin
62 if rising_edge(clk) then
63 if reset = '1' then
64 top <= 0;
65 else
66 if push = '1' then
67 memory(top) <= data_in;
68 top <= (top + 1) mod DEPTH;
69 end if;
70 end if;
71 end if;
72 end process write;
73
74 set_prev_op: process(clk)
75 begin
76 if rising_edge(clk) then
77 if reset = '1' then
78 prev_op <= FIFO_POP;
79 else
80 if push = '1' and pop = '1' then
81 -- Keep the same value for prev_op
82 elsif push = '1' then
83 prev_op <= FIFO_PUSH;
84 elsif pop = '1' then
85 prev_op <= FIFO_POP;
86 end if;
87 end if;
88 end if;
89 end process set_prev_op;
90
91 end architecture behaviour;