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/] [stratixiii/] [ddr_phy_stratixiii.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
library ieee;
2
use ieee.std_logic_1164.all;
3
library grlib;
4
use grlib.stdlib.all;
5
-- pragma translate_off
6
-- pragma translate_on
7
 
8
library techmap;
9
use techmap.gencomp.all;
10
------------------------------------------------------------------
11
-- Virtex5 DDR2 PHY ----------------------------------------------
12
------------------------------------------------------------------
13
 
14
entity stratixiii_ddr2_phy is
15
  generic (MHz : integer := 100; rstdelay : integer := 200;
16
           dbits : integer := 16; clk_mul : integer := 2; clk_div : integer := 2;
17
           ddelayb0 : integer := 0; ddelayb1 : integer := 0; ddelayb2 : integer := 0;
18
           ddelayb3 : integer := 0; ddelayb4 : integer := 0; ddelayb5 : integer := 0;
19
           ddelayb6 : integer := 0; ddelayb7 : integer := 0;
20
           numidelctrl : integer := 4; norefclk : integer := 0;
21
           tech : integer := stratix3; odten : integer := 0; rskew : integer := 0);
22
 
23
  port (
24
    rst        : in  std_ulogic;
25
    clk        : in  std_logic;        -- input clock
26
    clkref200  : in  std_logic;        -- input 200MHz clock
27
    clkout     : out std_ulogic;       -- system clock
28
    lock       : out std_ulogic;       -- DCM locked
29
 
30
    ddr_clk    : out std_logic_vector(2 downto 0);
31
    ddr_clkb   : out std_logic_vector(2 downto 0);
32
    ddr_cke    : out std_logic_vector(1 downto 0);
33
    ddr_csb    : out std_logic_vector(1 downto 0);
34
    ddr_web    : out std_ulogic;                       -- ddr write enable
35
    ddr_rasb   : out std_ulogic;                       -- ddr ras
36
    ddr_casb   : out std_ulogic;                       -- ddr cas
37
    ddr_dm     : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
38
    ddr_dqs    : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
39
    ddr_dqsn   : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqsn
40
    ddr_ad     : out std_logic_vector (13 downto 0);   -- ddr address
41
    ddr_ba     : out std_logic_vector (1 downto 0);    -- ddr bank address
42
    ddr_dq     : inout  std_logic_vector (dbits-1 downto 0); -- ddr data
43
    ddr_odt    : out std_logic_vector(1 downto 0);
44
 
45
    addr       : in  std_logic_vector (13 downto 0); -- data mask
46
    ba         : in  std_logic_vector ( 1 downto 0); -- data mask
47
    dqin       : out std_logic_vector (dbits*2-1 downto 0); -- ddr input data
48
    dqout      : in  std_logic_vector (dbits*2-1 downto 0); -- ddr input data
49
    dm         : in  std_logic_vector (dbits/4-1 downto 0); -- data mask
50
    oen        : in  std_ulogic;
51
    dqs        : in  std_ulogic;
52
    dqsoen     : in  std_ulogic;
53
    rasn       : in  std_ulogic;
54
    casn       : in  std_ulogic;
55
    wen        : in  std_ulogic;
56
    csn        : in  std_logic_vector(1 downto 0);
57
    cke        : in  std_logic_vector(1 downto 0);
58
    cal_en     : in  std_logic_vector(dbits/8-1 downto 0);
59
    cal_inc    : in  std_logic_vector(dbits/8-1 downto 0);
60
    cal_pll    : in  std_logic_vector(1 downto 0);
61
    cal_rst    : in  std_logic;
62
    odt        : in  std_logic_vector(1 downto 0)
63
  );
64
 
65
end;
66
 
67
architecture rtl of stratixiii_ddr2_phy is
68
 
69
  component apll IS
70
  generic (
71
    freq    : integer := 200;
72
    mult    : integer := 8;
73
    div     : integer := 5;
74
    rskew   : integer := 0
75
  );
76
        PORT
77
        (
78
                areset          : IN STD_LOGIC  := '0';
79
                inclk0          : IN STD_LOGIC  := '0';
80
    phasestep   : IN STD_LOGIC  := '0';
81
    phaseupdown : IN STD_LOGIC  := '0';
82
    scanclk     : IN STD_LOGIC  := '1';
83
                c0              : OUT STD_LOGIC ;
84
                c1              : OUT STD_LOGIC ;
85
                c2              : OUT STD_LOGIC ;
86
                c3              : OUT STD_LOGIC ;
87
                c4              : OUT STD_LOGIC ;
88
                locked          : OUT STD_LOGIC;
89
    phasedone : out std_logic
90
        );
91
  END component;
92
 
93
  component aclkout is
94
  port(
95
    clk     : in  std_logic;
96
    ddr_clk : out std_logic;
97
    ddr_clkn: out std_logic
98
  );
99
  end component;
100
 
101
  component actrlout is
102
  generic(
103
    power_up  : string := "high"
104
  );
105
  port(
106
    clk     : in  std_logic;
107
    i       : in  std_logic;
108
    o       : out std_logic
109
  );
110
  end component;
111
 
112
  component adqsout is
113
  port(
114
    clk       : in  std_logic; -- clk90
115
    dqs       : in  std_logic;
116
    dqs_oe    : in  std_logic;
117
    dqs_oct   : in  std_logic; -- gnd = disable
118
    dqs_pad   : out std_logic; -- DQS pad
119
    dqsn_pad  : out std_logic  -- DQSN pad
120
  );
121
  end component;
122
 
123
  component adqsin is
124
  port(
125
    dqs_pad   : in  std_logic; -- DQS pad
126
    dqsn_pad  : in  std_logic; -- DQSN pad
127
    dqs       : out std_logic
128
  );
129
  end component;
130
 
131
  component admout is
132
  port(
133
    clk       : in  std_logic; -- clk0
134
    dm_h      : in  std_logic;
135
    dm_l      : in  std_logic;
136
    dm_pad    : out std_logic  -- DQ pad
137
  );
138
  end component;
139
 
140
  component adqin is
141
  port(
142
    clk     : in  std_logic;
143
    dq_pad  : in  std_logic; -- DQ pad
144
    dq_h    : out std_logic;
145
    dq_l    : out std_logic;
146
    config_clk    : in  std_logic;
147
    config_clken  : in  std_logic;
148
    config_datain : in  std_logic;
149
    config_update : in  std_logic
150
  );
151
  end component;
152
 
153
  component adqout is
154
  port(
155
    clk       : in  std_logic; -- clk0
156
    clk_oct   : in  std_logic; -- clk90
157
    dq_h      : in  std_logic;
158
    dq_l      : in  std_logic;
159
    dq_oe     : in  std_logic;
160
    dq_oct    : in  std_logic; -- gnd = disable
161
    dq_pad    : out std_logic  -- DQ pad
162
  );
163
  end component;
164
 
165
signal reset                : std_logic;
166
signal vcc, gnd, oe         : std_ulogic;
167
signal locked, vlockl, lockl  : std_ulogic;
168
signal clk0r, clk90r, clk180r, clk270r, rclk  : std_ulogic;
169
signal ckel, ckel2          : std_logic_vector(1 downto 0);
170
signal odtl                 : std_logic_vector(1 downto 0);
171
signal dqsin, dqsin_reg     : std_logic_vector (7 downto 0);    -- ddr dqs
172
signal dqsn                 : std_logic_vector(dbits/8-1 downto 0);
173
signal dqsoenr              : std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
174
signal delayrst             : std_logic_vector(3 downto 0);
175
signal phasedone            : std_logic;
176
signal dqinl                : std_logic_vector (dbits-1 downto 0); -- ddr data
177
 
178
signal dqsin_tmp : std_logic;
179
 
180
type phy_r_type is record
181
  delay   : std_logic_vector(3 downto 0);
182
  count   : std_logic_vector(3 downto 0);
183
  update  : std_logic;
184
  sdata   : std_logic;
185
  enable  : std_logic;
186
  update_delay   : std_logic;
187
end record;
188
type phy_r_type_arr is array (7 downto 0) of phy_r_type;
189
signal r,rin : phy_r_type_arr;
190
signal rp : std_logic_vector(3 downto 0);
191
 
192
constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
193
 
194
attribute keep : boolean;
195
attribute syn_keep : boolean;
196
attribute syn_preserve : boolean;
197
attribute syn_keep of dqsn : signal is true;
198
attribute syn_preserve of dqsn : signal is true;
199
attribute syn_keep of dqsoenr : signal is true;
200
attribute syn_preserve of dqsoenr : signal is true;
201
attribute syn_keep of dqsin_reg : signal is true;
202
attribute syn_preserve of dqsin_reg : signal is true;
203
 
204
begin
205
 
206
  -----------------------------------------------------------------------------------
207
  -- Clock generation 
208
  -----------------------------------------------------------------------------------
209
  oe <= not oen;
210
  vcc <= '1'; gnd <= '0';
211
  reset <= not rst;
212
 
213
  -- Optional DDR clock multiplication
214
 
215
  pll0 : apll
216
  generic map(
217
      freq   => MHz,
218
      mult   => clk_mul,
219
      div    => clk_div,
220
      rskew  => rskew
221
    )
222
  port map(
223
                areset  => reset,
224
                inclk0  => clk,
225
    phasestep   => rp(1),
226
    phaseupdown => rp(3),
227
    scanclk     => clk0r,
228
                c0      => clk0r,
229
                c1      => clk90r,
230
                c2      => open, --clk180r,
231
                c3      => open, --clk270r,
232
                c4      => rclk,
233
                locked  => lockl,
234
    phasedone => phasedone
235
  );
236
 
237
  clk180r <= not clk0r;
238
  clk270r <= not clk90r;
239
  clkout <= clk0r;
240
 
241
  -----------------------------------------------------------------------------------
242
  -- Lock delay
243
  -----------------------------------------------------------------------------------
244
  rdel : if rstdelay /= 0 generate
245
    rcnt : process (clk0r)
246
    variable cnt : std_logic_vector(15 downto 0);
247
    variable vlock, co : std_ulogic;
248
    begin
249
      if rising_edge(clk0r) then
250
        co := cnt(15);
251
        vlockl <= vlock;
252
        if lockl = '0' then
253
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16); vlock := '0';
254
          cnt(0) := dqsin_reg(7) or dqsin_reg(6) or dqsin_reg(5) or dqsin_reg(4) or  -- dummy use of dqsin
255
                    dqsin_reg(3) or dqsin_reg(2) or dqsin_reg(1) or dqsin_reg(0);
256
        else
257
          if vlock = '0' then
258
            cnt := cnt -1;  vlock := cnt(15) and not co;
259
          end if;
260
        end if;
261
      end if;
262
      if lockl = '0' then
263
        vlock := '0';
264
      end if;
265
    end process;
266
  end generate;
267
 
268
  locked <= lockl when rstdelay = 0 else vlockl;
269
  lock <= locked;
270
 
271
  -----------------------------------------------------------------------------------
272
  -- Generate external DDR clock
273
  -----------------------------------------------------------------------------------
274
  ddrclocks : for i in 0 to 2 generate
275
    ddrclk_pad : aclkout port map(clk => clk90r, ddr_clk => ddr_clk(i), ddr_clkn => ddr_clkb(i));
276
  end generate;
277
 
278
  -----------------------------------------------------------------------------------
279
  --  DDR single-edge control signals
280
  -----------------------------------------------------------------------------------
281
  -- ODT pads
282
  odtgen : for i in 0 to 1 generate
283
    odtl(i) <= locked and odt(i);
284
    ddr_odt_pad : actrlout generic map(power_up => "low")
285
      port map(clk =>clk180r , i => odtl(i), o => ddr_odt(i));
286
  end generate;
287
 
288
  -- CSN and CKE
289
  ddrbanks : for i in 0 to 1 generate
290
    ddr_csn_pad : actrlout port map(clk =>clk180r , i => csn(i), o => ddr_csb(i));
291
 
292
    ckel(i) <= cke(i) and locked;
293
    ddr_cke_pad : actrlout generic map(power_up => "low")
294
      port map(clk =>clk0r , i => ckel(i), o => ddr_cke(i));
295
  end generate;
296
 
297
  -- RAS
298
    ddr_rasn_pad : actrlout port map(clk =>clk180r , i => rasn, o => ddr_rasb);
299
 
300
  -- CAS
301
    ddr_casn_pad : actrlout port map(clk =>clk180r , i => casn, o => ddr_casb);
302
 
303
  -- WEN
304
    ddr_wen_pad : actrlout port map(clk =>clk180r , i => wen, o => ddr_web);
305
 
306
  -- BA
307
  bagen : for i in 0 to 1 generate
308
    ddr_ba_pad : actrlout port map(clk =>clk180r , i => ba(i), o => ddr_ba(i));
309
  end generate;
310
 
311
  -- ADDRESS
312
  dagen : for i in 0 to 13 generate
313
    ddr_ad_pad : actrlout port map(clk =>clk180r , i => addr(i), o => ddr_ad(i));
314
  end generate;
315
 
316
  -----------------------------------------------------------------------------------
317
  -- DQS generation
318
  -----------------------------------------------------------------------------------
319
 
320
  dqsgen : for i in 0 to dbits/8-1 generate
321
 
322
    doen : process(clk180r)
323
    begin if rising_edge(clk180r) then dqsoenr(i) <= dqsoen; end if; end process;
324
 
325
    dsqreg : process(clk180r)
326
    begin if rising_edge(clk180r) then dqsn(i) <= oe; end if; end process;
327
 
328
    dqs_out_pad : adqsout port map(
329
      clk       => clk90r,     -- clk90
330
      dqs       => dqsn(i),
331
      dqs_oe    => dqsoenr(i),
332
      dqs_oct   => gnd,        -- gnd = disable
333
      dqs_pad   => ddr_dqs(i), -- DQS pad
334
      dqsn_pad  => ddr_dqsn(i) -- DQSN pad
335
    );
336
 
337
    dqs_in_pad : adqsin port map(
338
      dqs_pad   => ddr_dqs(i),
339
      dqsn_pad  => ddr_dqsn(i),
340
      dqs       => dqsin(i)
341
    );
342
    -- Dummy procces to sample dqsin
343
    process(clk0r)
344
    begin
345
      if rising_edge(clk0r) then
346
          dqsin_reg(i) <= dqsin(i);
347
      end if;
348
    end process;
349
 
350
  end generate;
351
 
352
  -----------------------------------------------------------------------------------
353
  -- DQM generation
354
  -----------------------------------------------------------------------------------
355
  dmgen : for i in 0 to dbits/8-1 generate
356
 
357
    ddr_dm_pad : admout port map(
358
      clk       => clk0r, -- clk0
359
      dm_h      => dm(i+dbits/8),
360
      dm_l      => dm(i),
361
      dm_pad    => ddr_dm(i)  -- DQ pad
362
    );
363
  end generate;
364
 
365
  -----------------------------------------------------------------------------------
366
  -- Data bus
367
  -----------------------------------------------------------------------------------
368
    ddgen : for i in 0 to dbits-1 generate
369
      -- DQ Input
370
      dq_in_pad : adqin port map(
371
        clk     => rclk,--clk0r,
372
        dq_pad  => ddr_dq(i), -- DQ pad
373
        dq_h    => dqin(i), --dqinl(i),
374
        dq_l    => dqin(i+dbits),--dqin(i),
375
        config_clk    => clk0r,
376
        config_clken  => r(i/8).enable,--io_config_clkena,
377
        config_datain => r(i/8).sdata,--io_config_datain,
378
        config_update => r(i/8).update_delay--io_config_update
379
      );
380
      --dinq1 : process (clk0r)
381
      --begin if rising_edge(clk0r) then dqin(i+dbits) <= dqinl(i); end if; end process;
382
 
383
      -- DQ Output  
384
      dq_out_pad : adqout port map(
385
        clk       => clk0r, -- clk0
386
        clk_oct   => clk90r, -- clk90
387
        dq_h      => dqout(i+dbits),
388
        dq_l      => dqout(i),
389
        dq_oe     => oen,
390
        dq_oct    => gnd, -- gnd = disable
391
        dq_pad    => ddr_dq(i)  -- DQ pad
392
      );
393
    end generate;
394
 
395
  -----------------------------------------------------------------------------------
396
  -- Delay control
397
  -----------------------------------------------------------------------------------
398
 
399
    delay_control : for i in 0 to dbits/8-1 generate
400
 
401
      process(r(i),cal_en(i), cal_inc(i), delayrst(3))
402
      variable v : phy_r_type;
403
      variable data : std_logic_vector(0 to 3);
404
      begin
405
        v := r(i);
406
        data := r(i).delay;
407
        v.update_delay := '0';
408
        if cal_en(i) = '1' then
409
          if cal_inc(i) = '1' then
410
            v.delay := r(i).delay + 1;
411
          else
412
            v.delay := r(i).delay - 1;
413
          end if;
414
          v.update := '1';
415
          v.count := (others => '0');
416
        end if;
417
 
418
        if r(i).update = '1' then
419
          v.enable := '1';
420
          v.sdata := '0';
421
 
422
          if r(i).count <= "1011" then
423
            v.count := r(i).count + 1;
424
          end if;
425
 
426
          if r(i).count <= "0011" then
427
            v.sdata := data(conv_integer(r(i).count));
428
          end if;
429
 
430
          if r(i).count = "1011" then
431
            v.update_delay := '1';
432
            v.enable := '0';
433
            v.update := '0';
434
          end if;
435
        end if;
436
 
437
        if delayrst(3) = '0' then
438
          v.delay := (others => '0');
439
          v.count := (others => '0');
440
          v.update := '0';
441
          v.enable := '0';
442
        end if;
443
 
444
        rin(i) <= v;
445
      end process;
446
 
447
    end generate;
448
 
449
      process(clk0r)
450
      begin
451
        if locked = '0' then
452
          delayrst <= (others => '0');
453
        elsif rising_edge(clk0r) then
454
          delayrst <= delayrst(2 downto 0) & '1';
455
          r <= rin;
456
          -- PLL phase config
457
          rp(0) <= cal_pll(0); rp(1) <= cal_pll(0) or rp(0);
458
          rp(2) <= cal_pll(1); rp(3) <= cal_pll(1) or rp(2);
459
        end if;
460
      end process;
461
 
462
end;
463
 
464
 
465
 

powered by: WebSVN 2.1.0

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