OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.24/] [fpga/] [src/] [ram/] [sdramcntl.vhd] - Blame information for rev 211

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 hellwig
--------------------------------------------------------------------
2
-- Company : XESS Corp.
3
-- Engineer : Dave Vanden Bout
4
-- Creation Date : 05/17/2005
5
-- Copyright : 2005, XESS Corp
6
-- Tool Versions : WebPACK 6.3.03i
7
--
8
-- Description:
9
-- SDRAM controller
10
--
11
-- Revision:
12
-- n.a. (because of hacking by Hellwig Geisse)
13
--
14
-- Additional Comments:
15
-- 1.4.0:
16
-- Added generic parameter to enable/disable independent active rows in each bank.
17
-- 1.3.0:
18
-- Modified to allow independently active rows in each bank.
19
-- 1.2.0:
20
-- Modified to allow pipelining of read/write operations.
21
-- 1.1.0:
22
-- Initial release.
23
--
24
-- License:
25
-- This code can be freely distributed and modified as long as
26
-- this header is not removed.
27
--------------------------------------------------------------------
28
 
29
library IEEE, UNISIM;
30
use IEEE.std_logic_1164.all;
31
use IEEE.std_logic_unsigned.all;
32
use IEEE.numeric_std.all;
33
 
34
entity sdramCntl is
35
  port(
36
    -- host side
37
    clk                  : in  std_logic;  -- master clock
38
    clk_ok               : in  std_logic;  -- true if clock is stable
39
    rd                   : in  std_logic;  -- initiate read operation
40
    wr                   : in  std_logic;  -- initiate write operation
41
    done                 : out std_logic;  -- read or write operation is done
42
    hAddr                : in  std_logic_vector(23 downto 0);  -- address from host to SDRAM
43
    hDIn                 : in  std_logic_vector(15 downto 0);  -- data from host       to SDRAM
44
    hDOut                : out std_logic_vector(15 downto 0);  -- data from SDRAM to host
45
 
46
    -- SDRAM side
47
    cke     : out std_logic;            -- clock-enable to SDRAM
48
    ce_n    : out std_logic;            -- chip-select to SDRAM
49
    ras_n   : out std_logic;            -- SDRAM row address strobe
50
    cas_n   : out std_logic;            -- SDRAM column address strobe
51
    we_n    : out std_logic;            -- SDRAM write enable
52
    ba      : out std_logic_vector(1 downto 0);  -- SDRAM bank address
53
    sAddr   : out std_logic_vector(12 downto 0);  -- SDRAM row/column address
54
    sDIn    : in  std_logic_vector(15 downto 0);  -- data from SDRAM
55
    sDOut   : out std_logic_vector(15 downto 0);  -- data to SDRAM
56
    sDOutEn : out std_logic;            -- true if data is output to SDRAM on sDOut
57
    dqmh    : out std_logic;            -- enable upper-byte of SDRAM databus if true
58
    dqml    : out std_logic             -- enable lower-byte of SDRAM databus if true
59
    );
60
end sdramCntl;
61
 
62
 
63
architecture arch of sdramCntl is
64
 
65
  constant YES                :    std_logic := '1';
66
  constant NO                 :    std_logic := '0';
67
 
68
  -- select one of two integers based on a Boolean
69
  function int_select(s : in boolean; a : in integer; b : in integer) return integer is
70
  begin
71
    if s then
72
      return a;
73
    else
74
      return b;
75
    end if;
76
    return a;
77
  end function int_select;
78
 
79
  constant OUTPUT : std_logic := '1';   -- direction of dataflow w.r.t. this controller
80
  constant INPUT  : std_logic := '0';
81
  constant NOP    : std_logic := '0';   -- no operation
82
  constant READ   : std_logic := '1';   -- read operation
83
  constant WRITE  : std_logic := '1';   -- write operation
84
 
85
  -- SDRAM timing parameters
86
  constant Tinit : natural := 200;      -- min initialization interval (us)
87
  constant Tras  : natural := 45;       -- min interval between active to precharge commands (ns)
88
  constant Trcd  : natural := 20;       -- min interval between active and R/W commands (ns)
89
  constant Tref  : natural := 64_000_000;  -- maximum refresh interval (ns)
90
  constant Trfc  : natural := 66;       -- duration of refresh operation (ns)
91
  constant Trp   : natural := 20;       -- min precharge command duration (ns)
92
  constant Twr   : natural := 15;       -- write recovery time (ns)
93
  constant Txsr  : natural := 75;       -- exit self-refresh time (ns)
94
 
95
  -- SDRAM timing parameters converted into clock cycles (based on FREQ = 50_000)
96
  constant NORM        : natural := 1_000_000;  -- normalize ns * KHz
97
  constant INIT_CYCLES : natural := 1+((Tinit*50_000)/1000);  -- SDRAM power-on initialization interval
98
  constant RAS_CYCLES  : natural := 1+((Tras*50_000)/NORM);  -- active-to-precharge interval
99
  constant RCD_CYCLES  : natural := 1+((Trcd*50_000)/NORM);  -- active-to-R/W interval
100
  constant REF_CYCLES  : natural := 1+(((Tref/8192)*50_000)/NORM);  -- interval between row refreshes
101
  constant RFC_CYCLES  : natural := 1+((Trfc*50_000)/NORM);  -- refresh operation interval
102
  constant RP_CYCLES   : natural := 1+((Trp*50_000)/NORM);  -- precharge operation interval
103
  constant WR_CYCLES   : natural := 1+((Twr*50_000)/NORM);  -- write recovery time
104
  constant XSR_CYCLES  : natural := 1+((Txsr*50_000)/NORM);  -- exit self-refresh time
105
  constant MODE_CYCLES : natural := 2;  -- mode register setup time
106
  constant CAS_CYCLES  : natural := 3;  -- CAS latency
107
  constant RFSH_OPS    : natural := 8;  -- number of refresh operations needed to init SDRAM
108
 
109
  -- timer registers that count down times for various SDRAM operations
110
  signal timer_r, timer_x       : natural range 0 to INIT_CYCLES;  -- current SDRAM op time
111
  signal rasTimer_r, rasTimer_x : natural range 0 to RAS_CYCLES;  -- active-to-precharge time
112
  signal wrTimer_r, wrTimer_x   : natural range 0 to WR_CYCLES;  -- write-to-precharge time
113
  signal refTimer_r, refTimer_x : natural range 0 to REF_CYCLES;  -- time between row refreshes
114
  signal rfshCntr_r, rfshCntr_x : natural range 0 to 8192;  -- counts refreshes that are neede
115
  signal nopCntr_r, nopCntr_x   : natural range 0 to 10000;  -- counts consecutive NOP operations
116
 
117
  signal doSelfRfsh : std_logic;        -- active when the NOP counter hits zero and self-refresh can start
118
 
119
  -- states of the SDRAM controller state machine
120
  type cntlState is (
121
    INITWAIT,                           -- initialization - waiting for power-on initialization to complete
122
    INITPCHG,                           -- initialization - initial precharge of SDRAM banks
123
    INITSETMODE,                        -- initialization - set SDRAM mode
124
    INITRFSH,                           -- initialization - do initial refreshes
125
    RW,                                 -- read/write/refresh the SDRAM
126
    ACTIVATE,                           -- open a row of the SDRAM for reading/writing
127
    REFRESHROW,                         -- refresh a row of the SDRAM
128
    SELFREFRESH                         -- keep SDRAM in self-refresh mode with CKE low
129
    );
130
  signal state_r, state_x : cntlState;  -- state register and next state
131
 
132
  -- commands that are sent to the SDRAM to make it perform certain operations
133
  -- commands use these SDRAM input pins (ce_n,ras_n,cas_n,we_n,dqmh,dqml)
134
  subtype sdramCmd is unsigned(5 downto 0);
135
  constant NOP_CMD    : sdramCmd := "011100";
136
  constant ACTIVE_CMD : sdramCmd := "001100";
137
  constant READ_CMD   : sdramCmd := "010100";
138
  constant WRITE_CMD  : sdramCmd := "010000";
139
  constant PCHG_CMD   : sdramCmd := "001011";
140
  constant MODE_CMD   : sdramCmd := "000011";
141
  constant RFSH_CMD   : sdramCmd := "000111";
142
 
143
  -- SDRAM mode register
144
  -- the SDRAM is placed in a non-burst mode (burst length = 1) with a 3-cycle CAS
145
  subtype sdramMode is std_logic_vector(12 downto 0);
146
  constant MODE : sdramMode := "000" & "0" & "00" & "011" & "0" & "000";
147
 
148
  -- the host address is decomposed into these sets of SDRAM address components
149
  constant ROW_LEN : natural := 13;  -- number of row address bits
150
  constant COL_LEN : natural := 9;  -- number of column address bits
151
  signal   bank    : std_logic_vector(ba'range);  -- bank address bits
152
  signal   row     : std_logic_vector(ROW_LEN - 1 downto 0);  -- row address within bank
153
  signal   col     : std_logic_vector(sAddr'range);  -- column address within row
154
 
155
  -- registers that store the currently active row in each bank of the SDRAM
156
  constant NUM_ACTIVE_ROWS            : integer := 1;
157
  type activeRowType is array(0 to NUM_ACTIVE_ROWS-1) of std_logic_vector(row'range);
158
  signal   activeRow_r, activeRow_x   : activeRowType;
159
  signal   activeFlag_r, activeFlag_x : std_logic_vector(0 to NUM_ACTIVE_ROWS-1);  -- indicates that some row in a bank is active
160
  signal   bankIndex                  : natural range 0 to NUM_ACTIVE_ROWS-1;  -- bank address bits
161
  signal   activeBank_r, activeBank_x : std_logic_vector(ba'range);  -- indicates the bank with the active row
162
  signal   doActivate                 : std_logic;  -- indicates when a new row in a bank needs to be activated
163
 
164
  -- there is a command bit embedded within the SDRAM column address
165
  constant CMDBIT_POS    : natural   := 10;  -- position of command bit
166
  constant AUTO_PCHG_ON  : std_logic := '1';  -- CMDBIT value to auto-precharge the bank
167
  constant AUTO_PCHG_OFF : std_logic := '0';  -- CMDBIT value to disable auto-precharge
168
  constant ONE_BANK      : std_logic := '0';  -- CMDBIT value to select one bank
169
  constant ALL_BANKS     : std_logic := '1';  -- CMDBIT value to select all banks
170
 
171
  -- status signals that indicate when certain operations are in progress
172
  signal wrInProgress       : std_logic;  -- write operation in progress
173
  signal rdInProgress       : std_logic;  -- read operation in progress
174
  signal activateInProgress : std_logic;  -- row activation is in progress
175
 
176
  -- these registers track the progress of read and write operations
177
  signal rdPipeline_r, rdPipeline_x : std_logic_vector(CAS_CYCLES+1 downto 0);  -- pipeline of read ops in progress
178
  signal wrPipeline_r, wrPipeline_x : std_logic_vector(0 downto 0);  -- pipeline of write ops (only need 1 cycle)
179
 
180
  -- registered outputs to host
181
  signal hDOut_r, hDOut_x                 : std_logic_vector(hDOut'range);  -- holds data read from SDRAM and sent to the host
182
 
183
  -- registered outputs to SDRAM
184
  signal cke_r, cke_x           : std_logic;  -- clock enable 
185
  signal cmd_r, cmd_x           : sdramCmd;  -- SDRAM command bits
186
  signal ba_r, ba_x             : std_logic_vector(ba'range);  -- SDRAM bank address bits
187
  signal sAddr_r, sAddr_x       : std_logic_vector(sAddr'range);  -- SDRAM row/column address
188
  signal sData_r, sData_x       : std_logic_vector(sDOut'range);  -- SDRAM out databus
189
  signal sDataDir_r, sDataDir_x : std_logic;  -- SDRAM databus direction control bit
190
 
191
begin
192
 
193
  -----------------------------------------------------------
194
  -- attach some internal signals to the I/O ports 
195
  -----------------------------------------------------------
196
 
197
  -- attach registered SDRAM control signals to SDRAM input pins
198
  (ce_n, ras_n, cas_n, we_n, dqmh, dqml) <= cmd_r;  -- SDRAM operation control bits
199
  cke                                    <= cke_r;  -- SDRAM clock enable
200
  ba                                     <= ba_r;  -- SDRAM bank address
201
  sAddr                                  <= sAddr_r;  -- SDRAM address
202
  sDOut                                  <= sData_r;  -- SDRAM output data bus
203
  sDOutEn                                <= YES when sDataDir_r = OUTPUT else NO;  -- output databus enable
204
 
205
  -- attach some port signals
206
  hDOut   <= hDOut_r;                   -- data back to host
207
 
208
 
209
  -----------------------------------------------------------
210
  -- compute the next state and outputs 
211
  -----------------------------------------------------------
212
 
213
  combinatorial : process(rd, wr, hAddr, hDIn, hDOut_r, sDIn, state_r,
214 122 hellwig
                          activeFlag_r, activeRow_r, activeBank_r,
215
                          rdPipeline_r, wrPipeline_r,
216 27 hellwig
                          nopCntr_r, rfshCntr_r, timer_r, rasTimer_r,
217
                          wrTimer_r, refTimer_r, cmd_r, cke_r)
218
  begin
219
 
220
    -----------------------------------------------------------
221
    -- setup default values for signals 
222
    -----------------------------------------------------------
223
 
224
    cke_x        <= YES;                -- enable SDRAM clock
225
    cmd_x        <= NOP_CMD;            -- set SDRAM command to no-operation
226
    sDataDir_x   <= INPUT;              -- accept data from the SDRAM
227
    sData_x      <= hDIn(sData_x'range);  -- output data from host to SDRAM
228
    state_x      <= state_r;            -- reload these registers and flags
229
    activeFlag_x <= activeFlag_r;       --              with their existing values
230
    activeRow_x  <= activeRow_r;
231
    activeBank_x <= activeBank_r;
232
    rfshCntr_x   <= rfshCntr_r;
233
 
234
    -----------------------------------------------------------
235
    -- setup default value for the SDRAM address 
236
    -----------------------------------------------------------
237
 
238
    -- extract bank field from host address
239
    ba_x                    <= hAddr(ba'length + ROW_LEN + COL_LEN - 1 downto ROW_LEN + COL_LEN);
240
    bank                    <= ba_x;
241
    bankIndex               <= 0;
242
    -- extract row, column fields from host address
243
    row                     <= hAddr(ROW_LEN + COL_LEN - 1 downto COL_LEN);
244
    -- extend column (if needed) until it is as large as the (SDRAM address bus - 1)
245
    col                     <= (others => '0');  -- set it to all zeroes
246
    col(COL_LEN-1 downto 0) <= hAddr(COL_LEN-1 downto 0);
247
    -- by default, set SDRAM address to the column address with interspersed
248
    -- command bit set to disable auto-precharge
249
    sAddr_x                 <= col(col'high-1 downto CMDBIT_POS) & AUTO_PCHG_OFF
250
                               & col(CMDBIT_POS-1 downto 0);
251
 
252
    -----------------------------------------------------------
253
    -- manage the read and write operation pipelines
254
    -----------------------------------------------------------
255
 
256
    -- determine if read operations are in progress by the presence of
257
    -- READ flags in the read pipeline 
258
    if rdPipeline_r(rdPipeline_r'high downto 1) /= 0 then
259
      rdInProgress <= YES;
260
    else
261
      rdInProgress <= NO;
262
    end if;
263
 
264
    -- enter NOPs into the read and write pipeline shift registers by default
265
    rdPipeline_x    <= NOP & rdPipeline_r(rdPipeline_r'high downto 1);
266
    wrPipeline_x(0) <= NOP;
267
 
268
    -- transfer data from SDRAM to the host data register if a read flag has exited the pipeline
269
    -- (the transfer occurs 1 cycle before we tell the host the read operation is done)
270
    if rdPipeline_r(1) = READ then
271
      -- get the SDRAM data for the host directly from the SDRAM if the controller and SDRAM are in-phase
272
      hDOut_x       <= sDIn(hDOut'range);
273
    else
274
      -- retain contents of host data registers if no data from the SDRAM has arrived yet
275
      hDOut_x         <= hDOut_r;
276
    end if;
277
 
278
    done   <= rdPipeline_r(0) or wrPipeline_r(0);  -- a read or write operation is done
279
 
280
    -----------------------------------------------------------
281
    -- manage row activation
282
    -----------------------------------------------------------
283
 
284
    -- request a row activation operation if the row of the current address
285
    -- does not match the currently active row in the bank, or if no row
286
    -- in the bank is currently active
287
    if (bank /= activeBank_r) or (row /= activeRow_r(bankIndex)) or (activeFlag_r(bankIndex) = NO) then
288
      doActivate <= YES;
289
    else
290
      doActivate <= NO;
291
    end if;
292
 
293
    -----------------------------------------------------------
294
    -- manage self-refresh
295
    -----------------------------------------------------------
296
 
297
    -- enter self-refresh if neither a read or write is requested for 10000 consecutive cycles.
298
    if (rd = YES) or (wr = YES) then
299
      -- any read or write resets NOP counter and exits self-refresh state
300
      nopCntr_x  <= 0;
301
      doSelfRfsh <= NO;
302
    elsif nopCntr_r /= 10000 then
303
      -- increment NOP counter whenever there is no read or write operation 
304
      nopCntr_x  <= nopCntr_r + 1;
305
      doSelfRfsh <= NO;
306
    else
307
      -- start self-refresh when counter hits maximum NOP count and leave counter unchanged
308
      nopCntr_x  <= nopCntr_r;
309
      doSelfRfsh <= YES;
310
    end if;
311
 
312
    -----------------------------------------------------------
313
    -- update the timers 
314
    -----------------------------------------------------------
315
 
316
    -- row activation timer
317
    if rasTimer_r /= 0 then
318
      -- decrement a non-zero timer and set the flag
319
      -- to indicate the row activation is still inprogress
320
      rasTimer_x         <= rasTimer_r - 1;
321
      activateInProgress <= YES;
322
    else
323
      -- on timeout, keep the timer at zero     and reset the flag
324
      -- to indicate the row activation operation is done
325
      rasTimer_x         <= rasTimer_r;
326
      activateInProgress <= NO;
327
    end if;
328
 
329
    -- write operation timer            
330
    if wrTimer_r /= 0 then
331
      -- decrement a non-zero timer and set the flag
332
      -- to indicate the write operation is still inprogress
333
      wrTimer_x    <= wrTimer_r - 1;
334
      wrInPRogress <= YES;
335
    else
336
      -- on timeout, keep the timer at zero and reset the flag that
337
      -- indicates a write operation is in progress
338
      wrTimer_x    <= wrTimer_r;
339
      wrInPRogress <= NO;
340
    end if;
341
 
342
    -- refresh timer            
343
    if refTimer_r /= 0 then
344
      refTimer_x <= refTimer_r - 1;
345
    else
346
      -- on timeout, reload the timer with the interval between row refreshes
347
      -- and increment the counter for the number of row refreshes that are needed
348
      refTimer_x <= REF_CYCLES;
349
      rfshCntr_x <= rfshCntr_r + 1;
350
    end if;
351
 
352
    -- main timer for sequencing SDRAM operations               
353
    if timer_r /= 0 then
354
      -- decrement the timer and do nothing else since the previous operation has not completed yet.
355
      timer_x <= timer_r - 1;
356
    else
357
      -- the previous operation has completed once the timer hits zero
358
      timer_x <= timer_r;               -- by default, leave the timer at zero
359
 
360
      -----------------------------------------------------------
361
      -- compute the next state and outputs 
362
      -----------------------------------------------------------
363
      case state_r is
364
 
365
        -----------------------------------------------------------
366
        -- let clock stabilize and then wait for the SDRAM to initialize 
367
        -----------------------------------------------------------
368
        when INITWAIT =>
369
                                        -- wait for SDRAM power-on initialization once the clock is stable
370
            timer_x <= INIT_CYCLES;     -- set timer for initialization duration
371
            state_x <= INITPCHG;
372
 
373
          -----------------------------------------------------------
374
          -- precharge all SDRAM banks after power-on initialization 
375
          -----------------------------------------------------------
376
        when INITPCHG =>
377
          cmd_x               <= PCHG_CMD;
378
          sAddr_x(CMDBIT_POS) <= ALL_BANKS;  -- precharge all banks
379
          timer_x             <= RP_CYCLES;  -- set timer for precharge operation duration
380
          rfshCntr_x          <= RFSH_OPS;  -- set counter for refresh ops needed after precharge
381
          state_x             <= INITRFSH;
382
 
383
          -----------------------------------------------------------
384
          -- refresh the SDRAM a number of times after initial precharge 
385
          -----------------------------------------------------------
386
        when INITRFSH =>
387
          cmd_x      <= RFSH_CMD;
388
          timer_x    <= RFC_CYCLES;     -- set timer to refresh operation duration
389
          rfshCntr_x <= rfshCntr_r - 1;  -- decrement refresh operation counter
390
          if rfshCntr_r = 1 then
391
            state_x  <= INITSETMODE;    -- set the SDRAM mode once all refresh ops are done
392
          end if;
393
 
394
          -----------------------------------------------------------
395
          -- set the mode register of the SDRAM 
396
          -----------------------------------------------------------
397
        when INITSETMODE =>
398
          cmd_x   <= MODE_CMD;
399
          sAddr_x <= MODE;              -- output mode register bits on the SDRAM address bits
400
          timer_x <= MODE_CYCLES;       -- set timer for mode setting operation duration
401
          state_x <= RW;
402
 
403
          -----------------------------------------------------------
404
          -- process read/write/refresh operations after initialization is done 
405
          -----------------------------------------------------------
406
        when RW                                      =>
407
          -----------------------------------------------------------
408
          -- highest priority operation: row refresh 
409
          -- do a refresh operation if the refresh counter is non-zero
410
          -----------------------------------------------------------
411
          if rfshCntr_r /= 0 then
412
                                        -- wait for any row activations, writes or reads to finish before doing a precharge
413
            if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
414
              cmd_x                       <= PCHG_CMD;  -- initiate precharge of the SDRAM
415
              sAddr_x(CMDBIT_POS)         <= ALL_BANKS;  -- precharge all banks
416
              timer_x                     <= RP_CYCLES;  -- set timer for this operation
417
              activeFlag_x                <= (others => NO);  -- all rows are inactive after a precharge operation
418
              state_x                     <= REFRESHROW;  -- refresh the SDRAM after the precharge
419
            end if;
420
            -----------------------------------------------------------
421
            -- do a host-initiated read operation 
422
            -----------------------------------------------------------
423
          elsif rd = YES then
424
                                          -- Wait one clock cycle if the bank address has just changed and each bank has its own active row.
425
            -- This gives extra time for the row activation circuitry.
426
            if (true) then
427
                                        -- activate a new row if the current read is outside the active row or bank
428
              if doActivate = YES then
429
                                        -- activate new row only if all previous activations, writes, reads are done
430
                if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
431
                  cmd_x                   <= PCHG_CMD;  -- initiate precharge of the SDRAM
432
                  sAddr_x(CMDBIT_POS)     <= ONE_BANK;  -- precharge this bank
433
                  timer_x                 <= RP_CYCLES;  -- set timer for this operation
434
                  activeFlag_x(bankIndex) <= NO;  -- rows in this bank are inactive after a precharge operation
435
                  state_x                 <= ACTIVATE;  -- activate the new row after the precharge is done
436
                end if;
437
                                        -- read from the currently active row if no previous read operation
438
                                        -- is in progress or if pipeline reads are enabled
439
                                        -- we can always initiate a read even if a write is already in progress
440
              elsif (rdInProgress = NO) then
441
                cmd_x                     <= READ_CMD;  -- initiate a read of the SDRAM
442
                                        -- insert a flag into the pipeline shift register that will exit the end
443
                                        -- of the shift register when the data from the SDRAM is available
444
                rdPipeline_x              <= READ & rdPipeline_r(rdPipeline_r'high downto 1);
445
              end if;
446
            end if;
447
            -----------------------------------------------------------
448
            -- do a host-initiated write operation 
449
            -----------------------------------------------------------
450
          elsif wr = YES then
451
                                          -- Wait one clock cycle if the bank address has just changed and each bank has its own active row.
452
            -- This gives extra time for the row activation circuitry.
453
            if (true) then
454
                                        -- activate a new row if the current write is outside the active row or bank
455
              if doActivate = YES then
456
                                        -- activate new row only if all previous activations, writes, reads are done
457
                if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
458
                  cmd_x                   <= PCHG_CMD;  -- initiate precharge of the SDRAM
459
                  sAddr_x(CMDBIT_POS)     <= ONE_BANK;  -- precharge this bank
460
                  timer_x                 <= RP_CYCLES;  -- set timer for this operation
461
                  activeFlag_x(bankIndex) <= NO;  -- rows in this bank are inactive after a precharge operation
462
                  state_x                 <= ACTIVATE;  -- activate the new row after the precharge is done
463
                end if;
464
                                        -- write to the currently active row if no previous read operations are in progress
465
              elsif rdInProgress = NO then
466
                cmd_x                     <= WRITE_CMD;  -- initiate the write operation
467
                sDataDir_x                <= OUTPUT;  -- turn on drivers to send data to SDRAM
468
                                        -- set timer so precharge doesn't occur too soon after write operation
469
                wrTimer_x                 <= WR_CYCLES;
470
                                        -- insert a flag into the 1-bit pipeline shift register that will exit on the
471
                                        -- next cycle.  The write into SDRAM is not actually done by that time, but
472
                                        -- this doesn't matter to the host
473
                wrPipeline_x(0)           <= WRITE;
474
              end if;
475
            end if;
476
            -----------------------------------------------------------
477
            -- do a host-initiated self-refresh operation 
478
            -----------------------------------------------------------
479
          elsif doSelfRfsh = YES then
480
                                        -- wait until all previous activations, writes, reads are done
481
            if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
482
              cmd_x                       <= PCHG_CMD;  -- initiate precharge of the SDRAM
483
              sAddr_x(CMDBIT_POS)         <= ALL_BANKS;  -- precharge all banks
484
              timer_x                     <= RP_CYCLES;  -- set timer for this operation
485
              activeFlag_x                <= (others => NO);  -- all rows are inactive after a precharge operation
486
              state_x                     <= SELFREFRESH;  -- self-refresh the SDRAM after the precharge
487
            end if;
488
            -----------------------------------------------------------
489
            -- no operation
490
            -----------------------------------------------------------
491
          else
492
            state_x                       <= RW;  -- continue to look for SDRAM operations to execute
493
          end if;
494
 
495
          -----------------------------------------------------------
496
          -- activate a row of the SDRAM 
497
          -----------------------------------------------------------
498
        when ACTIVATE                        =>
499
          cmd_x                   <= ACTIVE_CMD;
500
          sAddr_x                 <= (others => '0');  -- output the address for the row to be activated
501
          sAddr_x(row'range)      <= row;
502
          activeBank_x            <= bank;
503
          activeRow_x(bankIndex)  <= row;  -- store the new active SDRAM row address
504
          activeFlag_x(bankIndex) <= YES;  -- the SDRAM is now active
505
          rasTimer_x              <= RAS_CYCLES;  -- minimum time before another precharge can occur 
506
          timer_x                 <= RCD_CYCLES;  -- minimum time before a read/write operation can occur
507
          state_x                 <= RW;  -- return to do read/write operation that initiated this activation
508
 
509
          -----------------------------------------------------------
510
          -- refresh a row of the SDRAM         
511
          -----------------------------------------------------------
512
        when REFRESHROW =>
513
          cmd_x      <= RFSH_CMD;
514
          timer_x    <= RFC_CYCLES;     -- refresh operation interval
515
          rfshCntr_x <= rfshCntr_r - 1;  -- decrement the number of needed row refreshes
516
          state_x    <= RW;             -- process more SDRAM operations after refresh is done
517
 
518
          -----------------------------------------------------------
519
          -- place the SDRAM into self-refresh and keep it there until further notice           
520
          -----------------------------------------------------------
521
        when SELFREFRESH            =>
522
          if (doSelfRfsh = YES) then
523
                                        -- keep the SDRAM in self-refresh mode as long as requested and until there is a stable clock
524
            cmd_x        <= RFSH_CMD;   -- output the refresh command; this is only needed on the first clock cycle
525
            cke_x        <= NO;         -- disable the SDRAM clock
526
          else
527
                                        -- else exit self-refresh mode and start processing read and write operations
528
            cke_x        <= YES;        -- restart the SDRAM clock
529
            rfshCntr_x   <= 0;          -- no refreshes are needed immediately after leaving self-refresh
530
            activeFlag_x <= (others => NO);  -- self-refresh deactivates all rows
531
            timer_x      <= XSR_CYCLES;  -- wait this long until read and write operations can resume
532
            state_x      <= RW;
533
          end if;
534
 
535
          -----------------------------------------------------------
536
          -- unknown state
537
          -----------------------------------------------------------
538
        when others =>
539
          state_x <= INITWAIT;          -- reset state if in erroneous state
540
 
541
      end case;
542
    end if;
543
  end process combinatorial;
544
 
545
 
546
  -----------------------------------------------------------
547
  -- update registers on the appropriate clock edge     
548
  -----------------------------------------------------------
549
 
550
  update : process(clk_ok, clk)
551
  begin
552
 
553
    if clk_ok = NO then
554
      -- asynchronous reset
555
      state_r      <= INITWAIT;
556
      activeFlag_r <= (others => NO);
557
      rfshCntr_r   <= 0;
558
      timer_r      <= 0;
559
      refTimer_r   <= REF_CYCLES;
560
      rasTimer_r   <= 0;
561
      wrTimer_r    <= 0;
562
      nopCntr_r    <= 0;
563
      rdPipeline_r <= (others => '0');
564
      wrPipeline_r <= (others => '0');
565
      cke_r        <= NO;
566
      cmd_r        <= NOP_CMD;
567
      ba_r         <= (others => '0');
568
      sAddr_r      <= (others => '0');
569
      sData_r      <= (others => '0');
570
      sDataDir_r   <= INPUT;
571
      hDOut_r      <= (others => '0');
572
    elsif rising_edge(clk) then
573
      state_r      <= state_x;
574
      activeBank_r <= activeBank_x;
575
      activeRow_r  <= activeRow_x;
576
      activeFlag_r <= activeFlag_x;
577
      rfshCntr_r   <= rfshCntr_x;
578
      timer_r      <= timer_x;
579
      refTimer_r   <= refTimer_x;
580
      rasTimer_r   <= rasTimer_x;
581
      wrTimer_r    <= wrTimer_x;
582
      nopCntr_r    <= nopCntr_x;
583
      rdPipeline_r <= rdPipeline_x;
584
      wrPipeline_r <= wrPipeline_x;
585
      cke_r        <= cke_x;
586
      cmd_r        <= cmd_x;
587
      ba_r         <= ba_x;
588
      sAddr_r      <= sAddr_x;
589
      sData_r      <= sData_x;
590
      sDataDir_r   <= sDataDir_x;
591
      hDOut_r      <= hDOut_x;
592
    end if;
593
 
594
  end process update;
595
 
596
end arch;

powered by: WebSVN 2.1.0

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