summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/port_fifo.vhd
blob: ff8c93a99423ed5c71f1625d6cb907f0e3e9de1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity port_fifo is
generic (
        BITS : integer := 14
);
port (
        reset : in std_logic;

        rd_clk : in std_logic;
        rd_read : in std_logic;
        rd_data : out std_logic_vector(63 downto 0);
        rd_empty : out std_logic;
        rd_count : out std_logic_vector(BITS downto 0);

        wr_clk : in std_logic;
        wr_write : in std_logic;
        wr_data : in std_logic_vector(63 downto 0);
        wr_full : out std_logic;
        wr_count : out std_logic_vector(BITS downto 0)
);
end port_fifo;

architecture arch of port_fifo is

        component data_fifo port (
                rst : in std_logic;
                rd_clk : in std_logic;
                rd_en : in std_logic;
                dout : out std_logic_vector(63 downto 0);
                empty : out std_logic;
                rd_data_count : out std_logic_vector(BITS downto 0);
                wr_clk : in std_logic;
                wr_en : in std_logic;
                din : in std_logic_vector(63 downto 0);
                full : out std_logic;
                wr_data_count : out std_logic_vector(BITS downto 0)
        );
        end component;

        signal raw_read : std_logic;
        signal raw_data : std_logic_vector(63 downto 0);
        signal raw_empty : std_logic;
        signal raw_count : std_logic_vector(BITS downto 0);

        signal has_extra : std_logic;
        signal extra : std_logic_vector(63 downto 0);
begin
        rd_data <= extra when has_extra = '1' and rd_read = '0' else raw_data;
        rd_empty <= '0' when has_extra = '1' and rd_read = '0' else '1';
        rd_count <= std_logic_vector(unsigned(raw_count) + 1) when has_extra = '1' and rd_read = '0' else raw_count;

        raw_read <= '0' when has_extra = '1' and rd_read = '0' else '1';

        process (rd_clk, reset)
        begin
                if reset = '1' then
                        has_extra <= '0';
                        extra <= (others => '0');

                elsif rising_edge(rd_clk) then
                        if has_extra = '1' then
                                if rd_read = '1' then
                                        has_extra <= not raw_empty;
                                        extra <= raw_data;
                                end if;
                        else
                                if rd_read = '0' then
                                        has_extra <= not raw_empty;
                                        extra <= raw_data;
                                end if;
                        end if;
                end if;
        end process;

        fifo : data_fifo port map (
                rst => reset,

                rd_clk => rd_clk,
                rd_en => raw_read,
                dout => raw_data,
                empty => raw_empty,
                rd_data_count => raw_count,

                wr_clk => wr_clk,
                wr_en => wr_write,
                din => wr_data,
                full => wr_full,
                wr_data_count => wr_count
        );
end arch;