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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [techmap/] [unisim/] [ddr_phy_unisim.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-----------------------------------------------------------------------------
19
-- Entity:      various
20
-- File:        clkgen_xilinx.vhd
21
-- Author:      Jiri Gaisler, Gaisler Research
22
-- Description: DDR PHY for Virtex-2 and Virtex-4
23
------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.stdlib.all;
29
-- pragma translate_off
30
library unisim;
31
use unisim.BUFG;
32
use unisim.DCM;
33
use unisim.ODDR;
34
use unisim.FD;
35
use unisim.IDDR;
36
-- pragma translate_on
37
 
38
library techmap;
39
use techmap.gencomp.all;
40
 
41
------------------------------------------------------------------
42
-- Virtex4 DDR PHY -----------------------------------------------
43
------------------------------------------------------------------
44
 
45
entity virtex4_ddr_phy is
46
  generic (MHz : integer := 100; rstdelay : integer := 200;
47
        dbits : integer := 16; clk_mul : integer := 2 ;
48
        clk_div : integer := 2; rskew : integer := 0);
49
 
50
  port (
51
    rst       : in  std_ulogic;
52
    clk       : in  std_logic;                  -- input clock
53
    clkout    : out std_ulogic;                 -- system clock
54
    lock      : out std_ulogic;                 -- DCM locked
55
 
56
    ddr_clk     : out std_logic_vector(2 downto 0);
57
    ddr_clkb    : out std_logic_vector(2 downto 0);
58
    ddr_clk_fb_out  : out std_logic;
59
    ddr_clk_fb  : in std_logic;
60
    ddr_cke     : out std_logic_vector(1 downto 0);
61
    ddr_csb     : out std_logic_vector(1 downto 0);
62
    ddr_web     : out std_ulogic;                       -- ddr write enable
63
    ddr_rasb    : out std_ulogic;                       -- ddr ras
64
    ddr_casb    : out std_ulogic;                       -- ddr cas
65
    ddr_dm      : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
66
    ddr_dqs     : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
67
    ddr_ad      : out std_logic_vector (13 downto 0);   -- ddr address
68
    ddr_ba      : out std_logic_vector (1 downto 0);    -- ddr bank address
69
    ddr_dq      : inout  std_logic_vector (dbits-1 downto 0); -- ddr data
70
 
71
    addr        : in  std_logic_vector (13 downto 0); -- data mask
72
    ba          : in  std_logic_vector ( 1 downto 0); -- data mask
73
    dqin        : out std_logic_vector (dbits*2-1 downto 0); -- ddr input data
74
    dqout       : in  std_logic_vector (dbits*2-1 downto 0); -- ddr input data
75
    dm          : in  std_logic_vector (dbits/4-1 downto 0); -- data mask
76
    oen         : in  std_ulogic;
77
    dqs         : in  std_ulogic;
78
    dqsoen      : in  std_ulogic;
79
    rasn        : in  std_ulogic;
80
    casn        : in  std_ulogic;
81
    wen         : in  std_ulogic;
82
    csn         : in  std_logic_vector(1 downto 0);
83
    cke         : in  std_logic_vector(1 downto 0);
84
    ck          : in  std_logic_vector(2 downto 0)
85
  );
86
 
87
end;
88
 
89
architecture rtl of virtex4_ddr_phy is
90
 
91
  component DCM
92
    generic (
93
      CLKDV_DIVIDE : real := 2.0;
94
      CLKFX_DIVIDE : integer := 1;
95
      CLKFX_MULTIPLY : integer := 4;
96
      CLKIN_DIVIDE_BY_2 : boolean := false;
97
      CLKIN_PERIOD : real := 10.0;
98
      CLKOUT_PHASE_SHIFT : string := "NONE";
99
      CLK_FEEDBACK : string := "1X";
100
      DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS";
101
      DFS_FREQUENCY_MODE : string := "LOW";
102
      DLL_FREQUENCY_MODE : string := "LOW";
103
      DSS_MODE : string := "NONE";
104
      DUTY_CYCLE_CORRECTION : boolean := true;
105
      FACTORY_JF : bit_vector := X"C080";
106
      PHASE_SHIFT : integer := 0;
107
      STARTUP_WAIT : boolean := false
108
    );
109
    port (
110
      CLKFB    : in  std_logic;
111
      CLKIN    : in  std_logic;
112
      DSSEN    : in  std_logic;
113
      PSCLK    : in  std_logic;
114
      PSEN     : in  std_logic;
115
      PSINCDEC : in  std_logic;
116
      RST      : in  std_logic;
117
      CLK0     : out std_logic;
118
      CLK90    : out std_logic;
119
      CLK180   : out std_logic;
120
      CLK270   : out std_logic;
121
      CLK2X    : out std_logic;
122
      CLK2X180 : out std_logic;
123
      CLKDV    : out std_logic;
124
      CLKFX    : out std_logic;
125
      CLKFX180 : out std_logic;
126
      LOCKED   : out std_logic;
127
      PSDONE   : out std_logic;
128
      STATUS   : out std_logic_vector (7 downto 0));
129
  end component;
130
  component BUFG port (O : out std_logic; I : in std_logic); end component;
131
  component ODDR
132
    generic
133
      ( DDR_CLK_EDGE : string := "OPPOSITE_EDGE";
134
--        INIT : bit := '0';
135
        SRTYPE : string := "SYNC");
136
    port
137
      (
138
        Q : out std_ulogic;
139
        C : in std_ulogic;
140
        CE : in std_ulogic;
141
        D1 : in std_ulogic;
142
        D2 : in std_ulogic;
143
        R : in std_ulogic;
144
        S : in std_ulogic
145
      );
146
  end component;
147
  component FD
148
        generic ( INIT : bit := '0');
149
        port (  Q : out std_ulogic;
150
                C : in std_ulogic;
151
                D : in std_ulogic);
152
  end component;
153
    component IDDR
154
      generic ( DDR_CLK_EDGE : string := "SAME_EDGE";
155
          INIT_Q1 : bit := '0';
156
          INIT_Q2 : bit := '0';
157
          SRTYPE : string := "ASYNC");
158
      port
159
        ( Q1 : out std_ulogic;
160
          Q2 : out std_ulogic;
161
          C : in std_ulogic;
162
          CE : in std_ulogic;
163
          D : in std_ulogic;
164
          R : in std_ulogic;
165
          S : in std_ulogic);
166
    end component;
167
 
168
signal vcc, gnd, dqsn, oe, lockl : std_ulogic;
169
signal ddr_clk_fb_outr : std_ulogic;
170
signal ddr_clk_fbl, fbclk : std_ulogic;
171
signal ddr_rasnr, ddr_casnr, ddr_wenr : std_ulogic;
172
signal ddr_clkl, ddr_clkbl : std_logic_vector(2 downto 0);
173
signal ddr_csnr, ddr_ckenr, ckel : std_logic_vector(1 downto 0);
174
signal clk_0ro, clk_90ro, clk_180ro, clk_270ro : std_ulogic;
175
signal clk_0r, clk_90r, clk_180r, clk_270r : std_ulogic;
176
signal clk0r, clk90r, clk180r, clk270r : std_ulogic;
177
signal locked, vlockl, ddrclkfbl, dllfb : std_ulogic;
178
 
179
signal ddr_dqin         : std_logic_vector (dbits-1 downto 0); -- ddr data
180
signal ddr_dqout        : std_logic_vector (dbits-1 downto 0); -- ddr data
181
signal ddr_dqoen        : std_logic_vector (dbits-1 downto 0); -- ddr data
182
signal ddr_adr          : std_logic_vector (13 downto 0);   -- ddr address
183
signal ddr_bar          : std_logic_vector (1 downto 0);   -- ddr address
184
signal ddr_dmr          : std_logic_vector (dbits/8-1 downto 0);   -- ddr address
185
signal ddr_dqsin        : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
186
signal ddr_dqsoen       : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
187
signal ddr_dqsoutl      : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
188
signal dqsdel, dqsclk   : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
189
signal da               : std_logic_vector (dbits-1 downto 0); -- ddr data
190
signal dqinl            : std_logic_vector (dbits-1 downto 0); -- ddr data
191
signal dllrst           : std_logic_vector(0 to 3);
192
signal dll0rst, dll2rst : std_logic_vector(0 to 3);
193
signal mlock, mclkfb, mclk, mclkfx, mclk0 : std_ulogic;
194
signal rclk270b, rclk90b, rclk0b : std_ulogic;
195
signal rclk270, rclk90, rclk0 : std_ulogic;
196
 
197
constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
198
 
199
  attribute keep : boolean;
200
  attribute keep of rclk90b : signal is true;
201
  attribute syn_keep : boolean;
202
  attribute syn_keep of rclk90b : signal is true;
203
  attribute syn_preserve : boolean;
204
  attribute syn_preserve of rclk90b : signal is true;
205
 
206
  -- To prevent synplify 9.4 to remove any of these registers.
207
  attribute syn_noprune : boolean;
208
  attribute syn_noprune of FD : component is true;
209
  attribute syn_noprune of IDDR : component is true;
210
  attribute syn_noprune of ODDR : component is true;
211
 
212
begin
213
 
214
  oe <= not oen;
215
  vcc <= '1'; gnd <= '0';
216
 
217
  -- Optional DDR clock multiplication
218
 
219
  noclkscale : if clk_mul = clk_div generate
220
    mclk <= clk;
221
  end generate;
222
 
223
  clkscale : if clk_mul /= clk_div generate
224
 
225
    rstdel : process (clk, rst)
226
    begin
227
        if rst = '0' then dll0rst <= (others => '1');
228
        elsif rising_edge(clk) then
229
          dll0rst <= dll0rst(1 to 3) & '0';
230
        end if;
231
    end process;
232
 
233
    bufg0 : BUFG port map (I => mclkfx, O => mclk);
234
    bufg1 : BUFG port map (I => mclk0, O => mclkfb);
235
 
236
    dllm : DCM
237
      generic map (CLKFX_MULTIPLY => clk_mul, CLKFX_DIVIDE => clk_div)
238
      port map ( CLKIN => clk, CLKFB => mclkfb, DSSEN => gnd, PSCLK => gnd,
239
      PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => mclk0,
240
      LOCKED => mlock, CLKFX => mclkfx );
241
  end generate;
242
 
243
  -- DDR clock generation
244
 
245
  ddrref_pad : clkpad generic map (tech => virtex4)
246
        port map (ddr_clk_fb, ddrclkfbl);
247
 
248
  bufg1 : BUFG port map (I => clk_0ro, O => clk_0r);
249
--  bufg2 : BUFG port map (I => clk_90ro, O => clk_90r);
250
  clk_90r <= not clk_270r;
251
--  bufg3 : BUFG port map (I => clk_180ro, O => clk_180r);
252
  clk_180r <= not clk_0r;
253
  bufg4 : BUFG port map (I => clk_270ro, O => clk_270r);
254
 
255
  clkout <= clk_270r; clk0r <= clk_270r; clk90r <= clk_0r;
256
  clk180r <= clk_90r; clk270r <= clk_180r;
257
 
258
 
259
  dllfb <= clk_0r;
260
 
261
  dll : DCM generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2)
262
      port map ( CLKIN => mclk, CLKFB => dllfb, DSSEN => gnd, PSCLK => gnd,
263
      PSEN => gnd, PSINCDEC => gnd, RST => dllrst(0), CLK0 => clk_0ro,
264
      CLK90 => clk_90ro, CLK180 => clk_180ro, CLK270 => clk_270ro,
265
      LOCKED => lockl);
266
 
267
  rstdel : process (mclk, rst)
268
  begin
269
      if rst = '0' then dllrst <= (others => '1');
270
      elsif rising_edge(mclk) then
271
        dllrst <= dllrst(1 to 3) & '0';
272
      end if;
273
  end process;
274
 
275
  rdel : if rstdelay /= 0 generate
276
    rcnt : process (clk_0r)
277
    variable cnt : std_logic_vector(15 downto 0);
278
    variable vlock, co : std_ulogic;
279
    begin
280
      if rising_edge(clk_0r) then
281
        co := cnt(15);
282
        vlockl <= vlock;
283
        if lockl = '0' then
284
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16); vlock := '0';
285
        else
286
          if vlock = '0' then
287
            cnt := cnt -1;  vlock := cnt(15) and not co;
288
          end if;
289
        end if;
290
      end if;
291
      if lockl = '0' then
292
        vlock := '0';
293
      end if;
294
    end process;
295
  end generate;
296
 
297
  locked <= lockl when rstdelay = 0 else vlockl;
298
  lock <= locked;
299
 
300
  -- Generate external DDR clock
301
 
302
  fbdclk0r : ODDR port map ( Q => ddr_clk_fb_outr, C => clk90r, CE => vcc,
303
                D1 => vcc, D2 => gnd, R => gnd, S => gnd);
304
  fbclk_pad : outpad generic map (tech => virtex4, level => sstl2_i)
305
        port map (ddr_clk_fb_out, ddr_clk_fb_outr);
306
 
307
  ddrclocks : for i in 0 to 2 generate
308
    dclk0r : ODDR port map ( Q => ddr_clkl(i), C => clk90r, CE => vcc,
309
                D1 => vcc, D2 => gnd, R => gnd, S => gnd);
310
    ddrclk_pad : outpad generic map (tech => virtex4, level => sstl2_i)
311
        port map (ddr_clk(i), ddr_clkl(i));
312
 
313
    dclk0rb : ODDR port map ( Q => ddr_clkbl(i), C => clk90r, CE => vcc,
314
                D1 => gnd, D2 => vcc, R => gnd, S => gnd);
315
    ddrclkb_pad : outpad generic map (tech => virtex4, level => sstl2_i)
316
        port map (ddr_clkb(i), ddr_clkbl(i));
317
  end generate;
318
 
319
  ddrbanks : for i in 0 to 1 generate
320
    csn0gen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
321
        port map ( Q => ddr_csnr(i), C => clk0r, CE => vcc,
322
                D1 => csn(i), D2 => csn(i), R => gnd, S => gnd);
323
    csn0_pad : outpad generic map (tech => virtex4, level => sstl2_i)
324
        port map (ddr_csb(i), ddr_csnr(i));
325
 
326
    ckel(i) <= cke(i) and locked;
327
    ckegen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
328
        port map ( Q => ddr_ckenr(i), C => clk0r, CE => vcc,
329
                D1 => ckel(i), D2 => ckel(i), R => gnd, S => gnd);
330
    cke_pad : outpad generic map (tech => virtex4, level => sstl2_i)
331
        port map (ddr_cke(i), ddr_ckenr(i));
332
  end generate;
333
 
334
  rasgen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
335
        port map ( Q => ddr_rasnr, C => clk0r, CE => vcc,
336
                D1 => rasn, D2 => rasn, R => gnd, S => gnd);
337
  rasn_pad : outpad generic map (tech => virtex4, level => sstl2_i)
338
        port map (ddr_rasb, ddr_rasnr);
339
 
340
  casgen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
341
        port map ( Q => ddr_casnr, C => clk0r, CE => vcc,
342
                D1 => casn, D2 => casn, R => gnd, S => gnd);
343
  casn_pad : outpad generic map (tech => virtex4, level => sstl2_i)
344
        port map (ddr_casb, ddr_casnr);
345
 
346
  wengen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
347
        port map ( Q => ddr_wenr, C => clk0r, CE => vcc,
348
                D1 => wen, D2 => wen, R => gnd, S => gnd);
349
  wen_pad : outpad generic map (tech => virtex4, level => sstl2_i)
350
        port map (ddr_web, ddr_wenr);
351
 
352
  dmgen : for i in 0 to dbits/8-1 generate
353
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
354
               port map ( Q => ddr_dmr(i), C => clk0r, CE => vcc,
355
                D1 => dm(i+dbits/8), D2 => dm(i), R => gnd, S => gnd);
356
    ddr_bm_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
357
        port map (ddr_dm(i), ddr_dmr(i));
358
  end generate;
359
 
360
  bagen : for i in 0 to 1 generate
361
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
362
               port map ( Q => ddr_bar(i), C => clk0r, CE => vcc,
363
                D1 => ba(i), D2 => ba(i), R => gnd, S => gnd);
364
    ddr_ba_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
365
        port map (ddr_ba(i), ddr_bar(i));
366
  end generate;
367
 
368
  dagen : for i in 0 to 13 generate
369
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
370
               port map ( Q => ddr_adr(i), C => clk0r, CE => vcc,
371
                D1 => addr(i), D2 => addr(i), R => gnd, S => gnd);
372
    ddr_ad_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
373
        port map (ddr_ad(i), ddr_adr(i));
374
 
375
  end generate;
376
 
377
  -- DQS generation
378
  dsqreg : FD port map ( Q => dqsn, C => clk180r, D => oe);
379
  dqsgen : for i in 0 to dbits/8-1 generate
380
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
381
        port map ( Q => ddr_dqsin(i), C => clk90r, CE => vcc,
382
                D1 => dqsn, D2 => gnd, R => gnd, S => gnd);
383
    doen : FD port map ( Q => ddr_dqsoen(i), C => clk0r, D => dqsoen);
384
    dqs_pad : iopad generic map (tech => virtex4, level => sstl2_ii)
385
         port map (pad => ddr_dqs(i), i => ddr_dqsin(i), en => ddr_dqsoen(i),
386
                o => ddr_dqsoutl(i));
387
  end generate;
388
 
389
  -- Data bus
390
 
391
 
392
    read_rstdel : process (clk_0r, lockl)
393
    begin
394
        if lockl = '0' then dll2rst <= (others => '1');
395
        elsif rising_edge(clk_0r) then
396
          dll2rst <= dll2rst(1 to 3) & '0';
397
        end if;
398
    end process;
399
 
400
    bufg7 : BUFG port map (I => rclk0, O => rclk0b);
401
    bufg8 : BUFG port map (I => rclk90, O => rclk90b);
402
--    bufg9 : BUFG port map (I => rclk270, O => rclk270b);
403
    rclk270b <= not rclk90b;
404
 
405
  nops : if rskew = 0 generate
406
    read_dll : DCM
407
      generic map (clkin_period => 10.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS")
408
      port map ( CLKIN => ddrclkfbl, CLKFB => rclk0b, DSSEN => gnd, PSCLK => gnd,
409
      PSEN => gnd, PSINCDEC => gnd, RST => dll2rst(0), CLK0 => rclk0,
410
      CLK90 => rclk90, CLK270 => rclk270);
411
  end generate;
412
 
413
  ps : if rskew /= 0 generate
414
    read_dll : DCM
415
      generic map (clkin_period => 10.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS",
416
        CLKOUT_PHASE_SHIFT => "FIXED", PHASE_SHIFT => rskew)
417
      port map ( CLKIN => ddrclkfbl, CLKFB => rclk0b, DSSEN => gnd, PSCLK => gnd,
418
      PSEN => gnd, PSINCDEC => gnd, RST => dll2rst(0), CLK0 => rclk0,
419
      CLK90 => rclk90, CLK270 => rclk270);
420
  end generate;
421
 
422
    ddgen : for i in 0 to dbits-1 generate
423
      qi : IDDR generic map (DDR_CLK_EDGE => "OPPOSITE_EDGE")
424
      port map ( Q1 => dqinl(i), --(i+dbits), -- 1-bit output for positive edge of clock 
425
               Q2 => dqin(i), -- 1-bit output for negative edge of clock 
426
               C => rclk90b, --clk270r, --dqsclk((2*i)/dbits), -- 1-bit clock input 
427
              CE => vcc, -- 1-bit clock enable input 
428
               D => ddr_dqin(i), -- 1-bit DDR data input 
429
               R => gnd, -- 1-bit reset 
430
               S => gnd -- 1-bit set 
431
             );
432
 
433
      dinq1 : FD port map ( Q => dqin(i+dbits), C => rclk270b, D => dqinl(i));
434
      dout : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
435
        port map ( Q => ddr_dqout(i), C => clk0r, CE => vcc,
436
                D1 => dqout(i+dbits), D2 => dqout(i), R => gnd, S => gnd);
437
      doen : FD port map ( Q => ddr_dqoen(i), C => clk0r, D => oen);
438
      dq_pad : iopad generic map (tech => virtex4, level => sstl2_ii)
439
         port map (pad => ddr_dq(i), i => ddr_dqout(i), en => ddr_dqoen(i), o => ddr_dqin(i));
440
    end generate;
441
 
442
end;
443
 
444
library ieee;
445
use ieee.std_logic_1164.all;
446
-- pragma translate_off
447
library unisim;
448
use unisim.BUFG;
449
use unisim.DCM;
450
use unisim.FDDRRSE;
451
use unisim.IFDDRRSE;
452
use unisim.FD;
453
-- pragma translate_on
454
 
455
library grlib;
456
use grlib.stdlib.all;
457
library techmap;
458
use techmap.gencomp.all;
459
use techmap.oddrv2;
460
 
461
------------------------------------------------------------------
462
-- Virtex2 DDR PHY -----------------------------------------------
463
------------------------------------------------------------------
464
 
465
entity virtex2_ddr_phy is
466
  generic (MHz : integer := 100; rstdelay : integer := 200;
467
        dbits : integer := 16; clk_mul : integer := 2 ;
468
        clk_div : integer := 2; rskew : integer := 0);
469
 
470
  port (
471
    rst       : in  std_ulogic;
472
    clk       : in  std_logic;                  -- input clock
473
    clkout    : out std_ulogic;                 -- system clock
474
    lock      : out std_ulogic;                 -- DCM locked
475
 
476
    ddr_clk     : out std_logic_vector(2 downto 0);
477
    ddr_clkb    : out std_logic_vector(2 downto 0);
478
    ddr_clk_fb_out  : out std_logic;
479
    ddr_clk_fb  : in std_logic;
480
    ddr_cke     : out std_logic_vector(1 downto 0);
481
    ddr_csb     : out std_logic_vector(1 downto 0);
482
    ddr_web     : out std_ulogic;                       -- ddr write enable
483
    ddr_rasb    : out std_ulogic;                       -- ddr ras
484
    ddr_casb    : out std_ulogic;                       -- ddr cas
485
    ddr_dm      : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
486
    ddr_dqs     : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
487
    ddr_ad      : out std_logic_vector (13 downto 0);   -- ddr address
488
    ddr_ba      : out std_logic_vector (1 downto 0);    -- ddr bank address
489
    ddr_dq      : inout  std_logic_vector (dbits-1 downto 0); -- ddr data
490
 
491
    addr        : in  std_logic_vector (13 downto 0); -- data mask
492
    ba          : in  std_logic_vector ( 1 downto 0); -- data mask
493
    dqin        : out std_logic_vector (dbits*2-1 downto 0); -- ddr input data
494
    dqout       : in  std_logic_vector (dbits*2-1 downto 0); -- ddr input data
495
    dm          : in  std_logic_vector (dbits/4-1 downto 0); -- data mask
496
    oen         : in  std_ulogic;
497
    dqs         : in  std_ulogic;
498
    dqsoen      : in  std_ulogic;
499
    rasn        : in  std_ulogic;
500
    casn        : in  std_ulogic;
501
    wen         : in  std_ulogic;
502
    csn         : in  std_logic_vector(1 downto 0);
503
    cke         : in  std_logic_vector(1 downto 0)
504
  );
505
 
506
end;
507
 
508
architecture rtl of virtex2_ddr_phy is
509
 
510
  component DCM
511
    generic (
512
      CLKDV_DIVIDE : real := 2.0;
513
      CLKFX_DIVIDE : integer := 1;
514
      CLKFX_MULTIPLY : integer := 4;
515
      CLKIN_DIVIDE_BY_2 : boolean := false;
516
      CLKIN_PERIOD : real := 10.0;
517
      CLKOUT_PHASE_SHIFT : string := "NONE";
518
      CLK_FEEDBACK : string := "1X";
519
      DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS";
520
      DFS_FREQUENCY_MODE : string := "LOW";
521
      DLL_FREQUENCY_MODE : string := "LOW";
522
      DSS_MODE : string := "NONE";
523
      DUTY_CYCLE_CORRECTION : boolean := true;
524
      FACTORY_JF : bit_vector := X"C080";
525
      PHASE_SHIFT : integer := 0;
526
      STARTUP_WAIT : boolean := false
527
    );
528
    port (
529
      CLKFB    : in  std_logic;
530
      CLKIN    : in  std_logic;
531
      DSSEN    : in  std_logic;
532
      PSCLK    : in  std_logic;
533
      PSEN     : in  std_logic;
534
      PSINCDEC : in  std_logic;
535
      RST      : in  std_logic;
536
      CLK0     : out std_logic;
537
      CLK90    : out std_logic;
538
      CLK180   : out std_logic;
539
      CLK270   : out std_logic;
540
      CLK2X    : out std_logic;
541
      CLK2X180 : out std_logic;
542
      CLKDV    : out std_logic;
543
      CLKFX    : out std_logic;
544
      CLKFX180 : out std_logic;
545
      LOCKED   : out std_logic;
546
      PSDONE   : out std_logic;
547
      STATUS   : out std_logic_vector (7 downto 0));
548
  end component;
549
  component BUFG port (O : out std_logic; I : in std_logic); end component;
550
  component FDDRRSE
551
--    generic ( INIT : bit := '0');
552
    port
553
      (
554
        Q : out std_ulogic;
555
        C0 : in std_ulogic;
556
        C1 : in std_ulogic;
557
        CE : in std_ulogic;
558
        D0 : in std_ulogic;
559
        D1 : in std_ulogic;
560
        R : in std_ulogic;
561
        S : in std_ulogic
562
      );
563
  end component;
564
 
565
  component IFDDRRSE
566
        port (
567
                Q0 : out std_ulogic;
568
                Q1 : out std_ulogic;
569
                C0 : in std_ulogic;
570
                C1 : in std_ulogic;
571
                CE : in std_ulogic;
572
                D : in std_ulogic;
573
                R : in std_ulogic;
574
                S : in std_ulogic);
575
  end component;
576
  component FD
577
        generic ( INIT : bit := '0');
578
        port (  Q : out std_ulogic;
579
                C : in std_ulogic;
580
                D : in std_ulogic);
581
  end component;
582
 
583
  component oddrv2
584
  generic ( tech : integer := virtex4);
585
  port
586
    ( Q : out std_ulogic;
587
      C1 : in std_ulogic;
588
      C2 : in std_ulogic;
589
      CE : in std_ulogic;
590
      D1 : in std_ulogic;
591
      D2 : in std_ulogic;
592
      R : in std_ulogic;
593
      S : in std_ulogic);
594
  end component;
595
 
596
signal vcc, gnd, dqsn, oe, lockl : std_ulogic;
597
signal ddr_clk_fb_outr : std_ulogic;
598
signal ddr_clk_fbl, fbclk : std_ulogic;
599
signal ddr_rasnr, ddr_casnr, ddr_wenr : std_ulogic;
600
signal ddr_clkl, ddr_clkbl : std_logic_vector(2 downto 0);
601
signal ddr_csnr, ddr_ckenr, ckel : std_logic_vector(1 downto 0);
602
signal clk_0ro, clk_90ro, clk_180ro, clk_270ro : std_ulogic;
603
signal clk_0r, clk_90r, clk_180r, clk_270r : std_ulogic;
604
signal clk0r, clk90r, clk180r, clk270r : std_ulogic;
605
signal locked, vlockl, ddrclkfbl : std_ulogic;
606
signal ddr_dqin         : std_logic_vector (dbits-1 downto 0); -- ddr data
607
signal ddr_dqout        : std_logic_vector (dbits-1 downto 0); -- ddr data
608
signal ddr_dqoen        : std_logic_vector (dbits-1 downto 0); -- ddr data
609
signal ddr_adr          : std_logic_vector (13 downto 0);   -- ddr address
610
signal ddr_bar          : std_logic_vector (1 downto 0);   -- ddr address
611
signal ddr_dmr          : std_logic_vector (dbits/8-1 downto 0);   -- ddr address
612
signal ddr_dqsin        : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
613
signal ddr_dqsoen       : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
614
signal ddr_dqsoutl      : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
615
signal dqsdel, dqsclk   : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
616
signal da               : std_logic_vector (dbits-1 downto 0); -- ddr data
617
signal dqinl            : std_logic_vector (dbits-1 downto 0); -- ddr data
618
signal dllrst           : std_logic_vector(0 to 3);
619
signal dll0rst, dll2rst : std_logic_vector(0 to 3);
620
signal mlock, mclkfb, mclk, mclkfx, mclk0 : std_ulogic;
621
signal rclk270b, rclk90b, rclk0b : std_ulogic;
622
signal rclk270, rclk90, rclk0 : std_ulogic;
623
 
624
constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
625
 
626
-- To prevent synplify 9.4 to remove any of these registers.
627
attribute syn_noprune : boolean;
628
attribute syn_noprune of FD : component is true;
629
attribute syn_noprune of FDDRRSE : component is true;
630
attribute syn_noprune of IFDDRRSE : component is true;
631
attribute syn_noprune of oddrv2 : component is true;
632
 
633
begin
634
 
635
  oe <= not oen;
636
  vcc <= '1'; gnd <= '0';
637
 
638
  -- Optional DDR clock multiplication
639
 
640
  noclkscale : if clk_mul = clk_div generate
641
    mclk <= clk; mlock <= rst;
642
  end generate;
643
 
644
  clkscale : if clk_mul /= clk_div generate
645
 
646
    rstdel : process (clk, rst)
647
    begin
648
        if rst = '0' then dll0rst <= (others => '1');
649
        elsif rising_edge(clk) then
650
          dll0rst <= dll0rst(1 to 3) & '0';
651
        end if;
652
    end process;
653
 
654
    bufg0 : BUFG port map (I => mclkfx, O => mclk);
655
    bufg1 : BUFG port map (I => mclk0, O => mclkfb);
656
 
657
    dllm : DCM
658
      generic map (CLKFX_MULTIPLY => clk_mul, CLKFX_DIVIDE => clk_div,
659
        CLKIN_PERIOD => 10.0)
660
      port map ( CLKIN => clk, CLKFB => mclkfb, DSSEN => gnd, PSCLK => gnd,
661
      PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => mclk0,
662
      LOCKED => mlock, CLKFX => mclkfx );
663
  end generate;
664
 
665
  -- DDR output clock generation
666
 
667
  bufg1 : BUFG port map (I => clk_0ro, O => clk_0r);
668
--  bufg2 : BUFG port map (I => clk_90ro, O => clk_90r);
669
  clk_90r <= not clk_270r;
670
--  bufg3 : BUFG port map (I => clk_180ro, O => clk_180r);
671
  clk_180r <= not clk_0r;
672
  bufg4 : BUFG port map (I => clk_270ro, O => clk_270r);
673
 
674
  clkout <= clk_270r; clk0r <= clk_270r; clk90r <= clk_0r;
675
  clk180r <= clk_90r; clk270r <= clk_180r;
676
 
677
 
678
  dll : DCM generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2)
679
      port map ( CLKIN => mclk, CLKFB => clk_0r, DSSEN => gnd, PSCLK => gnd,
680
      PSEN => gnd, PSINCDEC => gnd, RST => dllrst(0), CLK0 => clk_0ro,
681
      CLK90 => clk_90ro, CLK180 => clk_180ro, CLK270 => clk_270ro,
682
      LOCKED => lockl);
683
 
684
  rstdel : process (mclk, mlock)
685
  begin
686
      if mlock = '0' then dllrst <= (others => '1');
687
      elsif rising_edge(mclk) then
688
        dllrst <= dllrst(1 to 3) & '0';
689
      end if;
690
  end process;
691
 
692
  rdel : if rstdelay /= 0 generate
693
    rcnt : process (clk_0r)
694
    variable cnt : std_logic_vector(15 downto 0);
695
    variable vlock, co : std_ulogic;
696
    begin
697
      if rising_edge(clk_0r) then
698
        co := cnt(15);
699
        vlockl <= vlock;
700
        if lockl = '0' then
701
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16); vlock := '0';
702
        else
703
          if vlock = '0' then
704
            cnt := cnt -1;  vlock := cnt(15) and not co;
705
          end if;
706
        end if;
707
      end if;
708
      if lockl = '0' then
709
        vlock := '0';
710
      end if;
711
    end process;
712
  end generate;
713
 
714
  locked <= lockl when rstdelay = 0 else vlockl;
715
  lock <= locked;
716
 
717
  -- Generate external DDR clock
718
 
719
  fbdclk0r : FDDRRSE port map ( Q => ddr_clk_fb_outr, C0 => clk90r, C1 => clk270r,
720
        CE => vcc, D0 => vcc, D1 => gnd, R => gnd, S => gnd);
721
  fbclk_pad : outpad generic map (tech => virtex4, level => sstl2_i)
722
        port map (ddr_clk_fb_out, ddr_clk_fb_outr);
723
 
724
  ddrclocks : for i in 0 to 2 generate
725
    dclk0r : FDDRRSE port map ( Q => ddr_clkl(i), C0 => clk90r, C1 => clk270r,
726
        CE => vcc, D0 => vcc, D1 => gnd, R => gnd, S => gnd);
727
    ddrclk_pad : outpad generic map (tech => virtex4, level => sstl2_i)
728
        port map (ddr_clk(i), ddr_clkl(i));
729
 
730
    dclk0rb : FDDRRSE port map ( Q => ddr_clkbl(i), C0 => clk90r, C1 => clk270r,
731
        CE => vcc, D0 => gnd, D1 => vcc, R => gnd, S => gnd);
732
    ddrclkb_pad : outpad generic map (tech => virtex4, level => sstl2_i)
733
        port map (ddr_clkb(i), ddr_clkbl(i));
734
  end generate;
735
 
736
  ddrbanks : for i in 0 to 1 generate
737
    csn0gen : FD port map ( Q => ddr_csnr(i), C => clk0r, D => csn(i));
738
    csn0_pad : outpad generic map (tech => virtex4, level => sstl2_i)
739
        port map (ddr_csb(i), ddr_csnr(i));
740
 
741
    ckel(i) <= cke(i) and locked;
742
    ckegen : FD port map ( Q => ddr_ckenr(i), C => clk0r, D => ckel(i));
743
    cke_pad : outpad generic map (tech => virtex4, level => sstl2_i)
744
        port map (ddr_cke(i), ddr_ckenr(i));
745
 
746
  end generate;
747
 
748
  --  DDR single-edge control signals
749
  rasgen : FD port map ( Q => ddr_rasnr, C => clk0r, D => rasn);
750
  rasn_pad : outpad generic map (tech => virtex4, level => sstl2_i)
751
        port map (ddr_rasb, ddr_rasnr);
752
 
753
  casgen : FD port map ( Q => ddr_casnr, C => clk0r, D => casn);
754
  casn_pad : outpad generic map (tech => virtex4, level => sstl2_i)
755
        port map (ddr_casb, ddr_casnr);
756
 
757
  wengen : FD port map ( Q => ddr_wenr, C => clk0r, D => wen);
758
  wen_pad : outpad generic map (tech => virtex4, level => sstl2_i)
759
        port map (ddr_web, ddr_wenr);
760
 
761
  dmgen : for i in 0 to dbits/8-1 generate
762
    da0 : oddrv2 port map ( Q => ddr_dmr(i), C1 => clk0r, C2 => clk180r,
763
        CE => vcc, D1 => dm(i+dbits/8), D2 => dm(i), R => gnd, S => gnd);
764
    ddr_bm_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
765
        port map (ddr_dm(i), ddr_dmr(i));
766
  end generate;
767
 
768
  bagen : for i in 0 to 1 generate
769
    da0 : FD port map ( Q => ddr_bar(i), C => clk0r, D => ba(i));
770
    ddr_ba_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
771
        port map (ddr_ba(i), ddr_bar(i));
772
  end generate;
773
 
774
  dagen : for i in 0 to 13 generate
775
    da0 : FD port map ( Q => ddr_adr(i), C => clk0r, D => addr(i));
776
    ddr_ad_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
777
        port map (ddr_ad(i), ddr_adr(i));
778
 
779
  end generate;
780
 
781
  -- DQS generation
782
  dsqreg : FD port map ( Q => dqsn, C => clk180r, D => oe);
783
  dqsgen : for i in 0 to dbits/8-1 generate
784
    da0 : oddrv2
785
        port map ( Q => ddr_dqsin(i), C1 => clk90r,  C2 => clk270r,
786
        CE => vcc, D1 => dqsn, D2 => gnd, R => gnd, S => gnd);
787
    doen : FD port map ( Q => ddr_dqsoen(i), C => clk0r, D => dqsoen);
788
    dqs_pad : iopad generic map (tech => virtex4, level => sstl2_ii)
789
         port map (pad => ddr_dqs(i), i => ddr_dqsin(i), en => ddr_dqsoen(i),
790
                o => ddr_dqsoutl(i));
791
  end generate;
792
 
793
  -- Data bus
794
 
795
  ddrref_pad : clkpad generic map (tech => virtex2)
796
        port map (ddr_clk_fb, ddrclkfbl);
797
 
798
    read_rstdel : process (clk_0r, lockl)
799
    begin
800
        if lockl = '0' then dll2rst <= (others => '1');
801
        elsif rising_edge(clk_0r) then
802
          dll2rst <= dll2rst(1 to 3) & '0';
803
        end if;
804
    end process;
805
 
806
    bufg7 : BUFG port map (I => rclk0, O => rclk0b);
807
    bufg8 : BUFG port map (I => rclk90, O => rclk90b);
808
--    bufg9 : BUFG port map (I => rclk270, O => rclk270b);
809
    rclk270b <= not rclk90b;
810
 
811
  nops : if rskew = 0 generate
812
    read_dll : DCM
813
      generic map (clkin_period => 10.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS")
814
      port map ( CLKIN => ddrclkfbl, CLKFB => rclk0b, DSSEN => gnd, PSCLK => gnd,
815
      PSEN => gnd, PSINCDEC => gnd, RST => dll2rst(0), CLK0 => rclk0,
816
      CLK90 => rclk90, CLK270 => rclk270);
817
  end generate;
818
 
819
  ps : if rskew /= 0 generate
820
    read_dll : DCM
821
      generic map (clkin_period => 10.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS",
822
        CLKOUT_PHASE_SHIFT => "FIXED", PHASE_SHIFT => rskew)
823
      port map ( CLKIN => ddrclkfbl, CLKFB => rclk0b, DSSEN => gnd, PSCLK => gnd,
824
      PSEN => gnd, PSINCDEC => gnd, RST => dll2rst(0), CLK0 => rclk0,
825
      CLK90 => rclk90, CLK270 => rclk270);
826
  end generate;
827
 
828
  ddgen : for i in 0 to dbits-1 generate
829
    qi : IFDDRRSE
830
    port map ( Q0 => dqinl(i), --(i+dbits), -- 1-bit output for positive edge of clock 
831
               Q1 => dqin(i), -- 1-bit output for negative edge of clock 
832
               C0 => rclk90b, -- clk270r, --dqsclk((2*i)/dbits), -- 1-bit clock input 
833
               C1 => rclk270b, -- clk90r, --dqsclk((2*i)/dbits), -- 1-bit clock input 
834
               CE => vcc, -- 1-bit clock enable input 
835
                D => ddr_dq(i), -- 1-bit DDR data input 
836
                R => gnd, -- 1-bit reset 
837
                S => gnd -- 1-bit set 
838
              );
839
 
840
--    dinq1 : FD port map ( Q => dqin(i+dbits), C => clk90r, D => dqinl(i));
841
    dinq1 : FD port map ( Q => dqin(i+dbits), C => rclk270b, D => dqinl(i));
842
    dout : oddrv2
843
        port map ( Q => ddr_dqout(i), C1 => clk0r, C2 => clk180r, CE => vcc,
844
                D1 => dqout(i+dbits), D2 => dqout(i), R => gnd, S => gnd);
845
    doen : FD port map ( Q => ddr_dqoen(i), C => clk0r, D => oen);
846
    dq_pad : iopad generic map (tech => virtex4, level => sstl2_ii)
847
         port map (pad => ddr_dq(i), i => ddr_dqout(i), en => ddr_dqoen(i), o => open); -- o => ddr_dqin(i));
848
  end generate;
849
 
850
 
851
 
852
end;
853
 
854
library ieee;
855
use ieee.std_logic_1164.all;
856
-- pragma translate_off
857
library unisim;
858
use unisim.BUFG;
859
use unisim.DCM;
860
use unisim.ODDR2;
861
use unisim.IDDR2;
862
use unisim.FD;
863
-- pragma translate_on
864
 
865
library grlib;
866
use grlib.stdlib.all;
867
library techmap;
868
use techmap.gencomp.all;
869
use techmap.oddrc3e;
870
 
871
------------------------------------------------------------------
872
-- Spartan3E DDR PHY -----------------------------------------------
873
------------------------------------------------------------------
874
 
875
entity spartan3e_ddr_phy is
876
  generic (MHz : integer := 100; rstdelay : integer := 200;
877
        dbits : integer := 16; clk_mul : integer := 2 ;
878
        clk_div : integer := 2; rskew : integer := 0);
879
 
880
  port (
881
    rst       : in  std_ulogic;
882
    clk       : in  std_logic;                  -- input clock
883
    clkout    : out std_ulogic;                 -- DDR state clock
884
    clkread   : out std_ulogic;                 -- DDR read clock
885
    lock      : out std_ulogic;                 -- DCM locked
886
 
887
    ddr_clk     : out std_logic_vector(2 downto 0);
888
    ddr_clkb    : out std_logic_vector(2 downto 0);
889
    ddr_clk_fb_out  : out std_logic;
890
    ddr_clk_fb  : in std_logic;
891
    ddr_cke     : out std_logic_vector(1 downto 0);
892
    ddr_csb     : out std_logic_vector(1 downto 0);
893
    ddr_web     : out std_ulogic;                       -- ddr write enable
894
    ddr_rasb    : out std_ulogic;                       -- ddr ras
895
    ddr_casb    : out std_ulogic;                       -- ddr cas
896
    ddr_dm      : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
897
    ddr_dqs     : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
898
    ddr_ad      : out std_logic_vector (13 downto 0);   -- ddr address
899
    ddr_ba      : out std_logic_vector (1 downto 0);    -- ddr bank address
900
    ddr_dq      : inout  std_logic_vector (dbits-1 downto 0); -- ddr data
901
 
902
    addr        : in  std_logic_vector (13 downto 0); -- data mask
903
    ba          : in  std_logic_vector ( 1 downto 0); -- data mask
904
    dqin        : out std_logic_vector (dbits*2-1 downto 0); -- ddr input data
905
    dqout       : in  std_logic_vector (dbits*2-1 downto 0); -- ddr input data
906
    dm          : in  std_logic_vector (dbits/4-1 downto 0); -- data mask
907
    oen         : in  std_ulogic;
908
    dqs         : in  std_ulogic;
909
    dqsoen      : in  std_ulogic;
910
    rasn        : in  std_ulogic;
911
    casn        : in  std_ulogic;
912
    wen         : in  std_ulogic;
913
    csn         : in  std_logic_vector(1 downto 0);
914
    cke         : in  std_logic_vector(1 downto 0)
915
  );
916
 
917
end;
918
 
919
architecture rtl of spartan3e_ddr_phy is
920
 
921
component oddrc3e
922
  generic ( tech : integer := virtex4);
923
  port
924
    ( Q : out std_ulogic;
925
      C1 : in std_ulogic;
926
      C2 : in std_ulogic;
927
      CE : in std_ulogic;
928
      D1 : in std_ulogic;
929
      D2 : in std_ulogic;
930
      R : in std_ulogic;
931
      S : in std_ulogic);
932
end component;
933
 
934
  component DCM
935
    generic (
936
      CLKDV_DIVIDE : real := 2.0;
937
      CLKFX_DIVIDE : integer := 1;
938
      CLKFX_MULTIPLY : integer := 4;
939
      CLKIN_DIVIDE_BY_2 : boolean := false;
940
      CLKIN_PERIOD : real := 10.0;
941
      CLKOUT_PHASE_SHIFT : string := "NONE";
942
      CLK_FEEDBACK : string := "1X";
943
      DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS";
944
      DFS_FREQUENCY_MODE : string := "LOW";
945
      DLL_FREQUENCY_MODE : string := "LOW";
946
      DSS_MODE : string := "NONE";
947
      DUTY_CYCLE_CORRECTION : boolean := true;
948
      FACTORY_JF : bit_vector := X"C080";
949
      PHASE_SHIFT : integer := 0;
950
      STARTUP_WAIT : boolean := false
951
    );
952
    port (
953
      CLKFB    : in  std_logic;
954
      CLKIN    : in  std_logic;
955
      DSSEN    : in  std_logic;
956
      PSCLK    : in  std_logic;
957
      PSEN     : in  std_logic;
958
      PSINCDEC : in  std_logic;
959
      RST      : in  std_logic;
960
      CLK0     : out std_logic;
961
      CLK90    : out std_logic;
962
      CLK180   : out std_logic;
963
      CLK270   : out std_logic;
964
      CLK2X    : out std_logic;
965
      CLK2X180 : out std_logic;
966
      CLKDV    : out std_logic;
967
      CLKFX    : out std_logic;
968
      CLKFX180 : out std_logic;
969
      LOCKED   : out std_logic;
970
      PSDONE   : out std_logic;
971
      STATUS   : out std_logic_vector (7 downto 0));
972
  end component;
973
  component BUFG port (O : out std_logic; I : in std_logic); end component;
974
  component FD
975
        generic ( INIT : bit := '0');
976
        port (  Q : out std_ulogic;
977
                C : in std_ulogic;
978
                D : in std_ulogic);
979
  end component;
980
 
981
  component ODDR2
982
        generic
983
        (
984
                DDR_ALIGNMENT : string := "NONE";
985
                INIT : bit := '0';
986
                SRTYPE : string := "SYNC"
987
        );
988
        port
989
        (
990
                Q : out std_ulogic;
991
                C0 : in std_ulogic;
992
                C1 : in std_ulogic;
993
                CE : in std_ulogic;
994
                D0 : in std_ulogic;
995
                D1 : in std_ulogic;
996
                R : in std_ulogic;
997
                S : in std_ulogic
998
        );
999
  end component;
1000
  component IDDR2
1001
        generic
1002
        (
1003
                DDR_ALIGNMENT : string := "NONE";
1004
                INIT_Q0 : bit := '0';
1005
                INIT_Q1 : bit := '0';
1006
                SRTYPE : string := "SYNC"
1007
        );
1008
        port
1009
        (
1010
                Q0 : out std_ulogic;
1011
                Q1 : out std_ulogic;
1012
                C0 : in std_ulogic;
1013
                C1 : in std_ulogic;
1014
                CE : in std_ulogic;
1015
                D : in std_ulogic;
1016
                R : in std_ulogic;
1017
                S : in std_ulogic
1018
        );
1019
  end component;
1020
 
1021
signal vcc, gnd, dqsn, oe, lockl : std_ulogic;
1022
signal ddr_clk_fb_outr : std_ulogic;
1023
signal ddr_clk_fbl, fbclk : std_ulogic;
1024
signal ddr_rasnr, ddr_casnr, ddr_wenr : std_ulogic;
1025
signal ddr_clkl, ddr_clkbl : std_logic_vector(2 downto 0);
1026
signal ddr_csnr, ddr_ckenr, ckel : std_logic_vector(1 downto 0);
1027
signal clk_0ro, clk_90ro, clk_180ro, clk_270ro : std_ulogic;
1028
signal clk_0r, clk_90r, clk_180r, clk_270r : std_ulogic;
1029
signal clk0r, clk90r, clk180r, clk270r : std_ulogic;
1030
signal locked, vlockl, ddrclkfbl, dllfb : std_ulogic;
1031
signal ddr_dqin         : std_logic_vector (dbits-1 downto 0); -- ddr data
1032
signal ddr_dqout        : std_logic_vector (dbits-1 downto 0); -- ddr data
1033
signal ddr_dqoen        : std_logic_vector (dbits-1 downto 0); -- ddr data
1034
signal ddr_adr          : std_logic_vector (13 downto 0);   -- ddr address
1035
signal ddr_bar          : std_logic_vector (1 downto 0);   -- ddr address
1036
signal ddr_dmr          : std_logic_vector (dbits/8-1 downto 0);   -- ddr address
1037
signal ddr_dqsin        : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1038
signal ddr_dqsoen       : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1039
signal ddr_dqsoutl      : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1040
signal dqsdel, dqsclk   : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1041
signal da               : std_logic_vector (dbits-1 downto 0); -- ddr data
1042
signal dqinl            : std_logic_vector (dbits-1 downto 0); -- ddr data
1043
signal dllrst           : std_logic_vector(0 to 3);
1044
signal dll0rst, dll2rst : std_logic_vector(0 to 3);
1045
signal mlock, mclkfb, mclk, mclkfx, mclk0 : std_ulogic;
1046
signal rclk270b, rclk90b, rclk0b : std_ulogic;
1047
signal rclk270, rclk90, rclk0 : std_ulogic;
1048
 
1049
constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
1050
 
1051
-- To prevent synplify 9.4 to remove any of these registers.
1052
attribute syn_noprune : boolean;
1053
attribute syn_noprune of FD : component is true;
1054
attribute syn_noprune of IDDR2 : component is true;
1055
attribute syn_noprune of ODDR2 : component is true;
1056
attribute syn_noprune of oddrc3e : component is true;
1057
 
1058
begin
1059
 
1060
  oe <= not oen;
1061
  vcc <= '1'; gnd <= '0';
1062
 
1063
  -- Optional DDR clock multiplication
1064
 
1065
  noclkscale : if clk_mul = clk_div generate
1066
    mclk <= clk; mlock <= rst;
1067
  end generate;
1068
 
1069
  clkscale : if clk_mul /= clk_div generate
1070
 
1071
    rstdel : process (clk, rst)
1072
    begin
1073
        if rst = '0' then dll0rst <= (others => '1');
1074
        elsif rising_edge(clk) then
1075
          dll0rst <= dll0rst(1 to 3) & '0';
1076
        end if;
1077
    end process;
1078
 
1079
    bufg0 : BUFG port map (I => mclkfx, O => mclk);
1080
    bufg1 : BUFG port map (I => mclk0, O => mclkfb);
1081
 
1082
    dllm : DCM
1083
      generic map (CLKFX_MULTIPLY => clk_mul, CLKFX_DIVIDE => clk_div,
1084
        CLKIN_PERIOD => 10.0)
1085
      port map ( CLKIN => clk, CLKFB => mclkfb, DSSEN => gnd, PSCLK => gnd,
1086
      PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => mclk0,
1087
      LOCKED => mlock, CLKFX => mclkfx );
1088
  end generate;
1089
 
1090
  -- DDR output clock generation
1091
 
1092
  bufg1 : BUFG port map (I => clk_0ro, O => clk_0r);
1093
--  bufg2 : BUFG port map (I => clk_90ro, O => clk_90r);
1094
  clk_90r <= not clk_270r;
1095
--  bufg3 : BUFG port map (I => clk_180ro, O => clk_180r);
1096
  clk_180r <= not clk_0r;
1097
  bufg4 : BUFG port map (I => clk_270ro, O => clk_270r);
1098
 
1099
  clkout <= clk_270r;
1100
--  clkout <= clk_90r when DDR_FREQ > 120 else clk_0r; 
1101
 
1102
  clk0r <= clk_270r; clk90r <= clk_0r;
1103
  clk180r <= clk_90r; clk270r <= clk_180r;
1104
 
1105
  dll : DCM generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2)
1106
      port map ( CLKIN => mclk, CLKFB => clk_0r, DSSEN => gnd, PSCLK => gnd,
1107
      PSEN => gnd, PSINCDEC => gnd, RST => dllrst(0), CLK0 => clk_0ro,
1108
      CLK90 => clk_90ro, CLK180 => clk_180ro, CLK270 => clk_270ro,
1109
      LOCKED => lockl);
1110
 
1111
  rstdel : process (mclk, mlock)
1112
  begin
1113
      if mlock = '0' then dllrst <= (others => '1');
1114
      elsif rising_edge(mclk) then
1115
        dllrst <= dllrst(1 to 3) & '0';
1116
      end if;
1117
  end process;
1118
 
1119
  rdel : if rstdelay /= 0 generate
1120
    rcnt : process (clk_0r)
1121
    variable cnt : std_logic_vector(15 downto 0);
1122
    variable vlock, co : std_ulogic;
1123
    begin
1124
      if rising_edge(clk_0r) then
1125
        co := cnt(15);
1126
        vlockl <= vlock;
1127
        if lockl = '0' then
1128
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16); vlock := '0';
1129
        else
1130
          if vlock = '0' then
1131
            cnt := cnt -1;  vlock := cnt(15) and not co;
1132
          end if;
1133
        end if;
1134
      end if;
1135
      if lockl = '0' then
1136
        vlock := '0';
1137
      end if;
1138
    end process;
1139
  end generate;
1140
 
1141
  locked <= lockl when rstdelay = 0 else vlockl;
1142
  lock <= locked;
1143
 
1144
  -- Generate external DDR clock
1145
 
1146
  fbdclk0r : ODDR2 port map ( Q => ddr_clk_fb_outr, C0 => clk90r, C1 => clk270r,
1147
        CE => vcc, D0 => vcc, D1 => gnd, R => gnd, S => gnd);
1148
  fbclk_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1149
        port map (ddr_clk_fb_out, ddr_clk_fb_outr);
1150
 
1151
  ddrclocks : for i in 0 to 2 generate
1152
    dclk0r : ODDR2 port map ( Q => ddr_clkl(i), C0 => clk90r, C1 => clk270r,
1153
        CE => vcc, D0 => vcc, D1 => gnd, R => gnd, S => gnd);
1154
    ddrclk_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1155
        port map (ddr_clk(i), ddr_clkl(i));
1156
 
1157
    dclk0rb : ODDR2 port map ( Q => ddr_clkbl(i), C0 => clk90r, C1 => clk270r,
1158
        CE => vcc, D0 => gnd, D1 => vcc, R => gnd, S => gnd);
1159
    ddrclkb_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1160
        port map (ddr_clkb(i), ddr_clkbl(i));
1161
  end generate;
1162
 
1163
  ddrbanks : for i in 0 to 1 generate
1164
    csn0gen : FD port map ( Q => ddr_csnr(i), C => clk0r, D => csn(i));
1165
    csn0_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1166
        port map (ddr_csb(i), ddr_csnr(i));
1167
 
1168
    ckel(i) <= cke(i) and locked;
1169
    ckegen : FD port map ( Q => ddr_ckenr(i), C => clk0r, D => ckel(i));
1170
    cke_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1171
        port map (ddr_cke(i), ddr_ckenr(i));
1172
 
1173
  end generate;
1174
 
1175
  --  DDR single-edge control signals
1176
  rasgen : FD port map ( Q => ddr_rasnr, C => clk0r, D => rasn);
1177
  rasn_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1178
        port map (ddr_rasb, ddr_rasnr);
1179
 
1180
  casgen : FD port map ( Q => ddr_casnr, C => clk0r, D => casn);
1181
  casn_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1182
        port map (ddr_casb, ddr_casnr);
1183
 
1184
  wengen : FD port map ( Q => ddr_wenr, C => clk0r, D => wen);
1185
  wen_pad : outpad generic map (tech => virtex4, level => sstl2_i)
1186
        port map (ddr_web, ddr_wenr);
1187
 
1188
  dmgen : for i in 0 to dbits/8-1 generate
1189
    da0 : oddrc3e
1190
        port map ( Q => ddr_dmr(i), C1 => clk0r, C2 => clk180r,
1191
        CE => vcc, D1 => dm(i+dbits/8), D2 => dm(i), R => gnd, S => gnd);
1192
    ddr_bm_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
1193
        port map (ddr_dm(i), ddr_dmr(i));
1194
  end generate;
1195
 
1196
  bagen : for i in 0 to 1 generate
1197
    da0 : FD port map ( Q => ddr_bar(i), C => clk0r, D => ba(i));
1198
    ddr_ba_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
1199
        port map (ddr_ba(i), ddr_bar(i));
1200
  end generate;
1201
 
1202
  dagen : for i in 0 to 13 generate
1203
    da0 : FD port map ( Q => ddr_adr(i), C => clk0r, D => addr(i));
1204
    ddr_ad_pad  : outpad generic map (tech => virtex4, level => sstl2_i)
1205
        port map (ddr_ad(i), ddr_adr(i));
1206
 
1207
  end generate;
1208
 
1209
  -- DQS generation
1210
  dsqreg : FD port map ( Q => dqsn, C => clk180r, D => oe);
1211
  dqsgen : for i in 0 to dbits/8-1 generate
1212
    da0 : oddrc3e
1213
        port map ( Q => ddr_dqsin(i), C1 => clk90r,  C2 => clk270r,
1214
        CE => vcc, D1 => dqsn, D2 => gnd, R => gnd, S => gnd);
1215
    doen : FD port map ( Q => ddr_dqsoen(i), C => clk0r, D => dqsoen);
1216
    dqs_pad : iopad generic map (tech => virtex4, level => sstl2_i)
1217
         port map (pad => ddr_dqs(i), i => ddr_dqsin(i), en => ddr_dqsoen(i),
1218
                o => ddr_dqsoutl(i));
1219
  end generate;
1220
 
1221
  -- Data bus
1222
 
1223
  ddrref_pad : clkpad generic map (tech => virtex2)
1224
        port map (ddr_clk_fb, ddrclkfbl);
1225
 
1226
 
1227
    read_rstdel : process (clk_0r, lockl)
1228
    begin
1229
        if lockl = '0' then dll2rst <= (others => '1');
1230
        elsif rising_edge(clk_0r) then
1231
          dll2rst <= dll2rst(1 to 3) & '0';
1232
        end if;
1233
    end process;
1234
 
1235
    bufg7 : BUFG port map (I => rclk0, O => rclk0b);
1236
    bufg8 : BUFG port map (I => rclk90, O => rclk90b);
1237
--    bufg9 : BUFG port map (I => rclk270, O => rclk270b);
1238
    rclk270b <= not rclk90b;
1239
    clkread <= not rclk90b;
1240
 
1241
  nops : if rskew = 0 generate
1242
    read_dll : DCM
1243
      generic map (clkin_period => 10.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS")
1244
      port map ( CLKIN => ddrclkfbl, CLKFB => rclk0b, DSSEN => gnd, PSCLK => gnd,
1245
      PSEN => gnd, PSINCDEC => gnd, RST => dll2rst(0), CLK0 => rclk0,
1246
      CLK90 => rclk90, CLK270 => rclk270);
1247
  end generate;
1248
  ps : if rskew /= 0 generate
1249
    read_dll : DCM
1250
      generic map (clkin_period => 10.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS",
1251
        CLKOUT_PHASE_SHIFT => "FIXED", PHASE_SHIFT => rskew)
1252
      port map ( CLKIN => ddrclkfbl, CLKFB => rclk0b, DSSEN => gnd, PSCLK => gnd,
1253
      PSEN => gnd, PSINCDEC => gnd, RST => dll2rst(0), CLK0 => rclk0,
1254
      CLK90 => rclk90, CLK270 => rclk270);
1255
  end generate;
1256
 
1257
  ddgen : for i in 0 to dbits-1 generate
1258
    qi : IDDR2
1259
    port map ( Q0 => dqinl(i), Q1 => dqin(i), C0 => rclk90b, C1 => rclk270b,
1260
               CE => vcc, D => ddr_dqin(i), R => gnd, S => gnd );
1261
    dinq1 : FD port map ( Q => dqin(i+dbits), C => rclk270b, D => dqinl(i));
1262
    dout : oddrc3e
1263
        port map ( Q => ddr_dqout(i), C1 => clk0r, C2 => clk180r, CE => vcc,
1264
                D1 => dqout(i+dbits), D2 => dqout(i), R => gnd, S => gnd);
1265
    doen : FD port map ( Q => ddr_dqoen(i), C => clk0r, D => oen);
1266
    dq_pad : iopad generic map (tech => virtex4, level => sstl2_i)
1267
       port map (pad => ddr_dq(i), i => ddr_dqout(i), en => ddr_dqoen(i), o => ddr_dqin(i));
1268
  end generate;
1269
 
1270
end;
1271
 
1272
library ieee;
1273
use ieee.std_logic_1164.all;
1274
library grlib;
1275
use grlib.stdlib.all;
1276
-- pragma translate_off
1277
library unisim;
1278
use unisim.BUFG;
1279
use unisim.DCM;
1280
use unisim.ODDR;
1281
use unisim.FD;
1282
use unisim.IDELAY;
1283
use unisim.ISERDES;
1284
use unisim.BUFIO;
1285
use unisim.IDELAYCTRL;
1286
-- pragma translate_on
1287
 
1288
library techmap;
1289
use techmap.gencomp.all;
1290
------------------------------------------------------------------
1291
-- Virtex5 DDR2 PHY ----------------------------------------------
1292
------------------------------------------------------------------
1293
 
1294
entity virtex5_ddr2_phy is
1295
  generic (MHz : integer := 100; rstdelay : integer := 200;
1296
           dbits : integer := 16; clk_mul : integer := 2; clk_div : integer := 2;
1297
           ddelayb0 : integer := 0; ddelayb1 : integer := 0; ddelayb2 : integer := 0;
1298
           ddelayb3 : integer := 0; ddelayb4 : integer := 0; ddelayb5 : integer := 0;
1299
           ddelayb6 : integer := 0; ddelayb7 : integer := 0;
1300
           numidelctrl : integer := 4; norefclk : integer := 0;
1301
           tech : integer := virtex5; odten : integer := 0);
1302
 
1303
  port (
1304
    rst        : in  std_ulogic;
1305
    clk        : in  std_logic;        -- input clock
1306
    clkref200  : in  std_logic;        -- input 200MHz clock
1307
    clkout     : out std_ulogic;       -- system clock
1308
    lock       : out std_ulogic;       -- DCM locked
1309
 
1310
    ddr_clk    : out std_logic_vector(2 downto 0);
1311
    ddr_clkb   : out std_logic_vector(2 downto 0);
1312
    ddr_cke    : out std_logic_vector(1 downto 0);
1313
    ddr_csb    : out std_logic_vector(1 downto 0);
1314
    ddr_web    : out std_ulogic;                       -- ddr write enable
1315
    ddr_rasb   : out std_ulogic;                       -- ddr ras
1316
    ddr_casb   : out std_ulogic;                       -- ddr cas
1317
    ddr_dm     : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
1318
    ddr_dqs    : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1319
    ddr_dqsn   : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqsn
1320
    ddr_ad     : out std_logic_vector (13 downto 0);   -- ddr address
1321
    ddr_ba     : out std_logic_vector (1 downto 0);    -- ddr bank address
1322
    ddr_dq     : inout  std_logic_vector (dbits-1 downto 0); -- ddr data
1323
    ddr_odt    : out std_logic_vector(1 downto 0);
1324
 
1325
    addr       : in  std_logic_vector (13 downto 0); -- data mask
1326
    ba         : in  std_logic_vector ( 1 downto 0); -- data mask
1327
    dqin       : out std_logic_vector (dbits*2-1 downto 0); -- ddr input data
1328
    dqout      : in  std_logic_vector (dbits*2-1 downto 0); -- ddr input data
1329
    dm         : in  std_logic_vector (dbits/4-1 downto 0); -- data mask
1330
    oen        : in  std_ulogic;
1331
    dqs        : in  std_ulogic;
1332
    dqsoen     : in  std_ulogic;
1333
    rasn       : in  std_ulogic;
1334
    casn       : in  std_ulogic;
1335
    wen        : in  std_ulogic;
1336
    csn        : in  std_logic_vector(1 downto 0);
1337
    cke        : in  std_logic_vector(1 downto 0);
1338
    cal_en     : in  std_logic_vector(dbits/8-1 downto 0);
1339
    cal_inc    : in  std_logic_vector(dbits/8-1 downto 0);
1340
    cal_rst    : in  std_logic;
1341
    odt        : in  std_logic_vector(1 downto 0)
1342
  );
1343
 
1344
end;
1345
 
1346
architecture rtl of virtex5_ddr2_phy is
1347
 
1348
  component DCM
1349
    generic (
1350
      CLKDV_DIVIDE : real := 2.0;
1351
      CLKFX_DIVIDE : integer := 1;
1352
      CLKFX_MULTIPLY : integer := 4;
1353
      CLKIN_DIVIDE_BY_2 : boolean := false;
1354
      CLKIN_PERIOD : real := 10.0;
1355
      CLKOUT_PHASE_SHIFT : string := "NONE";
1356
      CLK_FEEDBACK : string := "1X";
1357
      DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS";
1358
      DFS_FREQUENCY_MODE : string := "LOW";
1359
      DLL_FREQUENCY_MODE : string := "LOW";
1360
      DSS_MODE : string := "NONE";
1361
      DUTY_CYCLE_CORRECTION : boolean := true;
1362
      FACTORY_JF : bit_vector := X"C080";
1363
      PHASE_SHIFT : integer := 0;
1364
      STARTUP_WAIT : boolean := false
1365
    );
1366
    port (
1367
      CLKFB    : in  std_logic;
1368
      CLKIN    : in  std_logic;
1369
      DSSEN    : in  std_logic;
1370
      PSCLK    : in  std_logic;
1371
      PSEN     : in  std_logic;
1372
      PSINCDEC : in  std_logic;
1373
      RST      : in  std_logic;
1374
      CLK0     : out std_logic;
1375
      CLK90    : out std_logic;
1376
      CLK180   : out std_logic;
1377
      CLK270   : out std_logic;
1378
      CLK2X    : out std_logic;
1379
      CLK2X180 : out std_logic;
1380
      CLKDV    : out std_logic;
1381
      CLKFX    : out std_logic;
1382
      CLKFX180 : out std_logic;
1383
      LOCKED   : out std_logic;
1384
      PSDONE   : out std_logic;
1385
      STATUS   : out std_logic_vector (7 downto 0));
1386
  end component;
1387
 
1388
  component BUFG port (O : out std_logic; I : in std_logic); end component;
1389
  component ODDR
1390
    generic
1391
      ( DDR_CLK_EDGE : string := "OPPOSITE_EDGE";
1392
--        INIT : bit := '0';
1393
        SRTYPE : string := "SYNC");
1394
    port
1395
      (
1396
        Q : out std_ulogic;
1397
        C : in std_ulogic;
1398
        CE : in std_ulogic;
1399
        D1 : in std_ulogic;
1400
        D2 : in std_ulogic;
1401
        R : in std_ulogic;
1402
        S : in std_ulogic
1403
      );
1404
  end component;
1405
  component FD
1406
    generic ( INIT : bit := '0');
1407
    port (  Q : out std_ulogic;
1408
      C : in std_ulogic;
1409
      D : in std_ulogic);
1410
  end component;
1411
  component IDDR
1412
    generic ( DDR_CLK_EDGE : string := "SAME_EDGE";
1413
        INIT_Q1 : bit := '0';
1414
        INIT_Q2 : bit := '0';
1415
        SRTYPE : string := "ASYNC");
1416
    port
1417
      ( Q1 : out std_ulogic;
1418
        Q2 : out std_ulogic;
1419
        C : in std_ulogic;
1420
        CE : in std_ulogic;
1421
        D : in std_ulogic;
1422
        R : in std_ulogic;
1423
        S : in std_ulogic);
1424
  end component;
1425
 
1426
--  component BUFIO
1427
--  port (  O : out std_ulogic;
1428
--    I : in std_ulogic);
1429
--  end component;
1430
 
1431
  component IDELAY
1432
    generic ( IOBDELAY_TYPE : string := "DEFAULT";
1433
              IOBDELAY_VALUE : integer := 0);
1434
    port (  O : out std_ulogic;
1435
      C : in std_ulogic;
1436
      CE : in std_ulogic;
1437
      I : in std_ulogic;
1438
      INC : in std_ulogic;
1439
      RST : in std_ulogic);
1440
  end component;
1441
 
1442
--   component ISERDES
1443
--      generic
1444
--      (
1445
--         BITSLIP_ENABLE : boolean := false;
1446
--         DATA_RATE : string := "DDR";
1447
--         DATA_WIDTH : integer := 4;
1448
--         INIT_Q1 : bit := '0';
1449
--         INIT_Q2 : bit := '0';
1450
--         INIT_Q3 : bit := '0';
1451
--         INIT_Q4 : bit := '0';
1452
--         INTERFACE_TYPE : string := "MEMORY";
1453
--         IOBDELAY : string := "NONE";
1454
--         IOBDELAY_TYPE : string := "DEFAULT";
1455
--         IOBDELAY_VALUE : integer := 0;
1456
--         NUM_CE : integer := 2;
1457
--         SERDES_MODE : string := "MASTER";
1458
--         SRVAL_Q1 : bit := '0';
1459
--         SRVAL_Q2 : bit := '0';
1460
--         SRVAL_Q3 : bit := '0';
1461
--         SRVAL_Q4 : bit := '0'
1462
--      );
1463
--      port
1464
--      (
1465
--         O : out std_ulogic;
1466
--         Q1 : out std_ulogic;
1467
--         Q2 : out std_ulogic;
1468
--         Q3 : out std_ulogic;
1469
--         Q4 : out std_ulogic;
1470
--         Q5 : out std_ulogic;
1471
--         Q6 : out std_ulogic;
1472
--         SHIFTOUT1 : out std_ulogic;
1473
--         SHIFTOUT2 : out std_ulogic;
1474
--         BITSLIP : in std_ulogic;
1475
--         CE1 : in std_ulogic;
1476
--         CE2 : in std_ulogic;
1477
--         CLK : in std_ulogic;
1478
--         CLKDIV : in std_ulogic;
1479
--         D : in std_ulogic;
1480
--         DLYCE : in std_ulogic;
1481
--         DLYINC : in std_ulogic;
1482
--         DLYRST : in std_ulogic;
1483
--         OCLK : in std_ulogic;
1484
--         REV : in std_ulogic;
1485
--         SHIFTIN1 : in std_ulogic;
1486
--         SHIFTIN2 : in std_ulogic;
1487
--         SR : in std_ulogic
1488
--      );
1489
--   end component;
1490
 
1491
   component IDELAYCTRL
1492
   port (  RDY : out std_ulogic;
1493
      REFCLK : in std_ulogic;
1494
      RST : in std_ulogic);
1495
  end component;
1496
 
1497
--signal vcc, gnd, dqsn, oe, lockl : std_ulogic;
1498
signal vcc, gnd, oe, lockl : std_ulogic;
1499
signal dqsn : std_logic_vector(dbits/8-1 downto 0);
1500
 
1501
signal ddr_clk_fb_outr : std_ulogic;
1502
signal ddr_clk_fbl, fbclk : std_ulogic;
1503
signal ddr_rasnr, ddr_casnr, ddr_wenr : std_ulogic;
1504
signal ddr_clkl, ddr_clkbl : std_logic_vector(2 downto 0);
1505
signal ddr_csnr, ddr_ckenr, ckel : std_logic_vector(1 downto 0);
1506
signal clk_0ro, clk_90ro, clk_180ro, clk_270ro : std_ulogic;
1507
signal clk_0r, clk_90r, clk_180r, clk_270r : std_ulogic;
1508
signal clk0r, clk90r, clk180r, clk270r : std_ulogic;
1509
signal locked, vlockl, ddrclkfbl, dllfb : std_ulogic;
1510
 
1511
signal ddr_dqin, ddr_dqin_nodel : std_logic_vector (dbits-1 downto 0); -- ddr data
1512
signal ddr_dqout     : std_logic_vector (dbits-1 downto 0); -- ddr data
1513
signal ddr_dqoen     : std_logic_vector (dbits-1 downto 0); -- ddr data
1514
signal ddr_adr       : std_logic_vector (13 downto 0);   -- ddr address
1515
signal ddr_bar       : std_logic_vector (1 downto 0);   -- ddr address
1516
signal ddr_dmr       : std_logic_vector (dbits/8-1 downto 0);   -- ddr address
1517
signal ddr_dqsin     : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1518
signal ddr_dqsoen    : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1519
signal ddr_dqsoutl   : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1520
signal dqsdel, dqsclk, dqsclkn : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
1521
signal da            : std_logic_vector (dbits-1 downto 0); -- ddr data
1522
signal dqinl         : std_logic_vector (dbits-1 downto 0); -- ddr data
1523
signal dllrst        : std_logic_vector(0 to 3);
1524
signal dll0rst, dll2rst : std_logic_vector(0 to 3);
1525
signal mlock, mclkfb, mclk, mclkfx, mclk0 : std_ulogic;
1526
signal rclk270b, rclk90b, rclk0b : std_ulogic;
1527
signal rclk270, rclk90, rclk0 : std_ulogic;
1528
signal clk200, clk200_0, clk200fb, clk200fx, lock200 : std_logic;
1529
signal odtl : std_logic_vector(1 downto 0);
1530
signal refclk_rdy : std_logic_vector(numidelctrl-1 downto 0);
1531
 
1532
constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
1533
 
1534
type ddelay_type is array (7 downto 0) of integer;
1535
constant ddelay : ddelay_type := (ddelayb0, ddelayb1, ddelayb2,
1536
                                  ddelayb3, ddelayb4, ddelayb5,
1537
                                  ddelayb6, ddelayb7);
1538
 
1539
attribute syn_noprune : boolean;
1540
attribute syn_noprune of IDELAYCTRL : component is true;
1541
attribute syn_keep : boolean;
1542
attribute syn_keep of dqsclk : signal is true;
1543
attribute syn_preserve : boolean;
1544
attribute syn_preserve of dqsclk : signal is true;
1545
attribute syn_keep of dqsn : signal is true;
1546
attribute syn_preserve of dqsn : signal is true;
1547
 
1548
-- To prevent synplify 9.4 to remove any of these registers.
1549
attribute syn_noprune of FD : component is true;
1550
attribute syn_noprune of IDDR : component is true;
1551
attribute syn_noprune of ODDR : component is true;
1552
 
1553
attribute keep : boolean;
1554
attribute keep of mclkfx : signal is true;
1555
attribute keep of clk_90ro : signal is true;
1556
attribute syn_keep of mclkfx : signal is true;
1557
attribute syn_keep of clk_90ro : signal is true;
1558
 
1559
begin
1560
 
1561
   -- Generate 200 MHz ref clock if not supplied
1562
  refclkx : if norefclk = 0 generate
1563
    buf_clk200 : BUFG port map( I => clkref200, O => clk200);
1564
    lock200 <= '1';
1565
  end generate;
1566
 
1567
  norefclkx : if norefclk /= 0 generate
1568
    bufg0 : BUFG port map (I => clk200fx, O => clk200);
1569
    bufg1 : BUFG port map (I => clk200_0, O => clk200fb);
1570
 
1571
    HMODE_dll200 : if (tech = virtex4 and ((200 >= 210) or (MHz >= 210)))
1572
                      or (tech = virtex5 and ((200 >= 140) or (MHz >= 140))) generate
1573
      dll200 : DCM
1574
        generic map (CLKFX_MULTIPLY => 2000/MHz, CLKFX_DIVIDE => 10,
1575
                     DFS_FREQUENCY_MODE => "HIGH", DLL_FREQUENCY_MODE => "HIGH")
1576
        port map ( CLKIN => clk, CLKFB => clk200fb, DSSEN => gnd, PSCLK => gnd,
1577
        PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => clk200_0,
1578
        LOCKED => lock200, CLKFX => clk200fx);
1579
    end generate;
1580
    LMODE_dll200 : if not ((tech = virtex4 and ((200 >= 210) or (MHz >= 210)))
1581
                      or (tech = virtex5 and ((200 >= 140) or (MHz >= 140)))) generate
1582
      dll200 : DCM
1583
        generic map (CLKFX_MULTIPLY => 2000/MHz, CLKFX_DIVIDE => 10,
1584
                     DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "LOW")
1585
        port map ( CLKIN => clk, CLKFB => clk200fb, DSSEN => gnd, PSCLK => gnd,
1586
        PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => clk200_0,
1587
        LOCKED => lock200, CLKFX => clk200fx);
1588
    end generate;
1589
 
1590
  end generate;
1591
 
1592
  -- Delay control
1593
  idelctrl : for i in 0 to numidelctrl-1 generate
1594
     u : IDELAYCTRL port map (rst => dllrst(0), refclk => clk200, rdy => refclk_rdy(i));
1595
  end generate;
1596
 
1597
  oe <= not oen;
1598
  vcc <= '1'; gnd <= '0';
1599
 
1600
  -- Optional DDR clock multiplication
1601
 
1602
  noclkscale : if clk_mul = clk_div generate
1603
    --mclk <= clk;
1604
    dll0rst <= dllrst;
1605
    mlock <= '1';
1606
    mbufg0 : BUFG port map (I => clk, O => mclk);
1607
  end generate;
1608
 
1609
  clkscale : if clk_mul /= clk_div generate
1610
 
1611
    rstdel : process (clk, rst)
1612
    begin
1613
        if rst = '0' then dll0rst <= (others => '1');
1614
        elsif rising_edge(clk) then
1615
          dll0rst <= dll0rst(1 to 3) & '0';
1616
        end if;
1617
    end process;
1618
 
1619
    bufg0 : BUFG port map (I => mclkfx, O => mclk);
1620
    bufg1 : BUFG port map (I => mclk0, O => mclkfb);
1621
 
1622
    HMODE_dllm : if (tech = virtex4 and (((MHz*clk_mul)/clk_div >= 210) or (MHz >= 210)))
1623
                    or (tech = virtex5 and (((MHz*clk_mul)/clk_div >= 140) or (MHz >= 140))) generate
1624
      dllm : DCM
1625
        generic map (CLKFX_MULTIPLY => clk_mul, CLKFX_DIVIDE => clk_div,
1626
                     DFS_FREQUENCY_MODE => "HIGH", DLL_FREQUENCY_MODE => "HIGH")
1627
        port map ( CLKIN => clk, CLKFB => mclkfb, DSSEN => gnd, PSCLK => gnd,
1628
        PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => mclk0,
1629
        LOCKED => mlock, CLKFX => mclkfx );
1630
    end generate;
1631
    LMODE_dllm : if not ((tech = virtex4 and (((MHz*clk_mul)/clk_div >= 210) or (MHz >= 210)))
1632
                    or (tech = virtex5 and (((MHz*clk_mul)/clk_div >= 140) or (MHz >= 140)))) generate
1633
      dllm : DCM
1634
        generic map (CLKFX_MULTIPLY => clk_mul, CLKFX_DIVIDE => clk_div,
1635
                     DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "LOW")
1636
        port map ( CLKIN => clk, CLKFB => mclkfb, DSSEN => gnd, PSCLK => gnd,
1637
        PSEN => gnd, PSINCDEC => gnd, RST => dll0rst(0), CLK0 => mclk0,
1638
        LOCKED => mlock, CLKFX => mclkfx );
1639
    end generate;
1640
  end generate;
1641
 
1642
  -- DDR clock generation
1643
 
1644
--  bufg1 : BUFG port map (I => clk_0ro, O => clk0r);
1645
  clk0r <= mclk;
1646
 
1647
  bufg2 : BUFG port map (I => clk_90ro, O => clk90r);
1648
--  bufg3 : BUFG port map (I => clk_180ro, O => clk180r);
1649
  clk180r <= not mclk;
1650
--  bufg4 : BUFG port map (I => clk_270ro, O => clk270r);
1651
  clkout <= clk0r;
1652
--  dllfb  <= clk0r;  
1653
  dllfb  <= clk90r;
1654
 
1655
    HMODE_dll : if (tech = virtex4 and ((MHz*clk_mul)/clk_div >= 150))
1656
                   or (tech = virtex5 and ((MHz*clk_mul)/clk_div >= 120)) generate
1657
      dll : DCM generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2,
1658
                             DFS_FREQUENCY_MODE => "HIGH", DLL_FREQUENCY_MODE => "HIGH", --"HIGH")
1659
                             PHASE_SHIFT => 64, CLKOUT_PHASE_SHIFT => "FIXED")--, CLKIN_PERIOD => real((1000*clk_div)/(MHz*clk_mul)))
1660
          port map ( CLKIN => mclk, CLKFB => dllfb, DSSEN => gnd, PSCLK => gnd,
1661
          PSEN => gnd, PSINCDEC => gnd, RST => dllrst(0), CLK0 => clk_90ro,
1662
          CLK90 => open, CLK180 => open, CLK270 => open,
1663
          LOCKED => lockl);
1664
    end generate;
1665
    LMODE_dll : if not ((tech = virtex4 and ((MHz*clk_mul)/clk_div >= 150))
1666
                   or (tech = virtex5 and ((MHz*clk_mul)/clk_div >= 120))) generate
1667
      dll : DCM generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2,
1668
                             DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "LOW", --"HIGH")
1669
                             PHASE_SHIFT => 64, CLKOUT_PHASE_SHIFT => "FIXED")--, CLKIN_PERIOD => real((1000*clk_div)/(MHz*clk_mul)))
1670
          port map ( CLKIN => mclk, CLKFB => dllfb, DSSEN => gnd, PSCLK => gnd,
1671
          PSEN => gnd, PSINCDEC => gnd, RST => dllrst(0), CLK0 => clk_90ro,
1672
          CLK90 => open, CLK180 => open, CLK270 => open,
1673
          LOCKED => lockl);
1674
    end generate;
1675
 
1676
--  dll : DCM generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2, CLKIN_PERIOD => 6.25,
1677
--                         DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "HIGH") --"HIGH")
1678
--      port map ( CLKIN => mclk, CLKFB => dllfb, DSSEN => gnd, PSCLK => gnd,
1679
--      PSEN => gnd, PSINCDEC => gnd, RST => dllrst(0), CLK0 => clk_0ro,
1680
--      CLK90 => clk_90ro, CLK180 => clk_180ro, CLK270 => clk_270ro,
1681
--      LOCKED => lockl);
1682
 
1683
  rstdel : process (mclk, rst, mlock, lock200)
1684
  begin
1685
      if rst = '0' or mlock = '0' or lock200 = '0' then dllrst <= (others => '1');
1686
      elsif rising_edge(mclk) then
1687
         dllrst <= dllrst(1 to 3) & '0';
1688
      end if;
1689
  end process;
1690
 
1691
  rdel : if rstdelay /= 0 generate
1692
    --rcnt : process (clk_0r)
1693
    rcnt : process (clk0r)
1694
    variable cnt : std_logic_vector(15 downto 0);
1695
    variable vlock, co : std_ulogic;
1696
    begin
1697
      --if rising_edge(clk_0r) then
1698
      if rising_edge(clk0r) then
1699
        co := cnt(15);
1700
        vlockl <= vlock;
1701
        if lockl = '0' then
1702
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16); vlock := '0';
1703
        else
1704
          if vlock = '0' then
1705
            cnt := cnt -1;  vlock := cnt(15) and not co;
1706
          end if;
1707
        end if;
1708
      end if;
1709
      if lockl = '0' then
1710
        vlock := '0';
1711
      end if;
1712
    end process;
1713
  end generate;
1714
 
1715
  locked <= lockl when rstdelay = 0 else vlockl;
1716
  lock <= locked and orv(refclk_rdy);
1717
 
1718
  -- Generate external DDR clock
1719
  ddrclocks : for i in 0 to 2 generate
1720
    dclk0r : ODDR port map ( Q => ddr_clkl(i), C => clk90r, CE => vcc,
1721
                             D1 => vcc, D2 => gnd, R => gnd, S => gnd);
1722
    ddrclk_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1723
      port map (ddr_clk(i), ddr_clkl(i));
1724
-- Diff ddr_clk
1725
--    ddrclk_pad : outpad_ds generic map(tech => virtex5, level => sstl18_ii)
1726
--      port map (ddr_clk(i), ddr_clkb(i), ddr_clkl(i), gnd);
1727
    dclk0rb : ODDR port map ( Q => ddr_clkbl(i), C => clk90r, CE => vcc,
1728
                              D1 => gnd, D2 => vcc, R => gnd, S => gnd);
1729
    ddrclkb_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1730
      port map (ddr_clkb(i), ddr_clkbl(i));
1731
  end generate;
1732
 
1733
  -- ODT pads
1734
  odtgen : for i in 0 to 1 generate
1735
    odtl(i) <= locked and orv(refclk_rdy) and odt(i);
1736
    ddr_odt_pad  : outpad generic map (tech => virtex5, level => sstl18_i)
1737
      port map (ddr_odt(i), odtl(i));
1738
  end generate;
1739
 
1740
  ddrbanks : for i in 0 to 1 generate
1741
    csn0gen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
1742
      port map ( Q => ddr_csnr(i), C => clk0r, CE => vcc,
1743
                 D1 => csn(i), D2 => csn(i), R => gnd, S => gnd);
1744
    csn0_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1745
      port map (ddr_csb(i), ddr_csnr(i));
1746
 
1747
    ckel(i) <= cke(i) and locked;
1748
    ckegen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
1749
      port map ( Q => ddr_ckenr(i), C => clk0r, CE => vcc,
1750
                 D1 => ckel(i), D2 => ckel(i), R => gnd, S => gnd);
1751
    cke_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1752
      port map (ddr_cke(i), ddr_ckenr(i));
1753
  end generate;
1754
 
1755
  rasgen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
1756
    port map ( Q => ddr_rasnr, C => clk0r, CE => vcc,
1757
               D1 => rasn, D2 => rasn, R => gnd, S => gnd);
1758
  rasn_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1759
    port map (ddr_rasb, ddr_rasnr);
1760
 
1761
  casgen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
1762
    port map ( Q => ddr_casnr, C => clk0r, CE => vcc,
1763
               D1 => casn, D2 => casn, R => gnd, S => gnd);
1764
  casn_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1765
    port map (ddr_casb, ddr_casnr);
1766
 
1767
  wengen : ODDR  generic map (DDR_CLK_EDGE => "SAME_EDGE")
1768
    port map ( Q => ddr_wenr, C => clk0r, CE => vcc,
1769
               D1 => wen, D2 => wen, R => gnd, S => gnd);
1770
  wen_pad : outpad generic map (tech => virtex5, level => sstl18_i)
1771
    port map (ddr_web, ddr_wenr);
1772
 
1773
  dmgen : for i in 0 to dbits/8-1 generate
1774
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
1775
      port map ( Q => ddr_dmr(i), C => clk0r, CE => vcc,
1776
                 D1 => dm(i+dbits/8), D2 => dm(i), R => gnd, S => gnd);
1777
    ddr_bm_pad  : outpad generic map (tech => virtex5, level => sstl18_i)
1778
      port map (ddr_dm(i), ddr_dmr(i));
1779
  end generate;
1780
 
1781
  bagen : for i in 0 to 1 generate
1782
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
1783
      port map ( Q => ddr_bar(i), C => clk0r, CE => vcc,
1784
                 D1 => ba(i), D2 => ba(i), R => gnd, S => gnd);
1785
    ddr_ba_pad  : outpad generic map (tech => virtex5, level => sstl18_i)
1786
      port map (ddr_ba(i), ddr_bar(i));
1787
  end generate;
1788
 
1789
  dagen : for i in 0 to 13 generate
1790
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
1791
      port map ( Q => ddr_adr(i), C => clk0r, CE => vcc,
1792
                 D1 => addr(i), D2 => addr(i), R => gnd, S => gnd);
1793
    ddr_ad_pad  : outpad generic map (tech => virtex5, level => sstl18_i)
1794
      port map (ddr_ad(i), ddr_adr(i));
1795
  end generate;
1796
 
1797
  -- DQS generation
1798
  --dsqreg : FD port map ( Q => dqsn, C => clk180r, D => oe);
1799
  dqsgen : for i in 0 to dbits/8-1 generate
1800
    dsqreg : FD port map ( Q => dqsn(i), C => clk180r, D => oe);
1801
    da0 : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
1802
      port map ( Q => ddr_dqsin(i), C => clk90r, CE => vcc,
1803
                 --D1 => dqsn, D2 => gnd, R => gnd, S => gnd);
1804
                 D1 => dqsn(i), D2 => gnd, R => gnd, S => gnd);
1805
    doen : FD port map ( Q => ddr_dqsoen(i), C => clk0r, D => dqsoen);
1806
 
1807
    dqs_pad : iopad_ds generic map (tech => virtex5, level => sstl18_ii)
1808
      port map (padp => ddr_dqs(i), padn => ddr_dqsn(i),i => ddr_dqsin(i),
1809
                en => ddr_dqsoen(i), o => ddr_dqsoutl(i));
1810
 
1811
--    del_dqs0 : IDELAY generic map(IOBDELAY_TYPE => "FIXED", IOBDELAY_VALUE => 10)
1812
--      port map(O => dqsclk(i), I => ddr_dqsoutl(i), C => gnd, CE => gnd,
1813
--               INC => gnd, RST => dllrst(0));
1814
--    --buf_dqs0 : BUFIO port map(O => dqsclk(i), I => dqsdel(i));
1815
--    dqsclkn(i) <= not dqsclk(i);
1816
  end generate;
1817
 
1818
  -- Data bus
1819
    ddgen : for i in 0 to dbits-1 generate
1820
      del_dq0 : IDELAY generic map(IOBDELAY_TYPE => "VARIABLE", IOBDELAY_VALUE => ddelay(i/8))
1821
        --port map(O => ddr_dqin(i), I => ddr_dqin_nodel(i), C => clk_270r, CE => cal_en(i/8),
1822
        port map(O => ddr_dqin(i), I => ddr_dqin_nodel(i), C => clk0r, CE => cal_en(i/8),
1823
                 INC => cal_inc(i/8), RST => cal_rst);
1824
 
1825
      qi : IDDR generic map (DDR_CLK_EDGE => "OPPOSITE_EDGE")
1826
      port map ( Q1 => dqinl(i),   --(i+dbits), -- 1-bit output for positive edge of clock 
1827
                 Q2 => dqin(i),    --dqin(i), -- 1-bit output for negative edge of clock 
1828
                 --C => clk_90r,     --clk270r, --dqsclk((2*i)/dbits), -- 1-bit clock input 
1829
                 C => clk180r,     --clk270r, --dqsclk((2*i)/dbits), -- 1-bit clock input 
1830
                 CE => vcc,        -- 1-bit clock enable input 
1831
                 D => ddr_dqin(i), -- 1-bit DDR data input 
1832
                 R => gnd,         -- 1-bit reset 
1833
                 S => gnd          -- 1-bit set 
1834
               );
1835
      --dinq1 : FD port map ( Q => dqin(i+dbits), C => clk_270r, D => dqinl(i));
1836
      dinq1 : FD port map ( Q => dqin(i+dbits), C => clk0r, D => dqinl(i));
1837
 
1838
      --dqi : ISERDES generic map(IOBDELAY => "IFD", IOBDELAY_TYPE => "FIXED", IOBDELAY_VALUE => 0)
1839
      --  port map(O => open, Q1 => dqin(i), Q2 => dqin(i+dbits), Q3 => open, Q4 => open, Q5 => open, 
1840
      --           Q6 => open, SHIFTOUT1 => open, SHIFTOUT2 => open, BITSLIP => gnd, 
1841
      --           CE1 => vcc, CE2 => vcc, CLK => dqsclk(i/8), CLKDIV => clk0r, D => ddr_dqin(i), 
1842
      --           DLYCE => gnd, DLYINC => gnd, DLYRST => gnd, OCLK => clk0r, REV => gnd, 
1843
      --           SHIFTIN1 => gnd, SHIFTIN2 => gnd, SR => gnd);
1844
 
1845
      dout : ODDR generic map (DDR_CLK_EDGE => "SAME_EDGE")
1846
        port map ( Q => ddr_dqout(i), C => clk0r, CE => vcc,
1847
                   D1 => dqout(i+dbits), D2 => dqout(i), R => gnd, S => gnd);
1848
      doen : FD port map ( Q => ddr_dqoen(i), C => clk0r, D => oen);
1849
 
1850
      dq_pad : iopad generic map (tech => virtex5, level => sstl18_ii)
1851
         port map (pad => ddr_dq(i), i => ddr_dqout(i), en => ddr_dqoen(i), o => ddr_dqin_nodel(i)); --o => ddr_dqin(i)); 
1852
    end generate;
1853
end;
1854
 
1855
 
1856
------------------------------------------------------------------
1857
-- Spartan 3A DDR2 PHY -------------------------------------------
1858
------------------------------------------------------------------
1859
library ieee;
1860
use ieee.std_logic_1164.all;
1861
library grlib;
1862
use grlib.stdlib.all;
1863
-- pragma translate_off
1864
library unisim;
1865
use unisim.BUFG;
1866
use unisim.DCM;
1867
use unisim.IDDR2;
1868
use unisim.ODDR2;
1869
use unisim.FD;
1870
use unisim.BUFIO;
1871
-- pragma translate_on
1872
 
1873
library techmap;
1874
use techmap.gencomp.all;
1875
 
1876
entity spartan3a_ddr2_phy is
1877
  generic (MHz         : integer := 125; rstdelay : integer := 200;
1878
           dbits       : integer := 16;  clk_mul  : integer := 2;
1879
           clk_div     : integer := 2;   tech     : integer := spartan3;
1880
           rskew       : integer := 0);
1881
  port (   rst         : in  std_ulogic;
1882
           clk         : in  std_logic;        -- input clock
1883
           clkout      : out std_ulogic;       -- DDR clock
1884
           lock        : out std_ulogic;       -- DCM locked
1885
 
1886
           ddr_clk     : out std_logic_vector(2 downto 0);
1887
           ddr_clkb    : out std_logic_vector(2 downto 0);
1888
           ddr_clk_fb_out : out std_logic;
1889
           ddr_clk_fb  : in  std_logic;
1890
           ddr_cke     : out std_logic_vector(1 downto 0);
1891
           ddr_csb     : out std_logic_vector(1 downto 0);
1892
           ddr_web     : out std_ulogic;                               -- ddr write enable
1893
           ddr_rasb    : out std_ulogic;                               -- ddr ras
1894
           ddr_casb    : out std_ulogic;                               -- ddr cas
1895
           ddr_dm      : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
1896
           ddr_dqs     : inout std_logic_vector (dbits/8-1 downto 0);  -- ddr dqs
1897
           ddr_dqsn    : inout std_logic_vector (dbits/8-1 downto 0);  -- ddr dqsn
1898
           ddr_ad      : out std_logic_vector (13 downto 0);           -- ddr address
1899
           ddr_ba      : out std_logic_vector (1 downto 0);            -- ddr bank address
1900
           ddr_dq      : inout  std_logic_vector (dbits-1 downto 0);   -- ddr data
1901
           ddr_odt     : out std_logic_vector(1 downto 0);
1902
 
1903
           addr        : in  std_logic_vector (13 downto 0);           -- row address
1904
           ba          : in  std_logic_vector ( 1 downto 0);           -- bank address
1905
           dqin        : out std_logic_vector (dbits*2-1 downto 0);    -- ddr input data
1906
           dqout       : in  std_logic_vector (dbits*2-1 downto 0);    -- ddr output data
1907
           dm          : in  std_logic_vector (dbits/4-1 downto 0);    -- data mask
1908
           oen         : in  std_ulogic;
1909
           dqs         : in  std_ulogic;
1910
           dqsoen      : in  std_ulogic;
1911
           rasn        : in  std_ulogic;
1912
           casn        : in  std_ulogic;
1913
           wen         : in  std_ulogic;
1914
           csn         : in  std_logic_vector(1 downto 0);
1915
           cke         : in  std_logic_vector(1 downto 0);
1916
           cal_pll     : in  std_logic_vector(1 downto 0);
1917
           odt         : in  std_logic_vector(1 downto 0));
1918
end;
1919
 
1920
architecture rtl of spartan3a_ddr2_phy is
1921
  component DCM
1922
    generic (CLKDV_DIVIDE          :     real       := 2.0;
1923
             CLKFX_DIVIDE          :     integer    := 1;
1924
             CLKFX_MULTIPLY        :     integer    := 4;
1925
             CLKIN_DIVIDE_BY_2     :     boolean    := false;
1926
             CLKIN_PERIOD          :     real       := 10.0;
1927
             CLKOUT_PHASE_SHIFT    :     string     := "NONE";
1928
             CLK_FEEDBACK          :     string     := "1X";
1929
             DESKEW_ADJUST         :     string     := "SYSTEM_SYNCHRONOUS";
1930
             DFS_FREQUENCY_MODE    :     string     := "LOW";
1931
             DLL_FREQUENCY_MODE    :     string     := "LOW";
1932
             DSS_MODE              :     string     := "NONE";
1933
             DUTY_CYCLE_CORRECTION :     boolean    := true;
1934
             FACTORY_JF            :     bit_vector := X"C080";
1935
             PHASE_SHIFT           :     integer    := 0;
1936
             STARTUP_WAIT          :     boolean    := false);
1937
    port (   CLKFB                 : in  std_logic;
1938
             CLKIN                 : in  std_logic;
1939
             DSSEN                 : in  std_logic;
1940
             PSCLK                 : in  std_logic;
1941
             PSEN                  : in  std_logic;
1942
             PSINCDEC              : in  std_logic;
1943
             RST                   : in  std_logic;
1944
             CLK0                  : out std_logic;
1945
             CLK90                 : out std_logic;
1946
             CLK180                : out std_logic;
1947
             CLK270                : out std_logic;
1948
             CLK2X                 : out std_logic;
1949
             CLK2X180              : out std_logic;
1950
             CLKDV                 : out std_logic;
1951
             CLKFX                 : out std_logic;
1952
             CLKFX180              : out std_logic;
1953
             LOCKED                : out std_logic;
1954
             PSDONE                : out std_logic;
1955
             STATUS                : out std_logic_vector (7 downto 0));
1956
  end component;
1957
 
1958
  component BUFG
1959
    port (O : out std_logic;
1960
          I : in std_logic);
1961
  end component;
1962
 
1963
  component ODDR2
1964
    generic (DDR_ALIGNMENT : string := "NONE"; -- Sets output alignment to "NONE", "C0" or "C1"
1965
             INIT : bit := '0';                -- Sets initial state of the Q0  
1966
             SRTYPE : string := "SYNC");       -- Specifies "SYNC" or "ASYNC" set/reset
1967
    port (   Q  : out std_ulogic;              -- 1-bit DDR output data
1968
             C0 : in  std_ulogic;              -- 1-bit clock input
1969
             C1 : in  std_ulogic;              -- 1-bit clock input
1970
             CE : in  std_ulogic;              -- 1-bit clock enable input
1971
             D0 : in  std_ulogic;              -- 1-bit data input (associated with C1)
1972
             D1 : in  std_ulogic;              -- 1-bit data input (associated with C1)
1973
             R  : in  std_ulogic;              -- 1-bit reset input
1974
             S  : in  std_ulogic);             -- 1-bit set input
1975
  end component;
1976
 
1977
  component FD
1978
    generic (INIT : bit := '0');
1979
    port (   Q : out std_ulogic;
1980
             C : in std_ulogic;
1981
             D : in std_ulogic);
1982
  end component;
1983
 
1984
  component IDDR2
1985
    generic (DDR_ALIGNMENT : string := "NONE"; -- Sets output alignment to "NONE", "C0" or "C1"
1986
             INIT_Q0 : bit := '0';             -- Sets initial state of the Q0
1987
             INIT_Q1 : bit := '0';             -- Sets initial state of the Q1
1988
             SRTYPE  : string := "SYNC");      -- Specifies "SYNC" or "ASYNC" set/reset
1989
    port (   Q0 : out std_ulogic;              -- 1-bit output captured with C0 clock
1990
             Q1 : out std_ulogic;              -- 1-bit output captured with C1 clock
1991
             C0 : in  std_ulogic;              -- 1-bit clock input
1992
             C1 : in  std_ulogic;              -- 1-bit clock input
1993
             CE : in  std_ulogic;              -- 1-bit clock enable input
1994
             D  : in  std_ulogic;              -- 1-bit DDR data input
1995
             R  : in  std_ulogic;              -- 1-bit reset input
1996
             S  : in  std_ulogic);             -- 1-bit set input
1997
  end component;
1998
 
1999
  signal vcc, gnd, oe, lockl : std_ulogic;
2000
  signal dqsn                : std_logic_vector(dbits/8-1 downto 0);
2001
 
2002
  signal ddr_rasnr, ddr_casnr, ddr_wenr      : std_ulogic;
2003
  signal ddr_clkl, ddr_clkbl                 : std_logic_vector(2 downto 0);
2004
  signal ddr_csnr, ddr_ckenr, ckel           : std_logic_vector(1 downto 0);
2005
  signal ddr_clk_fbl, ddr_clk_fb_outl        : std_ulogic;
2006
  signal clk_90ro                            : std_ulogic;
2007
  signal clk0r, clk90r, clk180r, clk270r     : std_ulogic;
2008
  signal rclk0b, rclk90b, rclk180b, rclk270b : std_ulogic;
2009
  signal rclk0, rclk90, rclk270              : std_ulogic;
2010
  signal rclk0b_high, rclk90b_high, rclk270b_high : std_ulogic;
2011
  signal rclk0_high, rclk90_high, rclk270_high : std_ulogic;
2012
  signal locked, vlockl, dllfb               : std_ulogic;
2013
 
2014
  signal ddr_dqin                            : std_logic_vector (dbits-1 downto 0);    -- ddr data
2015
  signal ddr_dqout                           : std_logic_vector (dbits-1 downto 0);    -- ddr data
2016
  signal ddr_dqoen                           : std_logic_vector (dbits-1 downto 0);    -- ddr data
2017
  signal ddr_adr                             : std_logic_vector (13 downto 0);         -- ddr row address
2018
  signal ddr_bar                             : std_logic_vector (1 downto 0);          -- ddr bank address
2019
  signal ddr_dmr                             : std_logic_vector (dbits/8-1 downto 0);  -- ddr mask
2020
  signal ddr_dqsin                           : std_logic_vector (dbits/8-1 downto 0);  -- ddr dqs
2021
  signal ddr_dqsoen                          : std_logic_vector (dbits/8-1 downto 0);  -- ddr dqs
2022
  signal ddr_dqsoutl                         : std_logic_vector (dbits/8-1 downto 0);  -- ddr dqs
2023
  signal dqinl                               : std_logic_vector (dbits*2-1 downto 0);  -- ddr data
2024
  signal dllrst                              : std_ulogic;
2025
  signal dll0rst                             : std_ulogic;
2026
  signal dll1rst                             : std_ulogic;
2027
  signal mlock, mclkfb, mclk, mclkfx, mclk0  : std_ulogic;
2028
  signal odtl                                : std_logic_vector(1 downto 0);
2029
 
2030
  --signals needed for alignment with DQS
2031
  signal dm_delay                            : std_logic_vector (dbits/8-1 downto 0);
2032
  signal dqout_delay                         : std_logic_vector (dbits-1 downto 0);
2033
 
2034
  constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
2035
 
2036
  attribute keep                   : boolean;
2037
  attribute syn_keep               : boolean;
2038
  attribute syn_preserve           : boolean;
2039
  attribute syn_keep of dqsn       : signal is true;
2040
  attribute syn_preserve of dqsn   : signal is true;
2041
  attribute keep of mclkfx         : signal is true;
2042
  attribute keep of clk_90ro       : signal is true;
2043
  attribute syn_keep of mclkfx     : signal is true;
2044
  attribute syn_keep of clk_90ro   : signal is true;
2045
 
2046
  -- To prevent synplify 9.4 to remove any of these registers.
2047
  attribute syn_noprune : boolean;
2048
  attribute syn_noprune of FD : component is true;
2049
  attribute syn_noprune of IDDR2 : component is true;
2050
  attribute syn_noprune of ODDR2 : component is true;
2051
 
2052
begin
2053
 
2054
  oe <= not oen;
2055
  vcc <= '1'; gnd <= '0';
2056
 
2057
  -- Optional DDR clock multiplication
2058
 
2059
  noclkscale : if clk_mul = clk_div generate
2060
    mlock <= '1';
2061
    mbufg0 : BUFG port map (I => clk, O => mclk);
2062
  end generate;
2063
 
2064
  clkscale : if clk_mul /= clk_div generate
2065
    rstdel : process (clk, rst)
2066
    begin
2067
      if rst = '0' then
2068
        dll0rst <= '1';
2069
      elsif rising_edge(clk) then
2070
        dll0rst <= '0';
2071
      end if;
2072
    end process;
2073
 
2074
    bufg0 : BUFG port map (I => mclkfx, O => mclk);
2075
    bufg1 : BUFG port map (I => mclk0,  O => mclkfb);
2076
 
2077
    dllm : DCM
2078
      generic map (CLKFX_MULTIPLY => clk_mul, CLKFX_DIVIDE => clk_div)
2079
      port map (CLKIN => clk, CLKFB => mclkfb, DSSEN => gnd, PSCLK => gnd,
2080
                PSEN => gnd, PSINCDEC => gnd, RST => dll0rst, CLK0 => mclk0,
2081
                LOCKED => mlock, CLKFX => mclkfx );
2082
  end generate;
2083
 
2084
  -- DDR clock generation (90 degrees phase-shifted DLL)
2085
 
2086
  bufg2 : BUFG port map (I => clk_90ro, O => clk90r);
2087
  dllfb <= clk90r;
2088
 
2089
  dll : DCM
2090
    generic map (CLKFX_MULTIPLY => 2, CLKFX_DIVIDE => 2,
2091
                 CLKOUT_PHASE_SHIFT => "FIXED", PHASE_SHIFT => 64)
2092
    port map (CLKIN => mclk, CLKFB => dllfb, DSSEN => gnd, PSCLK => gnd,
2093
              PSEN => gnd, PSINCDEC => gnd, RST => dllrst, CLK0 => clk_90ro,
2094
              CLK90 => open, CLK180 => open, CLK270 => open,
2095
              LOCKED => lockl);
2096
 
2097
  clk0r   <= mclk;
2098
  clk180r <= not mclk;
2099
  clk270r <= not clk90r;
2100
  clkout  <= mclk;
2101
 
2102
  rstdel : process (mclk, rst, mlock)
2103
  begin
2104
    if rst = '0' or mlock = '0' then
2105
      dllrst <= '1';
2106
    elsif rising_edge(mclk) then
2107
      dllrst <= '0';
2108
    end if;
2109
  end process;
2110
 
2111
  rdel : if rstdelay /= 0 generate
2112
    rcnt : process (clk0r)
2113
      variable cnt : std_logic_vector(15 downto 0);
2114
      variable vlock, co : std_ulogic;
2115
    begin
2116
      if rising_edge(clk0r) then
2117
        co := cnt(15);
2118
        vlockl <= vlock;
2119
        if lockl = '0' then
2120
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16);
2121
          vlock := '0';
2122
        elsif vlock = '0' then
2123
          cnt := cnt -1;
2124
          vlock := cnt(15) and not co;
2125
        end if;
2126
      end if;
2127
      if lockl = '0' then
2128
        vlock := '0';
2129
      end if;
2130
    end process;
2131
  end generate;
2132
 
2133
  locked <= lockl when rstdelay = 0 else vlockl;
2134
  lock   <= locked;
2135
 
2136
  -- Generate external DDR clock
2137
  ddrclocks : for i in 0 to 2 generate
2138
    dclk0r : ODDR2
2139
      port map (Q => ddr_clkl(i), C0 => clk90r, C1 => clk270r, CE => vcc,
2140
                D0 => vcc, D1 => gnd, R => gnd, S => gnd);
2141
    ddrclk_pad : outpad
2142
      generic map (tech => virtex4, level => sstl18_i)
2143
      port map (ddr_clk(i), ddr_clkl(i));
2144
 
2145
    dclk0rb : ODDR2
2146
      port map (Q => ddr_clkbl(i), C0 => clk90r, C1 => clk270r, CE => vcc,
2147
                D0 => gnd, D1 => vcc, R => gnd, S => gnd);
2148
    ddrclkb_pad : outpad
2149
      generic map (tech => virtex4, level => sstl18_i)
2150
      port map (ddr_clkb(i), ddr_clkbl(i));
2151
  end generate;
2152
 
2153
  -- Generate the DDR clock to be fed back for DQ synchronization
2154
  dclkfb0r : ODDR2
2155
    port map (Q => ddr_clk_fb_outl, C0 => clk90r, C1 => clk270r, CE => vcc,
2156
              D0 => vcc, D1 => gnd, R => gnd, S => gnd);
2157
  ddrclkfb_pad : outpad
2158
    generic map (tech => virtex4, level => sstl18_i)
2159
    port map (ddr_clk_fb_out, ddr_clk_fb_outl);
2160
 
2161
  -- The above clock fed back for DQ synchronization
2162
  ddrref_pad : clkpad generic map (tech => virtex4)
2163
        port map (ddr_clk_fb, ddr_clk_fbl);
2164
 
2165
  -- ODT pads
2166
  odtgen : for i in 0 to 1 generate
2167
    odtl(i) <= locked and odt(i);
2168
    ddr_odt_pad : outpad
2169
      generic map (tech => virtex4, level => sstl18_i)
2170
      port map (ddr_odt(i), odtl(i));
2171
  end generate;
2172
 
2173
  --  DDR single-edge control signals
2174
  ddrbanks : for i in 0 to 1 generate
2175
    csn0gen : FD
2176
      port map ( Q => ddr_csnr(i), C => clk0r, D => csn(i));
2177
    csn0_pad : outpad
2178
      generic map (tech => virtex4, level => sstl18_i)
2179
      port map (ddr_csb(i), ddr_csnr(i));
2180
 
2181
    ckel(i) <= cke(i) and locked;
2182
    ckegen : FD
2183
      port map ( Q => ddr_ckenr(i), C => clk0r, D => ckel(i));
2184
    cke_pad : outpad
2185
      generic map (tech => virtex4, level => sstl18_i)
2186
      port map (ddr_cke(i), ddr_ckenr(i));
2187
  end generate;
2188
 
2189
  rasgen : FD
2190
    port map ( Q => ddr_rasnr, C => clk0r, D => rasn);
2191
  rasn_pad : outpad
2192
    generic map (tech => virtex4, level => sstl18_i)
2193
    port map (ddr_rasb, ddr_rasnr);
2194
 
2195
  casgen : FD
2196
    port map ( Q => ddr_casnr, C => clk0r, D => casn);
2197
  casn_pad : outpad
2198
    generic map (tech => virtex4, level => sstl18_i)
2199
    port map (ddr_casb, ddr_casnr);
2200
 
2201
  wengen : FD
2202
    port map ( Q => ddr_wenr, C => clk0r, D => wen);
2203
  wen_pad : outpad
2204
    generic map (tech => virtex4, level => sstl18_i)
2205
    port map (ddr_web, ddr_wenr);
2206
 
2207
  bagen : for i in 0 to 1 generate
2208
    ba0 : FD
2209
      port map ( Q => ddr_bar(i), C => clk0r, D => ba(i));
2210
    ddr_ba_pad  : outpad
2211
      generic map (tech => virtex4, level => sstl18_i)
2212
      port map (ddr_ba(i), ddr_bar(i));
2213
  end generate;
2214
 
2215
  addrgen : for i in 0 to 13 generate
2216
    addr0 : FD
2217
      port map ( Q => ddr_adr(i), C => clk0r, D => addr(i));
2218
    ddr_ad_pad : outpad
2219
      generic map (tech => virtex4, level => sstl18_i)
2220
      port map (ddr_ad(i), ddr_adr(i));
2221
  end generate;
2222
 
2223
  -- Data mask (DM) generation
2224
  dmgen : for i in 0 to dbits/8-1 generate
2225
    dq_delay : FD
2226
      port map ( Q => dm_delay(i), C => clk0r, D => dm(i));
2227
    dm0 : ODDR2
2228
      generic map (DDR_ALIGNMENT => "NONE")
2229
      port map (Q => ddr_dmr(i), C0 => clk0r, C1 => clk180r, CE => vcc,
2230
                D0 => dm(i+dbits/8), D1 => dm_delay(i), R => gnd, S => gnd);
2231
    ddr_bm_pad : outpad
2232
      generic map (tech => virtex4, level => sstl18_i)
2233
      port map (ddr_dm(i), ddr_dmr(i));
2234
  end generate;
2235
 
2236
  -- Data strobe (DQS) generation
2237
  dqsgen : for i in 0 to dbits/8-1 generate
2238
    dsqreg : FD port map ( Q => dqsn(i), C => clk180r, D => oe);
2239
    da0 : ODDR2
2240
      port map ( Q => ddr_dqsin(i), C0 => clk90r, C1 => clk270r, CE => vcc,
2241
                 D0 => dqsn(i), D1 => gnd, R => gnd, S => gnd);
2242
    doen : FD
2243
      port map ( Q => ddr_dqsoen(i), C => clk0r, D => dqsoen);
2244
 
2245
    dqs_pad : iopad_ds
2246
      generic map (tech => virtex5, level => sstl18_ii)
2247
      port map (padp => ddr_dqs(i), padn => ddr_dqsn(i), i => ddr_dqsin(i),
2248
                en => ddr_dqsoen(i), o => ddr_dqsoutl(i));
2249
  end generate;
2250
 
2251
  -- Phase shift the feedback clock and use it to latch DQ
2252
  rstphase : process (ddr_clk_fbl, rst, lockl)
2253
  begin
2254
    if rst = '0' or lockl = '0' then
2255
      dll1rst <= '1';
2256
    elsif rising_edge(ddr_clk_fbl) then
2257
      dll1rst <= '0';
2258
    end if;
2259
  end process;
2260
 
2261
  bufg7 : BUFG port map (I => rclk90,  O => rclk90b);
2262
  bufg8 : BUFG port map (I => rclk270, O => rclk270b);
2263
 
2264
  read_dll : DCM
2265
    generic map (clkin_period => 8.0, DESKEW_ADJUST => "SOURCE_SYNCHRONOUS",
2266
                 CLKOUT_PHASE_SHIFT => "VARIABLE", PHASE_SHIFT => rskew)
2267
    port map ( CLKIN => ddr_clk_fbl, CLKFB => rclk90b, DSSEN => gnd, PSCLK => mclk,
2268
               PSEN => cal_pll(0), PSINCDEC => cal_pll(1), RST => dll1rst, CLK0 => rclk90,
2269
               CLK90 => rclk180b, CLK180 => rclk270);
2270
 
2271
  -- Data bus
2272
  ddgen : for i in 0 to dbits-1 generate
2273
    qi : IDDR2
2274
      port map (Q0 => dqinl(i+dbits), -- 1-bit output for positive edge of C0
2275
                Q1 => dqinl(i),       -- 1-bit output for negative edge of C1
2276
                C0 => rclk90b,        -- 1-bit clock input 
2277
                C1 => rclk270b,       -- 1-bit clock input 
2278
                CE => vcc,            -- 1-bit clock enable input 
2279
                D  => ddr_dqin(i),    -- 1-bit DDR data input 
2280
                R  => gnd,            -- 1-bit reset 
2281
                S  => gnd);           -- 1-bit set 
2282
 
2283
    dinq0 : FD
2284
      port map ( Q => dqin(i+dbits), C => rclk180b, D => dqinl(i));
2285
    dinq1 : FD
2286
      port map ( Q => dqin(i), C => rclk180b, D => dqinl(i+dbits));
2287
 
2288
    dq_delay : FD
2289
      port map ( Q => dqout_delay(i), C => clk0r, D => dqout(i));
2290
 
2291
    dout : ODDR2
2292
      generic map (DDR_ALIGNMENT => "NONE")
2293
      port map (Q => ddr_dqout(i), C0 => clk0r, C1 => clk180r, CE => vcc,
2294
                D0 => dqout(i+dbits), D1 => dqout_delay(i), R => gnd, S => gnd);
2295
    doen : FD
2296
      port map (Q => ddr_dqoen(i), C => clk0r, D => oen);
2297
 
2298
    dq_pad : iopad
2299
      generic map (tech => virtex4, level => sstl18_ii)
2300
      port map (pad => ddr_dq(i), i => ddr_dqout(i), en => ddr_dqoen(i), o => ddr_dqin(i));
2301
  end generate;
2302
end;

powered by: WebSVN 2.1.0

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