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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [fpga/] [experiments/] [memspeed-2/] [src/] [ramctrl.v] - Blame information for rev 325

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 325 hellwig
//
2
// ramctrl.v -- RAM controller
3
//
4
 
5
 
6
`timescale 1ns/10ps
7
`default_nettype none
8
 
9
 
10
`define MODE            13'h0032        // CL = 3, sequ. burst length = 4
11
 
12
`define CMD_MRSET       3'b000          // mode register set
13
`define CMD_ARFRS       3'b001          // auto refresh
14
`define CMD_PRCHG       3'b010          // precharge (deactivate row/rows)
15
`define CMD_ACTV        3'b011          // select bank, activate row
16
`define CMD_WRITE       3'b100          // select bank & column, start write
17
`define CMD_READ        3'b101          // select bank & column, start read
18
`define CMD_BSTOP       3'b110          // burst stop
19
`define CMD_NOP         3'b111          // no operation
20
 
21
//
22
// Note: The FSM is a registered Mealy machine. Its actions, which
23
//       are noted here for a specific state, take place in the next
24
//       clock cycle. This is only a notational problem: the actions
25
//       should in fact be associated with state transitions.
26
//
27
// ST_RESET                             // NOP, CKE=0, CS_N=1, wait 100 us
28
`define ST_INIT0        5'd0            // NOP, CKE=1, CS_N=0, wait 100 us
29
`define ST_INIT1        5'd1            // PRECHARGE ALL
30
`define ST_INIT2        5'd2            // NOP, wait tRP - 1 cycle
31
`define ST_INIT3        5'd3            // AUTO REFRESH
32
`define ST_INIT4        5'd4            // NOP, wait tRFC - 1 cycle
33
`define ST_INIT5        5'd5            // AUTO REFRESH
34
`define ST_INIT6        5'd6            // NOP, wait tRFC - 1 cycle
35
`define ST_INIT7        5'd7            // MODE REGISTER SET
36
`define ST_INIT8        5'd8            // NOP, wait tMRD - 1 cycle
37
`define ST_IDLE         5'd9            // AUTO REFRESH, ACTIVE, or NOP
38
`define ST_RFRSH        5'd10           // NOP, wait tRFC - 1 cycle
39
`define ST_WRDATA0      5'd11           // NOP, wait tRCD - 1 cycle
40
`define ST_WRDATA1      5'd12           // WRITE, de=1
41
`define ST_WRDATA2      5'd13           // NOP, wait 3 cycles
42
`define ST_WRDATA3      5'd14           // NOP, ack=1, de=0
43
`define ST_WRDATA4      5'd15           // NOP, ack=0, wait 3 cycles
44
`define ST_RDDATA0      5'd16           // NOP, wait tRCD - 1 cycle
45
`define ST_RDDATA1      5'd17           // READ
46
`define ST_RDDATA2      5'd18           // NOP, wait 2 cycles
47
`define ST_RDDATA3      5'd19           // NOP, ld=1, wait 4 cycles
48
`define ST_RDDATA4      5'd20           // NOP, ack=1, ld=0
49
`define ST_RDDATA5      5'd21           // NOP, ack=0, wait 4 cycles
50
`define ST_RDINST0      5'd22           // NOP, wait tRCD - 1 cycle
51
`define ST_RDINST1      5'd23           // READ
52
`define ST_RDINST2      5'd24           // NOP, wait 2 cycles
53
`define ST_RDINST3      5'd25           // NOP, ld=1, wait 4 cycles
54
`define ST_RDINST4      5'd26           // NOP, ack=1, ld=0
55
`define ST_RDINST5      5'd27           // NOP, ack=0, wait 4 cycles
56
`define ST_ILLDA0       5'd28           // NOP, data_timeout=1
57
`define ST_ILLDA1       5'd29           // NOP, data_timeout=0
58
`define ST_ILLIA0       5'd30           // NOP, inst_timeout=1
59
`define ST_ILLIA1       5'd31           // NOP, inst_timeout=0
60
 
61
`define T_INIT0         14'd10000       // min 100 usec with CKE = 0
62
`define T_INIT1         14'd10000       // min 100 usec with CKE = 1
63
`define T_RP            14'd3           // min 20 ns row precharge time
64
`define T_RFC           14'd9           // min 66 ns auto refresh period
65
`define T_MRD           14'd3           // min load mode register delay
66
`define T_RCD           14'd3           // min 20 ns active-to-rw delay
67
 
68
`define REFCNT          10'd780          // 8192 refresh cycles per 64 ms
69
 
70
 
71
module ramctrl(clk_ok, clk,
72
               inst_stb, inst_addr,
73
               inst_dout, inst_ack,
74
               inst_timeout,
75
               data_stb, data_we,
76
               data_addr, data_din,
77
               data_dout, data_ack,
78
               data_timeout,
79
               sdram_cke, sdram_cs_n,
80
               sdram_ras_n, sdram_cas_n,
81
               sdram_we_n, sdram_ba, sdram_a,
82
               sdram_udqm, sdram_ldqm, sdram_dq);
83
    // internal interface signals
84
    input clk_ok;
85
    input clk;
86
    input inst_stb;
87
    input [25:0] inst_addr;
88
    output [63:0] inst_dout;
89
    output reg inst_ack;
90
    output reg inst_timeout;
91
    input data_stb;
92
    input data_we;
93
    input [25:0] data_addr;
94
    input [63:0] data_din;
95
    output [63:0] data_dout;
96
    output reg data_ack;
97
    output reg data_timeout;
98
    // external interface signals
99
    output reg sdram_cke;
100
    output reg sdram_cs_n;
101
    output sdram_ras_n;
102
    output sdram_cas_n;
103
    output sdram_we_n;
104
    output reg [1:0] sdram_ba;
105
    output reg [12:0] sdram_a;
106
    output sdram_udqm;
107
    output sdram_ldqm;
108
    inout [15:0] sdram_dq;
109
 
110
  reg [1:0] ram_cnt;
111
  wire [15:0] ram_dout;
112
  reg ram_de;
113
  reg [63:0] data;
114
  reg data_ld;
115
 
116
  wire inst_addr_out_of_range;
117
  wire data_addr_out_of_range;
118
 
119
  reg [2:0] ram_cmd;
120
  reg [1:0] ram_dqm;
121
  reg [13:0] count;
122
  reg [4:0] state;
123
 
124
  reg [9:0] refcnt;
125
  reg refflg;
126
  reg refrst;
127
 
128
  //
129
  // data output to ram
130
  //
131
 
132
  assign ram_dout[15:0] =
133
    ~ram_cnt[1] ? (~ram_cnt[0] ? data_din[63:48] : data_din[47:32]) :
134
                  (~ram_cnt[0] ? data_din[31:16] : data_din[15: 0]);
135
  assign sdram_dq[15:0] = ram_de ? ram_dout[15:0] : 16'hzzzz;
136
 
137
  //
138
  // data output to cache
139
  //
140
 
141
  always @(posedge clk) begin
142
    if (data_ld & (ram_cnt[1:0] == 2'b00)) begin
143
      data[63:48] <= sdram_dq[15:0];
144
    end
145
    if (data_ld & (ram_cnt[1:0] == 2'b01)) begin
146
      data[47:32] <= sdram_dq[15:0];
147
    end
148
    if (data_ld & (ram_cnt[1:0] == 2'b10)) begin
149
      data[31:16] <= sdram_dq[15:0];
150
    end
151
    if (data_ld & (ram_cnt[1:0] == 2'b11)) begin
152
      data[15: 0] <= sdram_dq[15:0];
153
    end
154
  end
155
 
156
  assign inst_dout[63:0] = data[63:0];
157
  assign data_dout[63:0] = data[63:0];
158
 
159
  //
160
  // address range check
161
  //
162
 
163
  assign inst_addr_out_of_range = | inst_addr[25:22];
164
  assign data_addr_out_of_range = | data_addr[25:22];
165
 
166
  //
167
  // ramctrl state machine
168
  //
169
 
170
  assign sdram_ras_n = ram_cmd[2];
171
  assign sdram_cas_n = ram_cmd[1];
172
  assign sdram_we_n = ram_cmd[0];
173
 
174
  assign sdram_udqm = ram_dqm[1];
175
  assign sdram_ldqm = ram_dqm[0];
176
 
177
  always @(posedge clk or negedge clk_ok) begin
178
    // asynchronous reset
179
    if (~clk_ok) begin
180
      inst_ack <= 0;
181
      inst_timeout <= 0;
182
      data_ack <= 0;
183
      data_timeout <= 0;
184
      sdram_cke <= 0;
185
      sdram_cs_n <= 1;
186
      ram_cnt <= 0;
187
      ram_de <= 0;
188
      data_ld <= 0;
189
      ram_cmd <= `CMD_NOP;
190
      ram_dqm <= 2'b11;
191
      count <= `T_INIT0 - 1;
192
      state <= `ST_INIT0;
193
      refrst <= 0;
194
    end else begin
195
      if (|count[13:0]) begin
196
        // wait until count = 0
197
        // if count is loaded with N on a state transition, the
198
        // new state will last for (N+1)/fclk cycles before (!)
199
        // any action specified in the new state will take place
200
        count <= count - 1;
201
        // ram_cnt cycles through the 16-bit half-words in SDRAM
202
        // during burst read/writes while the main state machine
203
        // waits, thus it must be incremented here
204
        ram_cnt <= ram_cnt + 1;
205
      end else begin
206
        case (state)
207
          //----------------------------
208
          // init
209
          //----------------------------
210
          `ST_INIT0:
211
            begin
212
              sdram_cke <= 1;
213
              sdram_cs_n <= 0;
214
              ram_cmd <= `CMD_NOP;
215
              count <= `T_INIT1 - 1;
216
              state <= `ST_INIT1;
217
            end
218
          `ST_INIT1:
219
            begin
220
              ram_cmd <= `CMD_PRCHG;
221
              sdram_ba <= 2'b00;        // don't care
222
              sdram_a <= 13'h0400;      // precharge all
223
              state <= `ST_INIT2;
224
            end
225
          `ST_INIT2:
226
            begin
227
              ram_cmd <= `CMD_NOP;
228
              count <= `T_RP - 2;
229
              state <= `ST_INIT3;
230
            end
231
          `ST_INIT3:
232
            begin
233
              ram_cmd <= `CMD_ARFRS;
234
              state <= `ST_INIT4;
235
            end
236
          `ST_INIT4:
237
            begin
238
              ram_cmd <= `CMD_NOP;
239
              count <= `T_RFC - 2;
240
              state <= `ST_INIT5;
241
            end
242
          `ST_INIT5:
243
            begin
244
              ram_cmd <= `CMD_ARFRS;
245
              state <= `ST_INIT6;
246
            end
247
          `ST_INIT6:
248
            begin
249
              ram_cmd <= `CMD_NOP;
250
              count <= `T_RFC - 2;
251
              state <= `ST_INIT7;
252
            end
253
          `ST_INIT7:
254
            begin
255
              ram_cmd <= `CMD_MRSET;
256
              sdram_ba <= 2'b00;
257
              sdram_a <= `MODE;
258
              state <= `ST_INIT8;
259
            end
260
          `ST_INIT8:
261
            begin
262
              ram_cmd <= `CMD_NOP;
263
              ram_dqm <= 2'b00;
264
              count <= `T_MRD - 2;
265
              state <= `ST_IDLE;
266
            end
267
          //----------------------------
268
          // idle
269
          //----------------------------
270
          `ST_IDLE:
271
            begin
272
              if (refflg) begin
273
                // refresh request
274
                ram_cmd <= `CMD_ARFRS;
275
                state <= `ST_RFRSH;
276
                refrst <= 1;
277
              end else begin
278
                if (data_stb) begin
279
                  if (data_addr_out_of_range) begin
280
                    // illegal data address
281
                    ram_cmd <= `CMD_NOP;
282
                    state <= `ST_ILLDA0;
283
                  end else begin
284
                    // data address is ok
285
                    if (data_we) begin
286
                      // data write request
287
                      ram_cmd <= `CMD_ACTV;
288
                      sdram_ba <= data_addr[21:20];
289
                      sdram_a <= data_addr[19:7];
290
                      state <= `ST_WRDATA0;
291
                    end else begin
292
                      // data read request
293
                      ram_cmd <= `CMD_ACTV;
294
                      sdram_ba <= data_addr[21:20];
295
                      sdram_a <= data_addr[19:7];
296
                      state <= `ST_RDDATA0;
297
                    end
298
                  end
299
                end else begin
300
                  if (inst_stb) begin
301
                    if (inst_addr_out_of_range) begin
302
                      // illegal inst address
303
                      ram_cmd <= `CMD_NOP;
304
                      state <= `ST_ILLIA0;
305
                    end else begin
306
                      // inst address is ok
307
                      // inst read request
308
                      ram_cmd <= `CMD_ACTV;
309
                      sdram_ba <= inst_addr[21:20];
310
                      sdram_a <= inst_addr[19:7];
311
                      state <= `ST_RDINST0;
312
                    end
313
                  end else begin
314
                    // no request
315
                    ram_cmd <= `CMD_NOP;
316
                    state <= `ST_IDLE;
317
                  end
318
                end
319
              end
320
            end
321
          //----------------------------
322
          // refresh
323
          //----------------------------
324
          `ST_RFRSH:
325
            begin
326
              ram_cmd <= `CMD_NOP;
327
              count <= `T_RFC - 2;
328
              state <= `ST_IDLE;
329
              refrst <= 0;
330
            end
331
          //----------------------------
332
          // write data
333
          //----------------------------
334
          `ST_WRDATA0:
335
            begin
336
              ram_cmd <= `CMD_NOP;
337
              count <= `T_RCD - 2;
338
              state <= `ST_WRDATA1;
339
            end
340
          `ST_WRDATA1:
341
            begin
342
              ram_cnt <= 0;
343
              ram_de <= 1;
344
              ram_cmd <= `CMD_WRITE;
345
              sdram_ba <= data_addr[21:20];
346
              sdram_a <= { 6'b0010, data_addr[6:0], 2'b00 };
347
              state <= `ST_WRDATA2;
348
            end
349
          `ST_WRDATA2:
350
            begin
351
              ram_cnt <= ram_cnt + 1;
352
              ram_cmd <= `CMD_NOP;
353
              count <= 2;
354
              state <= `ST_WRDATA3;
355
            end
356
          `ST_WRDATA3:
357
            begin
358
              data_ack <= 1;
359
              ram_de <= 0;
360
              ram_cmd <= `CMD_NOP;
361
              state <= `ST_WRDATA4;
362
            end
363
          `ST_WRDATA4:
364
            begin
365
              data_ack <= 0;
366
              ram_cmd <= `CMD_NOP;
367
              count <= 2;
368
              state <= `ST_IDLE;
369
            end
370
          //----------------------------
371
          // read data
372
          //----------------------------
373
          `ST_RDDATA0:
374
            begin
375
              ram_cmd <= `CMD_NOP;
376
              count <= `T_RCD - 2;
377
              state <= `ST_RDDATA1;
378
            end
379
          `ST_RDDATA1:
380
            begin
381
              ram_cmd <= `CMD_READ;
382
              sdram_ba <= data_addr[21:20];
383
              sdram_a <= { 6'b0010, data_addr[6:0], 2'b00 };
384
              state <= `ST_RDDATA2;
385
            end
386
          `ST_RDDATA2:
387
            begin
388
              ram_cmd <= `CMD_NOP;
389
              count <= 1;
390
              state <= `ST_RDDATA3;
391
            end
392
          `ST_RDDATA3:
393
            begin
394
              ram_cnt <= 0;
395
              data_ld <= 1;
396
              ram_cmd <= `CMD_NOP;
397
              count <= 3;
398
              state <= `ST_RDDATA4;
399
            end
400
          `ST_RDDATA4:
401
            begin
402
              data_ack <= 1;
403
              data_ld <= 0;
404
              ram_cmd <= `CMD_NOP;
405
              state <= `ST_RDDATA5;
406
            end
407
          `ST_RDDATA5:
408
            begin
409
              data_ack <= 0;
410
              ram_cmd <= `CMD_NOP;
411
              count <= 3;
412
              state <= `ST_IDLE;
413
            end
414
          //----------------------------
415
          // read inst
416
          //----------------------------
417
          `ST_RDINST0:
418
            begin
419
              ram_cmd <= `CMD_NOP;
420
              count <= `T_RCD - 2;
421
              state <= `ST_RDINST1;
422
            end
423
          `ST_RDINST1:
424
            begin
425
              ram_cmd <= `CMD_READ;
426
              sdram_ba <= inst_addr[21:20];
427
              sdram_a <= { 6'b0010, inst_addr[6:0], 2'b00 };
428
              state <= `ST_RDINST2;
429
            end
430
          `ST_RDINST2:
431
            begin
432
              ram_cmd <= `CMD_NOP;
433
              count <= 1;
434
              state <= `ST_RDINST3;
435
            end
436
          `ST_RDINST3:
437
            begin
438
              ram_cnt <= 0;
439
              data_ld <= 1;
440
              ram_cmd <= `CMD_NOP;
441
              count <= 3;
442
              state <= `ST_RDINST4;
443
            end
444
          `ST_RDINST4:
445
            begin
446
              inst_ack <= 1;
447
              data_ld <= 0;
448
              ram_cmd <= `CMD_NOP;
449
              state <= `ST_RDINST5;
450
            end
451
          `ST_RDINST5:
452
            begin
453
              inst_ack <= 0;
454
              ram_cmd <= `CMD_NOP;
455
              count <= 3;
456
              state <= `ST_IDLE;
457
            end
458
          //----------------------------
459
          // illegal data address
460
          //----------------------------
461
          `ST_ILLDA0:
462
            begin
463
              data_timeout <= 1;
464
              ram_cmd <= `CMD_NOP;
465
              state <= `ST_ILLDA1;
466
            end
467
          `ST_ILLDA1:
468
            begin
469
              data_timeout <= 0;
470
              ram_cmd <= `CMD_NOP;
471
              state <= `ST_IDLE;
472
            end
473
          //----------------------------
474
          // illegal inst address
475
          //----------------------------
476
          `ST_ILLIA0:
477
            begin
478
              inst_timeout <= 1;
479
              ram_cmd <= `CMD_NOP;
480
              state <= `ST_ILLIA1;
481
            end
482
          `ST_ILLIA1:
483
            begin
484
              inst_timeout <= 0;
485
              ram_cmd <= `CMD_NOP;
486
              state <= `ST_IDLE;
487
            end
488
          //----------------------------
489
          // not used
490
          //----------------------------
491
          default:
492
            begin
493
              inst_ack <= 0;
494
              inst_timeout <= 0;
495
              data_ack <= 0;
496
              data_timeout <= 0;
497
              sdram_cke <= 0;
498
              sdram_cs_n <= 1;
499
              ram_cnt <= 0;
500
              ram_de <= 0;
501
              data_ld <= 0;
502
              ram_cmd <= `CMD_NOP;
503
              ram_dqm <= 2'b11;
504
              count <= `T_INIT0 - 1;
505
              state <= `ST_INIT0;
506
              refrst <= 0;
507
            end
508
        endcase
509
      end
510
    end
511
  end
512
 
513
  //
514
  // refresh counter
515
  //
516
 
517
  always @(posedge clk or negedge clk_ok) begin
518
    if (~clk_ok) begin
519
      refcnt <= 10'd0;
520
    end else begin
521
      if (refcnt == 10'd0) begin
522
        refcnt <= `REFCNT;
523
        refflg <= 1;
524
      end else begin
525
        refcnt <= refcnt - 1;
526
        if (refrst) begin
527
          refflg <= 0;
528
        end
529
      end
530
    end
531
  end
532
 
533
endmodule

powered by: WebSVN 2.1.0

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