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

Subversion Repositories the_wizardry_project

[/] [the_wizardry_project/] [trunk/] [Wizardry/] [VHDL/] [Wizardry Top Level/] [Memory Design/] [MIG_top_00/] [MIG_data_path_0/] [MIG_tap_logic/] [MIG_tap_ctrl_0.vhd] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 mcwaccent
-------------------------------------------------------------------------------
2
-- Copyright (c) 2005-2007 Xilinx, Inc.
3
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
4
-------------------------------------------------------------------------------
5
--   ____  ____
6
--  /   /\/   /
7
-- /___/  \  /   Vendor             : Xilinx
8
-- \   \   \/    Version            : $Name: i+IP+131489 $
9
--  \   \        Application        : MIG
10
--  /   /        Filename           : MIG_tap_ctrl.vhd
11
-- /___/   /\    Date Last Modified : $Date: 2007/09/21 15:23:24 $
12
-- \   \  /  \   Date Created       : Mon May 2 2005
13
--  \___\/\___\
14
--
15
-- Device      : Virtex-4
16
-- Design Name : DDR SDRAM
17
-- Description: The tap control logic which claculates the relation between the
18
--              FPGA clock and the dqs from memory. It delays the dqs so as to
19
--              detect the edges of the dqs and then calculates the mid point
20
--              so that the data can be registered properly.
21
-------------------------------------------------------------------------------
22
 
23
library ieee;
24
use ieee.std_logic_1164.all;
25
use ieee.std_logic_unsigned.all;
26
library UNISIM;
27
use UNISIM.vcomponents.all;
28
 
29
entity MIG_tap_ctrl is
30
  port(
31
    clk                  : in  std_logic;
32
    reset                : in  std_logic;
33
    rdy_status           : in  std_logic;
34
    dqs                  : in  std_logic;
35
    ctrl_dummyread_start : in  std_logic;
36
    dlyinc               : out std_logic;
37
    dlyce                : out std_logic;
38
    dlyrst               : out std_logic;
39
    sel_done             : out std_logic;
40
    valid_data_tap_count : out std_logic;
41
    data_tap_count       : out std_logic_vector(5 downto 0)
42
    );
43
end MIG_tap_ctrl;
44
 
45
architecture arch of MIG_tap_ctrl is
46
 
47
  signal prev_dqs_level         : std_logic;
48
  signal dly_inc                : std_logic;
49
  signal dly_ce                 : std_logic;
50
  signal dly_rst                : std_logic;
51
  signal transition             : std_logic_vector(1 downto 0);
52
  signal first_edge             : std_logic;
53
  signal second_edge            : std_logic;
54
  signal second_edge_r1         : std_logic;
55
  signal second_edge_r2         : std_logic;
56
  signal second_edge_r3         : std_logic;
57
  signal transition_rst         : std_logic;
58
  signal sel_complete           : std_logic;
59
  signal tap_counter            : std_logic_vector(5 downto 0);
60
  signal first_edge_tap_count   : std_logic_vector(5 downto 0);
61
  signal second_edge_tap_count  : std_logic_vector(5 downto 0);
62
  signal pulse_width_tap_count  : std_logic_vector(5 downto 0);
63
  signal data_bit_tap_count     : std_logic_vector(5 downto 0);
64
  signal state                  : std_logic_vector(2 downto 0);
65
  signal idelay_rst_idle        : std_logic;
66
  signal idelay_rst_idle_r1     : std_logic;
67
  signal idelay_rst_idle_r2     : std_logic;
68
  signal idelay_rst_idle_r3     : std_logic;
69
  signal idelay_rst_idle_r4     : std_logic;
70
  signal idelay_rst_idle_r5     : std_logic;
71
  signal idelay_rst_idle_r6     : std_logic;
72
  signal idelay_inc_idle        : std_logic;
73
  signal idelay_inc_idle_r1     : std_logic;
74
  signal idelay_inc_idle_r2     : std_logic;
75
  signal idelay_inc_idle_r3     : std_logic;
76
  signal idelay_inc_idle_r4     : std_logic;
77
  signal idelay_inc_idle_r5     : std_logic;
78
  signal idelay_inc_idle_r6     : std_logic;
79
  signal detect_edge_idle       : std_logic;
80
  signal detect_edge_idle_r1    : std_logic;
81
  signal detect_edge_idle_r2    : std_logic;
82
  signal detect_edge_idle_r3    : std_logic;
83
  signal detect_edge_idle_r4    : std_logic;
84
  signal detect_edge_idle_r5    : std_logic;
85
  signal detect_edge_idle_r6    : std_logic;
86
  signal flag                   : std_logic_vector(3 downto 0);
87
  signal dly_after_first_cnt    : std_logic_vector(3 downto 0);
88
  signal pulse_center_tap_count : std_logic_vector(5 downto 0);
89
  signal valid_data_count       : std_logic;
90
  signal data_count_valid       : std_logic;
91
  signal dly_after_first        : std_logic_vector(3 downto 0);
92
  signal curr_dqs_level         : std_logic;
93
  signal delay_sel_done         : std_logic;
94
  signal reset_int              : std_logic;
95
  signal rst_r                  : std_logic;
96
 
97
  constant IDELAY_RST  : std_logic_vector(2 downto 0) := "000";
98
  constant IDLE        : std_logic_vector(2 downto 0) := "001";
99
  constant IDELAY_INC  : std_logic_vector(2 downto 0) := "010";
100
  constant DETECT_EDGE : std_logic_vector(2 downto 0) := "011";
101
 
102
attribute syn_preserve : boolean;
103
attribute syn_preserve of pulse_width_tap_count  : signal is true ;
104
 
105
begin
106
 
107
  process(clk)
108
  begin
109
    if clk'event and clk = '1' then
110
      rst_r <= reset;
111
    end if;
112
  end process;
113
 
114
  dlyinc               <= dly_inc;
115
  dlyce                <= dly_ce;
116
  dlyrst               <= dly_rst;
117
  sel_done             <= sel_complete;
118
  valid_data_tap_count <= valid_data_count;
119
  data_tap_count       <= data_bit_tap_count;
120
 
121
  data_count_valid <= '1' when (second_edge_r3 = '1') or (tap_counter = "111111") else '0';
122
  reset_int        <= not(rdy_status) or rst_r;
123
 
124
  delay_sel_done <= '1' when ((second_edge = '1') or (tap_counter = "111111")) else
125
                    '0' when (ctrl_dummyread_start = '0') else
126
                    sel_complete;
127
 
128
  dly_after_first <= "1001" when ((transition = "01") and (first_edge = '0')) else
129
                     (dly_after_first_cnt - '1') when ((dly_after_first_cnt /= "0000")
130
                                                       and (dly_inc = '1')) else
131
                     dly_after_first_cnt;
132
 
133
  curr_dqs_level <= dqs;
134
 
135
-- Shift registers for controls
136
  process(clk)
137
  begin
138
    if clk'event and clk = '1' then
139
      if reset_int = '1' then
140
        second_edge_r1      <= '0';
141
        second_edge_r2      <= '0';
142
        second_edge_r3      <= '0';
143
        idelay_rst_idle_r1  <= '0';
144
        idelay_rst_idle_r2  <= '0';
145
        idelay_rst_idle_r3  <= '0';
146
        idelay_rst_idle_r4  <= '0';
147
        idelay_rst_idle_r5  <= '0';
148
        idelay_rst_idle_r6  <= '0';
149
        idelay_inc_idle_r1  <= '0';
150
        idelay_inc_idle_r2  <= '0';
151
        idelay_inc_idle_r3  <= '0';
152
        idelay_inc_idle_r4  <= '0';
153
        idelay_inc_idle_r5  <= '0';
154
        idelay_inc_idle_r6  <= '0';
155
        detect_edge_idle_r1 <= '0';
156
        detect_edge_idle_r2 <= '0';
157
        detect_edge_idle_r3 <= '0';
158
        detect_edge_idle_r4 <= '0';
159
        detect_edge_idle_r5 <= '0';
160
        detect_edge_idle_r6 <= '0';
161
        valid_data_count    <= '0';
162
      else
163
        second_edge_r1      <= second_edge;
164
        second_edge_r2      <= second_edge_r1;
165
        second_edge_r3      <= second_edge_r2;
166
        idelay_rst_idle_r1  <= idelay_rst_idle;
167
        idelay_rst_idle_r2  <= idelay_rst_idle_r1;
168
        idelay_rst_idle_r3  <= idelay_rst_idle_r2;
169
        idelay_rst_idle_r4  <= idelay_rst_idle_r3;
170
        idelay_rst_idle_r5  <= idelay_rst_idle_r4;
171
        idelay_rst_idle_r6  <= idelay_rst_idle_r5;
172
        idelay_inc_idle_r1  <= idelay_inc_idle;
173
        idelay_inc_idle_r2  <= idelay_inc_idle_r1;
174
        idelay_inc_idle_r3  <= idelay_inc_idle_r2;
175
        idelay_inc_idle_r4  <= idelay_inc_idle_r3;
176
        idelay_inc_idle_r5  <= idelay_inc_idle_r4;
177
        idelay_inc_idle_r6  <= idelay_inc_idle_r5;
178
        detect_edge_idle_r1 <= detect_edge_idle;
179
        detect_edge_idle_r2 <= detect_edge_idle_r1;
180
        detect_edge_idle_r3 <= detect_edge_idle_r2;
181
        detect_edge_idle_r4 <= detect_edge_idle_r3;
182
        detect_edge_idle_r5 <= detect_edge_idle_r4;
183
        detect_edge_idle_r6 <= detect_edge_idle_r5;
184
        valid_data_count    <= data_count_valid;
185
      end if;
186
    end if;
187
  end process;
188
 
189
-- Tap Delay Selection Complete for Data bus associated with a dqs
190
  process(clk)
191
  begin
192
    if(clk'event and clk = '1') then
193
      if (reset_int = '1') then
194
        sel_complete <= '0';
195
      else
196
        sel_complete <= delay_sel_done;
197
      end if;
198
    end if;
199
  end process;
200
 
201
 
202
-- Start detection of second transition only after 10 taps from first transition
203
  process(clk)
204
  begin
205
    if(clk'event and clk = '1') then
206
      if (reset_int = '1') then
207
        dly_after_first_cnt <= "0000";
208
      else
209
        dly_after_first_cnt <= dly_after_first;
210
      end if;
211
    end if;
212
  end process;
213
 
214
 
215
-- Tap Counter
216
  process(clk)
217
  begin
218
    if(clk'event and clk = '1') then
219
      if ((reset_int = '1') or (tap_counter = "111111")) then
220
        tap_counter <= "000000";
221
      elsif (dly_inc = '1') then
222
        tap_counter <= tap_counter + '1';
223
      end if;
224
    end if;
225
  end process;
226
 
227
-- Tap value for Data IDELAY circuit
228
  process(clk)
229
  begin
230
    if(clk'event and clk = '1') then
231
      if (reset_int = '1') then
232
        first_edge_tap_count <= "000000";
233
      elsif ((transition = "01") and (first_edge = '0')) then
234
        first_edge_tap_count <= tap_counter;
235
      end if;
236
    end if;
237
  end process;
238
 
239
  process(clk)
240
  begin
241
    if(clk'event and clk = '1') then
242
      if (reset_int = '1') then
243
        second_edge_tap_count <= "000000";
244
      elsif ((transition = "10") and (second_edge = '0')) then
245
        second_edge_tap_count <= tap_counter;
246
      end if;
247
    end if;
248
  end process;
249
 
250
 
251
  process(clk)
252
  begin
253
    if(clk'event and clk = '1') then
254
      if (reset_int = '1') then
255
        pulse_width_tap_count <= "000000";
256
      elsif (second_edge_r1 = '1') then
257
        pulse_width_tap_count <= (second_edge_tap_count - first_edge_tap_count);
258
      end if;
259
    end if;
260
  end process;
261
 
262
 
263
  process(clk)
264
  begin
265
    if(clk'event and clk = '1') then
266
      if (reset_int = '1') then
267
        pulse_center_tap_count <= "000000";
268
      elsif (second_edge_r2 = '1') then
269
        pulse_center_tap_count <= '0' & pulse_width_tap_count(5 downto 1);
270
        -- Shift right to divide by 2 and find pulse center
271
      end if;
272
    end if;
273
  end process;
274
 
275
 
276
  process(clk)
277
  begin
278
    if(clk'event and clk = '1') then
279
      if (reset_int = '1') then
280
        data_bit_tap_count <= "000000";
281
      elsif (second_edge_r3 = '1') then  -- 2 edges detected
282
        data_bit_tap_count <= first_edge_tap_count + pulse_center_tap_count;
283
      elsif ((transition = "01") and ((tap_counter = "111111"))) then
284
        if (first_edge_tap_count(5) = '0') then
285
          data_bit_tap_count <= first_edge_tap_count + "010000";
286
        else
287
          data_bit_tap_count <= first_edge_tap_count - "010000";
288
        end if;
289
      elsif ((transition = "00") and ((tap_counter = "111111"))) then
290
        data_bit_tap_count <= "100000";
291
      end if;
292
    end if;
293
  end process;
294
 
295
 
296
-- Logic required to determine whether the registered dqs is on the edge of
297
-- meeting setup time in the FPGA clock domain.
298
-- If dqs is on the edge, then the vector 'flag' will not be "1111" or "0000" and
299
-- edge detection will not be executed.
300
-- If dqs is not on the edge, then the vector 'flag' will be "1111" or "0000" and
301
-- edge detection will be executed.
302
 
303
  process(clk)
304
  begin
305
    if clk'event and clk = '1' then
306
      if (reset_int = '1') then
307
        flag <= (others => '0');
308
      elsif (detect_edge_idle_r3 = '1' or idelay_inc_idle_r3 = '1' or
309
             idelay_rst_idle_r3 = '1') then
310
        if (curr_dqs_level /= prev_dqs_level) then
311
          flag(0) <= '0';
312
        else
313
          flag(0) <= '1';
314
        end if;
315
      elsif (detect_edge_idle_r4 = '1' or idelay_inc_idle_r4 = '1' or
316
             idelay_rst_idle_r4 = '1') then
317
        if (curr_dqs_level /= prev_dqs_level) then
318
          flag(1) <= '0';
319
        else
320
          flag(1) <= '1';
321
        end if;
322
      elsif (detect_edge_idle_r5 = '1' or idelay_inc_idle_r5 = '1' or
323
             idelay_rst_idle_r5 = '1') then
324
        if (curr_dqs_level /= prev_dqs_level) then
325
          flag(2) <= '0';
326
        else
327
          flag(2) <= '1';
328
        end if;
329
      elsif (detect_edge_idle_r6 = '1' or idelay_inc_idle_r6 = '1' or
330
             idelay_rst_idle_r6 = '1') then
331
        if (curr_dqs_level /= prev_dqs_level) then
332
          flag(3) <= '0';
333
        else
334
          flag(3) <= '1';
335
        end if;
336
 
337
      end if;
338
    end if;
339
  end process;
340
 
341
 
342
-- First and second edge assignment logic
343
  process(clk)
344
  begin
345
    if(clk'event and clk = '1') then
346
      if (reset_int = '1') then
347
        transition(1 downto 0) <= "00";
348
      elsif ((dly_after_first_cnt = "0000") and (state = DETECT_EDGE) and
349
             ((flag = X"0") or (flag = X"F"))) then
350
        if ((curr_dqs_level /= prev_dqs_level) and (transition_rst = '0') and
351
            (tap_counter > "000000")) then
352
          transition <= transition + '1';
353
        end if;
354
      elsif (transition_rst = '1') then
355
        transition <= "00";
356
      else
357
        transition <= transition;
358
      end if;
359
    end if;
360
  end process;
361
 
362
 
363
  process(clk)
364
  begin
365
    if(clk'event and clk = '1') then
366
      if (reset_int = '1') then
367
        transition_rst <= '0';
368
        first_edge     <= '0';
369
        second_edge    <= '0';
370
      else
371
        case transition is
372
          when "01" =>
373
            first_edge <= '1';
374
 
375
          when "10" =>
376
            if (transition_rst = '1') then
377
              second_edge    <= '0';
378
              transition_rst <= '0';
379
            else
380
              second_edge    <= '1';
381
              transition_rst <= '1';
382
            end if;
383
          when others =>
384
            first_edge  <= '0';
385
            second_edge <= '0';
386
        end case;
387
      end if;
388
    end if;
389
  end process;
390
 
391
-- State Machine for edge detection and midpoint determination
392
  process(clk)
393
  begin
394
    if(clk'event and clk = '1') then
395
      if (reset_int = '1') then         -- dqs IDELAY in reset
396
        dly_rst           <= '1';
397
        dly_ce            <= '0';
398
        dly_inc           <= '0';
399
        idelay_rst_idle   <= '0';
400
        detect_edge_idle  <= '0';
401
        idelay_inc_idle   <= '0';
402
        prev_dqs_level    <= curr_dqs_level;
403
        state(2 downto 0) <= IDELAY_RST;
404
      elsif ((ctrl_dummyread_start = '1') and (sel_complete = '0')) then
405
        case state is
406
          when "000" =>                 -- IDELAY_RST
407
            dly_rst           <= '1';
408
            dly_ce            <= '0';
409
            dly_inc           <= '0';
410
            idelay_rst_idle   <= '1';
411
            state(2 downto 0) <= IDLE;
412
          when "001" =>                 -- IDLE
413
            dly_rst          <= '0';
414
            dly_ce           <= '0';
415
            dly_inc          <= '0';
416
            idelay_rst_idle  <= '0';
417
            detect_edge_idle <= '0';
418
            idelay_inc_idle  <= '0';
419
            if (idelay_rst_idle_r5 = '1') then
420
              state(2 downto 0) <= IDELAY_INC;
421
            elsif ((idelay_inc_idle_r6 = '1') or ((detect_edge_idle_r6 = '1')
422
                    and (second_edge_r2 = '0') and (tap_counter /= "111111"))) then
423
              state(2 downto 0) <= DETECT_EDGE;
424
            else
425
              state(2 downto 0) <= IDLE;
426
            end if;
427
          when "010" =>                 -- IDELAY_INC
428
            dly_rst           <= '0';
429
            dly_ce            <= '1';
430
            dly_inc           <= '1';
431
            idelay_inc_idle   <= '1';
432
            state(2 downto 0) <= IDLE;
433
            if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then
434
              prev_dqs_level <= curr_dqs_level;
435
            else
436
              prev_dqs_level <= prev_dqs_level;
437
            end if;
438
 
439
          when "011" =>                 -- DETECT_EDGE
440
            dly_rst           <= '0';
441
            dly_ce            <= '1';
442
            dly_inc           <= '1';
443
            detect_edge_idle  <= '1';
444
            state(2 downto 0) <= IDLE;
445
            if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then
446
              prev_dqs_level <= curr_dqs_level;
447
            else
448
              prev_dqs_level <= prev_dqs_level;
449
            end if;
450
          when others =>
451
            dly_rst           <= '0';
452
            dly_ce            <= '0';
453
            dly_inc           <= '0';
454
            idelay_rst_idle   <= '0';
455
            detect_edge_idle  <= '0';
456
            idelay_inc_idle   <= '0';
457
            prev_dqs_level    <= curr_dqs_level;
458
            state(2 downto 0) <= IDLE;
459
        end case;
460
      else
461
        dly_rst          <= '0';
462
        dly_ce           <= '0';
463
        dly_inc          <= '0';
464
        idelay_rst_idle  <= '0';
465
        detect_edge_idle <= '0';
466
        idelay_inc_idle  <= '0';
467
        prev_dqs_level   <= curr_dqs_level;
468
        state            <= IDELAY_RST;
469
      end if;
470
    end if;
471
  end process;
472
 
473
end arch;

powered by: WebSVN 2.1.0

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