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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [System09_Xess_XuLA/] [sdramcntl.vhd] - Blame information for rev 122

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 122 dilbert57
library IEEE, UNISIM;
2
use IEEE.std_logic_1164.all;
3
 
4
package sdram is
5
 
6
  -- SDRAM controller
7
  component sdramCntl
8
    generic(
9
      FREQ                 :     natural := 100_000;  -- operating frequency in KHz
10
      IN_PHASE             :     boolean := true;  -- SDRAM and controller work on same or opposite clock edge
11
      PIPE_EN              :     boolean := false;  -- if true, enable pipelined read operations
12
      MAX_NOP              :     natural := 10000;  -- number of NOPs before entering self-refresh
13
      MULTIPLE_ACTIVE_ROWS :     boolean := false;  -- if true, allow an active row in each bank
14
      DATA_WIDTH           :     natural := 16;  -- host & SDRAM data width
15
      NROWS                :     natural := 8192;  -- number of rows in SDRAM array
16
      NCOLS                :     natural := 512;  -- number of columns in SDRAM array
17
      HADDR_WIDTH          :     natural := 24;  -- host-side address width
18
      SADDR_WIDTH          :     natural := 13  -- SDRAM-side address width
19
      );
20
    port(
21
      -- host side
22
      clk                  : in  std_logic;  -- master clock
23
      lock                 : in  std_logic;  -- true if clock is stable
24
      rst                  : in  std_logic;  -- reset
25
      rd                   : in  std_logic;  -- initiate read operation
26
      wr                   : in  std_logic;  -- initiate write operation
27
      earlyOpBegun         : out std_logic;  -- read/write/self-refresh op has begun (async)
28
      opBegun              : out std_logic;  -- read/write/self-refresh op has begun (clocked)
29
      rdPending            : out std_logic;  -- true if read operation(s) are still in the pipeline
30
      done                 : out std_logic;  -- read or write operation is done
31
      rdDone               : out std_logic;  -- read operation is done and data is available
32
      hAddr                : in  std_logic_vector(HADDR_WIDTH-1 downto 0);  -- address from host to SDRAM
33
      hDIn                 : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from host       to SDRAM
34
      hDOut                : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from SDRAM to host
35
      status               : out std_logic_vector(3 downto 0);  -- diagnostic status of the FSM         
36
      -- SDRAM side
37
      cke                  : out std_logic;  -- clock-enable to SDRAM
38
      ce_n                 : out std_logic;  -- chip-select to SDRAM
39
      ras_n                : out std_logic;  -- SDRAM row address strobe
40
      cas_n                : out std_logic;  -- SDRAM column address strobe
41
      we_n                 : out std_logic;  -- SDRAM write enable
42
      ba                   : out std_logic_vector(1 downto 0);  -- SDRAM bank address
43
      sAddr                : out std_logic_vector(SADDR_WIDTH-1 downto 0);  -- SDRAM row/column address
44
      sDIn                 : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from SDRAM
45
      sDOut                : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data to SDRAM
46
      sDOutEn              : out std_logic  -- true if data is output to SDRAM on sDOut
47
      );
48
  end component;
49
 
50
  -- dual-port interface to the SDRAM controller
51
  component dualport
52
    generic(
53
      PIPE_EN         :    boolean                       := false;  -- enable pipelined read operations
54
      PORT_TIME_SLOTS :    std_logic_vector(15 downto 0) := "1111000011110000";
55
      DATA_WIDTH      :    natural                       := 16;  -- host & SDRAM data width
56
      HADDR_WIDTH     :    natural                       := 23  -- host-side address width
57
      );
58
    port(
59
      clk             : in std_logic;   -- master clock
60
 
61
      -- host-side port 0
62
      rst0          : in  std_logic;    -- reset
63
      rd0           : in  std_logic;    -- initiate read operation
64
      wr0           : in  std_logic;    -- initiate write operation
65
      earlyOpBegun0 : out std_logic;    -- read/write op has begun (async)
66
      opBegun0      : out std_logic;    -- read/write op has begun (clocked)
67
      rdPending0    : out std_logic;    -- true if read operation(s) are still in the pipeline
68
      done0         : out std_logic;    -- read or write operation is done
69
      rdDone0       : out std_logic;    -- read operation is done and data is available
70
      hAddr0        : in  std_logic_vector(HADDR_WIDTH-1 downto 0);  -- address from host to SDRAM
71
      hDIn0         : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from host to SDRAM
72
      hDOut0        : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from SDRAM to host
73
      status0       : out std_logic_vector(3 downto 0);  -- diagnostic status of the SDRAM controller FSM         
74
 
75
      -- host-side port 1
76
      rst1          : in  std_logic;
77
      rd1           : in  std_logic;
78
      wr1           : in  std_logic;
79
      earlyOpBegun1 : out std_logic;
80
      opBegun1      : out std_logic;
81
      rdPending1    : out std_logic;
82
      done1         : out std_logic;
83
      rdDone1       : out std_logic;
84
      hAddr1        : in  std_logic_vector(HADDR_WIDTH-1 downto 0);
85
      hDIn1         : in  std_logic_vector(DATA_WIDTH-1 downto 0);
86
      hDOut1        : out std_logic_vector(DATA_WIDTH-1 downto 0);
87
      status1       : out std_logic_vector(3 downto 0);
88
 
89
      -- SDRAM controller port
90
      rst          : out std_logic;
91
      rd           : out std_logic;
92
      wr           : out std_logic;
93
      earlyOpBegun : in  std_logic;
94
      opBegun      : in  std_logic;
95
      rdPending    : in  std_logic;
96
      done         : in  std_logic;
97
      rdDone       : in  std_logic;
98
      hAddr        : out std_logic_vector(HADDR_WIDTH-1 downto 0);
99
      hDIn         : out std_logic_vector(DATA_WIDTH-1 downto 0);
100
      hDOut        : in  std_logic_vector(DATA_WIDTH-1 downto 0);
101
      status       : in  std_logic_vector(3 downto 0)
102
      );
103
  end component;
104
 
105
end package sdram;
106
 
107
 
108
 
109
 
110
--------------------------------------------------------------------
111
-- Company : XESS Corp.
112
-- Engineer : Dave Vanden Bout
113
-- Creation Date : 05/17/2005
114
-- Copyright : 2005, XESS Corp
115
-- Tool Versions : WebPACK 6.3.03i
116
--
117
-- Description:
118
-- SDRAM controller
119
--
120
-- Revision:
121
-- 1.5.0
122
--
123
-- Additional Comments:
124
-- 1.5.0:
125
-- John Kent 2008-03-28
126
-- added upper and lower data strobes.
127
-- 1.4.0:
128
-- Added generic parameter to enable/disable independent active rows in each bank.
129
-- 1.3.0:
130
-- Modified to allow independently active rows in each bank.
131
-- 1.2.0:
132
-- Modified to allow pipelining of read/write operations.
133
-- 1.1.0:
134
-- Initial release.
135
-- 2.0.0 John Kent
136
-- removed uds, lds, dmqu, dmql for XuLA implementation
137
--
138
-- License:
139
-- This code can be freely distributed and modified as long as
140
-- this header is not removed.
141
--------------------------------------------------------------------
142
 
143
library IEEE, UNISIM;
144
use IEEE.std_logic_1164.all;
145
use IEEE.std_logic_unsigned.all;
146
use IEEE.numeric_std.all;
147
use WORK.common.all;
148
 
149
entity sdramCntl is
150
  generic(
151
    FREQ                 :     natural := 100_000;  -- operating frequency in KHz
152
    IN_PHASE             :     boolean := true;  -- SDRAM and controller work on same or opposite clock edge
153
    PIPE_EN              :     boolean := false;  -- if true, enable pipelined read operations
154
    MAX_NOP              :     natural := 10000;  -- number of NOPs before entering self-refresh
155
    MULTIPLE_ACTIVE_ROWS :     boolean := false;  -- if true, allow an active row in each bank
156
    DATA_WIDTH           :     natural := 16;  -- host & SDRAM data width
157
    NROWS                :     natural := 4096;  -- number of rows in SDRAM array
158
    NCOLS                :     natural := 512;  -- number of columns in SDRAM array
159
    HADDR_WIDTH          :     natural := 24;  -- host-side address width
160
    SADDR_WIDTH          :     natural := 13  -- SDRAM-side address width
161
    );
162
  port(
163
    -- host side
164
    clk                  : in  std_logic;  -- master clock
165
    lock                 : in  std_logic;  -- true if clock is stable
166
    rst                  : in  std_logic;  -- reset
167
    rd                   : in  std_logic;  -- initiate read operation
168
    wr                   : in  std_logic;  -- initiate write operation
169
    earlyOpBegun         : out std_logic;  -- read/write/self-refresh op has begun (async)
170
    opBegun              : out std_logic;  -- read/write/self-refresh op has begun (clocked)
171
    rdPending            : out std_logic;  -- true if read operation(s) are still in the pipeline
172
    done                 : out std_logic;  -- read or write operation is done
173
    rdDone               : out std_logic;  -- read operation is done and data is available
174
    hAddr                : in  std_logic_vector(HADDR_WIDTH-1 downto 0);  -- address from host to SDRAM
175
    hDIn                 : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from host       to SDRAM
176
    hDOut                : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from SDRAM to host
177
    status               : out std_logic_vector(3 downto 0);  -- diagnostic status of the FSM         
178
 
179
    -- SDRAM side
180
    cke     : out std_logic;            -- clock-enable to SDRAM
181
    ce_n    : out std_logic;            -- chip-select to SDRAM
182
    ras_n   : out std_logic;            -- SDRAM row address strobe
183
    cas_n   : out std_logic;            -- SDRAM column address strobe
184
    we_n    : out std_logic;            -- SDRAM write enable
185
    ba      : out std_logic_vector(1 downto 0);  -- SDRAM bank address
186
    sAddr   : out std_logic_vector(SADDR_WIDTH-1 downto 0);  -- SDRAM row/column address
187
    sDIn    : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from SDRAM
188
    sDOut   : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data to SDRAM
189
    sDOutEn : out std_logic             -- true if data is output to SDRAM on sDOut
190
    );
191
end sdramCntl;
192
 
193
 
194
 
195
architecture arch of sdramCntl is
196
 
197
  constant OUTPUT : std_logic := '1';   -- direction of dataflow w.r.t. this controller
198
  constant INPUT  : std_logic := '0';
199
  constant NOP    : std_logic := '0';   -- no operation
200
  constant READ   : std_logic := '1';   -- read operation
201
  constant WRITE  : std_logic := '1';   -- write operation
202
 
203
  -- SDRAM timing parameters
204
  constant Tinit : natural := 200;      -- min initialization interval (us)
205
  constant Tras  : natural := 45;       -- min interval between active to precharge commands (ns)
206
  constant Trcd  : natural := 20;       -- min interval between active and R/W commands (ns)
207
  constant Tref  : natural := 64_000_000;  -- maximum refresh interval (ns)
208
  constant Trfc  : natural := 66;       -- duration of refresh operation (ns)
209
  constant Trp   : natural := 20;       -- min precharge command duration (ns)
210
  constant Twr   : natural := 15;       -- write recovery time (ns)
211
  constant Txsr  : natural := 75;       -- exit self-refresh time (ns)
212
 
213
  -- SDRAM timing parameters converted into clock cycles (based on FREQ)
214
  constant NORM        : natural := 1_000_000;  -- normalize ns * KHz
215
  constant INIT_CYCLES : natural := 1+((Tinit*FREQ)/1000);  -- SDRAM power-on initialization interval
216
  constant RAS_CYCLES  : natural := 1+((Tras*FREQ)/NORM);  -- active-to-precharge interval
217
  constant RCD_CYCLES  : natural := 1+((Trcd*FREQ)/NORM);  -- active-to-R/W interval
218
  constant REF_CYCLES  : natural := 1+(((Tref/NROWS)*FREQ)/NORM);  -- interval between row refreshes
219
  constant RFC_CYCLES  : natural := 1+((Trfc*FREQ)/NORM);  -- refresh operation interval
220
  constant RP_CYCLES   : natural := 1+((Trp*FREQ)/NORM);  -- precharge operation interval
221
  constant WR_CYCLES   : natural := 1+((Twr*FREQ)/NORM);  -- write recovery time
222
  constant XSR_CYCLES  : natural := 1+((Txsr*FREQ)/NORM);  -- exit self-refresh time
223
  constant MODE_CYCLES : natural := 2;  -- mode register setup time
224
  constant CAS_CYCLES  : natural := 3;  -- CAS latency
225
  constant RFSH_OPS    : natural := 8;  -- number of refresh operations needed to init SDRAM
226
 
227
  -- timer registers that count down times for various SDRAM operations
228
  signal timer_r, timer_x       : natural range 0 to INIT_CYCLES;  -- current SDRAM op time
229
  signal rasTimer_r, rasTimer_x : natural range 0 to RAS_CYCLES;  -- active-to-precharge time
230
  signal wrTimer_r, wrTimer_x   : natural range 0 to WR_CYCLES;  -- write-to-precharge time
231
  signal refTimer_r, refTimer_x : natural range 0 to REF_CYCLES;  -- time between row refreshes
232
  signal rfshCntr_r, rfshCntr_x : natural range 0 to NROWS;  -- counts refreshes that are neede
233
  signal nopCntr_r, nopCntr_x   : natural range 0 to MAX_NOP;  -- counts consecutive NOP operations
234
 
235
  signal doSelfRfsh : std_logic;        -- active when the NOP counter hits zero and self-refresh can start
236
 
237
  -- states of the SDRAM controller state machine
238
  type cntlState is (
239
    INITWAIT,                           -- initialization - waiting for power-on initialization to complete
240
    INITPCHG,                           -- initialization - initial precharge of SDRAM banks
241
    INITSETMODE,                        -- initialization - set SDRAM mode
242
    INITRFSH,                           -- initialization - do initial refreshes
243
    RW,                                 -- read/write/refresh the SDRAM
244
    ACTIVATE,                           -- open a row of the SDRAM for reading/writing
245
    REFRESHROW,                         -- refresh a row of the SDRAM
246
    SELFREFRESH                         -- keep SDRAM in self-refresh mode with CKE low
247
    );
248
  signal state_r, state_x : cntlState;  -- state register and next state
249
 
250
  -- commands that are sent to the SDRAM to make it perform certain operations
251
  -- commands use these SDRAM input pins (ce_n,ras_n,cas_n,we_n)
252
--  subtype sdramCmd is unsigned(5 downto 0);
253
--  constant NOP_CMD    : sdramCmd := "011100";
254
--  constant ACTIVE_CMD : sdramCmd := "001100";
255
--  constant READ_CMD   : sdramCmd := "010100";
256
--  constant WRITE_CMD  : sdramCmd := "010000";
257
--  constant PCHG_CMD   : sdramCmd := "001011";
258
--  constant MODE_CMD   : sdramCmd := "000011";
259
--  constant RFSH_CMD   : sdramCmd := "000111";
260
 
261
  -- commands that are sent to the SDRAM to make it perform certain operations
262
  -- commands use these SDRAM input pins (ce_n,ras_n,cas_n,we_n)
263
  subtype sdramCmd is unsigned(3 downto 0);
264
  constant NOP_CMD    : sdramCmd := "0111";
265
  constant ACTIVE_CMD : sdramCmd := "0011";
266
  constant READ_CMD   : sdramCmd := "0101";
267
  constant WRITE_CMD  : sdramCmd := "0100";
268
  constant PCHG_CMD   : sdramCmd := "0010";
269
  constant MODE_CMD   : sdramCmd := "0000";
270
  constant RFSH_CMD   : sdramCmd := "0001";
271
 
272
  -- SDRAM mode register
273
  -- the SDRAM is placed in a non-burst mode (burst length = 1) with a 3-cycle CAS
274
  subtype sdramMode is std_logic_vector(12 downto 0);
275
  constant MODE : sdramMode := "000" & "0" & "00" & "011" & "0" & "000";
276
 
277
  -- the host address is decomposed into these sets of SDRAM address components
278
  constant ROW_LEN : natural := log2(NROWS);  -- number of row address bits
279
  constant COL_LEN : natural := log2(NCOLS);  -- number of column address bits
280
  signal   bank    : std_logic_vector(ba'range);  -- bank address bits
281
  signal   row     : std_logic_vector(ROW_LEN - 1 downto 0);  -- row address within bank
282
  signal   col     : std_logic_vector(sAddr'range);  -- column address within row
283
 
284
  -- registers that store the currently active row in each bank of the SDRAM
285
  constant NUM_ACTIVE_ROWS            : integer := int_select(MULTIPLE_ACTIVE_ROWS = false, 1, 2**ba'length);
286
  type activeRowType is array(0 to NUM_ACTIVE_ROWS-1) of std_logic_vector(row'range);
287
  signal   activeRow_r, activeRow_x   : activeRowType;
288
  signal   activeFlag_r, activeFlag_x : std_logic_vector(0 to NUM_ACTIVE_ROWS-1);  -- indicates that some row in a bank is active
289
  signal   bankIndex                  : natural range 0 to NUM_ACTIVE_ROWS-1;  -- bank address bits
290
  signal   activeBank_r, activeBank_x : std_logic_vector(ba'range);  -- indicates the bank with the active row
291
  signal   doActivate                 : std_logic;  -- indicates when a new row in a bank needs to be activated
292
 
293
  -- there is a command bit embedded within the SDRAM column address
294
  constant CMDBIT_POS    : natural   := 10;  -- position of command bit
295
  constant AUTO_PCHG_ON  : std_logic := '1';  -- CMDBIT value to auto-precharge the bank
296
  constant AUTO_PCHG_OFF : std_logic := '0';  -- CMDBIT value to disable auto-precharge
297
  constant ONE_BANK      : std_logic := '0';  -- CMDBIT value to select one bank
298
  constant ALL_BANKS     : std_logic := '1';  -- CMDBIT value to select all banks
299
 
300
  -- status signals that indicate when certain operations are in progress
301
  signal wrInProgress       : std_logic;  -- write operation in progress
302
  signal rdInProgress       : std_logic;  -- read operation in progress
303
  signal activateInProgress : std_logic;  -- row activation is in progress
304
 
305
  -- these registers track the progress of read and write operations
306
  signal rdPipeline_r, rdPipeline_x : std_logic_vector(CAS_CYCLES+1 downto 0);  -- pipeline of read ops in progress
307
  signal wrPipeline_r, wrPipeline_x : std_logic_vector(0 downto 0);  -- pipeline of write ops (only need 1 cycle)
308
 
309
  -- registered outputs to host
310
  signal opBegun_r, opBegun_x             : std_logic;  -- true when SDRAM read or write operation is started
311
  signal hDOut_r, hDOut_x                 : std_logic_vector(hDOut'range);  -- holds data read from SDRAM and sent to the host
312
  signal hDOutOppPhase_r, hDOutOppPhase_x : std_logic_vector(hDOut'range);  -- holds data read from SDRAM   on opposite clock edge
313
 
314
  -- registered outputs to SDRAM
315
  signal cke_r, cke_x           : std_logic;  -- clock enable 
316
  signal cmd_r, cmd_x           : sdramCmd;  -- SDRAM command bits
317
  signal ba_r, ba_x             : std_logic_vector(ba'range);  -- SDRAM bank address bits
318
  signal sAddr_r, sAddr_x       : std_logic_vector(sAddr'range);  -- SDRAM row/column address
319
  signal sData_r, sData_x       : std_logic_vector(sDOut'range);  -- SDRAM out databus
320
  signal sDataDir_r, sDataDir_x : std_logic;  -- SDRAM databus direction control bit
321
 
322
begin
323
 
324
  -----------------------------------------------------------
325
  -- attach some internal signals to the I/O ports 
326
  -----------------------------------------------------------
327
 
328
  -- attach registered SDRAM control signals to SDRAM input pins
329
  (ce_n, ras_n, cas_n, we_n) <= cmd_r;  -- SDRAM operation control bits
330
  cke                        <= cke_r;  -- SDRAM clock enable
331
  ba                         <= ba_r;  -- SDRAM bank address
332
  sAddr                      <= sAddr_r;  -- SDRAM address
333
  sDOut                      <= sData_r;  -- SDRAM output data bus
334
  sDOutEn                    <= YES when sDataDir_r = OUTPUT else NO;  -- output databus enable
335
 
336
  -- attach some port signals
337
  hDOut   <= hDOut_r;                   -- data back to host
338
  opBegun <= opBegun_r;                 -- true if requested operation has begun
339
 
340
 
341
  -----------------------------------------------------------
342
  -- compute the next state and outputs 
343
  -----------------------------------------------------------
344
 
345
  combinatorial : process(rd, wr, hAddr, hDIn, hDOut_r, sDIn, state_r, opBegun_x,
346
                          activeFlag_r, activeRow_r, rdPipeline_r, wrPipeline_r,
347
                          hDOutOppPhase_r, nopCntr_r, lock, rfshCntr_r, timer_r, rasTimer_r,
348
                          wrTimer_r, refTimer_r, cmd_r, cke_r, activeBank_r, ba_r )
349
  begin
350
 
351
    -----------------------------------------------------------
352
    -- setup default values for signals 
353
    -----------------------------------------------------------
354
 
355
    opBegun_x    <= NO;                 -- no operations have begun
356
    earlyOpBegun <= opBegun_x;
357
    cke_x        <= YES;                -- enable SDRAM clock
358
    cmd_x        <= NOP_CMD;            -- set SDRAM command to no-operation
359
    sDataDir_x   <= INPUT;              -- accept data from the SDRAM
360
    sData_x      <= hDIn(sData_x'range);  -- output data from host to SDRAM
361
    state_x      <= state_r;            -- reload these registers and flags
362
    activeFlag_x <= activeFlag_r;       --              with their existing values
363
    activeRow_x  <= activeRow_r;
364
    activeBank_x <= activeBank_r;
365
    rfshCntr_x   <= rfshCntr_r;
366
 
367
    -----------------------------------------------------------
368
    -- setup default value for the SDRAM address 
369
    -----------------------------------------------------------
370
 
371
    -- extract bank field from host address
372
    ba_x                    <= hAddr(ba'length + ROW_LEN + COL_LEN - 1 downto ROW_LEN + COL_LEN);
373
    if MULTIPLE_ACTIVE_ROWS = true then
374
      bank                  <= (others => '0');
375
      bankIndex             <= CONV_INTEGER(ba_x);
376
    else
377
      bank                  <= ba_x;
378
      bankIndex             <= 0;
379
    end if;
380
    -- extract row, column fields from host address
381
    row                     <= hAddr(ROW_LEN + COL_LEN - 1 downto COL_LEN);
382
    -- extend column (if needed) until it is as large as the (SDRAM address bus - 1)
383
    col                     <= (others => '0');  -- set it to all zeroes
384
    col(COL_LEN-1 downto 0) <= hAddr(COL_LEN-1 downto 0);
385
    -- by default, set SDRAM address to the column address with interspersed
386
    -- command bit set to disable auto-precharge
387
    sAddr_x                 <= col(col'high downto CMDBIT_POS+1) & AUTO_PCHG_OFF
388
                               & col(CMDBIT_POS-1 downto 0);
389
 
390
    -----------------------------------------------------------
391
    -- manage the read and write operation pipelines
392
    -----------------------------------------------------------
393
 
394
    -- determine if read operations are in progress by the presence of
395
    -- READ flags in the read pipeline 
396
    if rdPipeline_r(rdPipeline_r'high downto 1) /= 0 then
397
      rdInProgress <= YES;
398
    else
399
      rdInProgress <= NO;
400
    end if;
401
    rdPending      <= rdInProgress;     -- tell the host if read operations are in progress
402
 
403
    -- enter NOPs into the read and write pipeline shift registers by default
404
    rdPipeline_x    <= NOP & rdPipeline_r(rdPipeline_r'high downto 1);
405
    wrPipeline_x(0) <= NOP;
406
 
407
    -- transfer data from SDRAM to the host data register if a read flag has exited the pipeline
408
    -- (the transfer occurs 1 cycle before we tell the host the read operation is done)
409
    if rdPipeline_r(1) = READ then
410
      hDOutOppPhase_x <= sDIn(hDOut'range);  -- gets value on the SDRAM databus on the opposite phase
411
      if IN_PHASE then
412
        -- get the SDRAM data for the host directly from the SDRAM if the controller and SDRAM are in-phase
413
        hDOut_x       <= sDIn(hDOut'range);
414
      else
415
        -- otherwise get the SDRAM data that was gathered on the previous opposite clock edge
416
        hDOut_x       <= hDOutOppPhase_r(hDOut'range);
417
      end if;
418
    else
419
      -- retain contents of host data registers if no data from the SDRAM has arrived yet
420
      hDOutOppPhase_x <= hDOutOppPhase_r;
421
      hDOut_x         <= hDOut_r;
422
    end if;
423
 
424
    done   <= rdPipeline_r(0) or wrPipeline_r(0);  -- a read or write operation is done
425
    rdDone <= rdPipeline_r(0);          -- SDRAM data available when a READ flag exits the pipeline 
426
 
427
    -----------------------------------------------------------
428
    -- manage row activation
429
    -----------------------------------------------------------
430
 
431
    -- request a row activation operation if the row of the current address
432
    -- does not match the currently active row in the bank, or if no row
433
    -- in the bank is currently active
434
    if (bank /= activeBank_r) or (row /= activeRow_r(bankIndex)) or (activeFlag_r(bankIndex) = NO) then
435
      doActivate <= YES;
436
    else
437
      doActivate <= NO;
438
    end if;
439
 
440
    -----------------------------------------------------------
441
    -- manage self-refresh
442
    -----------------------------------------------------------
443
 
444
    -- enter self-refresh if neither a read or write is requested for MAX_NOP consecutive cycles.
445
    if (rd = YES) or (wr = YES) then
446
      -- any read or write resets NOP counter and exits self-refresh state
447
      nopCntr_x  <= 0;
448
      doSelfRfsh <= NO;
449
    elsif nopCntr_r /= MAX_NOP then
450
      -- increment NOP counter whenever there is no read or write operation 
451
      nopCntr_x  <= nopCntr_r + 1;
452
      doSelfRfsh <= NO;
453
    else
454
      -- start self-refresh when counter hits maximum NOP count and leave counter unchanged
455
      nopCntr_x  <= nopCntr_r;
456
      doSelfRfsh <= YES;
457
    end if;
458
 
459
    -----------------------------------------------------------
460
    -- update the timers 
461
    -----------------------------------------------------------
462
 
463
    -- row activation timer
464
    if rasTimer_r /= 0 then
465
      -- decrement a non-zero timer and set the flag
466
      -- to indicate the row activation is still inprogress
467
      rasTimer_x         <= rasTimer_r - 1;
468
      activateInProgress <= YES;
469
    else
470
      -- on timeout, keep the timer at zero     and reset the flag
471
      -- to indicate the row activation operation is done
472
      rasTimer_x         <= rasTimer_r;
473
      activateInProgress <= NO;
474
    end if;
475
 
476
    -- write operation timer            
477
    if wrTimer_r /= 0 then
478
      -- decrement a non-zero timer and set the flag
479
      -- to indicate the write operation is still inprogress
480
      wrTimer_x    <= wrTimer_r - 1;
481
      wrInPRogress <= YES;
482
    else
483
      -- on timeout, keep the timer at zero and reset the flag that
484
      -- indicates a write operation is in progress
485
      wrTimer_x    <= wrTimer_r;
486
      wrInPRogress <= NO;
487
    end if;
488
 
489
    -- refresh timer            
490
    if refTimer_r /= 0 then
491
      refTimer_x <= refTimer_r - 1;
492
    else
493
      -- on timeout, reload the timer with the interval between row refreshes
494
      -- and increment the counter for the number of row refreshes that are needed
495
      refTimer_x <= REF_CYCLES;
496
      rfshCntr_x <= rfshCntr_r + 1;
497
    end if;
498
 
499
    -- main timer for sequencing SDRAM operations               
500
    if timer_r /= 0 then
501
      -- decrement the timer and do nothing else since the previous operation has not completed yet.
502
      timer_x <= timer_r - 1;
503
      status  <= "0000";
504
    else
505
      -- the previous operation has completed once the timer hits zero
506
      timer_x <= timer_r;               -- by default, leave the timer at zero
507
 
508
      -----------------------------------------------------------
509
      -- compute the next state and outputs 
510
      -----------------------------------------------------------
511
      case state_r is
512
 
513
        -----------------------------------------------------------
514
        -- let clock stabilize and then wait for the SDRAM to initialize 
515
        -----------------------------------------------------------
516
        when INITWAIT =>
517
          if lock = YES then
518
                                        -- wait for SDRAM power-on initialization once the clock is stable
519
            timer_x <= INIT_CYCLES;     -- set timer for initialization duration
520
            state_x <= INITPCHG;
521
          else
522
                                        -- disable SDRAM clock and return to this state if the clock is not stable
523
                                        -- this insures the clock is stable before enabling the SDRAM
524
                                        -- it also insures a clean startup if the SDRAM is currently in self-refresh mode
525
            cke_x   <= NO;
526
          end if;
527
          status    <= "0001";
528
 
529
          -----------------------------------------------------------
530
          -- precharge all SDRAM banks after power-on initialization 
531
          -----------------------------------------------------------
532
        when INITPCHG =>
533
          cmd_x               <= PCHG_CMD;
534
          sAddr_x(CMDBIT_POS) <= ALL_BANKS;  -- precharge all banks
535
          timer_x             <= RP_CYCLES;  -- set timer for precharge operation duration
536
          rfshCntr_x          <= RFSH_OPS;  -- set counter for refresh ops needed after precharge
537
          state_x             <= INITRFSH;
538
          status              <= "0010";
539
 
540
          -----------------------------------------------------------
541
          -- refresh the SDRAM a number of times after initial precharge 
542
          -----------------------------------------------------------
543
        when INITRFSH =>
544
          cmd_x      <= RFSH_CMD;
545
          timer_x    <= RFC_CYCLES;     -- set timer to refresh operation duration
546
          rfshCntr_x <= rfshCntr_r - 1;  -- decrement refresh operation counter
547
          if rfshCntr_r = 1 then
548
            state_x  <= INITSETMODE;    -- set the SDRAM mode once all refresh ops are done
549
          end if;
550
          status     <= "0011";
551
 
552
          -----------------------------------------------------------
553
          -- set the mode register of the SDRAM 
554
          -----------------------------------------------------------
555
        when INITSETMODE =>
556
          cmd_x   <= MODE_CMD;
557
          sAddr_x <= MODE;              -- output mode register bits on the SDRAM address bits
558
          timer_x <= MODE_CYCLES;       -- set timer for mode setting operation duration
559
          state_x <= RW;
560
          status  <= "0100";
561
 
562
          -----------------------------------------------------------
563
          -- process read/write/refresh operations after initialization is done 
564
          -----------------------------------------------------------
565
        when RW                                      =>
566
          -----------------------------------------------------------
567
          -- highest priority operation: row refresh 
568
          -- do a refresh operation if the refresh counter is non-zero
569
          -----------------------------------------------------------
570
          if rfshCntr_r /= 0 then
571
                                        -- wait for any row activations, writes or reads to finish before doing a precharge
572
            if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
573
              cmd_x                       <= PCHG_CMD;  -- initiate precharge of the SDRAM
574
              sAddr_x(CMDBIT_POS)         <= ALL_BANKS;  -- precharge all banks
575
              timer_x                     <= RP_CYCLES;  -- set timer for this operation
576
              activeFlag_x                <= (others => NO);  -- all rows are inactive after a precharge operation
577
              state_x                     <= REFRESHROW;  -- refresh the SDRAM after the precharge
578
            end if;
579
            status                        <= "0101";
580
            -----------------------------------------------------------
581
            -- do a host-initiated read operation 
582
            -----------------------------------------------------------
583
          elsif rd = YES then
584
                                          -- Wait one clock cycle if the bank address has just changed and each bank has its own active row.
585
            -- This gives extra time for the row activation circuitry.
586
            if (ba_x = ba_r) or (MULTIPLE_ACTIVE_ROWS=false) then
587
                                        -- activate a new row if the current read is outside the active row or bank
588
              if doActivate = YES then
589
                                        -- activate new row only if all previous activations, writes, reads are done
590
                if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
591
                  cmd_x                   <= PCHG_CMD;  -- initiate precharge of the SDRAM
592
                  sAddr_x(CMDBIT_POS)     <= ONE_BANK;  -- precharge this bank
593
                  timer_x                 <= RP_CYCLES;  -- set timer for this operation
594
                  activeFlag_x(bankIndex) <= NO;  -- rows in this bank are inactive after a precharge operation
595
                  state_x                 <= ACTIVATE;  -- activate the new row after the precharge is done
596
                end if;
597
                                        -- read from the currently active row if no previous read operation
598
                                        -- is in progress or if pipeline reads are enabled
599
                                        -- we can always initiate a read even if a write is already in progress
600
              elsif (rdInProgress = NO) or PIPE_EN then
601
                cmd_x                     <= READ_CMD;  -- initiate a read of the SDRAM
602
                                        -- insert a flag into the pipeline shift register that will exit the end
603
                                        -- of the shift register when the data from the SDRAM is available
604
                rdPipeline_x              <= READ & rdPipeline_r(rdPipeline_r'high downto 1);
605
                opBegun_x                 <= YES;  -- tell the host the requested operation has begun
606
              end if;
607
            end if;
608
            status                        <= "0110";
609
            -----------------------------------------------------------
610
            -- do a host-initiated write operation 
611
            -----------------------------------------------------------
612
          elsif wr = YES then
613
                                          -- Wait one clock cycle if the bank address has just changed and each bank has its own active row.
614
            -- This gives extra time for the row activation circuitry.
615
            if (ba_x = ba_r) or (MULTIPLE_ACTIVE_ROWS=false) then
616
                                        -- activate a new row if the current write is outside the active row or bank
617
              if doActivate = YES then
618
                                        -- activate new row only if all previous activations, writes, reads are done
619
                if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
620
                  cmd_x                   <= PCHG_CMD;  -- initiate precharge of the SDRAM
621
                  sAddr_x(CMDBIT_POS)     <= ONE_BANK;  -- precharge this bank
622
                  timer_x                 <= RP_CYCLES;  -- set timer for this operation
623
                  activeFlag_x(bankIndex) <= NO;  -- rows in this bank are inactive after a precharge operation
624
                  state_x                 <= ACTIVATE;  -- activate the new row after the precharge is done
625
                end if;
626
                                        -- write to the currently active row if no previous read operations are in progress
627
              elsif rdInProgress = NO then
628
                cmd_x                     <= WRITE_CMD;  -- initiate the write operation
629
                sDataDir_x                <= OUTPUT;  -- turn on drivers to send data to SDRAM
630
                                        -- set timer so precharge doesn't occur too soon after write operation
631
                wrTimer_x                 <= WR_CYCLES;
632
                                        -- insert a flag into the 1-bit pipeline shift register that will exit on the
633
                                        -- next cycle.  The write into SDRAM is not actually done by that time, but
634
                                        -- this doesn't matter to the host
635
                wrPipeline_x(0)           <= WRITE;
636
                opBegun_x                 <= YES;  -- tell the host the requested operation has begun
637
              end if;
638
            end if;
639
            status                        <= "0111";
640
            -----------------------------------------------------------
641
            -- do a host-initiated self-refresh operation 
642
            -----------------------------------------------------------
643
          elsif doSelfRfsh = YES then
644
                                        -- wait until all previous activations, writes, reads are done
645
            if (activateInProgress = NO) and (wrInProgress = NO) and (rdInProgress = NO) then
646
              cmd_x                       <= PCHG_CMD;  -- initiate precharge of the SDRAM
647
              sAddr_x(CMDBIT_POS)         <= ALL_BANKS;  -- precharge all banks
648
              timer_x                     <= RP_CYCLES;  -- set timer for this operation
649
              activeFlag_x                <= (others => NO);  -- all rows are inactive after a precharge operation
650
              state_x                     <= SELFREFRESH;  -- self-refresh the SDRAM after the precharge
651
            end if;
652
            status                        <= "1000";
653
            -----------------------------------------------------------
654
            -- no operation
655
            -----------------------------------------------------------
656
          else
657
            state_x                       <= RW;  -- continue to look for SDRAM operations to execute
658
            status                        <= "1001";
659
          end if;
660
 
661
          -----------------------------------------------------------
662
          -- activate a row of the SDRAM 
663
          -----------------------------------------------------------
664
        when ACTIVATE                        =>
665
          cmd_x                   <= ACTIVE_CMD;
666
          sAddr_x                 <= (others => '0');  -- output the address for the row to be activated
667
          sAddr_x(row'range)      <= row;
668
          activeBank_x            <= bank;
669
          activeRow_x(bankIndex)  <= row;  -- store the new active SDRAM row address
670
          activeFlag_x(bankIndex) <= YES;  -- the SDRAM is now active
671
          rasTimer_x              <= RAS_CYCLES;  -- minimum time before another precharge can occur 
672
          timer_x                 <= RCD_CYCLES;  -- minimum time before a read/write operation can occur
673
          state_x                 <= RW;  -- return to do read/write operation that initiated this activation
674
          status                  <= "1010";
675
 
676
          -----------------------------------------------------------
677
          -- refresh a row of the SDRAM         
678
          -----------------------------------------------------------
679
        when REFRESHROW =>
680
          cmd_x      <= RFSH_CMD;
681
          timer_x    <= RFC_CYCLES;     -- refresh operation interval
682
          rfshCntr_x <= rfshCntr_r - 1;  -- decrement the number of needed row refreshes
683
          state_x    <= RW;             -- process more SDRAM operations after refresh is done
684
          status     <= "1011";
685
 
686
          -----------------------------------------------------------
687
          -- place the SDRAM into self-refresh and keep it there until further notice           
688
          -----------------------------------------------------------
689
        when SELFREFRESH            =>
690
          if (doSelfRfsh = YES) or (lock = NO) then
691
                                        -- keep the SDRAM in self-refresh mode as long as requested and until there is a stable clock
692
            cmd_x        <= RFSH_CMD;   -- output the refresh command; this is only needed on the first clock cycle
693
            cke_x        <= NO;         -- disable the SDRAM clock
694
          else
695
                                        -- else exit self-refresh mode and start processing read and write operations
696
            cke_x        <= YES;        -- restart the SDRAM clock
697
            rfshCntr_x   <= 0;          -- no refreshes are needed immediately after leaving self-refresh
698
            activeFlag_x <= (others => NO);  -- self-refresh deactivates all rows
699
            timer_x      <= XSR_CYCLES;  -- wait this long until read and write operations can resume
700
            state_x      <= RW;
701
          end if;
702
          status         <= "1100";
703
 
704
          -----------------------------------------------------------
705
          -- unknown state
706
          -----------------------------------------------------------
707
        when others =>
708
          state_x <= INITWAIT;          -- reset state if in erroneous state
709
          status  <= "1101";
710
 
711
      end case;
712
    end if;
713
  end process combinatorial;
714
 
715
 
716
  -----------------------------------------------------------
717
  -- update registers on the appropriate clock edge     
718
  -----------------------------------------------------------
719
 
720
  update : process(rst, clk)
721
  begin
722
 
723
    if rst = YES then
724
      -- asynchronous reset
725
      state_r      <= INITWAIT;
726
      activeFlag_r <= (others => NO);
727
      rfshCntr_r   <= 0;
728
      timer_r      <= 0;
729
      refTimer_r   <= REF_CYCLES;
730
      rasTimer_r   <= 0;
731
      wrTimer_r    <= 0;
732
      nopCntr_r    <= 0;
733
      opBegun_r    <= NO;
734
      rdPipeline_r <= (others => '0');
735
      wrPipeline_r <= (others => '0');
736
      cke_r        <= NO;
737
      cmd_r        <= NOP_CMD;
738
      ba_r         <= (others => '0');
739
      sAddr_r      <= (others => '0');
740
      sData_r      <= (others => '0');
741
      sDataDir_r   <= INPUT;
742
      hDOut_r      <= (others => '0');
743
    elsif rising_edge(clk) then
744
      state_r      <= state_x;
745
      activeBank_r <= activeBank_x;
746
      activeRow_r  <= activeRow_x;
747
      activeFlag_r <= activeFlag_x;
748
      rfshCntr_r   <= rfshCntr_x;
749
      timer_r      <= timer_x;
750
      refTimer_r   <= refTimer_x;
751
      rasTimer_r   <= rasTimer_x;
752
      wrTimer_r    <= wrTimer_x;
753
      nopCntr_r    <= nopCntr_x;
754
      opBegun_r    <= opBegun_x;
755
      rdPipeline_r <= rdPipeline_x;
756
      wrPipeline_r <= wrPipeline_x;
757
      cke_r        <= cke_x;
758
      cmd_r        <= cmd_x;
759
      ba_r         <= ba_x;
760
      sAddr_r      <= sAddr_x;
761
      sData_r      <= sData_x;
762
      sDataDir_r   <= sDataDir_x;
763
      hDOut_r      <= hDOut_x;
764
    end if;
765
 
766
    -- the register that gets data from the SDRAM and holds it for the host
767
    -- is clocked on the opposite edge.  We don't use this register if IN_PHASE=TRUE.
768
    if rst = YES then
769
      hDOutOppPhase_r <= (others => '0');
770
    elsif falling_edge(clk) then
771
      hDOutOppPhase_r <= hDOutOppPhase_x;
772
    end if;
773
 
774
  end process update;
775
 
776
end arch;
777
 
778
 
779
 
780
 
781
--------------------------------------------------------------------
782
-- Company : XESS Corp.
783
-- Engineer : Dave Vanden Bout
784
-- Creation Date : 06/01/2005
785
-- Copyright : 2005, XESS Corp
786
-- Tool Versions : WebPACK 6.3.03i
787
--
788
-- Description:
789
-- Dual-port front-end for SDRAM controller. Supports two
790
-- independent I/O ports to the SDRAM.
791
--
792
-- Revision:
793
-- 1.2.0:
794
--     added upper and lower data strobe
795
--     John Kent - 2008-03-23
796
--
797
-- 1.0.0
798
--     Dave Vanden Bout - 2005-01-06
799
--
800
-- Additional Comments:
801
--
802
-- License:
803
-- This code can be freely distributed and modified as long as
804
-- this header is not removed.
805
--------------------------------------------------------------------
806
 
807
library IEEE, UNISIM;
808
use IEEE.std_logic_1164.all;
809
use IEEE.std_logic_unsigned.all;
810
use IEEE.numeric_std.all;
811
use WORK.common.all;
812
 
813
entity dualport is
814
  generic(
815
    PIPE_EN         :    boolean                       := false;  -- enable pipelined read operations
816
    PORT_TIME_SLOTS :    std_logic_vector(15 downto 0) := "1111000011110000";
817
    DATA_WIDTH      :    natural                       := 16;  -- host & SDRAM data width
818
    HADDR_WIDTH     :    natural                       := 23  -- host-side address width
819
    );
820
  port(
821
    clk             : in std_logic;     -- master clock
822
 
823
    -- host-side port 0
824
    rst0          : in  std_logic;      -- reset
825
    rd0           : in  std_logic;      -- initiate read operation
826
    wr0           : in  std_logic;      -- initiate write operation
827
    earlyOpBegun0 : out std_logic;      -- read/write op has begun (async)
828
    opBegun0      : out std_logic;      -- read/write op has begun (clocked)
829
    rdPending0    : out std_logic;      -- true if read operation(s) are still in the pipeline
830
    done0         : out std_logic;      -- read or write operation is done
831
    rdDone0       : out std_logic;      -- read operation is done and data is available
832
    hAddr0        : in  std_logic_vector(HADDR_WIDTH-1 downto 0);  -- address from host to SDRAM
833
    hDIn0         : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from host to SDRAM
834
    hDOut0        : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from SDRAM to host
835
    status0       : out std_logic_vector(3 downto 0);  -- diagnostic status of the SDRAM controller FSM         
836
 
837
    -- host-side port 1
838
    rst1          : in  std_logic;
839
    rd1           : in  std_logic;
840
    wr1           : in  std_logic;
841
    earlyOpBegun1 : out std_logic;
842
    opBegun1      : out std_logic;
843
    rdPending1    : out std_logic;
844
    done1         : out std_logic;
845
    rdDone1       : out std_logic;
846
    hAddr1        : in  std_logic_vector(HADDR_WIDTH-1 downto 0);
847
    hDIn1         : in  std_logic_vector(DATA_WIDTH-1 downto 0);
848
    hDOut1        : out std_logic_vector(DATA_WIDTH-1 downto 0);
849
    status1       : out std_logic_vector(3 downto 0);
850
 
851
    -- SDRAM controller port
852
    rst          : out std_logic;
853
    rd           : out std_logic;
854
    wr           : out std_logic;
855
    earlyOpBegun : in  std_logic;
856
    opBegun      : in  std_logic;
857
    rdPending    : in  std_logic;
858
    done         : in  std_logic;
859
    rdDone       : in  std_logic;
860
    hAddr        : out std_logic_vector(HADDR_WIDTH-1 downto 0);
861
    hDIn         : out std_logic_vector(DATA_WIDTH-1 downto 0);
862
    hDOut        : in  std_logic_vector(DATA_WIDTH-1 downto 0);
863
    status       : in  std_logic_vector(3 downto 0)
864
    );
865
end dualport;
866
 

powered by: WebSVN 2.1.0

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