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/] [ddr2sp16a.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:      ddr2sp16a
20
-- File:        ddr2sp16a.vhd
21
-- Author:      Nils-Johan Wessman - Gaisler Research
22
-- Description: 16-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 ddr2sp16a 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 ddr2sp16a 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
 
120
-- local registers
121
 
122
type ahb_reg_type is record
123
   hready      : std_ulogic;
124
   hsel        : std_ulogic;
125
   hio         : std_ulogic;
126
   startsd     : std_ulogic;
127
   write       : std_ulogic;
128
   state       : ahb_state_type;
129
   haddr       : std_logic_vector(31 downto 0);
130
   hrdata      : std_logic_vector(31 downto 0);
131
   hwdata      : std_logic_vector(31 downto 0);
132
   hwrite      : std_ulogic;
133
   htrans      : std_logic_vector(1 downto 0);
134
   hresp       : std_logic_vector(1 downto 0);
135
   raddr       : std_logic_vector(abuf-1 downto 0);
136
   size        : std_logic_vector(1 downto 0);
137
   acc         : access_param;
138
   sync        : std_logic_vector(2 downto 1);
139
   startsd_ack : std_logic;
140
end record;
141
 
142
type ddr_reg_type is record
143
   startsd     : std_ulogic;
144
   startsdold  : std_ulogic;
145
   burst       : std_ulogic;
146
   hready      : std_ulogic;
147
   bdrive      : std_ulogic;
148
   qdrive      : std_ulogic;
149
   nbdrive     : std_ulogic;
150
   mstate      : mcycletype;
151
   sdstate     : sdcycletype;
152
   cmstate     : mcycletype;
153
   istate      : icycletype;
154
   trfc        : std_logic_vector(4 downto 0);
155
   refresh     : std_logic_vector(11 downto 0);
156
   sdcsn       : std_logic_vector(1  downto 0);
157
   sdwen       : std_ulogic;
158
   rasn        : std_ulogic;
159
   casn        : std_ulogic;
160
   dqm         : std_logic_vector(3 downto 0);
161
   dqm_dly     : std_logic_vector(3 downto 0);  -- *** ??? delay ctrl
162
   address     : std_logic_vector(15 downto 2);  -- memory address
163
   ba          : std_logic_vector(1  downto 0);
164
   waddr       : std_logic_vector(abuf-1 downto 0);
165
   waddr_d     : std_logic_vector(abuf-1 downto 0); -- Same as waddr but delayed to compensate for pipelined output data
166
   cfg         : sdram_cfg_type;
167
   readdly     : std_logic_vector(1 downto 0); -- added read latency
168
   newcom      : std_logic; -- start sec. read/write
169
   wdata       : std_logic_vector(31 downto 0);
170
   initnopdly  : std_logic_vector(7 downto 0); -- 400 ns delay
171
   sync        : std_logic;
172
   odt         : std_logic_vector(1 downto 0);
173
   sdo_bdrive  : std_logic; -- *** ??? delay ctrl
174
   sdo_qdrive  : std_logic; -- *** ??? delay ctrl
175
end record;
176
 
177
signal vcc, rwrite : std_ulogic;
178
signal r, ri : ddr_reg_type;
179
signal ra, rai : ahb_reg_type;
180
signal rdata, wdata, rwdata, rbdrive, ribdrive : std_logic_vector(31 downto 0);
181
signal waddr2 : std_logic_vector(abuf-1 downto 0);
182
signal ddr_rst : std_logic;
183
signal ddr_rst_gen  : std_logic_vector(3 downto 0);
184
attribute syn_preserve : boolean;
185
attribute syn_preserve of rbdrive : signal is true;
186
 
187
begin
188
 
189
   vcc <= '1';
190
 
191
   ddr_rst <= (ddr_rst_gen(3) and ddr_rst_gen(2) and ddr_rst_gen(1) and rst); -- Reset signal in DDR clock domain
192
 
193
   ahb_ctrl : process(rst, ahbsi, r, ra, rdata)
194
   variable v       : ahb_reg_type;             -- local variables for registers
195
   variable startsd : std_ulogic;
196
   variable dout    : std_logic_vector(31 downto 0);
197
   variable ready   : std_logic;
198
   begin
199
 
200
      v := ra; v.hrdata := rdata; v.hresp := HRESP_OKAY;
201
      v.write := '0';
202
 
203
      -- Sync ------------------------------------------------
204
      v.sync(1) := r.startsdold; v.sync(2) := ra.sync(1);
205
      ready := ra.startsd_ack xor ra.sync(2);
206
      --------------------------------------------------------
207
 
208
      if ((ahbsi.hready and ahbsi.hsel(hindex)) = '1') then
209
         v.htrans := ahbsi.htrans; v.haddr := ahbsi.haddr;
210
         v.size := ahbsi.hsize(1 downto 0); v.hwrite := ahbsi.hwrite;
211
         if ahbsi.htrans(1) = '1' then
212
            v.hio := ahbsi.hmbsel(1);
213
            v.hsel := '1'; v.hready := '0';
214
         end if;
215
      end if;
216
 
217
      if ahbsi.hready = '1' then v.hsel := ahbsi.hsel(hindex); end if;
218
 
219
      case ra.state is
220
      when midle =>
221
         if ((v.hsel and v.htrans(1)) = '1') then
222
            if v.hwrite = '0' then
223
               v.state := rhold; v.startsd := not ra.startsd;
224
            else v.state := dwrite; v.hready := '1'; v.write := '1'; end if;
225
         end if;
226
         v.raddr := ra.haddr(7 downto 2);
227
         if ahbsi.hready = '1' then
228
            v.acc := (v.haddr, v.size, v.hwrite, v.hio);
229
         end if;
230
      when rhold =>
231
         v.raddr := ra.haddr(7 downto 2);
232
         if ready = '1' then
233
            v.state := dread; v.hready := '1'; v.raddr := ra.raddr + 1;
234
         end if;
235
      when dread =>
236
         v.raddr := ra.raddr + 1; v.hready := '1';
237
         if ((v.hsel and v.htrans(1) and v.htrans(0)) = '0')
238
            or (ra.raddr(2 downto 0) = "000") then
239
            v.state := midle; v.hready := not (v.hsel and v.htrans(1));
240
            if (v.hsel and v.htrans(1) and v.hwrite) = '1' then
241
               v.state := dwrite; v.hready := '1'; v.write := '1';
242
            end if;
243
            v.startsd_ack := ra.startsd;
244
         end if;
245
         v.acc := (v.haddr, v.size, v.hwrite, v.hio);
246
      when dwrite =>
247
         v.raddr := ra.haddr(7 downto 2); v.write := '1'; v.hready := '1';
248
         if ((v.hsel and v.htrans(1) and v.htrans(0)) = '0')
249
            or ((ra.haddr(4 downto 2) = "111") and (ra.write = '1')) then
250
            v.startsd := not ra.startsd; v.state := whold1;
251
            v.write := '0'; v.hready := not (v.hsel and v.htrans(1));
252
         end if;
253
      when whold1 =>
254
         v.state := whold2;
255
      when whold2 =>
256
         if ready = '1' then
257
            v.state := midle; v.acc := (v.haddr, v.size, v.hwrite, v.hio);
258
            v.startsd_ack := ra.startsd;
259
         end if;
260
      end case;
261
 
262
      v.hwdata := ahbsi.hwdata;
263
 
264
      if (ahbsi.hready and ahbsi.hsel(hindex) ) = '1' then
265
         if ahbsi.htrans(1) = '0' then v.hready := '1'; end if;
266
      end if;
267
 
268
      dout := ra.hrdata(31 downto 0);
269
 
270
      if rst = '0' then
271
         v.hsel         := '0';
272
         v.hready       := '1';
273
         v.state        := midle;
274
         v.startsd      := '0';
275
         v.startsd_ack  := '0';
276
         v.hio          := '0';
277
      end if;
278
 
279
      rai <= v;
280
      ahbso.hready  <= ra.hready;
281
      ahbso.hresp   <= ra.hresp;
282
      ahbso.hrdata  <= dout;
283
      ahbso.hcache  <= not ra.hio;
284
 
285
   end process;
286
 
287
   ddr_ctrl : process(ddr_rst, r, ra, sdi, rbdrive, wdata)
288
   variable v       : ddr_reg_type;    -- local variables for registers
289
   variable startsd : std_ulogic;
290
   variable dataout : std_logic_vector(31 downto 0); -- data from memory
291
   variable dqm     : std_logic_vector(3 downto 0);
292
   variable raddr   : std_logic_vector(13 downto 0);
293
   variable adec    : std_ulogic;
294
   variable rams    : std_logic_vector(1 downto 0);
295
   variable ba      : std_logic_vector(1 downto 0);
296
   variable haddr   : std_logic_vector(31 downto 0);
297
   variable hsize   : std_logic_vector(1 downto 0);
298
   variable hwrite  : std_ulogic;
299
   variable htrans  : std_logic_vector(1 downto 0);
300
   variable hready  : std_ulogic;
301
   variable vbdrive : std_logic_vector(31 downto 0);
302
   variable bdrive  : std_ulogic;
303
   variable writecfg: std_ulogic;
304
   variable regsd   : std_logic_vector(31 downto 0);   -- data from registers
305
   variable readdata: std_logic_vector(31 downto 0);   -- data from DDR
306
   begin
307
 
308
-- Variable default settings to avoid latches
309
 
310
      v := r; v.hready := '0'; writecfg := '0'; vbdrive := rbdrive;
311
      readdata := sdi.data(31 downto 0);
312
      v.qdrive :='0';
313
      v.cfg.cal_en    :=  (others => '0'); v.cfg.cal_inc   :=  (others => '0');
314
      v.cfg.cal_pll   :=  (others => '0');                                            -- *** ??? pll_reconf
315
      v.cfg.cal_rst   :=  '0';
316
      v.wdata := wdata; -- pipeline output data
317
      v.dqm_dly := r.dqm;                                                             -- *** ??? delay ctrl
318
 
319
      regsd := (others => '0');
320
      if ra.acc.haddr(3 downto 2) = "00" then
321
         regsd(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
         regsd(11 downto 0) := r.cfg.refresh;
325
      elsif ra.acc.haddr(3 downto 2) = "01" then
326
         regsd(8 downto 0) := conv_std_logic_vector(MHz, 9);
327
         regsd(14 downto 12) := conv_std_logic_vector(1, 3);
328
      else
329
         regsd(17 downto 16) := r.cfg.readdly;
330
         regsd(22 downto 18) := r.cfg.trfc;
331
         regsd(27 downto 23) := r.cfg.twr;
332
         regsd(28) := r.cfg.trp;
333
      end if;
334
 
335
 
336
-- generate DQM from address and write size
337
 
338
      case ra.acc.size is
339
      when "00" =>
340
         case ra.acc.haddr(1 downto 0) is
341
         when "00" => dqm := "0111";
342
         when "01" => dqm := "1011";
343
         when "10" => dqm := "1101";
344
         when others => dqm := "1110";
345
         end case;
346
      when "01" =>
347
         if ra.acc.haddr(1) = '0' then dqm := "0011"; else  dqm := "1100"; end if;
348
      when others => dqm := "0000";
349
      end case;
350
 
351
      -- Sync ------------------------------------------
352
      v.sync := ra.startsd; v.startsd := r.sync;
353
      --------------------------------------------------
354
 
355
      --v.startsd := ra.startsd;
356
 
357
---- main FSM
358
--
359
--      case r.mstate is
360
--      when midle =>
361
--         if  r.startsd = '1' then
362
--            if (r.sdstate = sidle) and (r.cfg.command = "000") 
363
--               and (r.cmstate = midle) then
364
--               startsd := '1'; v.mstate := active;
365
--            end if;
366
--         end if;
367
--      when others => null;
368
--      end case;
369
 
370
      startsd := r.startsd xor r.startsdold;
371
 
372
-- generate row and column address size
373
 
374
      haddr := ra.acc.haddr;
375
      haddr(31 downto 20) := haddr(31 downto 20) and not conv_std_logic_vector(hmask, 12);
376
 
377
      case r.cfg.csize is
378
      when "00" => raddr := haddr(23 downto 10);
379
      when "01" => raddr := haddr(24 downto 11);
380
      when "10" => raddr := haddr(25 downto 12);
381
      when others => raddr := haddr(26 downto 13);
382
      end case;
383
 
384
-- generate bank address
385
 
386
      ba := genmux(r.cfg.bsize, haddr(29 downto 22)) &
387
            genmux(r.cfg.bsize, haddr(28 downto 21));
388
 
389
-- generate chip select
390
 
391
      adec := genmux(r.cfg.bsize, haddr(30 downto 23));
392
 
393
      rams := adec & not adec;
394
 
395
-- sdram access FSM
396
 
397
      if r.trfc /= "00000" then v.trfc := r.trfc - 1; end if;
398
 
399
      case r.sdstate is
400
      when sidle =>
401
         if (startsd = '1') and (r.cfg.command = "000") and (r.cmstate = midle)
402
            and (r.istate = finish) then
403
            v.address := raddr; v.ba := ba;
404
            if ra.acc.hio = '0' then
405
               v.sdcsn := not rams(1 downto 0); v.rasn := '0'; v.sdstate := act1;
406
            else v.sdstate := ioreg1; end if;
407
         end if;
408
         v.waddr := ra.acc.haddr(7 downto 2);
409
      when act1 =>
410
         v.rasn := '1'; v.trfc := r.cfg.trfc;
411
         if r.cfg.trcd = '1' then v.sdstate := act2;
412
         else v.sdstate := act3;
413
         end if;
414
         --v.waddr := ra.acc.haddr(7 downto 2);
415
         v.waddr := ra.acc.haddr(7 downto 3) & '0'; --& ra.acc.haddr(2);
416
         v.waddr_d := ra.acc.haddr(7 downto 3) & '0'; --& ra.acc.haddr(2);
417
         if ra.acc.hwrite = '1' then
418
           if odten /= 0 then v.odt := (others => '1'); end if; -- *** ??? odt
419
         end if;
420
      when act2 =>
421
         v.sdstate := act3;
422
      when act3 =>
423
         v.casn := '0';
424
         --v.address := ra.acc.haddr(13 downto 11) & '0' & ra.acc.haddr(10 downto 2) & '0';
425
         v.address := ra.acc.haddr(13 downto 11) & '0' & ra.acc.haddr(10 downto 3) & "00";
426
         v.hready := ra.acc.hwrite;
427
         if ra.acc.hwrite = '1' then
428
            v.sdstate := wr0;
429
            v.sdwen := '0';
430
            --v.waddr := r.waddr + 1;                           -- *** ??? delay ctrl
431
            v.trfc := r.cfg.twr;
432
         else v.sdstate := rd1; end if;
433
         v.burst := '0';
434
      when wr0 =>
435
         v.casn := '1'; v.sdwen := '1'; v.bdrive := '0'; v.qdrive := '1';
436
         if r.waddr_d = ra.acc.haddr(7 downto 2) then
437
            v.dqm := dqm;
438
            v.waddr_d := r.waddr_d + 1;
439
            v.waddr := r.waddr + 1;
440
            v.sdstate := wr1;
441
            if (r.waddr_d /= ra.raddr) then v.hready := '1'; end if;
442
         else
443
            v.burst := '1';
444
            v.waddr_d := r.waddr_d + 1;
445
            v.waddr := r.waddr + 1;
446
            v.dqm := (others => '1');
447
         end if;
448
         if r.burst = '1' and r.address(5 downto 4) < ra.raddr(2 downto 1) then
449
            v.address(5 downto 4) := r.address(5 downto 4) + 1;
450
            v.sdwen := '0'; v.casn := '0';
451
            v.trfc := r.cfg.twr;
452
         end if;
453
      when wr1 =>
454
         v.sdwen := '1';  v.casn := '1';  v.qdrive := '1';
455
         v.waddr_d := r.waddr_d + 1;
456
         v.waddr := r.waddr + 1;
457
         if (r.waddr_d <= ra.raddr) and (r.waddr_d /= "000000") and (r.hready = '1') then
458
            v.hready := '1';
459
            v.burst := '0';
460
            if r.burst = '0' and r.address(5 downto 4) < ra.raddr(2 downto 1) then
461
               v.address(5 downto 4) := r.address(5 downto 4) + 1;
462
               v.sdwen := '0'; v.casn := '0';
463
               v.trfc := r.cfg.twr;
464
               v.burst := '1';
465
            end if;
466
         else
467
            v.sdstate := wr2;
468
            v.dqm := (others => '1');
469
            v.startsdold := r.startsd;
470
         end if;
471
      when wr2 =>
472
         v.sdstate := wr3; v.qdrive := '1';
473
      when wr3 =>
474
         v.sdstate := wr4a; v.qdrive := '1';
475
      when wr4a =>
476
         v.bdrive := '1'; v.qdrive := '1';
477
         if r.trfc = "00000" then -- wait to not violate TWR timing
478
            v.sdstate := wr4b;
479
         end if;
480
      when wr4b =>
481
         v.bdrive := '1';
482
         v.rasn := '0'; v.sdwen := '0'; v.sdstate := wr4; v.qdrive := '1';
483
      when wr4 =>
484
         v.sdcsn := "11"; v.rasn := '1'; v.sdwen := '1';  v.qdrive := '0';
485
         v.sdstate := wr5;
486
      when wr5 =>
487
         v.odt := (others => '0'); -- *** ??? odt
488
         v.sdstate := sidle;
489
      when rd1 =>
490
         v.casn := '1'; v.sdstate := rd7;
491
         v.newcom := '1';
492
      when rd7 =>
493
         v.casn := '1'; v.sdstate := rd8;
494
         --v.readdly := r.cfg.readdly;
495
         v.readdly := r.cfg.readdly + 1;                                              -- *** ??? delay ctrl
496
         v.newcom := not r.newcom;
497
         if r.address(5 downto 4) /= "11" then
498
            v.casn := '0'; v.burst := '1'; v.address(5 downto 4) := r.address(5 downto 4) + 1;
499
         end if;
500
      when rd8 => -- (CL = 3)
501
         v.casn := '1';
502
         v.newcom := not r.newcom;
503
         if r.readdly = "00" then -- add read delay 
504
            v.sdstate := rd2;
505
         else
506
            v.readdly := r.readdly - 1;
507
         end if;
508
         if r.address(5 downto 4) /= "11" and r.newcom = '1' then
509
            v.casn := '0'; v.burst := '1'; v.address(5 downto 4) := r.address(5 downto 4) + 1;
510
         end if;
511
      when rd2 =>
512
         v.casn := '1'; v.sdstate := rd3;
513
         v.newcom := not r.newcom;
514
         if r.address(5 downto 4) /= "11" and r.newcom = '1' then
515
            v.casn := '0'; v.burst := '1'; v.address(5 downto 4) := r.address(5 downto 4) + 1;
516
         end if;
517
      when rd3 =>
518
         if fast = 0 then v.startsdold := r.startsd; end if;
519
         v.sdstate := rd4; v.hready := '1'; v.casn := '1';
520
         v.newcom := not r.newcom;
521
         if r.sdwen = '0' then
522
            v.rasn := '1'; v.sdwen := '1'; v.sdcsn := "11"; v.dqm := (others => '1');
523
         end if;
524
         if v.hready = '1' then v.waddr := r.waddr + 1; end if;
525
         if r.address(5 downto 4) /= "11" and r.newcom = '1' then
526
            v.casn := '0'; v.burst := '1'; v.address(5 downto 4) := r.address(5 downto 4) + 1;
527
         end if;
528
      when rd4 =>
529
         v.hready := '1'; v.casn := '1';
530
         v.newcom := not r.newcom;
531
         if (r.sdcsn /= "11") and (r.waddr(1 downto 0) = "11") and (r.burst = '1') then
532
            v.burst := '0';
533
         elsif (r.sdcsn = "11") or (r.waddr(1 downto 0) = "11") then
534
            v.dqm := (others => '1'); v.burst := '0';
535
            if fast /= 0 then v.startsdold := r.startsd; end if;
536
            if (r.sdcsn /= "11") then
537
               v.rasn := '0'; v.sdwen := '0'; v.sdstate := rd5;
538
            else
539
               if r.cfg.trp = '1' then v.sdstate := rd6;
540
               else v.sdstate := sidle; end if;
541
            end if;
542
         end if;
543
         if v.hready = '1' then v.waddr := r.waddr + 1; end if;
544
         if r.address(5 downto 4) /= "11" and r.newcom = '1' then
545
            v.casn := '0'; v.burst := '1'; v.address(5 downto 4) := r.address(5 downto 4) + 1;
546
         end if;
547
      when rd5 =>
548
         if r.cfg.trp = '1' then v.sdstate := rd6;
549
         else v.sdstate := sidle; end if;
550
         v.sdcsn := (others => '1'); v.rasn := '1'; v.sdwen := '1';
551
         v.dqm := (others => '1');
552
      when rd6 =>
553
         v.sdstate := sidle; v.dqm := (others => '1');
554
         v.sdcsn := (others => '1'); v.rasn := '1'; v.sdwen := '1';
555
      when ioreg1 =>
556
         readdata := regsd; v.sdstate := ioreg2;
557
         if ra.acc.hwrite = '0' then v.hready := '1'; end if;
558
      when ioreg2 =>
559
         readdata := regsd; v.sdstate := sidle;
560
         writecfg := ra.acc.hwrite; v.startsdold := r.startsd;
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 := "01";
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
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 delay
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   :=  r.wdata(11 downto 0);
699
            v.cfg.cke       :=  r.wdata(15);
700
            v.cfg.renable   :=  r.wdata(16);
701
            v.cfg.dllrst    :=  r.wdata(17);
702
            v.cfg.command   :=  r.wdata(20 downto 18);
703
            v.cfg.csize     :=  r.wdata(22 downto 21);
704
            v.cfg.bsize     :=  r.wdata(25 downto 23);
705
            v.cfg.trcd      :=  r.wdata(26);
706
            v.cfg.emr       :=  r.wdata(29 downto 28);
707
            v.cfg.ocd       :=  r.wdata(30);
708
            v.cfg.refon     :=  r.wdata(31);
709
         elsif r.waddr(1 downto 0) = "10" then
710
            v.cfg.cal_en    :=  r.wdata( 7 downto  0);
711
            v.cfg.cal_inc   :=  r.wdata(15 downto  8);
712
            v.cfg.readdly   :=  r.wdata(17 downto 16);
713
            v.cfg.trfc      :=  r.wdata(22 downto 18);
714
            v.cfg.twr       :=  r.wdata(27 downto 23);
715
            v.cfg.trp       :=  r.wdata(28);
716
            v.cfg.cal_pll   :=  r.wdata(30 downto 29);                -- *** ??? pll_reconf
717
            v.cfg.cal_rst   :=  r.wdata(31);
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
      rwdata <= readdata;
767
 
768
   end process;
769
 
770
   sdo.sdcke     <= (others => r.cfg.cke);
771
   ahbso.hconfig <= hconfig;
772
   ahbso.hirq    <= (others => '0');
773
   ahbso.hindex  <= hindex;
774
 
775
   ahbregs : process(clk_ahb) begin
776
      if rising_edge(clk_ahb) then
777
         ra <= rai;
778
      end if;
779
   end process;
780
 
781
   ddrregs : process(clk_ddr, rst, ddr_rst) begin
782
      if rising_edge(clk_ddr) then
783
         r <= ri; rbdrive <= ribdrive;
784
         ddr_rst_gen <= ddr_rst_gen(2 downto 0) & '1';
785
      end if;
786
      if (rst = '0') then
787
         ddr_rst_gen <= "0000";
788
      end if;
789
      if (ddr_rst = '0') then
790
         r.sdcsn  <= (others => '1'); r.bdrive <= '1'; r.nbdrive <= '0';
791
         if oepol = 0 then rbdrive <= (others => '1');
792
         else rbdrive <= (others => '0'); end if;
793
         r.cfg.cke <= '0';
794
         r.odt <= (others => '0');
795
      end if;
796
   end process;
797
 
798
   sdo.address  <= '0' & r.address; --'0' & ri.address;                     -- *** ??? delay ctrl
799
   sdo.ba       <= r.ba; --ri.ba;                                           -- *** ??? delay ctrl
800
   sdo.bdrive   <= r.sdo_bdrive; --r.nbdrive when oepol = 1 else r.bdrive;  -- *** ??? delay ctrl
801
   sdo.qdrive   <= r.sdo_qdrive; --not (ri.qdrive or r.nbdrive);            -- *** ??? delay ctrl
802
   sdo.vbdrive  <= rbdrive;
803
   sdo.sdcsn    <= r.sdcsn; --ri.sdcsn;                                     -- *** ??? delay ctrl
804
   sdo.sdwen    <= r.sdwen; --ri.sdwen;                                     -- *** ??? delay ctrl
805
   sdo.dqm      <= "111111111111" & r.dqm_dly; --"111111111111" & r.dqm;    -- *** ??? delay ctrl
806
   sdo.rasn     <= r.rasn; --ri.rasn;                                       -- *** ??? delay ctrl
807
   sdo.casn     <= r.casn; --ri.casn;                                       -- *** ??? delay ctrl
808
   --sdo.data     <= zero32 & zero32 & zero32 & wdata;
809
   sdo.data     <= zero32 & zero32 & zero32 & r.wdata;
810
 
811
   sdo.cal_en   <= r.cfg.cal_en;
812
   sdo.cal_inc  <= r.cfg.cal_inc;
813
   sdo.cal_pll  <= r.cfg.cal_pll;                                           -- *** ??? pll_reconf
814
   sdo.cal_rst  <= r.cfg.cal_rst;
815
   sdo.odt      <= r.odt;
816
 
817
   read_buff : syncram_2p
818
   generic map (tech => memtech, abits => 6, dbits => 32, sepclk => 1, wrfst => 0)
819
   port map ( rclk => clk_ahb, renable => vcc, raddress => rai.raddr,
820
              dataout => rdata, wclk => clk_ddr, write => ri.hready,
821
              waddress => r.waddr, datain => rwdata);
822
 
823
   write_buff : syncram_2p
824
   generic map (tech => memtech, abits => 6, dbits => 32, sepclk => 1, wrfst => 0)
825
   port map ( rclk => clk_ddr, renable => vcc, raddress => r.waddr,
826
              dataout => wdata, wclk => clk_ahb, write => ra.write,
827
              waddress => ra.haddr(7 downto 2), datain => ahbsi.hwdata);
828
 
829
-- pragma translate_off
830
   bootmsg : report_version
831
   generic map (
832
      msg1 => "ddr2sp" & tost(hindex) & ": 16-bit DDR2 controller rev " &
833
              tost(REVISION) & ", " & tost(Mbyte) & " Mbyte, " & tost(MHz) &
834
              " MHz DDR clock");
835
-- pragma translate_on
836
end;

powered by: WebSVN 2.1.0

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