OpenCores
URL https://opencores.org/ocsvn/bw_tiff_compression/bw_tiff_compression/trunk

Subversion Repositories bw_tiff_compression

[/] [bw_tiff_compression/] [trunk/] [DualClkFIFO.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 amulder
----------------------------------------------------------------------------------
2
-- Company:        
3
-- Engineer:        Aart Mulder
4
-- 
5
-- Create Date:    12:56:08 01/02/2013 
6
-- Design Name: 
7
-- Module Name:    DualClkFIFO - Behavioral 
8
-- Project Name:         CCITT4
9
--
10
-- Description:    This design describes a dual clock FIFO.
11
--                 The value of MEMORY_SIZE_G must be equal to 2^MEMORY_ADDRESS_WIDTH
12
--                 The empty_o
13
--
14
-- Revision: 
15
-- Revision 0.01 - File Created
16
----------------------------------------------------------------------------------
17
library IEEE;
18
use IEEE.STD_LOGIC_1164.ALL;
19
use IEEE.NUMERIC_STD.ALL;
20
 
21
entity DualClkFIFO is
22
        Generic (
23
                DATA_WIDTH_G           : integer := 51;
24
                MEMORY_SIZE_G          : integer := 16;
25
                MEMORY_ADDRESS_WIDTH_G : integer := 4
26
        );
27
        Port (
28
                rst_i    : in  STD_LOGIC;
29
                wr_clk_i : in  STD_LOGIC;
30
                rd_clk_i : in  STD_LOGIC;
31
                empty_o  : out STD_LOGIC;
32
                full_o   : out STD_LOGIC;
33
                pull_i   : in  STD_LOGIC;
34
                valid_o  : out STD_LOGIC;
35
                push_i   : in  STD_LOGIC;
36
                used_o   : out UNSIGNED(MEMORY_ADDRESS_WIDTH_G-1 downto 0);
37
                d_i      : in  STD_LOGIC_VECTOR(DATA_WIDTH_G-1 downto 0);
38
                d_o      : out STD_LOGIC_VECTOR(DATA_WIDTH_G-1 downto 0)
39
        );
40
end DualClkFIFO;
41
 
42
architecture Behavioral of DualClkFIFO is
43
        signal valid : std_logic := '0';
44
        signal used, wr_addr, rd_addr : unsigned(MEMORY_ADDRESS_WIDTH_G-1 downto 0) := (others => '0');
45
        signal data_out, data_out_cache : std_logic_vector(DATA_WIDTH_G-1 downto 0) := (others => '0');
46
begin
47
        DualClkRAM_ins : entity work.DualClkRAM
48
        GENERIC MAP (
49
                DATA_WIDTH_G => DATA_WIDTH_G,
50
                MEMORY_SIZE_G  => MEMORY_SIZE_G,
51
                MEMORY_ADDRESS_WIDTH_G => MEMORY_ADDRESS_WIDTH_G
52
        )
53
        PORT MAP (
54
                wr_clk_i => wr_clk_i,
55
                rd_clk_i => rd_clk_i,
56
                wr_en_i => '1',
57
                rd_en_i => '1',
58
                rd_i => pull_i,
59
                wr_i=> push_i,
60
                rd_addr_i => rd_addr,
61
                wr_addr_i => wr_addr,
62
                d_i => d_i,
63
                d_o => data_out
64
        );
65
 
66
        data_out_cache_process : process(rd_clk_i)
67
        begin
68
                if rd_clk_i'event and rd_clk_i = '1' then
69
                        if valid = '1' then
70
                                data_out_cache <= data_out;
71
                        else
72
                                data_out_cache <= data_out_cache;
73
                        end if;
74
                end if;
75
        end process data_out_cache_process;
76
 
77
        d_o <= data_out when valid = '1' else data_out_cache;
78
 
79
        counter_wr_addr_ins : entity work.counter
80
        generic map (
81
                COUNTER_WIDTH_G => MEMORY_ADDRESS_WIDTH_G,
82
                START_VALUE_G   => 0,
83
                MAX_VALUE_G     => MEMORY_SIZE_G-1,
84
                ASYNCHRONOUS_RESET_G => true
85
        )
86
        port map (
87
                reset_i     => rst_i,
88
                clk_i       => wr_clk_i,
89
                en_i        => push_i,
90
                cnt_o       => wr_addr,
91
                overflow_o  => open
92
        );
93
 
94
        fifo_valid_pin_process : process(rd_clk_i)
95
        begin
96
                if rd_clk_i'event and rd_clk_i = '1' then
97
                        if rst_i = '1' then
98
                                valid <= '0';
99
                        elsif pull_i = '1' then
100
                                valid <= '1';
101
                        else
102
                                valid <= '0';
103
                        end if;
104
                end if;
105
        end process fifo_valid_pin_process;
106
        valid_o <= valid;
107
 
108
        counter_rd_addr_ins : entity work.counter
109
        generic map (
110
                COUNTER_WIDTH_G => MEMORY_ADDRESS_WIDTH_G,
111
                START_VALUE_G   => 0,
112
                MAX_VALUE_G     => MEMORY_SIZE_G-1,
113
                ASYNCHRONOUS_RESET_G => true
114
        )
115
        port map (
116
                reset_i     => rst_i,
117
                clk_i       => rd_clk_i,
118
                en_i        => pull_i,
119
                cnt_o       => rd_addr,
120
                overflow_o  => open
121
        );
122
 
123
        empty_o <= '1' when wr_addr = rd_addr else '0';
124
        -- wr_addr = 1, rd_addr = 3, MEMORY_SIZE_G = 4
125
        --  This gives: used = 1+(4-3) = 2
126
        -- wr_addr = 0, rd_addr = 1, MEMORY_SIZE_G = 4
127
        --  This gives: used = 0+(4-1) = 3
128
        -- wr_addr = 2, rd_addr = 3, MEMORY_SIZE_G = 4
129
        --  This gives: used = 2+(4-3) = 3
130
        --  So: used = wr_addr + (MEMORY_SIZE_G - 1 - rd_addr)
131
        used <= wr_addr - rd_addr when wr_addr >= rd_addr else wr_addr + (to_unsigned(MEMORY_SIZE_G, MEMORY_ADDRESS_WIDTH_G) - rd_addr);
132
        used_o <= used;
133
        full_o <= '1' when used = to_unsigned(MEMORY_SIZE_G-1, MEMORY_ADDRESS_WIDTH_G) else '0';
134
end Behavioral;
135
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.