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

powered by: WebSVN 2.1.0

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