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/] [inferred/] [ddr_phy_inferred.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:      generic_ddr_phy
20
-- File:        ddr_phy_inferred.vhd
21
-- Author:      Nils-Johan Wessman - Gaisler Research
22
-- Description: Generic DDR PHY
23
------------------------------------------------------------------------------
24
 
25
--###################################################################################
26
-- Generic DDR Output Register
27
--###################################################################################
28
library ieee;
29
use ieee.std_logic_1164.all;
30
entity gen_ddr_phy_oreg is
31
  generic(
32
    sameedge : integer := 0
33
         );
34
  port(
35
    Q : out std_ulogic;
36
    C0 : in std_ulogic;
37
    C1 : in std_ulogic;
38
    CE : in std_ulogic;
39
    D0 : in std_ulogic;
40
    D1 : in std_ulogic;
41
    R  : in std_ulogic;
42
    S  : in std_ulogic
43
      );
44
end;
45
 
46
architecture rtl of gen_ddr_phy_oreg is
47
signal tmpD1, Q1, Q2 : std_logic;
48
begin
49
  same_edge : if sameedge = 0 generate
50
    tmpD1 <= D1;
51
  end generate;
52
 
53
  nosame_edge : if sameedge = 1 generate
54
    reg : process(C0)
55
    begin
56
      if rising_edge(C0) then
57
          tmpD1 <= D1;
58
      end if;
59
    end process;
60
  end generate;
61
 
62
  reg : process(C0)
63
  begin
64
    if rising_edge(C0) then
65
      Q1 <= D0;
66
    end if;
67
  end process;
68
 
69
  regn : process(C0)
70
  begin
71
    if falling_edge(C0) then
72
      Q2 <= tmpD1;
73
    end if;
74
  end process;
75
 
76
  Q <= Q1 when C0 = '1' else Q2;
77
 
78
end;
79
 
80
--###################################################################################
81
-- Generic DDR Inout Register
82
--###################################################################################
83
library ieee;
84
use ieee.std_logic_1164.all;
85
entity gen_ddr_phy_ireg is
86
  port(
87
    Q0 : out std_ulogic;
88
    Q1 : out std_ulogic;
89
    C0 : in std_ulogic;
90
    C1 : in std_ulogic;
91
    CE : in std_ulogic;
92
    D  : in std_ulogic;
93
    R  : in std_ulogic;
94
    S  : in std_ulogic
95
      );
96
end;
97
 
98
architecture rtl of gen_ddr_phy_ireg is
99
begin
100
  reg0 : process(C0)
101
  begin
102
    if rising_edge(C0) then
103
      if R = '1' then Q0 <= '0';
104
      elsif S = '1' then Q0 <= '1';
105
      elsif CE = '1' then Q0 <= D; end if;
106
    end if;
107
  end process;
108
  reg1 : process(C1)
109
  begin
110
    if rising_edge(C1) then
111
      if R = '1' then Q1 <= '0';
112
      elsif S = '1' then Q1 <= '1';
113
      elsif CE = '1' then Q1 <= D; end if;
114
    end if;
115
  end process;
116
end;
117
 
118
--###################################################################################
119
-- Generic DDR Register
120
--###################################################################################
121
library ieee;
122
use ieee.std_logic_1164.all;
123
entity gen_ddr_phy_reg is
124
  port(
125
    Q : out std_ulogic;
126
    C : in std_ulogic;
127
    D  : in std_ulogic
128
      );
129
end;
130
 
131
architecture rtl of gen_ddr_phy_reg is
132
begin
133
  reg : process(C)
134
  begin
135
    if rising_edge(C) then Q <= D; end if;
136
  end process;
137
end;
138
 
139
--###################################################################################
140
-- Generic DDR PHY
141
--###################################################################################
142
library ieee;
143
use ieee.std_logic_1164.all;
144
library techmap;
145
use techmap.gencomp.all;
146
library grlib;
147
use grlib.stdlib.all;
148
 
149
entity generic_ddr_phy is
150
  generic (MHz : integer := 100; rstdelay : integer := 200;
151
    dbits : integer := 16; clk_mul : integer := 2 ;
152
    clk_div : integer := 2; rskew : integer := 0; mobile : integer := 0);
153
  port(
154
    rst       : in  std_ulogic;
155
    clk       : in  std_logic;  -- input clock
156
    clkout    : out std_ulogic; -- system clock
157
    --clkread   : out std_ulogic;
158
    lock      : out std_ulogic; -- DCM locked
159
 
160
    ddr_clk   : out std_logic_vector(2 downto 0);
161
    ddr_clkb  : out std_logic_vector(2 downto 0);
162
    ddr_clk_fb_out  : out std_logic;
163
    ddr_clk_fb: in std_logic;
164
    ddr_cke   : out std_logic_vector(1 downto 0);
165
    ddr_csb   : out std_logic_vector(1 downto 0);
166
    ddr_web   : out std_ulogic;                       -- ddr write enable
167
    ddr_rasb  : out std_ulogic;                       -- ddr ras
168
    ddr_casb  : out std_ulogic;                       -- ddr cas
169
    ddr_dm    : out std_logic_vector (dbits/8-1 downto 0);    -- ddr dm
170
    ddr_dqs   : inout std_logic_vector (dbits/8-1 downto 0);    -- ddr dqs
171
    ddr_ad    : out std_logic_vector (13 downto 0);   -- ddr address
172
    ddr_ba    : out std_logic_vector (1 downto 0);    -- ddr bank address
173
    ddr_dq    : inout  std_logic_vector (dbits-1 downto 0); -- ddr data
174
 
175
    addr      : in  std_logic_vector (13 downto 0); -- data mask
176
    ba        : in  std_logic_vector ( 1 downto 0); -- data mask
177
    dqin      : out std_logic_vector (dbits*2-1 downto 0); -- ddr input data
178
    dqout     : in  std_logic_vector (dbits*2-1 downto 0); -- ddr input data
179
    dm        : in  std_logic_vector (dbits/4-1 downto 0); -- data mask
180
    oen       : in  std_ulogic;
181
    dqs       : in  std_ulogic;
182
    dqsoen    : in  std_ulogic;
183
    rasn      : in  std_ulogic;
184
    casn      : in  std_ulogic;
185
    wen       : in  std_ulogic;
186
    csn       : in  std_logic_vector(1 downto 0);
187
    cke       : in  std_logic_vector(1 downto 0);
188
    ck        : in  std_logic_vector(2 downto 0);
189
    moben     : in  std_logic -- Mobile DDR enable
190
      );
191
end;
192
 
193
architecture rtl of generic_ddr_phy is
194
component gen_ddr_phy_oreg is
195
generic(sameedge : integer := 0 );
196
port(Q : out std_ulogic; C0 : in std_ulogic; C1 : in std_ulogic; CE : in std_ulogic;
197
     D0 : in std_ulogic; D1 : in std_ulogic; R  : in std_ulogic; S  : in std_ulogic);
198
end component;
199
component gen_ddr_phy_ireg is
200
  port(Q0 : out std_ulogic; Q1 : out std_ulogic; C0 : in std_ulogic; C1 : in std_ulogic;
201
       CE : in std_ulogic; D  : in std_ulogic; R  : in std_ulogic; S  : in std_ulogic);
202
end component;
203
component gen_ddr_phy_reg is
204
  port(Q : out std_ulogic; C : in std_ulogic; D  : in std_ulogic);
205
end component;
206
 
207
signal vcc, gnd : std_logic;                                    -- VCC and GND
208
signal clk0r, clk90r, clk180r, clk270r : std_ulogic := '0';     -- Clocks
209
signal rclk90r, rclk270r : std_ulogic;                          -- DDR Read clock
210
signal ddr_clkl, ddr_clkbl, ckn : std_logic_vector(2 downto 0); -- DDR clk generation
211
signal ddr_rasnr, ddr_casnr, ddr_wenr : std_ulogic;             -- RAS, CAS, WEN generation
212
signal ddr_csnr, ddr_ckenr, ckel : std_logic_vector(1 downto 0);-- CSN, CKE generation
213
signal ddr_adr      : std_logic_vector (13 downto 0);           -- DDR ADDRESS generation
214
signal ddr_bar      : std_logic_vector (1 downto 0);            -- DDR BA generation
215
 
216
signal dqsn, oe     : std_logic;                                -- DQS generation
217
signal ddr_dqsin    : std_logic_vector (dbits/8-1 downto 0);    -- DQS generation
218
signal ddr_dqsoen   : std_logic_vector (dbits/8-1 downto 0);    -- DQS generation
219
signal ddr_dqsoutl  : std_logic_vector (dbits/8-1 downto 0);    -- DQS generation
220
 
221
signal ddr_dmr      : std_logic_vector (dbits/8-1 downto 0);    -- DQM generation
222
 
223
signal ddr_dqin     : std_logic_vector (dbits-1 downto 0);      -- DDR DQ generation
224
signal ddr_dqout    : std_logic_vector (dbits-1 downto 0);      -- DDR DQ generation
225
signal ddr_dqoen    : std_logic_vector (dbits-1 downto 0);      -- DDR DQ generation
226
signal dqinl,dqinl2 : std_logic_vector (dbits-1 downto 0);      -- DDR DQ generation
227
signal dqinl3,dqinl4: std_logic_vector (dbits-1 downto 0);      -- DDR DQ generation
228
 
229
signal lockl, locked, vlockl : std_ulogic;                      -- Lock delay
230
 
231
constant DDR_FREQ : integer := (MHz * clk_mul) / clk_div;
232
constant clkperiod : real := ((100000.0 / real(DDR_FREQ))/2.0)/100.0;
233
constant phase90 : real := ((100000.0 / real(DDR_FREQ))/4.0)/100.0;
234
constant readskew : real := ((100000.0 / real(DDR_FREQ))*real(rskew))/25500.0;
235
begin
236
  oe <= not oen;
237
  vcc <= '1'; gnd <= '0';
238
 
239
  -----------------------------------------------------------------------------------
240
  -- Clock generation (Only for simulation)
241
  -----------------------------------------------------------------------------------
242
  -- Phase shifted clocks
243
  -- *** Should be generated from clk input ***
244
-- pragma translate_off
245
  clk0r <= not clk0r after clkperiod* 1 ns;
246
  clk90r <= transport clk0r after phase90 *1 ns;
247
-- pragma translate_on
248
  clk180r <= not clk0r;
249
  clk270r <= not clk90r;
250
 
251
  -- Clock to DDR controller
252
  clkout <= clk0r;
253
 
254
  -- Read clocks
255
-- pragma translate_off
256
  rclk90r <= transport ddr_clk_fb after readskew*1 ns;
257
-- pragma translate_on
258
  rclk270r <= not rclk90r;
259
 
260
  -- Clock generator lock signal
261
  lockl <= rst;
262
 
263
  -----------------------------------------------------------------------------------
264
  -- Lock delay
265
  -----------------------------------------------------------------------------------
266
 
267
  rdel : if rstdelay /= 0 generate
268
    rcnt : process (clk0r)
269
    variable cnt : std_logic_vector(15 downto 0);
270
    variable vlock, co : std_ulogic;
271
    begin
272
      if rising_edge(clk0r) then
273
        co := cnt(15);
274
        vlockl <= vlock;
275
        if lockl = '0' then
276
          cnt := conv_std_logic_vector(rstdelay*DDR_FREQ, 16); vlock := '0';
277
        else
278
          if vlock = '0' then
279
            cnt := cnt -1;  vlock := cnt(15) and not co;
280
          end if;
281
        end if;
282
      end if;
283
      if lockl = '0' then
284
        vlock := '0';
285
      end if;
286
    end process;
287
  end generate;
288
 
289
  locked <= lockl when rstdelay = 0 else vlockl;
290
  lock <= locked;
291
  -----------------------------------------------------------------------------------
292
  -- Generate external DDR clock
293
  -----------------------------------------------------------------------------------
294
 
295
  --fbdclk0r : FDDRRSE port map ( Q => ddr_clk_fb_outr, C0 => clk90r, C1 => clk270r,
296
  --  CE => vcc, D0 => vcc, D1 => gnd, R => gnd, S => gnd);
297
  --fbclk_pad : outpad generic map (tech => virtex4, level => sstl2_i) 
298
  --  port map (ddr_clk_fb_out, ddr_clk_fb_outr);
299
 
300
  ddrclocks : for i in 0 to 2 generate
301
    ckn(i) <= not ck(i);
302
 
303
    -- DDR_CLK
304
    dclk0r : gen_ddr_phy_oreg port map ( Q => ddr_clkl(i), C0 => clk90r, C1 => clk270r,
305
      CE => vcc, D0 => ck(i), D1 => gnd, R => gnd, S => gnd);
306
    ddrclk_pad : outpad generic map (tech => 0)
307
      port map (ddr_clk(i), ddr_clkl(i));
308
 
309
    -- DDR_CLKB
310
    dclk0rb : gen_ddr_phy_oreg port map ( Q => ddr_clkbl(i), C0 => clk90r, C1 => clk270r,
311
      CE => vcc, D0 => ckn(i), D1 => vcc, R => gnd, S => gnd);
312
    ddrclkb_pad : outpad generic map (tech => 0)
313
      port map (ddr_clkb(i), ddr_clkbl(i));
314
  end generate;
315
 
316
 
317
  -----------------------------------------------------------------------------------
318
  --  DDR single-edge control signals
319
  -----------------------------------------------------------------------------------
320
  -- RAS
321
  rasgen : gen_ddr_phy_reg port map ( Q => ddr_rasnr, C => clk0r, D => rasn);
322
  rasn_pad : outpad generic map (tech => 0)
323
    port map (ddr_rasb, ddr_rasnr);
324
 
325
  -- CAS
326
  casgen : gen_ddr_phy_reg port map ( Q => ddr_casnr, C => clk0r, D => casn);
327
  casn_pad : outpad generic map (tech => 0)
328
    port map (ddr_casb, ddr_casnr);
329
 
330
  -- WEN
331
  wengen : gen_ddr_phy_reg port map ( Q => ddr_wenr, C => clk0r, D => wen);
332
  wen_pad : outpad generic map (tech => 0)
333
    port map (ddr_web, ddr_wenr);
334
 
335
  -- BA
336
  bagen : for i in 0 to 1 generate
337
    da0 : gen_ddr_phy_reg port map ( Q => ddr_bar(i), C => clk0r, D => ba(i));
338
    ddr_ba_pad  : outpad generic map (tech => 0)
339
      port map (ddr_ba(i), ddr_bar(i));
340
  end generate;
341
 
342
  -- ADDRESS
343
  dagen : for i in 0 to 13 generate
344
    da0 : gen_ddr_phy_reg port map ( Q => ddr_adr(i), C => clk0r, D => addr(i));
345
    ddr_ad_pad  : outpad generic map (tech => 0)
346
      port map (ddr_ad(i), ddr_adr(i));
347
  end generate;
348
 
349
  -- CSN and CKE
350
  ddrbanks : for i in 0 to 1 generate
351
    csn0gen : gen_ddr_phy_reg port map ( Q => ddr_csnr(i), C => clk0r, D => csn(i));
352
    csn0_pad : outpad generic map (tech => 0)
353
      port map (ddr_csb(i), ddr_csnr(i));
354
    ckel(i) <= cke(i) and (locked or moben); -- CKE Starts high for Mobile DDR
355
    ckegen : gen_ddr_phy_reg port map ( Q => ddr_ckenr(i), C => clk0r, D => ckel(i));
356
    cke_pad : outpad generic map (tech => 0)
357
      port map (ddr_cke(i), ddr_ckenr(i));
358
  end generate;
359
 
360
  -----------------------------------------------------------------------------------
361
  -- DQS generation
362
  -----------------------------------------------------------------------------------
363
  dsqreg : gen_ddr_phy_reg port map ( Q => dqsn, C => clk180r, D => oe);
364
  dqsgen : for i in 0 to dbits/8-1 generate
365
    da0 : gen_ddr_phy_oreg
366
      generic map(sameedge => 1)
367
      port map( Q => ddr_dqsin(i), C0 => clk90r,  C1 => clk270r,
368
        CE => vcc, D0 => dqsn, D1 => gnd, R => gnd, S => gnd);
369
    doen : gen_ddr_phy_reg port map ( Q => ddr_dqsoen(i), C => clk0r, D => dqsoen);
370
    dqs_pad : iopad generic map (tech => 0)
371
      port map (pad => ddr_dqs(i), i => ddr_dqsin(i), en => ddr_dqsoen(i),
372
        o => ddr_dqsoutl(i));
373
  end generate;
374
 
375
  -----------------------------------------------------------------------------------
376
  -- DQM generation
377
  -----------------------------------------------------------------------------------
378
  dmgen : for i in 0 to dbits/8-1 generate
379
    da0 : gen_ddr_phy_oreg
380
      generic map(sameedge => 1)
381
      port map ( Q => ddr_dmr(i), C0 => clk0r, C1 => clk180r,
382
        CE => vcc, D0 => dm(i+dbits/8), D1 => dm(i), R => gnd, S => gnd);
383
    ddr_bm_pad  : outpad generic map (tech => 0)
384
      port map (ddr_dm(i), ddr_dmr(i));
385
  end generate;
386
 
387
  -----------------------------------------------------------------------------------
388
  -- Data bus
389
  -----------------------------------------------------------------------------------
390
 
391
  ddgen : for i in 0 to dbits-1 generate
392
    -- DQ Input
393
    nomobile : if mobile = 0 generate -- No Mobile DDR support
394
      dinq1 : gen_ddr_phy_reg port map ( Q => dqin(i+dbits), C => rclk90r, D => dqinl(i));  -- Standard DDR
395
      dqin(i) <= dqinl2(i);
396
    end generate;
397
    mobsupport : if (mobile = 1) or (mobile = 2) generate -- Standard/Mobile DDR support
398
      dinq1 : gen_ddr_phy_reg port map ( Q => dqinl3(i), C => rclk90r, D => dqinl(i));      -- Standard DDR
399
      dinq2 : gen_ddr_phy_reg port map ( Q => dqinl4(i), C => rclk90r, D => dqinl2(i));     -- Mobile DDR    
400
      dqin(i) <= dqinl2(i) when moben = '0' else dqinl3(i);
401
      dqin(i+dbits) <= dqinl3(i) when moben = '0' else dqinl4(i);
402
    end generate;
403
    mobenable : if mobile = 3 generate -- Mobile DDR support
404
      dinq1 : gen_ddr_phy_reg port map ( Q => dqin(i), C => rclk90r, D => dqinl(i));        -- Mobile DDR
405
      dinq2 : gen_ddr_phy_reg port map ( Q => dqin(i+dbits), C => rclk90r, D => dqinl2(i));
406
    end generate;
407
 
408
    qi : gen_ddr_phy_ireg
409
    port map ( Q0 => dqinl(i),    -- 1-bit output for positive edge of clock 
410
               Q1 => dqinl2(i),   -- 1-bit output for negative edge of clock 
411
               C0 => rclk270r,    -- 1-bit clock input 
412
               C1 => rclk90r,     -- 1-bit clock input 
413
               CE => vcc,         -- 1-bit clock enable input 
414
               D => ddr_dqin(i),  -- 1-bit DDR data input 
415
               R => gnd,          -- 1-bit reset 
416
               S => gnd           -- 1-bit set 
417
             );
418
 
419
    -- DQ Output
420
    da0 : gen_ddr_phy_oreg
421
      generic map(sameedge => 1)
422
      port map ( Q => ddr_dqout(i), C0 => clk0r, C1 => clk180r, CE => vcc,
423
        D0 => dqout(i+dbits), D1 => dqout(i), R => gnd, S => gnd);
424
 
425
    -- DQ Output enable
426
    doen : gen_ddr_phy_reg port map ( Q => ddr_dqoen(i), C => clk0r, D => oen);
427
 
428
    -- DQ PAD
429
    dq_pad : iopad generic map (tech => 0)
430
         port map (pad => ddr_dq(i), i => ddr_dqout(i), en => ddr_dqoen(i), o => ddr_dqin(i));
431
  end generate;
432
 
433
  -----------------------------------------------------------------------------------
434
  --
435
  -----------------------------------------------------------------------------------
436
 
437
end;

powered by: WebSVN 2.1.0

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