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/] [gaisler/] [ddr/] [ddr2sp32a.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:      ddr2sp32a
20
-- File:        ddr2sp32a.vhd
21
-- Author:      Nils-Johan Wessman - Gaisler Research
22
-- Description: 32-bit DDR2 memory controller with asych AHB interface
23
------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.amba.all;
29
use grlib.stdlib.all;
30
library gaisler;
31
use grlib.devices.all;
32
use gaisler.memctrl.all;
33
library techmap;
34
use techmap.gencomp.all;
35
 
36
entity ddr2sp32a is
37
   generic (
38
      memtech : integer := 0;
39
      hindex  : integer := 0;
40
      haddr   : integer := 0;
41
      hmask   : integer := 16#f00#;
42
      ioaddr  : integer := 16#000#;
43
      iomask  : integer := 16#fff#;
44
      MHz     : integer := 100;
45
      TRFC    : integer := 130;
46
      col     : integer := 9;
47
      Mbyte   : integer := 8;
48
      fast    : integer := 0;
49
      pwron   : integer := 0;
50
      oepol   : integer := 0;
51
      readdly : integer := 1;
52
      odten   : integer := 0
53
   );
54
   port (
55
      rst     : in  std_ulogic;
56
      clk_ddr : in  std_ulogic;
57
      clk_ahb : in  std_ulogic;
58
      ahbsi   : in  ahb_slv_in_type;
59
      ahbso   : out ahb_slv_out_type;
60
      sdi     : in  sdctrl_in_type;
61
      sdo     : out sdctrl_out_type
62
   );
63
end;
64
 
65
architecture rtl of ddr2sp32a is
66
 
67
constant REVISION  : integer := 0;
68
 
69
constant CMD_PRE  : std_logic_vector(2 downto 0) := "010";
70
constant CMD_REF  : std_logic_vector(2 downto 0) := "100";
71
constant CMD_LMR  : std_logic_vector(2 downto 0) := "110";
72
constant CMD_EMR  : std_logic_vector(2 downto 0) := "111";
73
 
74
constant odtvalue : std_logic_vector(1 downto 0) := conv_std_logic_vector(odten, 2);
75
 
76
constant abuf : integer := 6;
77
constant hconfig : ahb_config_type := (
78
 
79
   4 => ahb_membar(haddr, '1', '1', hmask),
80
   5 => ahb_iobar(ioaddr, iomask),
81
   others => zero32);
82
 
83
type mcycletype is (midle, active, ext, leadout);
84
type ahb_state_type is (midle, rhold, dread, dwrite, whold1, whold2);
85
type sdcycletype is (act1, act2, act3, rd1, rd2, rd3, rd4, rd5, rd6, rd7, rd8,
86
                     wr0, wr1, wr2, wr3, wr4a, wr4b, wr4, wr5, sidle, ioreg1, ioreg2);
87
type icycletype is (iidle, pre, ref1, ref2, emode23, emode, lmode, emodeocd, finish);
88
 
89
-- sdram configuration register
90
 
91
type sdram_cfg_type is record
92
   command  : std_logic_vector(2 downto 0);
93
   csize    : std_logic_vector(1 downto 0);
94
   bsize    : std_logic_vector(2 downto 0);
95
   trcd     : std_ulogic;  -- tCD : 2/3 clock cycles
96
   trfc     : std_logic_vector(4 downto 0);
97
   trp      : std_ulogic;  -- precharge to activate: 2/3 clock cycles
98
   refresh  : std_logic_vector(11 downto 0);
99
   renable  : std_ulogic;
100
   dllrst   : std_ulogic;
101
   refon    : std_ulogic;
102
   cke      : std_ulogic;
103
   cal_en   : std_logic_vector(7 downto 0);
104
   cal_inc  : std_logic_vector(7 downto 0);
105
   cal_pll  : std_logic_vector(1 downto 0);  -- *** ??? pll_reconf
106
   cal_rst  : std_logic;
107
   readdly  : std_logic_vector(1 downto 0);
108
   twr      : std_logic_vector(4 downto 0);
109
   emr      : std_logic_vector(1 downto 0); -- selects EM register
110
   ocd      : std_ulogic; -- enable/disable ocd
111
end record;
112
 
113
type access_param is record
114
   haddr    : std_logic_vector(31 downto 0);
115
   size     : std_logic_vector(1 downto 0);
116
   hwrite   : std_ulogic;
117
   hio      : std_ulogic;
118
end record;
119
-- local registers
120
 
121
type ahb_reg_type is record
122
   hready   : std_ulogic;
123
   hsel     : std_ulogic;
124
   hio      : std_ulogic;
125
   startsd  : std_ulogic;
126
   write    : std_logic_vector(1 downto 0);
127
   state    : ahb_state_type;
128
   haddr    : std_logic_vector(31 downto 0);
129
   hrdata   : std_logic_vector(31 downto 0);
130
   hwdata   : std_logic_vector(31 downto 0);
131
   hwrite   : std_ulogic;
132
   htrans   : std_logic_vector(1 downto 0);
133
   hresp    : std_logic_vector(1 downto 0);
134
   raddr    : std_logic_vector(abuf-1 downto 0);
135
   size     : std_logic_vector(1 downto 0);
136
   acc      : access_param;
137
   sync        : std_logic_vector(2 downto 1);
138
   startsd_ack : std_logic;
139
end record;
140
 
141
type ddr_reg_type is record
142
   startsd     : std_ulogic;
143
   startsdold  : std_ulogic;
144
   hready      : std_ulogic;
145
   bdrive      : std_ulogic;
146
   qdrive      : std_ulogic;
147
   nbdrive     : std_ulogic;
148
   mstate      : mcycletype;
149
   sdstate     : sdcycletype;
150
   cmstate     : mcycletype;
151
   istate      : icycletype;
152
   trfc        : std_logic_vector(4 downto 0);
153
   refresh     : std_logic_vector(11 downto 0);
154
   sdcsn       : std_logic_vector(1  downto 0);
155
   sdwen       : std_ulogic;
156
   rasn        : std_ulogic;
157
   casn        : std_ulogic;
158
   dqm         : std_logic_vector(7 downto 0);
159
   dqm_dly     : std_logic_vector(7 downto 0);  -- *** ??? delay ctrl
160
   address     : std_logic_vector(15 downto 2);  -- memory address
161
   ba          : std_logic_vector(1  downto 0);
162
   waddr       : std_logic_vector(abuf-1 downto 0);
163
   waddr_d     : std_logic_vector(abuf-1 downto 0); -- Same as waddr but delayed to compensate for pipelined output data
164
   cfg         : sdram_cfg_type;
165
   hrdata      : std_logic_vector(63 downto 0);
166
   readdly     : std_logic_vector(1 downto 0); -- added read latency
167
   newcom      : std_logic_vector(1 downto 0); -- start sec. read/write
168
   wdata       : std_logic_vector(63 downto 0);
169
   initnopdly  : std_logic_vector(7 downto 0); -- 400 ns delay
170
   sync        : std_logic;
171
   odt          : std_logic_vector(1 downto 0);
172
   sdo_bdrive   : std_logic; -- *** ??? delay ctrl
173
   sdo_qdrive   : std_logic; -- *** ??? delay ctrl
174
end record;
175
 
176
signal vcc : std_ulogic;
177
signal r, ri : ddr_reg_type;
178
signal ra, rai : ahb_reg_type;
179
signal rbdrive, ribdrive : std_logic_vector(31 downto 0);
180
signal rdata, wdata : std_logic_vector(63 downto 0);
181
signal ddr_rst : std_logic;
182
signal ddr_rst_gen  : std_logic_vector(3 downto 0);
183
attribute syn_preserve : boolean;
184
attribute syn_preserve of rbdrive : signal is true;
185
 
186
begin
187
 
188
   vcc <= '1';
189
 
190
   ddr_rst <= (ddr_rst_gen(3) and ddr_rst_gen(2) and ddr_rst_gen(1) and rst); -- Reset signal in DDR clock domain
191
 
192
   ahb_ctrl : process(rst, ahbsi, r, ra, rdata)
193
   variable v       : ahb_reg_type;    -- local variables for registers
194
   variable startsd : std_ulogic;
195
   variable dout    : std_logic_vector(31 downto 0);
196
   variable ready   : std_logic;
197
   begin
198
 
199
      v := ra; v.hresp := HRESP_OKAY; v.write := "00";
200
 
201
      if ra.raddr(0) = '0' then v.hrdata := rdata(63 downto 32);
202
      else v.hrdata := rdata(31 downto 0); end if;
203
 
204
      -- Sync ------------------------------------------------
205
      v.sync(1) := r.startsdold; v.sync(2) := ra.sync(1);
206
      ready := ra.startsd_ack xor ra.sync(2);
207
      --------------------------------------------------------
208
 
209
      if ((ahbsi.hready and ahbsi.hsel(hindex)) = '1') then
210
         v.htrans := ahbsi.htrans; v.haddr := ahbsi.haddr;
211
         v.size := ahbsi.hsize(1 downto 0); v.hwrite := ahbsi.hwrite;
212
         if ahbsi.htrans(1) = '1' then
213
            v.hio := ahbsi.hmbsel(1);
214
            v.hsel := '1'; v.hready := '0';
215
         end if;
216
      end if;
217
 
218
      if ahbsi.hready = '1' then v.hsel := ahbsi.hsel(hindex); end if;
219
 
220
      case ra.state is
221
      when midle =>
222
         if ((v.hsel and v.htrans(1)) = '1') then
223
            if v.hwrite = '0' then
224
               v.state := rhold; v.startsd := not ra.startsd;
225
            else
226
               v.state := dwrite; v.hready := '1';
227
               v.write(0) := not v.haddr(2); v.write(1) := v.haddr(2);
228
            end if;
229
         end if;
230
         v.raddr := ra.haddr(7 downto 2);
231
         if ahbsi.hready = '1' then
232
            v.acc := (v.haddr, v.size, v.hwrite, v.hio);
233
         end if;
234
      when rhold =>
235
         v.raddr := ra.haddr(7 downto 2);
236
         if ready = '1' then
237
            v.state := dread; v.hready := '1'; v.raddr := ra.raddr + 1;
238
         end if;
239
      when dread =>
240
         v.raddr := ra.raddr + 1; v.hready := '1';
241
         if ((v.hsel and v.htrans(1) and v.htrans(0)) = '0')
242
            or (ra.raddr(2 downto 0) = "000") then
243
            v.state := midle; v.hready := '0';
244
            v.startsd_ack := ra.startsd;
245
         end if;
246
         v.acc := (v.haddr, v.size, v.hwrite, v.hio);
247
      when dwrite =>
248
         v.raddr := ra.haddr(7 downto 2); v.hready := '1';
249
         v.write(0) := not v.haddr(2); v.write(1) := v.haddr(2);
250
         if ((v.hsel and v.htrans(1) and v.htrans(0)) = '0')
251
            or (ra.haddr(4 downto 2) = "111") then
252
            v.startsd := not ra.startsd; v.state := whold1;
253
            v.write := "00"; v.hready := '0';
254
         end if;
255
      when whold1 =>
256
         v.state := whold2;
257
      when whold2 =>
258
         if ready = '1' then
259
            v.state := midle; v.acc := (v.haddr, v.size, v.hwrite, v.hio);
260
            v.startsd_ack := ra.startsd;
261
         end if;
262
      end case;
263
 
264
      v.hwdata := ahbsi.hwdata;
265
 
266
      if (ahbsi.hready and ahbsi.hsel(hindex) ) = '1' then
267
         if ahbsi.htrans(1) = '0' then v.hready := '1'; end if;
268
      end if;
269
 
270
      dout := ra.hrdata(31 downto 0);
271
 
272
      if rst = '0' then
273
         v.hsel         := '0';
274
         v.hready       := '1';
275
         v.state        := midle;
276
         v.startsd      := '0';
277
         v.startsd_ack  := '0';
278
         v.hio          := '0';
279
      end if;
280
 
281
      rai <= v;
282
      ahbso.hready  <= ra.hready;
283
      ahbso.hresp   <= ra.hresp;
284
      ahbso.hrdata  <= dout;
285
      ahbso.hcache  <= not ra.hio;
286
 
287
   end process;
288
 
289
   ddr_ctrl : process(ddr_rst, r, ra, sdi, rbdrive, wdata)
290
   variable v        : ddr_reg_type;    -- local variables for registers
291
   variable startsd  : std_ulogic;
292
   variable dqm      : std_logic_vector(7 downto 0);
293
   variable raddr    : std_logic_vector(13 downto 0);
294
   variable adec     : std_ulogic;
295
   variable rams     : std_logic_vector(1 downto 0);
296
   variable ba       : std_logic_vector(1 downto 0);
297
   variable haddr    : std_logic_vector(31 downto 0);
298
   variable hsize    : std_logic_vector(1 downto 0);
299
   variable hwrite   : std_ulogic;
300
   variable htrans   : std_logic_vector(1 downto 0);
301
   variable hready   : std_ulogic;
302
   variable vbdrive  : std_logic_vector(31 downto 0);
303
   variable bdrive   : std_ulogic;
304
   variable writecfg : std_ulogic;
305
   variable regsd1   : std_logic_vector(31 downto 0);   -- data from registers
306
   variable regsd2   : std_logic_vector(31 downto 0);   -- data from registers
307
   variable regsd3   : std_logic_vector(31 downto 0);   -- data from registers
308
   begin
309
 
310
-- Variable default settings to avoid latches
311
 
312
      v := r; v.hready := '0'; writecfg := '0'; vbdrive := rbdrive;
313
      v.hrdata := sdi.data(63 downto 0); v.qdrive :='0';
314
      v.cfg.cal_en    :=  (others => '0'); v.cfg.cal_inc   :=  (others => '0');
315
      v.cfg.cal_pll   :=  (others => '0');                                            -- *** ??? pll_reconf
316
      v.cfg.cal_rst   :=  '0';
317
      v.wdata := wdata; -- pipeline output data
318
      v.dqm_dly := r.dqm;                                                             -- *** ??? delay ctrl
319
 
320
      regsd1 := (others => '0');
321
      regsd1(31 downto 15) := r.cfg.refon & r.cfg.ocd & r.cfg.emr & '0' & r.cfg.trcd &
322
                              r.cfg.bsize & r.cfg.csize & r.cfg.command &
323
                              r.cfg.dllrst & r.cfg.renable & r.cfg.cke;
324
      regsd1(11 downto 0) := r.cfg.refresh;
325
      regsd2 := (others => '0');
326
      regsd2(8 downto 0) := conv_std_logic_vector(MHz, 9);
327
      regsd2(14 downto 12) := conv_std_logic_vector(2, 3);
328
      regsd3 := (others => '0');
329
      regsd3(17 downto 16) := r.cfg.readdly;
330
      regsd3(22 downto 18) := r.cfg.trfc;
331
      regsd3(27 downto 23) := r.cfg.twr;
332
      regsd3(28) := r.cfg.trp;
333
 
334
-- generate DQM from address and write size
335
 
336
      case ra.acc.size is
337
      when "00" =>
338
         case ra.acc.haddr(2 downto 0) is
339
         when "000" => dqm := "01111111";
340
         when "001" => dqm := "10111111";
341
         when "010" => dqm := "11011111";
342
         when "011" => dqm := "11101111";
343
         when "100" => dqm := "11110111";
344
         when "101" => dqm := "11111011";
345
         when "110" => dqm := "11111101";
346
         when others => dqm := "11111110";
347
         end case;
348
      when "01" =>
349
         case ra.acc.haddr(2 downto 1) is
350
         when "00"   => dqm := "00111111";
351
         when "01"   => dqm := "11001111";
352
         when "10"   => dqm := "11110011";
353
         when others => dqm := "11111100";
354
         end case;
355
      when others => dqm := "00000000";
356
      end case;
357
 
358
      -- Sync ------------------------------------------
359
      v.sync := ra.startsd; v.startsd := r.sync;
360
      --------------------------------------------------
361
 
362
      --v.startsd := ra.startsd;
363
 
364
---- main FSM
365
--
366
--      case r.mstate is
367
--      when midle =>
368
--         if  r.startsd = '1' then
369
--            if (r.sdstate = sidle) and (r.cfg.command = "000") 
370
--               and (r.cmstate = midle) then
371
--               startsd := '1'; v.mstate := active;
372
--            end if;
373
--         end if;
374
--      when others => null;
375
--      end case;
376
 
377
      startsd := r.startsd xor r.startsdold;
378
 
379
-- generate row and column address size
380
 
381
      haddr := ra.acc.haddr;
382
      haddr(31 downto 20) := haddr(31 downto 20) and not conv_std_logic_vector(hmask, 12);
383
 
384
      case r.cfg.csize is
385
      when "00" => raddr := haddr(24 downto 11);
386
      when "01" => raddr := haddr(25 downto 12);
387
      when "10" => raddr := haddr(26 downto 13);
388
      when others => raddr := haddr(27 downto 14);
389
      end case;
390
 
391
-- generate bank address
392
 
393
      ba := genmux(r.cfg.bsize, haddr(29 downto 22)) &
394
            genmux(r.cfg.bsize, haddr(28 downto 21));
395
 
396
-- generate chip select
397
 
398
      adec := genmux(r.cfg.bsize, haddr(30 downto 23));
399
 
400
      rams := adec & not adec;
401
 
402
-- sdram access FSM
403
 
404
      if r.trfc /= "00000" then v.trfc := r.trfc - 1; end if;
405
 
406
      case r.sdstate is
407
      when sidle =>
408
         if (startsd = '1') and (r.cfg.command = "000") and (r.cmstate = midle)
409
            and (r.istate = finish) then
410
            v.address := raddr; v.ba := ba;
411
            if ra.acc.hio = '0' then
412
               v.sdcsn := not rams(1 downto 0); v.rasn := '0'; v.sdstate := act1;
413
            else v.sdstate := ioreg1; end if;
414
         end if;
415
         v.waddr := ra.acc.haddr(7 downto 2);
416
      when act1 =>
417
         v.rasn := '1'; v.trfc := r.cfg.trfc;
418
         if r.cfg.trcd = '1' then v.sdstate := act2;
419
         else v.sdstate := act3;
420
         end if;
421
         --v.waddr := ra.acc.haddr(7 downto 2);
422
         v.waddr := ra.acc.haddr(7 downto 4) & '0' & ra.acc.haddr(2);
423
         v.waddr_d := ra.acc.haddr(7 downto 4) & '0' & ra.acc.haddr(2);
424
         if ra.acc.hwrite = '1' then
425
           if odten /= 0 then v.odt := (others => '1'); end if; -- *** ??? odt
426
         end if;
427
      when act2 =>
428
         v.sdstate := act3;
429
      when act3 =>
430
         v.casn := '0';
431
         --v.address := ra.acc.haddr(14 downto 12) & '0' & ra.acc.haddr(11 downto 3) & '0';
432
         v.address := ra.acc.haddr(14 downto 12) & '0' & ra.acc.haddr(11 downto 4) & "00";
433
         v.hready := ra.acc.hwrite;
434
         if ra.acc.hwrite = '1' then
435
            v.sdstate := wr0;
436
            v.sdwen := '0';
437
            --v.waddr := r.waddr + 2; v.waddr(0) := '0';        -- *** ??? delay ctrl
438
            v.trfc := r.cfg.twr;
439
         else v.sdstate := rd1; end if;
440
         v.newcom(0) :=  '0';
441
         if (ra.acc.haddr(4) = '1' or ra.raddr(2 downto 0) < "100") then v.newcom(1) := '1';
442
         else v.newcom(1) := '0'; end if;
443
      when wr0 =>
444
         v.address(4) := not ra.acc.haddr(4); -- set start address for new write command
445
         v.casn := '1'; v.sdwen := '1'; v.bdrive := '0'; v.qdrive := '1';
446
         if r.waddr_d = ra.acc.haddr(7 downto 2) then
447
            v.dqm := dqm;
448
            v.waddr_d := r.waddr_d + 2; v.waddr_d(0) := '0';
449
            v.waddr := r.waddr + 2;
450
            v.sdstate := wr1;
451
            if (r.waddr_d /= ra.raddr) then v.hready := '1';
452
               if r.waddr_d(0) = '1' then v.dqm(7 downto 4) := (others => '1'); end if;
453
            else
454
               if r.waddr_d(0) = '0' then v.dqm(3 downto 0) := (others => '1');
455
               else v.dqm(7 downto 4) := (others => '1'); end if;
456
            end if;
457
         else
458
            v.newcom(0) := '1'; -- start new command
459
            v.waddr_d := r.waddr_d + 2;
460
            v.waddr := r.waddr + 2;
461
            v.dqm := (others => '1');
462
         end if;
463
         if r.newcom(1 downto 0) = "01" then -- start new write command
464
            v.newcom(1) := '1'; -- new command done
465
            v.sdwen := '0'; v.casn := '0';
466
            v.trfc := r.cfg.twr;
467
         end if;
468
      when wr1 =>
469
         v.sdwen := '1';  v.casn := '1';  v.qdrive := '1';
470
         v.waddr_d := r.waddr_d + 2; v.dqm(7 downto 4) := (others => '0');
471
         v.waddr := r.waddr + 2;
472
         if r.newcom(1) = '0' then -- start new write command
473
            v.newcom(1) := '1'; -- new command done
474
            v.sdwen := '0'; v.casn := '0';
475
            v.trfc := r.cfg.twr;
476
         end if;
477
         if (r.waddr_d <= ra.raddr) and (r.waddr_d(5 downto 1) /= "00000") and (r.hready = '1')
478
         then
479
            v.hready := '1';
480
            if  (r.waddr_d = ra.raddr) and (r.waddr_d /= "000000") and (r.waddr_d(0) = '0') then
481
               v.dqm(3 downto 0) := (others => '1');
482
            end if;
483
         else
484
            v.sdstate := wr2;
485
            v.dqm := (others => '1');
486
            v.startsdold := r.startsd;
487
         end if;
488
      when wr2 =>
489
         v.sdstate := wr3; v.qdrive := '1';
490
      when wr3 =>
491
         v.sdstate := wr4a; v.qdrive := '1';
492
      when wr4a =>
493
         v.bdrive := '1'; v.qdrive := '1';
494
         if r.trfc = "00000" then -- wait to not violate TWR timing
495
            v.sdstate := wr4b;
496
         end if;
497
      when wr4b =>
498
         v.bdrive := '1';
499
         v.rasn := '0'; v.sdwen := '0'; v.sdstate := wr4; v.qdrive := '1'; -- precharge
500
      when wr4 =>
501
         v.sdcsn := "11"; v.rasn := '1'; v.sdwen := '1';  v.qdrive := '0';
502
         v.sdstate := wr5;
503
      when wr5 =>
504
         v.odt := (others => '0'); -- *** ??? odt
505
         v.sdstate := sidle;
506
      when rd1 =>
507
         v.address(4) := not ra.acc.haddr(4); -- Set address for next read command
508
         v.casn := '1'; v.sdstate := rd7;
509
      when rd7 =>
510
         v.casn := '1'; v.sdstate := rd8;
511
         --v.readdly := r.cfg.readdly;
512
         v.readdly := r.cfg.readdly + 1;                                              -- *** ??? delay ctrl
513
         if ra.acc.haddr(4) = '0' then -- start new read command if needed.
514
            v.casn := '0';
515
         end if;
516
      when rd8 => -- (CL = 3)
517
         v.casn := '1';
518
         if r.readdly = "00" then -- add read delay
519
            v.sdstate := rd2;
520
         else
521
            v.readdly := r.readdly - 1;
522
         end if;
523
      when rd2 =>
524
         v.casn := '1'; v.sdstate := rd3;
525
      when rd3 =>
526
         if fast = 0 then v.startsdold := r.startsd; end if;
527
         v.sdstate := rd4; v.hready := '1'; v.casn := '1';
528
         if v.hready = '1' then v.waddr := r.waddr + 2; end if;
529
      when rd4 =>
530
         v.hready := '1'; v.casn := '1';
531
         if (r.sdcsn = "11") or (r.waddr(2 downto 1) = "11") then
532
            v.dqm := (others => '1');
533
            if fast /= 0 then v.startsdold := r.startsd; end if;
534
            if (r.sdcsn /= "11") then
535
               v.rasn := '0'; v.sdwen := '0'; v.sdstate := rd5; -- precharge
536
            else
537
               if r.cfg.trp = '1' then v.sdstate := rd6;
538
               else v.sdstate := sidle; end if;
539
            end if;
540
         end if;
541
         if v.hready = '1' then v.waddr := r.waddr + 2; end if;
542
      when rd5 =>
543
         if r.cfg.trp = '1' then v.sdstate := rd6;
544
         else v.sdstate := sidle; end if;
545
         v.sdcsn := (others => '1'); v.rasn := '1'; v.sdwen := '1';
546
         v.dqm := (others => '1');
547
      when rd6 =>
548
         v.sdstate := sidle; v.dqm := (others => '1');
549
         v.sdcsn := (others => '1'); v.rasn := '1'; v.sdwen := '1';
550
      when ioreg1 =>
551
         if r.waddr(1) = '0' then
552
            v.hrdata := regsd1 & regsd2;
553
         else
554
            v.hrdata := regsd3 & regsd3;
555
         end if;
556
         v.sdstate := ioreg2;
557
         if ra.acc.hwrite = '0' then v.hready := '1'; end if;
558
      when ioreg2 =>
559
         writecfg := ra.acc.hwrite; v.startsdold := r.startsd;
560
         v.sdstate := sidle;
561
      when others =>
562
         v.sdstate := sidle;
563
      end case;
564
 
565
-- sdram commands
566
 
567
      case r.cmstate is
568
      when midle =>
569
         if r.sdstate = sidle then
570
            case r.cfg.command is
571
            when CMD_PRE => -- precharge
572
               v.sdcsn := (others => '0'); v.rasn := '0'; v.sdwen := '0';
573
               v.address(12) := '1'; v.cmstate := active;
574
            when CMD_REF => -- auto-refresh
575
               v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0';
576
               v.cmstate := active;
577
            when CMD_EMR => -- load-ext-mode-reg
578
               v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0';
579
               v.sdwen := '0'; v.cmstate := active; v.ba := r.cfg.emr; --v.ba select EM register
580
               --v.address := "0000"&r.cfg.ocd&r.cfg.ocd&r.cfg.ocd&"0000000"; 
581
               if r.cfg.emr = "01" then
582
                 v.address := "0000"&r.cfg.ocd&r.cfg.ocd&r.cfg.ocd
583
                              & odtvalue(1)&"000"&odtvalue(0)&"00";
584
               else
585
                 v.address := "0000"&r.cfg.ocd&r.cfg.ocd&r.cfg.ocd&"0000000";
586
               end if;
587
            when CMD_LMR => -- load-mode-reg
588
               v.sdcsn := (others => '0'); v.rasn := '0'; v.casn := '0';
589
               v.sdwen := '0'; v.cmstate := active; v.ba := "00";
590
               v.address := "00010" & r.cfg.dllrst & "0" & "01" & "10010";  -- CAS = 3 WR = 3 burts = 4
591
            when others => null;
592
            end case;
593
         end if;
594
      when active =>
595
         v.sdcsn := (others => '1'); v.rasn := '1'; v.casn := '1';
596
         v.sdwen := '1'; v.cfg.command := "000";
597
         v.cmstate := leadout; v.trfc := r.cfg.trfc;
598
      when others =>
599
         if r.trfc = "00000" then v.cmstate := midle; end if;
600
      end case;
601
 
602
-- sdram init
603
 
604
      case r.istate is
605
      when iidle =>
606
         if r.cfg.renable = '1' then
607
            v.cfg.cke := '1'; v.cfg.dllrst := '1';
608
            v.ba := "00"; v.cfg.ocd := '0'; v.cfg.emr := "10"; -- EMR(2)
609
            if r.cfg.cke = '1' then
610
               if r.initnopdly = "00000000" then -- 400 ns of NOP and CKE
611
                  v.istate := pre; v.cfg.command := CMD_PRE;
612
               else
613
                  v.initnopdly := r.initnopdly - 1;
614
               end if;
615
            end if;
616
         end if;
617
      when pre =>
618
         if r.cfg.command = "000" then
619
            v.cfg.command := "11" & r.cfg.dllrst; -- CMD_LMR/CMD_EMR 
620
            if r.cfg.dllrst = '1' then v.istate := emode23; else v.istate := lmode; end if;
621
         end if;
622
      when emode23 =>
623
         if r.cfg.command = "000" then
624
            if r.cfg.emr = "11" then
625
               v.cfg.emr := "01"; -- (EMR(1))
626
               v.istate := emode; v.cfg.command := CMD_EMR;
627
            else
628
               v.cfg.emr := "11"; v.cfg.command := CMD_EMR; -- EMR(3)
629
            end if;
630
         end if;
631
      when emode =>
632
         if r.cfg.command = "000" then
633
            v.istate := lmode; v.cfg.command := CMD_LMR;
634
         end if;
635
      when lmode =>
636
         if r.cfg.command = "000" then
637
            if r.cfg.dllrst = '1' then
638
               if r.refresh(9 downto 8) = "00" then -- > 200 clocks delay
639
                  v.cfg.command := CMD_PRE; v.istate := ref1;
640
               end if;
641
            else
642
               v.istate := emodeocd;
643
               v.cfg.ocd := '1'; v.cfg.command := CMD_EMR;
644
            end if;
645
         end if;
646
      when ref1 =>
647
         if r.cfg.command = "000" then
648
            v.cfg.command := CMD_REF; v.cfg.dllrst := '0'; v.istate := ref2;
649
         end if;
650
      when ref2 =>
651
         if r.cfg.command = "000" then
652
            v.cfg.command := CMD_REF; v.istate := pre;
653
         end if;
654
      when emodeocd =>
655
         if r.cfg.command = "000" then
656
            if r.cfg.ocd = '0' then -- Exit OCD
657
               v.istate := finish;
658
               v.cfg.refon := '1'; v.cfg.renable := '0';
659
            else                    -- Default OCD
660
               v.cfg.ocd := '0';
661
               v.cfg.command := CMD_EMR;
662
            end if;
663
         end if;
664
         v.cfg.cal_rst   :=  '1'; -- reset data bit dely
665
      when others =>
666
         --if odten /= 0 then v.odt := (others => '1'); end if;  -- *** ??? odt
667
         if r.cfg.renable = '1' then
668
            v.istate := iidle; v.cfg.dllrst := '1';
669
            v.initnopdly := (others => '1');
670
            v.odt := (others => '0');
671
         end if;
672
      end case;
673
 
674
---- second part of main fsm
675
--
676
--      case r.mstate is
677
--      when active =>
678
--         if v.hready = '1' then
679
--            v.mstate := midle;
680
--         end if;
681
--      when others => null;
682
--      end case;
683
 
684
-- sdram refresh counter
685
 
686
      if ((r.cfg.refon = '1') and (r.istate = finish)) or (r.cfg.dllrst = '1') then
687
         v.refresh := r.refresh - 1;
688
         if (v.refresh(11) and not r.refresh(11))  = '1' then
689
            v.refresh := r.cfg.refresh;
690
            if r.cfg.dllrst = '0' then v.cfg.command := "100"; end if;
691
         end if;
692
      end if;
693
 
694
-- AHB register access
695
 
696
      if (ra.acc.hio and ra.acc.hwrite and writecfg) = '1' then
697
         if r.waddr(1 downto 0) = "00" then
698
            v.cfg.refresh   :=  wdata(11+32 downto 0+32);
699
            v.cfg.cke       :=  wdata(15+32);
700
            v.cfg.renable   :=  wdata(16+32);
701
            v.cfg.dllrst    :=  wdata(17+32);
702
            v.cfg.command   :=  wdata(20+32 downto 18+32);
703
            v.cfg.csize     :=  wdata(22+32 downto 21+32);
704
            v.cfg.bsize     :=  wdata(25+32 downto 23+32);
705
            v.cfg.trcd      :=  wdata(26+32);
706
            v.cfg.emr       :=  wdata(29+32 downto 28+32);
707
            v.cfg.ocd       :=  wdata(30+32);
708
            v.cfg.refon     :=  wdata(31+32);
709
         elsif r.waddr(1 downto 0) = "10" then
710
            v.cfg.cal_en    :=  wdata( 7+32 downto  0+32);
711
            v.cfg.cal_inc   :=  wdata(15+32 downto  8+32);
712
            v.cfg.readdly   :=  wdata(17+32 downto 16+32);
713
            v.cfg.trfc      :=  wdata(22+32 downto 18+32);
714
            v.cfg.twr       :=  wdata(27+32 downto 23+32);
715
            v.cfg.trp       :=  wdata(28+32);
716
            v.cfg.cal_pll   :=  wdata(30+32 downto 29+32);                            -- *** ??? pll_reconf
717
            v.cfg.cal_rst   :=  wdata(31+32);
718
         end if;
719
      end if;
720
 
721
      v.nbdrive := not v.bdrive;
722
 
723
      if oepol = 1 then bdrive := r.nbdrive; vbdrive := (others => v.nbdrive);
724
      else bdrive := r.bdrive; vbdrive := (others => v.bdrive);end if;
725
 
726
-- reset
727
 
728
      if ddr_rst = '0' then
729
         v.sdstate      := sidle;
730
         v.mstate       := midle;
731
         v.istate       := finish;
732
         v.cmstate      := midle;
733
         v.cfg.command  := "000";
734
         v.cfg.csize    := conv_std_logic_vector(col-9, 2);
735
         v.cfg.bsize    := conv_std_logic_vector(log2(Mbyte/8), 3);
736
         v.cfg.refon    :=  '0';
737
         v.cfg.trfc     := conv_std_logic_vector(TRFC*MHz/1000-2, 5);
738
         v.cfg.refresh  := conv_std_logic_vector(7800*MHz/1000, 12);
739
         v.cfg.twr      := conv_std_logic_vector((15)*MHz/1000+3, 5);
740
         v.refresh      :=  (others => '0');
741
         v.dqm          := (others => '1');
742
         v.sdwen        := '1';
743
         v.rasn         := '1';
744
         v.casn         := '1';
745
         v.hready       := '0';
746
         v.startsd      := '0';
747
         v.startsdold   := '0';
748
         v.cfg.dllrst   := '0';
749
         v.cfg.cke      := '0';
750
         v.cfg.ocd      := '0';
751
         v.cfg.readdly  := conv_std_logic_vector(readdly, 2);
752
         v.initnopdly   := (others => '1');
753
         if MHz > 130 then v.cfg.trcd :=  '1'; else v.cfg.trcd :=  '0'; end if;
754
         if MHz > 130 then v.cfg.trp := '1'; else v.cfg.trp := '0'; end if;
755
         if pwron = 1 then v.cfg.renable :=  '1';
756
         else v.cfg.renable :=  '0'; end if;
757
         v.odt          := (others => '0');
758
      end if;
759
 
760
      if oepol = 1 then v.sdo_bdrive := r.nbdrive;            -- *** ??? delay ctrl
761
      else v.sdo_bdrive := r.bdrive; end if;
762
      v.sdo_qdrive := not (v.qdrive or r.nbdrive);
763
 
764
      ri <= v;
765
      ribdrive <= vbdrive;
766
 
767
   end process;
768
 
769
   sdo.sdcke     <= (others => r.cfg.cke);
770
   ahbso.hconfig <= hconfig;
771
   ahbso.hirq    <= (others => '0');
772
   ahbso.hindex  <= hindex;
773
 
774
   ahbregs : process(clk_ahb) begin
775
      if rising_edge(clk_ahb) then
776
         ra <= rai;
777
      end if;
778
   end process;
779
 
780
   ddrregs : process(clk_ddr, rst, ddr_rst) begin
781
      if rising_edge(clk_ddr) then
782
         r <= ri; rbdrive <= ribdrive;
783
         ddr_rst_gen <= ddr_rst_gen(2 downto 0) & '1';
784
      end if;
785
      if (rst = '0') then
786
         ddr_rst_gen <= "0000";
787
      end if;
788
      if (ddr_rst = '0') then
789
         r.sdcsn  <= (others => '1'); r.bdrive <= '1'; r.nbdrive <= '0';
790
         if oepol = 0 then rbdrive <= (others => '1');
791
         else rbdrive <= (others => '0'); end if;
792
         r.cfg.cke <= '0';
793
         r.odt <= (others => '0');
794
      end if;
795
   end process;
796
 
797
   sdo.address  <= '0' & r.address; --'0' & ri.address;                     -- *** ??? delay ctrl
798
   sdo.ba       <= r.ba; --ri.ba;                                           -- *** ??? delay ctrl
799
   sdo.bdrive   <= r.sdo_bdrive; --r.nbdrive when oepol = 1 else r.bdrive;  -- *** ??? delay ctrl
800
   sdo.qdrive   <= r.sdo_qdrive; --not (ri.qdrive or r.nbdrive);            -- *** ??? delay ctrl
801
   sdo.vbdrive  <= rbdrive;
802
   sdo.sdcsn    <= r.sdcsn; --ri.sdcsn;                                     -- *** ??? delay ctrl
803
   sdo.sdwen    <= r.sdwen; --ri.sdwen;                                     -- *** ??? delay ctrl
804
   sdo.dqm      <= "11111111" & r.dqm_dly; --"11111111" & r.dqm;            -- *** ??? delay ctrl
805
   sdo.rasn     <= r.rasn; --ri.rasn;                                       -- *** ??? delay ctrl
806
   sdo.casn     <= r.casn; --ri.casn;                                       -- *** ??? delay ctrl
807
   --sdo.data     <= zero32 & zero32 & wdata;
808
   sdo.data     <= zero32 & zero32 & r.wdata;
809
   sdo.cal_en   <= r.cfg.cal_en;
810
   sdo.cal_inc  <= r.cfg.cal_inc;
811
   sdo.cal_pll  <= r.cfg.cal_pll;                                           -- *** ??? pll_reconf
812
   sdo.cal_rst  <= r.cfg.cal_rst;
813
   sdo.odt      <= r.odt;
814
 
815
   read_buff : syncram_2p
816
   generic map (tech => memtech, abits => 5, dbits => 64, sepclk => 1, wrfst => 0)
817
   port map ( rclk => clk_ahb, renable => vcc, raddress => rai.raddr(5 downto 1),
818
              dataout => rdata, wclk => clk_ddr, write => ri.hready,
819
              waddress => r.waddr(5 downto 1), datain => ri.hrdata);
820
 
821
   write_buff1 : syncram_2p
822
   generic map (tech => memtech, abits => 5, dbits => 32, sepclk => 1, wrfst => 0)
823
   port map ( rclk => clk_ddr, renable => vcc, raddress => r.waddr(5 downto 1),
824
              dataout => wdata(63 downto 32), wclk => clk_ahb, write => ra.write(0),
825
              waddress => ra.haddr(7 downto 3), datain => ahbsi.hwdata);
826
 
827
   write_buff2 : syncram_2p
828
   generic map (tech => memtech, abits => 5, dbits => 32, sepclk => 1, wrfst => 0)
829
   port map ( rclk => clk_ddr, renable => vcc, raddress => r.waddr(5 downto 1),
830
              dataout => wdata(31 downto 0), wclk => clk_ahb, write => ra.write(1),
831
              waddress => ra.haddr(7 downto 3), datain => ahbsi.hwdata);
832
 
833
-- pragma translate_off
834
   bootmsg : report_version
835
   generic map (
836
      msg1 => "ddr2sp" & tost(hindex) & ": 32-bit DDR2 controller rev " &
837
              tost(REVISION) & ", " & tost(Mbyte) & " Mbyte, " & tost(MHz) &
838
              " MHz DDR clock");
839
-- pragma translate_on
840
end;

powered by: WebSVN 2.1.0

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