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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.storage/] [fifos/] [gray_fifo/] [1.0/] [vhd/] [cdc_fifo_ctrl.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
 
5
use work.gray_code.all;
6
 
7
entity cdc_fifo_ctrl is
8
 
9
  generic (
10
    READ_AHEAD_g  : integer := 0;
11
    SYNC_CLOCKS_g : integer := 0;
12
    depth_log2_g  : integer := 0);
13
 
14
  port (
15
    rst_n : in std_logic;
16
 
17
    rd_clk       : in  std_logic;
18
    rd_en_in     : in  std_logic;
19
    rd_empty_out : out std_logic;
20
    rd_one_d_out : out std_logic;
21
    rd_addr_out  : out std_logic_vector (depth_log2_g-1 downto 0);
22
 
23
    wr_clk       : in  std_logic;
24
    wr_en_in     : in  std_logic;
25
    wr_full_out  : out std_logic;
26
    wr_one_p_out : out std_logic;
27
    wr_addr_out  : out std_logic_vector (depth_log2_g-1 downto 0)
28
    );
29
 
30
end entity cdc_fifo_ctrl;
31
 
32
architecture rtl of cdc_fifo_ctrl is
33
 
34
 
35
--  signal wr_counter_synchronized_r : unsigned (depth_log2_g-1 downto 0);
36
 
37
 
38
  -- (rd_clk) registers
39
  signal rd_counter_r            : unsigned (depth_log2_g-1 downto 0);
40
  signal rd_counter_gray_r       : std_logic_vector(depth_log2_g-1 downto 0);
41
  signal wr_counter_gray_sync1_r : std_logic_vector (depth_log2_g-1 downto 0);
42
  signal wr_counter_gray_sync2_r : std_logic_vector (depth_log2_g-1 downto 0);
43
  signal wr_counter_gray_sync3_r : std_logic_vector (depth_log2_g-1 downto 0);
44
  signal rd_empty : std_logic;
45
 
46
  -- (wr_clk) registers
47
  signal wr_counter_r            : unsigned (depth_log2_g-1 downto 0);
48
  signal wr_counter_gray_r       : std_logic_vector(depth_log2_g-1 downto 0);
49
  signal rd_counter_gray_sync1_r : std_logic_vector (depth_log2_g-1 downto 0);
50
  signal rd_counter_gray_sync2_r : std_logic_vector (depth_log2_g-1 downto 0);
51
  signal rd_counter_gray_sync3_r : std_logic_vector (depth_log2_g-1 downto 0);
52
 
53
  signal rd_counter_next : unsigned (depth_log2_g-1 downto 0);
54
  signal wr_counter_next : unsigned (depth_log2_g-1 downto 0);
55
 
56
  signal wr_counter_gray_syncd : std_logic_vector(depth_log2_g-1 downto 0);
57
  signal rd_counter_gray_syncd : std_logic_vector(depth_log2_g-1 downto 0);
58
begin  -- architecture rtl
59
 
60
  -- concurrent assignments
61
  wr_addr_out <= std_logic_vector(wr_counter_r);
62
 
63
  --AK TESTE CAHNGED
64
  -- data is available at the same clock cylce as the rd_en_in = '1'
65
  readahead : if READ_AHEAD_g /= 0 generate
66
    rd_addr_out <= std_logic_vector(rd_counter_next) when (rd_en_in = '1' and rd_empty = '0') else
67
                   std_logic_vector(rd_counter_r);
68
  end generate readahead;
69
 
70
  -- data is available at the next clock cycle
71
  no_readahead : if READ_AHEAD_g = 0 generate
72
    rd_addr_out <= std_logic_vector(rd_counter_r);
73
  end generate no_readahead;
74
 
75
 
76
  -- purpose: counter logic for write address (binary counter + gray counter)
77
  -- type   : sequential
78
  -- inputs : wr_clk, rst_n
79
  -- outputs: 
80
  wr_counter_next <= wr_counter_r + 1;
81
  write_counter : process (rst_n, wr_clk) is
82
  begin  -- process write_counter
83
    if (rst_n = '0') then               -- asynchronous reset (active low)
84
      wr_counter_r      <= (others => '0');
85
      wr_counter_gray_r <= (others => '0');
86
      wr_counter_gray_sync1_r <= (others => '0');
87
    elsif rising_edge(wr_clk) then      -- rising clock edge
88
      -- check also if becoming full
89
      if (wr_en_in = '1') then
90
        wr_counter_r      <= wr_counter_next;
91
        wr_counter_gray_r <= gray_encode(wr_counter_next);
92
      end if;
93
      wr_counter_gray_sync1_r <= wr_counter_gray_r;
94
    end if;
95
  end process write_counter;
96
 
97
  -- purpose: counter logic for read address (binary counter & gray counter)
98
  -- type   : sequential
99
  -- inputs : rd_clk, rst_n
100
  -- outputs: 
101
  rd_counter_next <= rd_counter_r + 1;
102
  read_counter : process (rd_clk, rst_n) is
103
  begin  -- process read_counter
104
    if (rst_n = '0') then               -- asynchronous reset (active low)
105
      rd_counter_r      <= (others => '0');
106
      rd_counter_gray_r <= (others => '0');
107
    elsif rising_edge(rd_clk) then      -- rising clock edge
108
      -- check also if becoming empty
109
      if (rd_en_in = '1') then  --  and (not rd_counter_gray_r = wr_counter_gray_syncd)
110
        rd_counter_r      <= rd_counter_next;
111
        rd_counter_gray_r <= gray_encode(rd_counter_next);
112
      end if;
113
    end if;
114
  end process read_counter;
115
 
116
 
117
  syncd_clocks : if SYNC_CLOCKS_g /= 0 generate
118
    -- use only 1 synchronization register
119
    wr_counter_gray_syncd <= wr_counter_gray_sync1_r;
120
    rd_counter_gray_syncd <= rd_counter_gray_sync1_r;
121
  end generate syncd_clocks;
122
 
123
  no_syncd_clocks : if SYNC_CLOCKS_g = 0 generate
124
    -- use 2 synchronization registers
125
--    wr_counter_gray_syncd <= wr_counter_gray_sync2_r;
126
    rd_counter_gray_syncd <= rd_counter_gray_sync2_r;
127
    wr_counter_gray_syncd <= wr_counter_gray_sync3_r;
128
--    rd_counter_gray_syncd <= rd_counter_gray_sync3_r;
129
 
130
  end generate no_syncd_clocks;
131
 
132
 
133
  rd_empty_out <= rd_empty;
134
 
135
  -- purpose: determines whether the fifo is empty or not
136
  -- combinational inputs : rd_counter_r, wr_counter_sync2_r outputs:
137
  -- empty
138
  empty_logic : process (rd_counter_gray_r, wr_counter_gray_syncd,
139
                         rd_counter_r) is
140
  begin  -- process empty_logic
141
    if (rd_counter_gray_r = wr_counter_gray_syncd) then
142
      rd_empty <= '1';
143
    else
144
      rd_empty <= '0';
145
    end if;
146
 
147
    if (gray_encode(rd_counter_r+1) = wr_counter_gray_syncd) then
148
      rd_one_d_out <= '1';
149
    else
150
      rd_one_d_out <= '0';
151
    end if;
152
  end process empty_logic;
153
 
154
 
155
 
156
  full_logic : process (rd_counter_gray_syncd, wr_counter_next) is
157
  begin  -- process full_logic
158
    if (rd_counter_gray_syncd = gray_encode(wr_counter_next)) then
159
      wr_full_out <= '1';
160
    else
161
      wr_full_out <= '0';
162
    end if;
163
 
164
    if rd_counter_gray_syncd = gray_encode(wr_counter_next+1) then
165
      wr_one_p_out <= '1';
166
    else
167
      wr_one_p_out <= '0';
168
    end if;
169
 
170
  end process full_logic;
171
 
172
-- purpose: Synchronizes write counter value to read -side clock domain.
173
-- type   : sequential (avoids meta-stability)
174
-- inputs : rd_clk, rst_n
175
-- outputs: 
176
  rd_synchronizer : process (rd_clk, rst_n) is
177
  begin  -- process rd_synchronizer
178
    if rst_n = '0' then                 -- asynchronous reset (active low)
179
--      wr_counter_gray_sync1_r <= (others => '0');
180
      wr_counter_gray_sync2_r <= (others => '0');
181
      wr_counter_gray_sync3_r <= (others => '0');
182
    elsif rising_edge(rd_clk) then      -- rising clock edge
183
--        wr_counter_gray_sync1_r <= wr_counter_gray_r;      
184
      wr_counter_gray_sync2_r <= wr_counter_gray_sync1_r;
185
      wr_counter_gray_sync3_r <= wr_counter_gray_sync2_r;
186
    end if;
187
  end process rd_synchronizer;
188
 
189
-- purpose: Synchronizes read counter value to write -side clock domain.
190
-- type   : sequential (avoids meta-stability)
191
-- inputs : wr_clk, rst_n
192
-- outputs: 
193
  wr_synchronizer : process (rst_n, wr_clk) is
194
  begin  -- process rd_synchronizer
195
    if rst_n = '0' then                 -- asynchronous reset (active low)
196
      rd_counter_gray_sync1_r <= (others => '0');
197
      rd_counter_gray_sync2_r <= (others => '0');
198
      rd_counter_gray_sync3_r <= (others => '0');
199
    elsif rising_edge(wr_clk) then      -- rising clock edge
200
      rd_counter_gray_sync1_r <= rd_counter_gray_r;
201
      rd_counter_gray_sync2_r <= rd_counter_gray_sync1_r;
202
      rd_counter_gray_sync3_r <= rd_counter_gray_sync2_r;
203
    end if;
204
  end process wr_synchronizer;
205
 
206
end architecture rtl;

powered by: WebSVN 2.1.0

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