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/] [ddrctrl.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:      ddrctrl
20
-- File:        ddrctrl.vhd
21
-- Author:      David Lindh - Gaisler Research
22
-- Description: DDR-RAM memory controller with AMBA interface
23
------------------------------------------------------------------------------
24
 
25
 
26
library ieee;
27
use ieee.std_logic_1164.all;
28
library grlib;
29
use grlib.amba.all;
30
use grlib.stdlib.all;
31
library gaisler;
32
use grlib.devices.all;
33
use gaisler.memctrl.all;
34
library techmap;
35
use techmap.gencomp.all;
36
use techmap.allmem.all;
37
use gaisler.ddrrec.all;
38
 
39
 
40
entity ddrctrl is
41
  generic (
42
    hindex1    :     integer := 0;
43
    haddr1     :     integer := 0;
44
    hmask1     :     integer := 16#f80#;
45
    hindex2    :     integer := 0;
46
    haddr2     :     integer := 0;
47
    hmask2     :     integer := 16#f80#;
48
    pindex     :     integer := 3;
49
    paddr      :     integer := 0;
50
    numahb     :     integer := 1;       -- Allowed: 1, 2
51
    ahb1sepclk :     integer := 0;       -- Allowed: 0, 1
52
    ahb2sepclk :     integer := 0;       -- Allowed: 0, 1
53
    modbanks   :     integer := 1;       -- Allowed: 1, 2
54
    numchips   :     integer := 2;       -- Allowed: 1, 2, 4, 8, 16
55
    chipbits   :     integer := 16;      -- Allowed: 4, 8, 16
56
    chipsize   :     integer := 256;     -- Allowed: 64, 128, 256, 512, 1024 (MB)
57
    plldelay   :     integer := 0;       -- Allowed: 0, 1 (Use 200us start up delay)
58
    tech       :     integer := virtex2;
59
    clkperiod  :     integer := 10);     -- (ns)
60
  port (
61
    rst       : in  std_ulogic;
62
    clk0      : in  std_ulogic;
63
    clk90     : in  std_ulogic;
64
    clk180    : in  std_ulogic;
65
    clk270    : in  std_ulogic;
66
    hclk1     : in  std_ulogic;
67
    hclk2     : in  std_ulogic;
68
    pclk      : in  std_ulogic;
69
    ahb1si    : in  ahb_slv_in_type;
70
    ahb1so    : out ahb_slv_out_type;
71
    ahb2si    : in  ahb_slv_in_type;
72
    ahb2so    : out ahb_slv_out_type;
73
    apbsi     : in  apb_slv_in_type;
74
    apbso     : out apb_slv_out_type;
75
    ddsi      : out ddrmem_in_type;
76
    ddso      : in  ddrmem_out_type);
77
end ddrctrl;
78
 
79
architecture rtl of ddrctrl is
80
 
81
 
82
 
83
-------------------------------------------------------------------------------
84
  -- Constants
85
-------------------------------------------------------------------------------
86
 
87
  constant DELAY_15600NS   : integer := (15600 / clkperiod);
88
  constant DELAY_7800NS    : integer := (7800 / clkperiod);
89
  constant DELAY_7_15600NS : integer := (7*(15600 / clkperiod));
90
  constant DELAY_7_7800NS  : integer := (7*(7800 / clkperiod));
91
  constant DELAY_200US : integer := (200000 / clkperiod);
92
 
93
  constant REVISION : integer := 0;
94
  constant pmask    : integer := 16#fff#;
95
  constant pconfig  : apb_config_type := (
96
 
97
  1 => apb_iobar(paddr, pmask));
98
 
99
  constant dqsize     : integer := numchips*chipbits;
100
  constant dmsize     : integer := (dqsize/8);
101
  constant strobesize : integer := (dqsize/8) * dmvector(chipbits);
102
 
103
-------------------------------------------------------------------------------
104
-- Signals
105
-------------------------------------------------------------------------------
106
 
107
  signal toAHB        : two_ahb_ctrl_in_type;
108
  signal fromAHB      : two_ahb_ctrl_out_type;
109
  signal fromAHB2Main : two_ahb_ctrl_out_type;
110
  signal apbr         : apb_reg_type;
111
  signal apbri        : apb_reg_type;
112
  signal fromAPB      : apb_ctrl_out_type;
113
  signal fromAPB2Main : apb_ctrl_out_type;
114
  signal mainr        : main_reg_type;
115
  signal mainri       : main_reg_type;
116
  signal fromMain     : main_ctrl_out_type;
117
  signal fromMain2APB : apb_ctrl_in_type;
118
  signal fromMain2AHB : two_ahb_ctrl_in_type;
119
  signal fromMain2HS  : hs_in_type;
120
  signal toHS         : hs_in_type;
121
  signal fromHS       : hs_out_type;
122
 
123
begin  -- achitecture rtl
124
 
125
-------------------------------------------------------------------------------
126
-- Error reports
127
  assert (tech = virtex2 or tech = virtex4 or tech = lattice) report "Unsupported technology by DDR controller (generic tech)" severity failure;
128
  assert (modbanks=1 or modbanks=2) report "Only 1 or 2 module banks is supported (generic modbanks)" severity failure;
129
  assert (chipbits=4 or chipbits=8 or chipbits=16) report "DDR chips either have 4, 8 or 16 bits output (generic chipbits)" severity failure;
130
  assert (chipsize=64 or chipsize=128 or chipsize=256 or chipsize=512 or chipsize=1024) report "DDR chips either have 64, 128, 256, 512 or 1024 Mbit size" severity failure;
131
  assert (buffersize>=2) report "Buffer must have room for at least 2 bursts (generic buffersize)" severity failure;
132
  assert (plldelay=0 or plldelay=1) report "Invalid setting for DDRRAM PLL delay (generic plldelay)" severity failure;
133
  assert (numahb=1 or numahb=2) report "Only one or two AHB interfaces can be used (generic numahb)" severity failure;
134
 
135
 
136
-------------------------------------------------------------------------------
137
-- APB control
138
    -- Controls APB bus. Contains the DDRCFG register. Clear memcmd
139
    -- bits when a memory command requested on APB is complete.
140
   apbcomb : process(apbr, apbsi, fromMain2APB, rst)
141
     variable v : apb_reg_type;
142
   begin
143
     v:= apbr;
144
     if rst = '0' then -- Reset
145
       v.ddrcfg_reg := ddrcfg_reset;
146
     elsif fromMain2APB.apb_cmd_done = '1' then -- Clear memcmd bits
147
       v.ddrcfg_reg(28 downto 27) := "00";
148
     elsif (apbsi.psel(pindex) and apbsi.penable and apbsi.pwrite) = '1' then -- Write
149
       v.ddrcfg_reg := apbsi.pwdata(31 downto 1) & fromMain2APB.ready;
150
     else
151
       v.ddrcfg_reg(0) := fromMain2APB.ready;
152
     end if;
153
     apbri <= v;
154
     fromAPB.ddrcfg_reg <= v.ddrcfg_reg;
155
   end process apbcomb;
156
 
157
   apbclk : process(pclk)
158
     begin
159
       if rising_edge(pclk) then apbr <= apbri; end if;
160
   end process;
161
 
162
   apbso.prdata <= fromAPB.ddrcfg_reg; apbso.pirq <= (others => '0');
163
   apbso.pindex <= pindex; apbso.pconfig <= pconfig;
164
 
165
 
166
-------------------------------------------------------------------------------
167
 -- Main controller
168
-------------------------------------------------------------------------------
169
   maincomb     : process(mainr, fromAHB, fromAHB2Main, fromAPB2Main, rst, fromHS)
170
     variable v : main_reg_type;
171
   begin
172
     v := mainr; v.loadcmdbuffer := '0'; -- Clear Cmd loading bit
173
 
174
-------------------------------------------------------------------------------
175
     -- DDRCFG control
176
     -- Reads DDRCFG from APB controller. Handles refresh command from refresh
177
     -- timer and memoory comand requested on APB.
178
 
179
     case v.apbstate is
180
       when idle =>
181
         v.apb_cmd_done := '0';
182
         -- Refresh timer signals refresh
183
         if v.doRefresh = '1' and v.ddrcfg.refresh = '1' then
184
           v.apbstate := refresh;
185
         -- LMR cmd on APB bus
186
         elsif fromAPB2Main.ddrcfg_reg(28 downto 27) = "11" then
187
            v.lockAHB := "11";
188
            v.apbstate := wait_lmr1;
189
         -- Refresh or Precharge cmd on APB BUS
190
         elsif fromAPB2Main.ddrcfg_reg(28 downto 27) > "00" then
191
           v.apbstate := cmd;
192
           -- Nothing to be done
193
         else
194
           v.ddrcfg.memcmd  := "00";
195
         end if;
196
 
197
       -- Refresh from Timer
198
       when refresh =>
199
         if v.mainstate = idle then v.ddrcfg.memcmd := "10"; end if;
200
         if v.dorefresh = '0' then v.ddrcfg.memcmd := "00"; v.apbstate := idle; end if;
201
 
202
       -- Refresh or Precharge from APB BUS
203
       when cmd =>
204
         if v.mainstate = idle then v.ddrcfg.memcmd := fromAPB2Main.ddrcfg_reg(28 downto 27); end if;
205
         v.apbstate := cmdDone;
206
 
207
      -- Wait until no more cmd can arrive from AHB ctrl 
208
       when wait_lmr1 => v.apbstate := wait_lmr2;
209
       when wait_lmr2 => v.apbstate := cmdlmr;
210
 
211
       when cmdlmr =>
212
         -- Check that no new R/W cmd is to be performed
213
         if fromAHB2Main(0).rw_cmd_valid = v.rw_cmd_done(0) and
214
           fromAHB2Main(1).rw_cmd_valid = v.rw_cmd_done(1)  and v.mainstate = idle then
215
           v.ddrcfg.memcmd := "11";
216
           v.ddrcfg.cas := fromAPB2Main.ddrcfg_reg(30 downto 29);
217
           v.ddrcfg.bl := fromAPB2Main.ddrcfg_reg(26 downto 25);
218
           v.apbstate := cmdDone;
219
         end if;
220
 
221
       when cmdDone =>
222
         v.lockAHB := "00";
223
         if v.memCmdDone = '1' then
224
           v.ddrcfg.memcmd := "00"; v.apb_cmd_done := '1'; v.apbstate := cmdDone2;
225
         end if;
226
 
227
       when cmdDone2 =>
228
           if fromAPB2Main.ddrcfg_reg(28 downto 27) = "00" then
229
             v.apb_cmd_done := '0'; v.apbstate := idle;
230
           end if;
231
     end case;
232
 
233
 
234
     if v.mainstate = idle  then
235
       v.ddrcfg.refresh    := fromAPB2Main.ddrcfg_reg(31);
236
       v.ddrcfg.autopre    := fromAPB2Main.ddrcfg_reg(24);
237
       v.ddrcfg.r_predict  := fromAPB2Main.ddrcfg_reg(23 downto 22);
238
       v.ddrcfg.w_prot     := fromAPB2Main.ddrcfg_reg(21 downto 20);
239
       v.ddrcfg.ready      := fromAPB2Main.ddrcfg_reg(0);
240
     end if;
241
 -------------------------------------------------------------------------------
242
     -- Calcualtes burst length
243
     case v.ddrcfg.bl is
244
       when "00"   => v.burstlength := 2;
245
       when "01"   => v.burstlength := 4;
246
       when "10"   => v.burstlength := 8;
247
       when others => v.burstlength := 8;
248
     end case;
249
 
250
 -------------------------------------------------------------------------------
251
     -- Calculates row and column address
252
 
253
     v.tmpcoladdress := (others => (others => '0'));
254
     v.rowaddress    := (others => (others => '0'));
255
     v.coladdress    := (others => (others => '0'));
256
     v.tmpcolbits := 0; v.colbits := 0; v.rowbits := 0;
257
 
258
     -- Based on the size of the chip its organization can be calculated
259
     case chipsize is
260
       when 64     => v.tmpcolbits := 10; v.rowbits := 12; v.refreshTime := DELAY_15600NS; v.maxRefreshTime := DELAY_7_15600NS;  -- 64Mbit
261
       when 128    => v.tmpcolbits := 11; v.rowbits := 12; v.refreshTime := DELAY_15600NS; v.maxRefreshTime := DELAY_7_15600NS;  -- 128Mbit
262
       when 256    => v.tmpcolbits := 11; v.rowbits := 13; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- 256Mbit
263
       when 512    => v.tmpcolbits := 12; v.rowbits := 13; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- 512Mbit
264
       when 1024   => v.tmpcolbits := 12; v.rowbits := 14; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- 1Gbit                 
265
       when others => v.tmpcolbits := 10; v.rowbits := 12; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- Others 64Mbit
266
     end case;
267
     case chipbits is
268
       when 4      => v.colbits := v.tmpcolbits;      -- x4 bits
269
       when 8      => v.colbits := (v.tmpcolbits-1);  -- x8 bits
270
       when 16     => v.colbits := (v.tmpcolbits-2);  -- x16 bits
271
       when others => null;
272
     end case;
273
     v.addressrange := v.colbits + v.rowbits;
274
 
275
      -- AHB controller 1 --
276
      for i in 0 to ahbadr loop
277
       if (i < v.colbits) then
278
         v.tmpcoladdress(0)(i) := fromAHB(0).asramso.dataout(i); end if;
279
       if (i < (v.addressrange) and i >= v.colbits) then
280
         v.rowaddress(0)(i-v.colbits)  := fromAHB(0).asramso.dataout(i); end if;
281
       if (i < (v.addressrange+2) and i >= v.addressrange) then
282
         v.intbankbits(0)(i - v.addressrange) := fromAHB(0).asramso.dataout(i); end if;
283
     end loop;
284
 
285
     -- Inserts bank address and auto precharge bit as A10
286
     v.coladdress(0)(adrbits-1 downto 0)           := v.intbankbits(0) &
287
                                                 v.tmpcoladdress(0)(12 downto 10) &  -- Bit 13 to 11
288
                                                 v.ddrcfg.autopre &  -- Bit 10
289
                                                 v.tmpcoladdress(0)(9 downto 0);  --Bit 9 to 0
290
     v.rowaddress(0)(adrbits-1 downto (adrbits-2)) := v.intbankbits(0);
291
 
292
     -- Calculate total numer of useable address bits
293
     if modbanks = 2 then
294
       -- Calculate memory module bank (CS signals)
295
       if fromAHB(0).asramso.dataout(v.addressrange +2) = '0' then
296
         v.bankselect(0) := BANK0;
297
       else
298
         v.bankselect(0) := BANK1;
299
       end if;
300
     else
301
       v.bankselect(0)   := BANK0;
302
     end if;
303
 
304
     -- This is for keeping track of which banks has a active row
305
     v.pre_bankadr(0):= conv_integer(v.bankselect(0)(0) & v.rowaddress(0)(adrbits-1 downto (adrbits-2)));
306
 
307
 
308
     -- AHB Controller 2 --
309
     for i in 0 to ahbadr loop
310
       if (i < v.colbits) then
311
         v.tmpcoladdress(1)(i) := fromAHB(1).asramso.dataout(i); end if;
312
       if (i < (v.addressrange) and i >= v.colbits) then
313
         v.rowaddress(1)(i-v.colbits)  := fromAHB(1).asramso.dataout(i); end if;
314
       if (i < (v.addressrange+2) and i >= v.addressrange) then
315
         v.intbankbits(1)(i - v.addressrange) := fromAHB(1).asramso.dataout(i); end if;
316
     end loop;
317
 
318
     -- Inserts bank address and auto precharge bit as A10
319
     v.coladdress(1)(adrbits-1 downto 0)         := v.intbankbits(1) &
320
                                                 v.tmpcoladdress(1)(12 downto 10) &  -- Bit 13 to 11
321
                                                 v.ddrcfg.autopre &  -- Bit 10
322
                                                 v.tmpcoladdress(1)(9 downto 0);  --Bit 9 to 0
323
     v.rowaddress(1)(adrbits-1 downto (adrbits-2)) := v.intbankbits(1);
324
 
325
     -- Calculate total numer of useable address bits
326
     if modbanks = 2 then
327
       -- Calculate memory module bank (CS signals)
328
       if fromAHB(1).asramso.dataout(v.addressrange +2) = '0' then
329
         v.bankselect(1) := BANK0;
330
       else
331
         v.bankselect(1) := BANK1;
332
       end if;
333
     else
334
       v.bankselect(1)   := BANK0;
335
     end if;
336
 
337
     -- This is for keeping track of which banks has a active row
338
     v.pre_bankadr(1):= conv_integer(v.bankselect(1)(0) & v.rowaddress(1)(adrbits-1 downto (adrbits-2)));
339
     -- ((1bit(Lower/upper half if 32 bit mode))) + 1bit(module bank select) +
340
     -- 2bits(Chip bank selekt) + Xbits(address, depending on chip size)
341
 
342
 
343
 
344
 
345
 -------------------------------------------------------------------------------
346
 -- Calculate LMR command address
347
     v.lmradr(adrbits-1 downto 7) := (others => '0');
348
     -- CAS value
349
     case v.ddrcfg.cas is
350
       when "00" => v.lmradr(6 downto 4) := "010";
351
       when "01" => v.lmradr(6 downto 4) := "110";
352
       when "10" => v.lmradr(6 downto 4) := "011";
353
       when others => v.lmradr(6 downto 4) := "010";
354
     end case;
355
     -- Burst type, seqencial or interleaved (fixed att seqencial)
356
     v.lmradr(3) := '0';
357
     -- Burst length
358
     case v.ddrcfg.bl is
359
       when "00" => v.lmradr(2 downto 0) := "001";
360
       when "01" => v.lmradr(2 downto 0) := "010";
361
       when "10" => v.lmradr(2 downto 0) := "011";
362
       when others => v.lmradr(2 downto 0) := "010";
363
     end case;
364
 
365
 
366
 
367
 
368
 -------------------------------------------------------------------------------
369
 -- Auto refresh timer
370
     case v.timerstate is
371
       when t1 =>
372
         v.doRefresh  := '0'; v.refreshcnt := v.refreshTime; v.timerstate := t2;
373
       when t2 =>
374
         v.doRefresh  := '0'; v.refreshcnt := mainr.refreshcnt -1;
375
         if v.refreshcnt < 50 then v.timerstate := t3; end if;
376
       when t3 =>
377
         if mainr.refreshcnt > 1 then v.refreshcnt := mainr.refreshcnt -1; end if;
378
         v.doRefresh    := '1';
379
         if v.refreshDone = '1' then
380
           v.refreshcnt := mainr.refreshcnt + v.refreshTime;
381
           v.timerstate := t4;
382
         end if;
383
       when t4 =>
384
         v.doRefresh  := '0'; v.timerstate := t2; when others => null;
385
     end case;
386
 
387
 
388
 
389
 
390
 -------------------------------------------------------------------------------
391
 -- Init statemachine
392
     case v.initstate is
393
       when idle =>
394
         v.memInitDone := '0';
395
         if v.doMemInit = '1' then
396
           if plldelay = 1 then
397
             -- Using refrshtimer for initial wait
398
             v.refreshcnt := DELAY_200US +50; v.timerstate := t2; v.initstate := i1;
399
           else v.initstate := i2; end if;
400
         end if;
401
       when i1 =>
402
         if v.doRefresh = '1' then v.initstate := i2; end if;
403
       when i2 =>
404
         v.cs := "00";
405
         if fromHS.hs_busy = '0' then
406
           v.cmdbufferdata := CMD_NOP; v.loadcmdbuffer := '1'; v.initstate := i3;
407
         end if;
408
       when i3 =>
409
         if fromHS.hs_busy = '0' then
410
           v.cmdbufferdata := CMD_PRE; v.loadcmdbuffer := '1';
411
           v.adrbufferdata(10) := '1'; v.initstate := i4;
412
         end if;
413
       when i4 =>
414
         if fromHS.hs_busy = '0' then
415
           v.cmdbufferdata := CMD_LMR; v.loadcmdbuffer := '1';
416
           v.adrbufferdata(adrbits-1 downto (adrbits-2)) := "01";
417
           v.adrbufferdata((adrbits -3) downto 0)      := (others => '0');
418
           v.initstate := i5;
419
         end if;
420
       when i5 =>
421
         if fromHS.hs_busy = '0' then
422
           v.cmdbufferdata := CMD_LMR; v.loadcmdbuffer := '1'; v.adrbufferdata := v.lmradr;
423
           v.refreshcnt := 250; v.timerstate := t2;  --200 cycle count
424
           v.adrbufferdata(8) := '1'; v.initstate := i6;
425
         end if;
426
       when i6 =>
427
         if fromHS.hs_busy = '0' then
428
           v.cmdbufferdata := CMD_PRE; v.loadcmdbuffer := '1';
429
           v.adrbufferdata(10) := '1'; v.initstate := i7;
430
         end if;
431
       when i7 =>
432
         if fromHS.hs_busy = '0' then
433
           v.cmdbufferdata := CMD_AR; v.loadcmdbuffer := '1'; v.initstate := i8;
434
         end if;
435
       when i8 =>
436
         if fromHS.hs_busy = '0' then
437
           v.cmdbufferdata := CMD_AR; v.loadcmdbuffer := '1'; v.initstate := i9;
438
         end if;
439
       when i9 =>
440
         if fromHS.hs_busy = '0' then
441
           v.cmdbufferdata   := CMD_LMR; v.loadcmdbuffer := '1'; v.adrbufferdata := v.lmradr;
442
           v.initstate := i10;
443
         end if;
444
       when i10 =>
445
         if v.doRefresh = '1' then v.initstate := i11; end if;
446
       when i11 =>
447
         v.memInitDone := '1';
448
         if v.doMemInit = '0' then v.initstate := idle; end if;
449
       when others => null;
450
     end case;
451
 
452
 
453
 
454
 
455
 -------------------------------------------------------------------------------
456
 -- Main controller statemachine
457
     case v.mainstate is
458
       -- Initialize memory
459
       when init   =>
460
         v.doMemInit   := '1';
461
         v.ready       := '0';
462
         if v.memInitDone = '1' then
463
           v.mainstate := idle;
464
         end if;
465
 
466
         -- Await command 
467
       when idle =>
468
         v.doMemInit   := '0';
469
         v.RefreshDone := '0';
470
         v.memCmdDone  := '0';
471
         v.ready       := '1';
472
         v.use_bl      := mainr.burstlength;
473
         v.use_cas     := mainr.ddrcfg.cas;
474
 
475
         if v.ddrcfg.memcmd /= "00" then
476
           v.mainstate := c1;
477
         elsif fromAHB2Main(0).rw_cmd_valid /= v.rw_cmd_done(0) or
478
               fromAHB2Main(1).rw_cmd_valid /= v.rw_cmd_done(1) then
479
 
480
           -- This code is to add read priority between the ahb controllers
481
 
482
--            if fromAHB2Main(0).rw_cmd_valid /= v.rw_cmd_done(0) and
483
--             fromAHB(0).asramso.dataout(ahbadr) = '0' then
484
--              v.use_ahb := 0;
485
--              v.use_buf := v.rw_cmd_done(0)+1;
486
--            elsif fromAHB2Main(1).rw_cmd_valid /= v.rw_cmd_done(1) and
487
--             fromAHB(1).asramso.dataout(ahbadr) = '0' then
488
--              v.use_ahb := 1;
489
--              v.use_buf := v.rw_cmd_done(1)+1;
490
           if fromAHB2Main(0).rw_cmd_valid /= v.rw_cmd_done(0) then
491
             v.use_ahb := 0;
492
             v.use_buf := v.rw_cmd_done(0)+1;
493
           else
494
             v.use_ahb := 1;
495
             v.use_buf := v.rw_cmd_done(1)+1;
496
           end if;
497
 
498
            -- Check if the chip bank which is to be R/W has a row open
499
            if mainr.pre_chg(v.pre_bankadr(v.use_ahb)) = '1' then
500
              -- Check if the row which is open is the same that will be R/W
501
              if mainr.pre_row(v.pre_bankadr(v.use_ahb)) = v.rowaddress(v.use_ahb) then
502
                v.mainstate := rw;
503
 
504
                -- R/W to a different row then the one open, has to precharge and
505
                -- activate new row
506
              else
507
                v.mainstate := pre1;
508
              end if;
509
              -- No row open, has to activate row
510
            else
511
              v.mainstate := act1;
512
            end if;
513
         end if;
514
           -- Nothing to do, if 10 idle cycles, run Refreash (if needed)
515
         if v.idlecnt = 10 and v.refreshcnt < v.maxRefreshTime then
516
           v.doRefresh  := '1';
517
           v.idlecnt    := 0;
518
           v.timerstate := t3;
519
           v.refreshcnt := mainr.refreshcnt + v.refreshTime;
520
         elsif v.idlecnt = 10 then
521
           v.idlecnt    := 0;
522
         else
523
           v.idlecnt    := mainr.idlecnt + 1;
524
         end if;
525
 
526
 
527
 
528
         -- Precharge memory
529
       when pre1 =>
530
         if fromHS.hs_busy = '0' then
531
         v.cs := v.bankselect(mainr.use_ahb);
532
         -- Select chip bank to precharge
533
         v.adrbufferdata := (others => '0');
534
         v.adrbufferdata(adrbits-1 downto (adrbits-2)) := v.rowaddress(mainr.use_ahb)(adrbits-1 downto (adrbits-2));
535
         v.cmdbufferdata := CMD_PRE;
536
         -- Clear bit in register for active rows
537
         v.pre_chg(v.pre_bankadr(mainr.use_ahb)):= '0';
538
         v.loadcmdbuffer := '1';
539
         v.mainstate := act1;
540
       end if;
541
 
542
 
543
 
544
         -- Activate row in  memory
545
       when act1 =>                      -- Get adr and cmd from AHB, set to HS
546
         if fromHS.hs_busy = '0' then
547
           v.cs            := v.bankselect(mainr.use_ahb);
548
           v.cmdbufferdata := CMD_ACTIVE;
549
           v.adrbufferdata := v.rowaddress(mainr.use_ahb);
550
           v.loadcmdbuffer := '1';
551
 
552
         -- Set bit in register for active row if auto-precharge is disabled
553
           if v.ddrcfg.autopre = '0' then
554
             v.pre_chg(v.pre_bankadr(mainr.use_ahb)) := '1';
555
             v.pre_row(v.pre_bankadr(mainr.use_ahb)) := v.rowaddress(mainr.use_ahb);
556
           end if;
557
           v.mainstate := rw;
558
         end if;
559
 
560
 
561
 
562
       -- Issu read or write to HS part
563
       when rw =>
564
        if fromAHB(mainr.use_ahb).asramso.dataout(ahbadr) = '1' then
565
          v.cmdbufferdata   := CMD_WRITE;
566
        else
567
          v.cmdbufferdata   := CMD_READ;
568
        end if;
569
        if v.ddrcfg.autopre = '1' then
570
           v.pre_chg(v.pre_bankadr(mainr.use_ahb)) := '0';
571
        end if;
572
        v.adrbufferdata   := v.coladdress(mainr.use_ahb);
573
        v.cs            := v.bankselect(mainr.use_ahb);
574
        v.idlecnt   := 0;
575
        if fromHS.hs_busy = '0' then
576
          if fromAHB2Main(mainr.use_ahb).w_data_valid /= v.rw_cmd_done(mainr.use_ahb) then
577
            v.loadcmdbuffer := '1';
578
            v.rw_cmd_done(mainr.use_ahb)   := v.rw_cmd_done(mainr.use_ahb)+1;
579
            v.sync2_adr(mainr.use_ahb)     := v.rw_cmd_done(mainr.use_ahb)+1;
580
            v.mainstate     := idle;
581
          end if;
582
        end if;
583
 
584
       -- Issue prechare, auto refresh or LMR to HS part
585
       when c1 =>
586
        v.idlecnt   := 0;
587
        if fromHS.hs_busy = '0' then
588
         v.cs                    := BANK01;
589
         case v.ddrcfg.memCmd is
590
           when "01"                        =>  -- Precharge all
591
             v.cmdbufferdata     := CMD_PRE;
592
             v.adrbufferdata(10) := '1';
593
             v.pre_chg           := (others => '0');
594
             v.memCmdDone        := '1';
595
             v.mainstate         := c2;
596
 
597
           when "10" =>                  -- AutoRefresh
598
             -- All banks have to be precharged before AR
599
             if v.pre_chg = "00000000" then
600
               v.cmdbufferdata := CMD_AR;
601
               v.memCmdDone        := '1';
602
               v.mainstate         := c2;
603
               v.refreshDone       := '1';
604
 
605
             else                        -- Run Precharge, and let AR begin when finished
606
               v.cmdbufferdata     := CMD_PRE;
607
               v.adrbufferdata(10) := '1';
608
               v.pre_chg           := (others => '0');
609
               v.mainstate         := idle;
610
             end if;
611
 
612
           when "11"   =>                -- LMR
613
            -- All banks have to be precharged before LMR
614
            if v.pre_chg = "00000000" then
615
             v.cmdbufferdata := CMD_LMR;
616
             v.adrbufferdata := v.lmradr;
617
             v.memCmdDone    := '1';
618
             v.mainstate     := c2;
619
            else
620
               v.cmdbufferdata     := CMD_PRE;
621
               v.adrbufferdata(10) := '1';
622
               v.pre_chg           := (others => '0');
623
               v.mainstate         := idle;
624
            end if;
625
           when others => null;
626
         end case;
627
         v.loadcmdbuffer     := '1';
628
       end if;
629
 
630
       when c2 =>
631
         if v.ddrcfg.memCmd = "00" then
632
           v.refreshDone := '0';
633
           v.mainstate   := idle;
634
         end if;
635
 
636
       when others =>
637
         v.mainstate := init;
638
     end case;
639
 
640
     -- Reset
641
     if rst = '0' then
642
       -- Main controller
643
       v.mainstate        := init;
644
       v.loadcmdbuffer    := '0';
645
       v.cmdbufferdata    := CMD_NOP;
646
       v.adrbufferdata    := (others => '0');
647
       v.use_ahb          := 0;
648
       v.use_bl           := 4;
649
       v.use_cas          := "00";
650
       v.use_buf          := (others => '1');
651
       v.burstlength      := 8;
652
       v.rw_cmd_done      := (others => (others => '1'));
653
       v.lmradr           := (others => '0');
654
       v.memCmdDone       := '0';
655
       v.lockAHB          := "00";
656
       v.pre_row          := (others => (others => '0'));
657
       v.pre_chg          := (others => '0');
658
       v.pre_bankadr      := (0,0);
659
       v.sync2_adr        := (others =>(others => '0'));
660
 
661
       -- For init statemachine
662
       v.initstate   := idle;
663
       v.doMemInit   := '0';
664
       v.memInitDone := '0';
665
       v.initDelay   := 0;
666
       v.cs          := "11";
667
 
668
       -- For address calculator
669
       v.coladdress    := (others => (others => '0'));
670
       v.tmpcoladdress := (others => (others => '0'));
671
       v.rowaddress    := (others => (others => '0'));
672
       v.addressrange  := 0;
673
       v.tmpcolbits    := 0;
674
       v.colbits       := 0;
675
       v.rowbits       := 0;
676
       v.bankselect    := ("11","11");
677
       v.intbankbits   := ("00","00");
678
 
679
       -- For refresh timer statemachine
680
       v.timerstate     := t2;
681
       v.doRefresh      := '0';
682
       v.refreshDone    := '0';
683
       v.refreshTime    := 0;
684
       v.maxRefreshTime := 0;
685
       v.idlecnt        := 0;
686
       v.refreshcnt     := DELAY_200us;
687
 
688
       -- For DDRCFG register
689
       v.apbstate       := idle;
690
       v.apb_cmd_done   := '0';
691
       v.ready          := '0';
692
       v.ddrcfg := (ddrcfg_reset(31),ddrcfg_reset(30 downto 29),ddrcfg_reset(28 downto 27),
693
                    ddrcfg_reset(26 downto 25),ddrcfg_reset(24),ddrcfg_reset(23 downto 22),
694
                    ddrcfg_reset(21 downto 20),'0');
695
 
696
     end if;
697
 
698
 
699
     -- Set output signals
700
     mainri  <= v;
701
 
702
     fromMain.hssi.bl           <= v.use_bl;
703
     fromMain.hssi.ml           <= fromAHB(mainr.use_ahb).burst_dm(conv_integer(mainr.use_buf));
704
     fromMain.hssi.cas          <= v.use_cas;
705
     fromMain.hssi.buf          <= v.use_buf;
706
     fromMain.hssi.ahb          <= v.use_ahb;
707
     fromMain.hssi.cs           <= v.cs;
708
     fromMain.hssi.cmd          <= v.cmdbufferdata;
709
     fromMain.hssi.cmd_valid    <= v.loadcmdbuffer;
710
     fromMain.hssi.adr          <= v.adrbufferdata;
711
     fromMain.ahbctrlsi(0).burstlength      <= v.burstlength;
712
     fromMain.ahbctrlsi(1).burstlength      <= v.burstlength;
713
     fromMain.ahbctrlsi(0).r_predict        <= v.ddrcfg.r_predict(0);
714
     fromMain.ahbctrlsi(1).r_predict        <= v.ddrcfg.r_predict(1);
715
     fromMain.ahbctrlsi(0).w_prot           <= v.ddrcfg.w_prot(0);
716
     fromMain.ahbctrlsi(1).w_prot           <= v.ddrcfg.w_prot(1);
717
     fromMain.ahbctrlsi(0).locked           <= v.lockAHB(0);
718
     fromMain.ahbctrlsi(1).locked           <= v.lockAHB(1);
719
     fromMain.ahbctrlsi(0).asramsi.raddress <= v.sync2_adr(0);
720
     fromMain.ahbctrlsi(1).asramsi.raddress <= v.sync2_adr(1);
721
     fromMain.apbctrlsi.apb_cmd_done     <= v.apb_cmd_done;
722
     fromMain.apbctrlsi.ready            <= v.ready;
723
   end process;
724
 
725
 
726
 --Main clocked register
727
   mainclk : process(clk0)
728
   begin
729
 
730
     if rising_edge(clk0) then
731
       mainr <= mainri;
732
 
733
       -- Register to sync between different clock domains
734
       fromAPB2Main.ddrcfg_reg <= fromAPB.ddrcfg_reg;
735
 
736
       -- Makes signals from main to AHB, ABP, HS registerd
737
       fromMain2AHB <= fromMain.ahbctrlsi;
738
       fromMain2APB <= fromMain.apbctrlsi;
739
       fromMain2HS <= fromMain.hssi;
740
     end if;
741
   end process;
742
 
743
 
744
 
745
  -- Sync of incoming data valid signals from AHB
746
  -- Either if separate clock domains or if syncram_2p
747
  -- doesn't support write through (write first)
748
  a1rt : if ahb1sepclk = 1 or syncram_2p_write_through(tech) = 0 generate
749
    regip1 : process(clk0)
750
    begin
751
      if rising_edge(clk0) then
752
        fromAHB2Main(0).rw_cmd_valid <= fromAHB(0).rw_cmd_valid;
753
        fromAHB2Main(0).w_data_valid <= fromAHB(0).w_data_valid;
754
      end if;
755
    end process;
756
  end generate;
757
  arf : if not (ahb1sepclk = 1 or syncram_2p_write_through(tech) = 0) generate
758
    fromAHB2Main(0).rw_cmd_valid <= fromAHB(0).rw_cmd_valid;
759
    fromAHB2Main(0).w_data_valid <= fromAHB(0).w_data_valid;
760
  end generate;
761
 
762
  a2rt : if ahb2sepclk = 1 or syncram_2p_write_through(tech) = 0 generate
763
    regip2 : process(clk0)
764
    begin
765
      if rising_edge(clk0) then
766
        fromAHB2Main(1).rw_cmd_valid <= fromAHB(1).rw_cmd_valid;
767
        fromAHB2Main(1).w_data_valid <= fromAHB(1).w_data_valid;
768
      end if;
769
    end process;
770
  end generate;
771
  a2rf : if  not (ahb1sepclk = 1 or syncram_2p_write_through(tech) = 0) generate
772
    fromAHB2Main(1).rw_cmd_valid <= fromAHB(1).rw_cmd_valid;
773
    fromAHB2Main(1).w_data_valid <= fromAHB(1).w_data_valid;
774
  end generate;
775
 
776
-------------------------------------------------------------------------------
777
-- High speed interface (Physical layer towards memory)
778
-------------------------------------------------------------------------------
779
 
780
  D0 : hs
781
    generic map(
782
      tech      => tech,
783
      dqsize    => dqsize,
784
      dmsize    => dmsize,
785
      strobesize => strobesize,
786
      clkperiod => clkperiod)
787
    port map(
788
      rst       => rst,
789
      clk0      => clk0,
790
      clk90     => clk90,
791
      clk180    => clk180,
792
      clk270    => clk270,
793
      hclk      => pclk,
794
      hssi      => toHS,
795
      hsso      => fromHS);
796
 
797
  A0 : ahb_slv
798
    generic map(
799
      hindex          => hindex1,
800
      haddr           => haddr1,
801
      hmask           => hmask1,
802
      sepclk          => ahb1sepclk,
803
      dqsize          => dqsize,
804
      dmsize          => dmsize,
805
      tech            => tech)
806
    port map (
807
      rst             => rst,
808
      hclk            => hclk1,
809
      clk0            => clk0,
810
      csi             => toAHB(0),
811
      cso             => fromAHB(0));
812
 
813
  B1: if numahb = 2 generate
814
     A1 : ahb_slv
815
    generic map(
816
      hindex          => hindex2,
817
      haddr           => haddr2,
818
      hmask           => hmask2,
819
      sepclk          => ahb2sepclk,
820
      dqsize          => dqsize,
821
      dmsize          => dmsize)
822
    port map (
823
      rst             => rst,
824
      hclk            => hclk2,
825
      clk0            => clk0,
826
      csi             => toAHB(1),
827
      cso             => fromAHB(1));
828
  end generate;
829
 
830
  B2 : if numahb /= 2 generate
831
    fromAHB(1).rw_cmd_valid <= (others => '1');
832
  end generate;
833
-------------------------------------------------------------------------------
834
-- Mapping signals
835
 
836
  -- Signals to HS
837
  toHS.bl <=  fromMain.hssi.bl;
838
  toHS.ml <= fromMain.hssi.ml;
839
  toHS.cas <= fromMain.hssi.cas;
840
  toHS.buf <= fromMain.hssi.buf;
841
  toHS.ahb <= fromMain.hssi.ahb;
842
  toHS.cs <=  fromMain.hssi.cs;
843
  toHS.adr <= fromMain.hssi.adr;
844
  toHS.cmd <= fromMain.hssi.cmd;
845
  toHS.cmd_valid <= fromMain.hssi.cmd_valid;
846
 
847
  toHS.dsramso(0) <= fromAHB(0).dsramso;
848
  toHS.dsramso(1) <= fromAHB(1).dsramso;
849
  toHS.ddso <= ddso;
850
 
851
 
852
  -- Signals to AHB ctrl 1
853
  toAHB(0).ahbsi <= ahb1si;
854
  toAHB(0).asramsi <= fromMain.ahbctrlsi(0).asramsi;
855
  toAHB(0).dsramsi <= fromHS.dsramsi(0);
856
  toAHB(0).burstlength <= fromMain2AHB(0).burstlength;
857
  toAHB(0).r_predict <= fromMain2AHB(0).r_predict;
858
  toAHB(0).w_prot <= fromMain2AHB(0).w_prot;
859
  toAHB(0).locked <= fromMain2AHB(0).locked;
860
  toAHB(0).rw_cmd_done <=  fromHS.cmdDone(0);
861
 
862
   -- Signals to AHB ctrl 2
863
  toAHB(1).ahbsi <= ahb2si;
864
  toAHB(1).asramsi <= fromMain.ahbctrlsi(1).asramsi;
865
  toAHB(1).dsramsi <= fromHS.dsramsi(1);
866
  toAHB(1).burstlength <= fromMain2AHB(1).burstlength;
867
  toAHB(1).r_predict <= fromMain2AHB(1).r_predict;
868
  toAHB(1).w_prot <= fromMain2AHB(1).w_prot;
869
  toAHB(1).locked <= fromMain2AHB(1).locked;
870
  toAHB(1).rw_cmd_done <=  fromHS.cmdDone(1);
871
 
872
 
873
  -- Ouput signals
874
  ahb1so <= fromAHB(0).ahbso;
875
  ahb2so <= fromAHB(1).ahbso;
876
  ddsi <= fromHS.ddsi;
877
 
878
 
879
end rtl;

powered by: WebSVN 2.1.0

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