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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [verilog/] [mt48lc16m16a2.v] - Blame information for rev 403

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 julius
/**************************************************************************
2
*
3
*    File Name:  MT48LC16M16A2.V
4
*      Version:  2.1
5
*         Date:  June 6th, 2002
6
*        Model:  BUS Functional
7
*    Simulator:  Model Technology
8
*
9
* Dependencies:  None
10
*
11
*        Email:  modelsupport@micron.com
12
*      Company:  Micron Technology, Inc.
13
*        Model:  MT48LC16M16A2 (4Meg x 16 x 4 Banks)
14
*
15
*  Description:  Micron 256Mb SDRAM Verilog model
16
*
17
*   Limitation:  - Doesn't check for 8192 cycle refresh
18
*
19
*         Note:  - Set simulator resolution to "ps" accuracy
20
*                - Set Debug = 0 to disable $display messages
21
*
22
*   Disclaimer:  THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
23
*                WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
24
*                IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
25
*                A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
26
*
27
*                Copyright © 2001 Micron Semiconductor Products, Inc.
28
*                All rights researved
29
*
30
* Rev  Author          Date        Changes
31
* ---  --------------------------  ---------------------------------------
32
* 2.1  SH              06/06/2002  - Typo in bank multiplex
33
*      Micron Technology Inc.
34
*
35
* 2.0  SH              04/30/2002  - Second release
36
*      Micron Technology Inc.
37
*
38
**************************************************************************/
39
 
40 44 julius
`include "timescale.v"
41 403 julius
`include "test-defines.v"
42 6 julius
 
43 403 julius
// Uncomment one of the following to have the appropriate size definitions
44
// for the part.
45
//`define MT48LC32M16   // 64MB part
46
`define MT48LC16M16   // 32MB part
47
//`define MT48LC4M16    //  8MB part
48
 
49 6 julius
module mt48lc16m16a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);
50
 
51
 
52 403 julius
`ifdef MT48LC32M16
53
   // Params. for  mt48lc32m16a2 (64MB part)
54
   parameter addr_bits =      13;
55
   parameter col_bits  =      10;
56
   parameter mem_sizes = 8388606;
57
`endif
58
 
59
`ifdef MT48LC16M16
60
   // Params. for  mt48lc16m16a2 (32MB part)
61
   parameter addr_bits =      13;
62
   parameter col_bits  =       9;
63
   parameter mem_sizes = 4194303;
64
`endif
65
 
66
`ifdef MT48LC4M16
67
  //Params for mt48lc4m16a2 (8MB part)
68
   parameter addr_bits =      12;
69
   parameter col_bits  =       8;
70
   parameter mem_sizes =   1048575;
71
`endif
72
 
73
   // Common to all parts
74
   parameter data_bits =      16;
75
 
76
 
77
 
78 6 julius
    inout     [data_bits - 1 : 0] Dq;
79 403 julius
    input [addr_bits - 1 : 0]      Addr;
80 6 julius
    input                 [1 : 0] Ba;
81
    input                         Clk;
82
    input                         Cke;
83
    input                         Cs_n;
84
    input                         Ras_n;
85
    input                         Cas_n;
86
    input                         We_n;
87
    input                 [1 : 0] Dqm;
88
 
89
    reg       [data_bits - 1 : 0] Bank0 [0 : mem_sizes];
90
    reg       [data_bits - 1 : 0] Bank1 [0 : mem_sizes];
91
    reg       [data_bits - 1 : 0] Bank2 [0 : mem_sizes];
92
    reg       [data_bits - 1 : 0] Bank3 [0 : mem_sizes];
93 403 julius
       reg       [31 : 0] Bank0_32bit [0 : (mem_sizes/2)]; // Temporary 32-bit wide array to hold readmemh()'d data before loading into 16-bit wide array
94 6 julius
    reg                   [1 : 0] Bank_addr [0 : 3];                // Bank Address Pipeline
95
    reg        [col_bits - 1 : 0] Col_addr [0 : 3];                 // Column Address Pipeline
96
    reg                   [3 : 0] Command [0 : 3];                  // Command Operation Pipeline
97
    reg                   [1 : 0] Dqm_reg0, Dqm_reg1;               // DQM Operation Pipeline
98
    reg       [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
99
 
100
    reg       [addr_bits - 1 : 0] Mode_reg;
101
    reg       [data_bits - 1 : 0] Dq_reg, Dq_dqm;
102
    reg        [col_bits - 1 : 0] Col_temp, Burst_counter;
103
 
104
    reg                           Act_b0, Act_b1, Act_b2, Act_b3;   // Bank Activate
105
    reg                           Pc_b0, Pc_b1, Pc_b2, Pc_b3;       // Bank Precharge
106
 
107
    reg                   [1 : 0] Bank_precharge       [0 : 3];     // Precharge Command
108
    reg                           A10_precharge        [0 : 3];     // Addr[10] = 1 (All banks)
109
    reg                           Auto_precharge       [0 : 3];     // RW Auto Precharge (Bank)
110
    reg                           Read_precharge       [0 : 3];     // R  Auto Precharge
111
    reg                           Write_precharge      [0 : 3];     //  W Auto Precharge
112
    reg                           RW_interrupt_read    [0 : 3];     // RW Interrupt Read with Auto Precharge
113
    reg                           RW_interrupt_write   [0 : 3];     // RW Interrupt Write with Auto Precharge
114
    reg                   [1 : 0] RW_interrupt_bank;                // RW Interrupt Bank
115
    integer                       RW_interrupt_counter [0 : 3];     // RW Interrupt Counter
116
    integer                       Count_precharge      [0 : 3];     // RW Auto Precharge Counter
117
 
118
    reg                           Data_in_enable;
119
    reg                           Data_out_enable;
120
 
121
    reg                   [1 : 0] Bank, Prev_bank;
122
    reg       [addr_bits - 1 : 0] Row;
123
    reg        [col_bits - 1 : 0] Col, Col_brst;
124
 
125
    // Internal system clock
126
    reg                           CkeZ, Sys_clk;
127
 
128
    // Commands Decode
129
    wire      Active_enable    = ~Cs_n & ~Ras_n &  Cas_n &  We_n;
130
    wire      Aref_enable      = ~Cs_n & ~Ras_n & ~Cas_n &  We_n;
131
    wire      Burst_term       = ~Cs_n &  Ras_n &  Cas_n & ~We_n;
132
    wire      Mode_reg_enable  = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n;
133
    wire      Prech_enable     = ~Cs_n & ~Ras_n &  Cas_n & ~We_n;
134
    wire      Read_enable      = ~Cs_n &  Ras_n & ~Cas_n &  We_n;
135
    wire      Write_enable     = ~Cs_n &  Ras_n & ~Cas_n & ~We_n;
136
 
137
    // Burst Length Decode
138
    wire      Burst_length_1   = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0];
139
    wire      Burst_length_2   = ~Mode_reg[2] & ~Mode_reg[1] &  Mode_reg[0];
140
    wire      Burst_length_4   = ~Mode_reg[2] &  Mode_reg[1] & ~Mode_reg[0];
141
    wire      Burst_length_8   = ~Mode_reg[2] &  Mode_reg[1] &  Mode_reg[0];
142
    wire      Burst_length_f   =  Mode_reg[2] &  Mode_reg[1] &  Mode_reg[0];
143
 
144
    // CAS Latency Decode
145
    wire      Cas_latency_2    = ~Mode_reg[6] &  Mode_reg[5] & ~Mode_reg[4];
146
    wire      Cas_latency_3    = ~Mode_reg[6] &  Mode_reg[5] &  Mode_reg[4];
147
 
148
    // Write Burst Mode
149
    wire      Write_burst_mode = Mode_reg[9];
150
 
151
    wire      Debug            = 1'b0;                          // Debug messages : 1 = On
152
    wire      Dq_chk           = Sys_clk & Data_in_enable;      // Check setup/hold time for DQ
153
 
154
    assign    Dq               = Dq_reg;                        // DQ buffer
155
 
156
    // Commands Operation
157
    `define   ACT       0
158
    `define   NOP       1
159
    `define   READ      2
160
    `define   WRITE     3
161
    `define   PRECH     4
162
    `define   A_REF     5
163
    `define   BST       6
164
    `define   LMR       7
165
 
166
    // Timing Parameters for -7E PC133 CL2
167
    parameter tAC  =   5.4;
168
    parameter tHZ  =   5.4;
169
    parameter tOH  =   3.0;
170
    parameter tMRD =   2.0;     // 2 Clk Cycles
171
    parameter tRAS =  37.0;
172
    parameter tRC  =  60.0;
173
    parameter tRCD =  15.0;
174
    parameter tRFC =  66.0;
175
    parameter tRP  =  15.0;
176
    parameter tRRD =  14.0;
177
    parameter tWRa =   7.0;     // A2 Version - Auto precharge mode (1 Clk + 7 ns)
178
    parameter tWRm =  14.0;     // A2 Version - Manual precharge mode (14 ns)
179
 
180
    // Timing Check variable
181
    time  MRD_chk;
182
    time  WR_chkm [0 : 3];
183
    time  RFC_chk, RRD_chk;
184
    time  RC_chk0, RC_chk1, RC_chk2, RC_chk3;
185
    time  RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
186
    time  RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
187
    time  RP_chk0, RP_chk1, RP_chk2, RP_chk3;
188
 
189 403 julius
   integer mem_cnt;
190
 
191
 
192 6 julius
    initial begin
193
        Dq_reg = {data_bits{1'bz}};
194
        Data_in_enable = 0; Data_out_enable = 0;
195
        Act_b0 = 1; Act_b1 = 1; Act_b2 = 1; Act_b3 = 1;
196
        Pc_b0 = 0; Pc_b1 = 0; Pc_b2 = 0; Pc_b3 = 0;
197
        WR_chkm[0] = 0; WR_chkm[1] = 0; WR_chkm[2] = 0; WR_chkm[3] = 0;
198
        RW_interrupt_read[0] = 0; RW_interrupt_read[1] = 0; RW_interrupt_read[2] = 0; RW_interrupt_read[3] = 0;
199
        RW_interrupt_write[0] = 0; RW_interrupt_write[1] = 0; RW_interrupt_write[2] = 0; RW_interrupt_write[3] = 0;
200
        MRD_chk = 0; RFC_chk = 0; RRD_chk = 0;
201
        RAS_chk0 = 0; RAS_chk1 = 0; RAS_chk2 = 0; RAS_chk3 = 0;
202
        RCD_chk0 = 0; RCD_chk1 = 0; RCD_chk2 = 0; RCD_chk3 = 0;
203
        RC_chk0 = 0; RC_chk1 = 0; RC_chk2 = 0; RC_chk3 = 0;
204
        RP_chk0 = 0; RP_chk1 = 0; RP_chk2 = 0; RP_chk3 = 0;
205
        $timeformat (-9, 1, " ns", 12);
206 403 julius
//`define INIT_CLEAR_MEM_BANKS       
207
`ifdef INIT_CLEAR_MEM_BANKS // Added, jb
208
       // Initialse the memory before we use it, clearing x's
209
       for(mem_cnt = 0; mem_cnt < mem_sizes; mem_cnt = mem_cnt + 1)
210
         begin
211
            Bank0[mem_cnt] = 0;
212
            Bank1[mem_cnt] = 0;
213
            Bank2[mem_cnt] = 0;
214
            Bank3[mem_cnt] = 0;
215
         end
216
`endif
217 6 julius
 
218 403 julius
`ifdef PRELOAD_RAM // Added jb
219
       $display("* Preloading SDRAM bank 0.\n");
220
       // Uses the vmem file for the internal SRAM, so words are 32-bits wide
221
       // and we need to copy them into the 16-bit wide array, which the simulator
222
       // can't figure out how to do, so we'll do it manually here.
223
       $readmemh("sram.vmem", Bank0_32bit);
224
       for (mem_cnt=0;mem_cnt < (mem_sizes/2); mem_cnt = mem_cnt + 1)
225
         begin
226
            Bank0[(mem_cnt*2)+1] = Bank0_32bit[mem_cnt][15:0];
227
            Bank0[(mem_cnt*2)] = Bank0_32bit[mem_cnt][31:16];
228
         end
229
`endif
230
end
231
 
232 6 julius
    // System clock generator
233
    always begin
234
        @ (posedge Clk) begin
235
            Sys_clk = CkeZ;
236
            CkeZ = Cke;
237
        end
238
        @ (negedge Clk) begin
239
            Sys_clk = 1'b0;
240
        end
241
    end
242
 
243
    always @ (posedge Sys_clk) begin
244
        // Internal Commamd Pipelined
245
        Command[0] = Command[1];
246
        Command[1] = Command[2];
247
        Command[2] = Command[3];
248
        Command[3] = `NOP;
249
 
250
        Col_addr[0] = Col_addr[1];
251
        Col_addr[1] = Col_addr[2];
252
        Col_addr[2] = Col_addr[3];
253
        Col_addr[3] = {col_bits{1'b0}};
254
 
255
        Bank_addr[0] = Bank_addr[1];
256
        Bank_addr[1] = Bank_addr[2];
257
        Bank_addr[2] = Bank_addr[3];
258
        Bank_addr[3] = 2'b0;
259
 
260
        Bank_precharge[0] = Bank_precharge[1];
261
        Bank_precharge[1] = Bank_precharge[2];
262
        Bank_precharge[2] = Bank_precharge[3];
263
        Bank_precharge[3] = 2'b0;
264
 
265
        A10_precharge[0] = A10_precharge[1];
266
        A10_precharge[1] = A10_precharge[2];
267
        A10_precharge[2] = A10_precharge[3];
268
        A10_precharge[3] = 1'b0;
269
 
270
        // Dqm pipeline for Read
271
        Dqm_reg0 = Dqm_reg1;
272
        Dqm_reg1 = Dqm;
273
 
274
        // Read or Write with Auto Precharge Counter
275
        if (Auto_precharge[0] === 1'b1) begin
276
            Count_precharge[0] = Count_precharge[0] + 1;
277
        end
278
        if (Auto_precharge[1] === 1'b1) begin
279
            Count_precharge[1] = Count_precharge[1] + 1;
280
        end
281
        if (Auto_precharge[2] === 1'b1) begin
282
            Count_precharge[2] = Count_precharge[2] + 1;
283
        end
284
        if (Auto_precharge[3] === 1'b1) begin
285
            Count_precharge[3] = Count_precharge[3] + 1;
286
        end
287
 
288
        // Read or Write Interrupt Counter
289
        if (RW_interrupt_write[0] === 1'b1) begin
290
            RW_interrupt_counter[0] = RW_interrupt_counter[0] + 1;
291
        end
292
        if (RW_interrupt_write[1] === 1'b1) begin
293
            RW_interrupt_counter[1] = RW_interrupt_counter[1] + 1;
294
        end
295
        if (RW_interrupt_write[2] === 1'b1) begin
296
            RW_interrupt_counter[2] = RW_interrupt_counter[2] + 1;
297
        end
298
        if (RW_interrupt_write[3] === 1'b1) begin
299
            RW_interrupt_counter[3] = RW_interrupt_counter[3] + 1;
300
        end
301
 
302
        // tMRD Counter
303
        MRD_chk = MRD_chk + 1;
304
 
305
        // Auto Refresh
306
        if (Aref_enable === 1'b1) begin
307
            if (Debug) begin
308
                $display ("%m : at time %t AREF : Auto Refresh", $time);
309
            end
310
 
311
            // Auto Refresh to Auto Refresh
312
            if ($time - RFC_chk < tRFC) begin
313
                $display ("%m : at time %t ERROR: tRFC violation during Auto Refresh", $time);
314
            end
315
 
316
            // Precharge to Auto Refresh
317
            if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
318
                ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
319
                $display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $time);
320
            end
321
 
322
            // Precharge to Refresh
323
            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
324
                $display ("%m : at time %t ERROR: All banks must be Precharge before Auto Refresh", $time);
325
            end
326
 
327
            // Load Mode Register to Auto Refresh
328
            if (MRD_chk < tMRD) begin
329
                $display ("%m : at time %t ERROR: tMRD violation during Auto Refresh", $time);
330
            end
331
 
332
            // Record Current tRFC time
333
            RFC_chk = $time;
334
        end
335
 
336
        // Load Mode Register
337
        if (Mode_reg_enable === 1'b1) begin
338
            // Register Mode
339
            Mode_reg = Addr;
340
 
341
            // Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode
342
            if (Debug) begin
343
                $display ("%m : at time %t LMR  : Load Mode Register", $time);
344
                // CAS Latency
345
                case (Addr[6 : 4])
346
                    3'b010  : $display ("%m :                             CAS Latency      = 2");
347
                    3'b011  : $display ("%m :                             CAS Latency      = 3");
348
                    default : $display ("%m :                             CAS Latency      = Reserved");
349
                endcase
350
 
351
                // Burst Length
352
                case (Addr[2 : 0])
353
                    3'b000  : $display ("%m :                             Burst Length     = 1");
354
                    3'b001  : $display ("%m :                             Burst Length     = 2");
355
                    3'b010  : $display ("%m :                             Burst Length     = 4");
356
                    3'b011  : $display ("%m :                             Burst Length     = 8");
357
                    3'b111  : $display ("%m :                             Burst Length     = Full");
358
                    default : $display ("%m :                             Burst Length     = Reserved");
359
                endcase
360
 
361
                // Burst Type
362
                if (Addr[3] === 1'b0) begin
363
                    $display ("%m :                             Burst Type       = Sequential");
364
                end else if (Addr[3] === 1'b1) begin
365
                    $display ("%m :                             Burst Type       = Interleaved");
366
                end else begin
367
                    $display ("%m :                             Burst Type       = Reserved");
368
                end
369
 
370
                // Write Burst Mode
371
                if (Addr[9] === 1'b0) begin
372
                    $display ("%m :                             Write Burst Mode = Programmed Burst Length");
373
                end else if (Addr[9] === 1'b1) begin
374
                    $display ("%m :                             Write Burst Mode = Single Location Access");
375
                end else begin
376
                    $display ("%m :                             Write Burst Mode = Reserved");
377
                end
378
            end
379
 
380
            // Precharge to Load Mode Register
381
            if (Pc_b0 === 1'b0 && Pc_b1 === 1'b0 && Pc_b2 === 1'b0 && Pc_b3 === 1'b0) begin
382
                $display ("%m : at time %t ERROR: all banks must be Precharge before Load Mode Register", $time);
383
            end
384
 
385
            // Precharge to Load Mode Register
386
            if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
387
                ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
388
                $display ("%m : at time %t ERROR: tRP violation during Load Mode Register", $time);
389
            end
390
 
391
            // Auto Refresh to Load Mode Register
392
            if ($time - RFC_chk < tRFC) begin
393
                $display ("%m : at time %t ERROR: tRFC violation during Load Mode Register", $time);
394
            end
395
 
396
            // Load Mode Register to Load Mode Register
397
            if (MRD_chk < tMRD) begin
398
                $display ("%m : at time %t ERROR: tMRD violation during Load Mode Register", $time);
399
            end
400
 
401
            // Reset MRD Counter
402
            MRD_chk = 0;
403
        end
404
 
405
        // Active Block (Latch Bank Address and Row Address)
406
        if (Active_enable === 1'b1) begin
407
            // Activate an open bank can corrupt data
408
            if ((Ba === 2'b00 && Act_b0 === 1'b1) || (Ba === 2'b01 && Act_b1 === 1'b1) ||
409
                (Ba === 2'b10 && Act_b2 === 1'b1) || (Ba === 2'b11 && Act_b3 === 1'b1)) begin
410
                $display ("%m : at time %t ERROR: Bank already activated -- data can be corrupted", $time);
411
            end
412
 
413
            // Activate Bank 0
414
            if (Ba === 2'b00 && Pc_b0 === 1'b1) begin
415
                // Debug Message
416
                if (Debug) begin
417
                    $display ("%m : at time %t ACT  : Bank = 0 Row = %h", $time, Addr);
418
                end
419
 
420
                // ACTIVE to ACTIVE command period
421
                if ($time - RC_chk0 < tRC) begin
422
                    $display ("%m : at time %t ERROR: tRC violation during Activate bank 0", $time);
423
                end
424
 
425
                // Precharge to Activate Bank 0
426
                if ($time - RP_chk0 < tRP) begin
427
                    $display ("%m : at time %t ERROR: tRP violation during Activate bank 0", $time);
428
                end
429
 
430
                // Record variables
431
                Act_b0 = 1'b1;
432
                Pc_b0 = 1'b0;
433
                B0_row_addr = Addr [addr_bits - 1 : 0];
434
                RAS_chk0 = $time;
435
                RC_chk0 = $time;
436
                RCD_chk0 = $time;
437
            end
438
 
439
            if (Ba == 2'b01 && Pc_b1 == 1'b1) begin
440
                // Debug Message
441
                if (Debug) begin
442
                    $display ("%m : at time %t ACT  : Bank = 1 Row = %h", $time, Addr);
443
                end
444
 
445
                // ACTIVE to ACTIVE command period
446
                if ($time - RC_chk1 < tRC) begin
447
                    $display ("%m : at time %t ERROR: tRC violation during Activate bank 1", $time);
448
                end
449
 
450
                // Precharge to Activate Bank 1
451
                if ($time - RP_chk1 < tRP) begin
452
                    $display ("%m : at time %t ERROR: tRP violation during Activate bank 1", $time);
453
                end
454
 
455
                // Record variables
456
                Act_b1 = 1'b1;
457
                Pc_b1 = 1'b0;
458
                B1_row_addr = Addr [addr_bits - 1 : 0];
459
                RAS_chk1 = $time;
460
                RC_chk1 = $time;
461
                RCD_chk1 = $time;
462
            end
463
 
464
            if (Ba == 2'b10 && Pc_b2 == 1'b1) begin
465
                // Debug Message
466
                if (Debug) begin
467
                    $display ("%m : at time %t ACT  : Bank = 2 Row = %h", $time, Addr);
468
                end
469
 
470
                // ACTIVE to ACTIVE command period
471
                if ($time - RC_chk2 < tRC) begin
472
                    $display ("%m : at time %t ERROR: tRC violation during Activate bank 2", $time);
473
                end
474
 
475
                // Precharge to Activate Bank 2
476
                if ($time - RP_chk2 < tRP) begin
477
                    $display ("%m : at time %t ERROR: tRP violation during Activate bank 2", $time);
478
                end
479
 
480
                // Record variables
481
                Act_b2 = 1'b1;
482
                Pc_b2 = 1'b0;
483
                B2_row_addr = Addr [addr_bits - 1 : 0];
484
                RAS_chk2 = $time;
485
                RC_chk2 = $time;
486
                RCD_chk2 = $time;
487
            end
488
 
489
            if (Ba == 2'b11 && Pc_b3 == 1'b1) begin
490
                // Debug Message
491
                if (Debug) begin
492
                    $display ("%m : at time %t ACT  : Bank = 3 Row = %h", $time, Addr);
493
                end
494
 
495
                // ACTIVE to ACTIVE command period
496
                if ($time - RC_chk3 < tRC) begin
497
                    $display ("%m : at time %t ERROR: tRC violation during Activate bank 3", $time);
498
                end
499
 
500
                // Precharge to Activate Bank 3
501
                if ($time - RP_chk3 < tRP) begin
502
                    $display ("%m : at time %t ERROR: tRP violation during Activate bank 3", $time);
503
                end
504
 
505
                // Record variables
506
                Act_b3 = 1'b1;
507
                Pc_b3 = 1'b0;
508
                B3_row_addr = Addr [addr_bits - 1 : 0];
509
                RAS_chk3 = $time;
510
                RC_chk3 = $time;
511
                RCD_chk3 = $time;
512
            end
513
 
514
            // Active Bank A to Active Bank B
515
            if ((Prev_bank != Ba) && ($time - RRD_chk < tRRD)) begin
516
                $display ("%m : at time %t ERROR: tRRD violation during Activate bank = %h", $time, Ba);
517
            end
518
 
519
            // Auto Refresh to Activate
520
            if ($time - RFC_chk < tRFC) begin
521
                $display ("%m : at time %t ERROR: tRFC violation during Activate bank = %h", $time, Ba);
522
            end
523
 
524
            // Load Mode Register to Active
525
            if (MRD_chk < tMRD ) begin
526
                $display ("%m : at time %t ERROR: tMRD violation during Activate bank = %h", $time, Ba);
527
            end
528
 
529
            // Record variables for checking violation
530
            RRD_chk = $time;
531
            Prev_bank = Ba;
532
        end
533
 
534
        // Precharge Block
535
        if (Prech_enable == 1'b1) begin
536
            // Load Mode Register to Precharge
537
            if ($time - MRD_chk < tMRD) begin
538
                $display ("%m : at time %t ERROR: tMRD violaiton during Precharge", $time);
539
            end
540
 
541
            // Precharge Bank 0
542
            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin
543
                Act_b0 = 1'b0;
544
                Pc_b0 = 1'b1;
545
                RP_chk0 = $time;
546
 
547
                // Activate to Precharge
548
                if ($time - RAS_chk0 < tRAS) begin
549
                    $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
550
                end
551
 
552
                // tWR violation check for write
553
                if ($time - WR_chkm[0] < tWRm) begin
554
                    $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
555
                end
556
            end
557
 
558
            // Precharge Bank 1
559
            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin
560
                Act_b1 = 1'b0;
561
                Pc_b1 = 1'b1;
562
                RP_chk1 = $time;
563
 
564
                // Activate to Precharge
565
                if ($time - RAS_chk1 < tRAS) begin
566
                    $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
567
                end
568
 
569
                // tWR violation check for write
570
                if ($time - WR_chkm[1] < tWRm) begin
571
                    $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
572
                end
573
            end
574
 
575
            // Precharge Bank 2
576
            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin
577
                Act_b2 = 1'b0;
578
                Pc_b2 = 1'b1;
579
                RP_chk2 = $time;
580
 
581
                // Activate to Precharge
582
                if ($time - RAS_chk2 < tRAS) begin
583
                    $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
584
                end
585
 
586
                // tWR violation check for write
587
                if ($time - WR_chkm[2] < tWRm) begin
588
                    $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
589
                end
590
            end
591
 
592
            // Precharge Bank 3
593
            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin
594
                Act_b3 = 1'b0;
595
                Pc_b3 = 1'b1;
596
                RP_chk3 = $time;
597
 
598
                // Activate to Precharge
599
                if ($time - RAS_chk3 < tRAS) begin
600
                    $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
601
                end
602
 
603
                // tWR violation check for write
604
                if ($time - WR_chkm[3] < tWRm) begin
605
                    $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
606
                end
607
            end
608
 
609
            // Terminate a Write Immediately (if same bank or all banks)
610
            if (Data_in_enable === 1'b1 && (Bank === Ba || Addr[10] === 1'b1)) begin
611
                Data_in_enable = 1'b0;
612
            end
613
 
614
            // Precharge Command Pipeline for Read
615
            if (Cas_latency_3 === 1'b1) begin
616
                Command[2] = `PRECH;
617
                Bank_precharge[2] = Ba;
618
                A10_precharge[2] = Addr[10];
619
            end else if (Cas_latency_2 === 1'b1) begin
620
                Command[1] = `PRECH;
621
                Bank_precharge[1] = Ba;
622
                A10_precharge[1] = Addr[10];
623
            end
624
        end
625
 
626
        // Burst terminate
627
        if (Burst_term === 1'b1) begin
628
            // Terminate a Write Immediately
629
            if (Data_in_enable == 1'b1) begin
630
                Data_in_enable = 1'b0;
631
            end
632
 
633
            // Terminate a Read Depend on CAS Latency
634
            if (Cas_latency_3 === 1'b1) begin
635
                Command[2] = `BST;
636
            end else if (Cas_latency_2 == 1'b1) begin
637
                Command[1] = `BST;
638
            end
639
 
640
            // Display debug message
641
            if (Debug) begin
642
                $display ("%m : at time %t BST  : Burst Terminate",$time);
643
            end
644
        end
645
 
646
        // Read, Write, Column Latch
647
        if (Read_enable === 1'b1) begin
648
            // Check to see if bank is open (ACT)
649
            if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
650
                (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
651
                $display("%m : at time %t ERROR: Bank is not Activated for Read", $time);
652
            end
653
 
654
            // Activate to Read or Write
655
            if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) ||
656
                (Ba == 2'b01) && ($time - RCD_chk1 < tRCD) ||
657
                (Ba == 2'b10) && ($time - RCD_chk2 < tRCD) ||
658
                (Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin
659
                $display("%m : at time %t ERROR: tRCD violation during Read", $time);
660
            end
661
 
662
            // CAS Latency pipeline
663
            if (Cas_latency_3 == 1'b1) begin
664
                Command[2] = `READ;
665
                Col_addr[2] = Addr;
666
                Bank_addr[2] = Ba;
667
            end else if (Cas_latency_2 == 1'b1) begin
668
                Command[1] = `READ;
669
                Col_addr[1] = Addr;
670
                Bank_addr[1] = Ba;
671
            end
672
 
673
            // Read interrupt Write (terminate Write immediately)
674
            if (Data_in_enable == 1'b1) begin
675
                Data_in_enable = 1'b0;
676
 
677
                // Interrupting a Write with Autoprecharge
678
                if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin
679
                    RW_interrupt_write[RW_interrupt_bank] = 1'b1;
680
                    RW_interrupt_counter[RW_interrupt_bank] = 0;
681
 
682
                    // Display debug message
683
                    if (Debug) begin
684
                        $display ("%m : at time %t NOTE : Read interrupt Write with Autoprecharge", $time);
685
                    end
686
                end
687
            end
688
 
689
            // Write with Auto Precharge
690
            if (Addr[10] == 1'b1) begin
691
                Auto_precharge[Ba] = 1'b1;
692
                Count_precharge[Ba] = 0;
693
                RW_interrupt_bank = Ba;
694
                Read_precharge[Ba] = 1'b1;
695
            end
696
        end
697
 
698
        // Write Command
699
        if (Write_enable == 1'b1) begin
700
            // Activate to Write
701
            if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
702
                (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
703
                $display("%m : at time %t ERROR: Bank is not Activated for Write", $time);
704
            end
705
 
706
            // Activate to Read or Write
707
            if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) ||
708
                (Ba == 2'b01) && ($time - RCD_chk1 < tRCD) ||
709
                (Ba == 2'b10) && ($time - RCD_chk2 < tRCD) ||
710
                (Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin
711
                $display("%m : at time %t ERROR: tRCD violation during Read", $time);
712
            end
713
 
714
            // Latch Write command, Bank, and Column
715
            Command[0] = `WRITE;
716
            Col_addr[0] = Addr;
717
            Bank_addr[0] = Ba;
718
 
719
            // Write interrupt Write (terminate Write immediately)
720
            if (Data_in_enable == 1'b1) begin
721
                Data_in_enable = 1'b0;
722
 
723
                // Interrupting a Write with Autoprecharge
724
                if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin
725
                    RW_interrupt_write[RW_interrupt_bank] = 1'b1;
726
 
727
                    // Display debug message
728
                    if (Debug) begin
729
                        $display ("%m : at time %t NOTE : Read Bank %h interrupt Write Bank %h with Autoprecharge", $time, Ba, RW_interrupt_bank);
730
                    end
731
                end
732
            end
733
 
734
            // Write interrupt Read (terminate Read immediately)
735
            if (Data_out_enable == 1'b1) begin
736
                Data_out_enable = 1'b0;
737
 
738
                // Interrupting a Read with Autoprecharge
739
                if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Read_precharge[RW_interrupt_bank] == 1'b1) begin
740
                    RW_interrupt_read[RW_interrupt_bank] = 1'b1;
741
 
742
                    // Display debug message
743
                    if (Debug) begin
744
                        $display ("%m : at time %t NOTE : Write Bank %h interrupt Read Bank %h with Autoprecharge", $time, Ba, RW_interrupt_bank);
745
                    end
746
                end
747
            end
748
 
749
            // Write with Auto Precharge
750
            if (Addr[10] == 1'b1) begin
751
                Auto_precharge[Ba] = 1'b1;
752
                Count_precharge[Ba] = 0;
753
                RW_interrupt_bank = Ba;
754
                Write_precharge[Ba] = 1'b1;
755
            end
756
        end
757
 
758
        /*
759
            Write with Auto Precharge Calculation
760
                The device start internal precharge when:
761
                    1.  Meet minimum tRAS requirement
762
                and 2.  tWR cycle(s) after last valid data
763
                 or 3.  Interrupt by a Read or Write (with or without Auto Precharge)
764
 
765
            Note: Model is starting the internal precharge 1 cycle after they meet all the
766
                  requirement but tRP will be compensate for the time after the 1 cycle.
767
        */
768
        if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin
769
            if ((($time - RAS_chk0 >= tRAS) &&                                                          // Case 1
770
               (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) ||   // Case 2
771
                 (Burst_length_2 == 1'b1                              && Count_precharge [0] >= 2) ||
772
                 (Burst_length_4 == 1'b1                              && Count_precharge [0] >= 4) ||
773
                 (Burst_length_8 == 1'b1                              && Count_precharge [0] >= 8))) ||
774
                 (RW_interrupt_write[0] == 1'b1 && RW_interrupt_counter[0] >= 1)) begin                 // Case 3
775
                    Auto_precharge[0] = 1'b0;
776
                    Write_precharge[0] = 1'b0;
777
                    RW_interrupt_write[0] = 1'b0;
778
                    Pc_b0 = 1'b1;
779
                    Act_b0 = 1'b0;
780
                    RP_chk0 = $time + tWRa;
781
                    if (Debug) begin
782
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
783
                    end
784
            end
785
        end
786
        if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin
787
            if ((($time - RAS_chk1 >= tRAS) &&                                                          // Case 1
788
               (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) ||   // Case 2
789
                 (Burst_length_2 == 1'b1                              && Count_precharge [1] >= 2) ||
790
                 (Burst_length_4 == 1'b1                              && Count_precharge [1] >= 4) ||
791
                 (Burst_length_8 == 1'b1                              && Count_precharge [1] >= 8))) ||
792
                 (RW_interrupt_write[1] == 1'b1 && RW_interrupt_counter[1] >= 1)) begin                 // Case 3
793
                    Auto_precharge[1] = 1'b0;
794
                    Write_precharge[1] = 1'b0;
795
                    RW_interrupt_write[1] = 1'b0;
796
                    Pc_b1 = 1'b1;
797
                    Act_b1 = 1'b0;
798
                    RP_chk1 = $time + tWRa;
799
                    if (Debug) begin
800
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
801
                    end
802
            end
803
        end
804
        if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin
805
            if ((($time - RAS_chk2 >= tRAS) &&                                                          // Case 1
806
               (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) ||   // Case 2
807
                 (Burst_length_2 == 1'b1                              && Count_precharge [2] >= 2) ||
808
                 (Burst_length_4 == 1'b1                              && Count_precharge [2] >= 4) ||
809
                 (Burst_length_8 == 1'b1                              && Count_precharge [2] >= 8))) ||
810
                 (RW_interrupt_write[2] == 1'b1 && RW_interrupt_counter[2] >= 1)) begin                 // Case 3
811
                    Auto_precharge[2] = 1'b0;
812
                    Write_precharge[2] = 1'b0;
813
                    RW_interrupt_write[2] = 1'b0;
814
                    Pc_b2 = 1'b1;
815
                    Act_b2 = 1'b0;
816
                    RP_chk2 = $time + tWRa;
817
                    if (Debug) begin
818
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
819
                    end
820
            end
821
        end
822
        if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin
823
            if ((($time - RAS_chk3 >= tRAS) &&                                                          // Case 1
824
               (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) ||   // Case 2
825
                 (Burst_length_2 == 1'b1                              && Count_precharge [3] >= 2) ||
826
                 (Burst_length_4 == 1'b1                              && Count_precharge [3] >= 4) ||
827
                 (Burst_length_8 == 1'b1                              && Count_precharge [3] >= 8))) ||
828
                 (RW_interrupt_write[3] == 1'b1 && RW_interrupt_counter[3] >= 1)) begin                 // Case 3
829
                    Auto_precharge[3] = 1'b0;
830
                    Write_precharge[3] = 1'b0;
831
                    RW_interrupt_write[3] = 1'b0;
832
                    Pc_b3 = 1'b1;
833
                    Act_b3 = 1'b0;
834
                    RP_chk3 = $time + tWRa;
835
                    if (Debug) begin
836
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
837
                    end
838
            end
839
        end
840
 
841
        //  Read with Auto Precharge Calculation
842
        //      The device start internal precharge:
843
        //          1.  Meet minimum tRAS requirement
844
        //      and 2.  CAS Latency - 1 cycles before last burst
845
        //       or 3.  Interrupt by a Read or Write (with or without AutoPrecharge)
846
        if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin
847
            if ((($time - RAS_chk0 >= tRAS) &&                                                      // Case 1
848
                ((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) ||                             // Case 2
849
                 (Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) ||
850
                 (Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) ||
851
                 (Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) ||
852
                 (RW_interrupt_read[0] == 1'b1)) begin                                              // Case 3
853
                    Pc_b0 = 1'b1;
854
                    Act_b0 = 1'b0;
855
                    RP_chk0 = $time;
856
                    Auto_precharge[0] = 1'b0;
857
                    Read_precharge[0] = 1'b0;
858
                    RW_interrupt_read[0] = 1'b0;
859
                    if (Debug) begin
860
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
861
                    end
862
            end
863
        end
864
        if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin
865
            if ((($time - RAS_chk1 >= tRAS) &&
866
                ((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) ||
867
                 (Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) ||
868
                 (Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) ||
869
                 (Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) ||
870
                 (RW_interrupt_read[1] == 1'b1)) begin
871
                    Pc_b1 = 1'b1;
872
                    Act_b1 = 1'b0;
873
                    RP_chk1 = $time;
874
                    Auto_precharge[1] = 1'b0;
875
                    Read_precharge[1] = 1'b0;
876
                    RW_interrupt_read[1] = 1'b0;
877
                    if (Debug) begin
878
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
879
                    end
880
            end
881
        end
882
        if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin
883
            if ((($time - RAS_chk2 >= tRAS) &&
884
                ((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) ||
885
                 (Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) ||
886
                 (Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) ||
887
                 (Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) ||
888
                 (RW_interrupt_read[2] == 1'b1)) begin
889
                    Pc_b2 = 1'b1;
890
                    Act_b2 = 1'b0;
891
                    RP_chk2 = $time;
892
                    Auto_precharge[2] = 1'b0;
893
                    Read_precharge[2] = 1'b0;
894
                    RW_interrupt_read[2] = 1'b0;
895
                    if (Debug) begin
896
                        $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
897
                    end
898
            end
899
        end
900
        if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin
901
            if ((($time - RAS_chk3 >= tRAS) &&
902
                ((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) ||
903
                 (Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) ||
904
                 (Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) ||
905
                 (Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) ||
906
                 (RW_interrupt_read[3] == 1'b1)) begin
907
                    Pc_b3 = 1'b1;
908
                    Act_b3 = 1'b0;
909
                    RP_chk3 = $time;
910
                    Auto_precharge[3] = 1'b0;
911
                    Read_precharge[3] = 1'b0;
912
                    RW_interrupt_read[3] = 1'b0;
913
                    if (Debug) begin
914
                        $display("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
915
                    end
916
            end
917
        end
918
 
919
        // Internal Precharge or Bst
920
        if (Command[0] == `PRECH) begin                         // Precharge terminate a read with same bank or all banks
921
            if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin
922
                if (Data_out_enable == 1'b1) begin
923
                    Data_out_enable = 1'b0;
924
                end
925
            end
926
        end else if (Command[0] == `BST) begin                  // BST terminate a read to current bank
927
            if (Data_out_enable == 1'b1) begin
928
                Data_out_enable = 1'b0;
929
            end
930
        end
931
 
932
        if (Data_out_enable == 1'b0) begin
933
            Dq_reg <= #tOH {data_bits{1'bz}};
934
        end
935
 
936
        // Detect Read or Write command
937
        if (Command[0] == `READ) begin
938
            Bank = Bank_addr[0];
939
            Col = Col_addr[0];
940
            Col_brst = Col_addr[0];
941
            case (Bank_addr[0])
942
                2'b00 : Row = B0_row_addr;
943
                2'b01 : Row = B1_row_addr;
944
                2'b10 : Row = B2_row_addr;
945
                2'b11 : Row = B3_row_addr;
946
            endcase
947
            Burst_counter = 0;
948
            Data_in_enable = 1'b0;
949
            Data_out_enable = 1'b1;
950
        end else if (Command[0] == `WRITE) begin
951
            Bank = Bank_addr[0];
952
            Col = Col_addr[0];
953
            Col_brst = Col_addr[0];
954
            case (Bank_addr[0])
955
                2'b00 : Row = B0_row_addr;
956
                2'b01 : Row = B1_row_addr;
957
                2'b10 : Row = B2_row_addr;
958
                2'b11 : Row = B3_row_addr;
959
            endcase
960
            Burst_counter = 0;
961
            Data_in_enable = 1'b1;
962
            Data_out_enable = 1'b0;
963
        end
964
 
965
        // DQ buffer (Driver/Receiver)
966
        if (Data_in_enable == 1'b1) begin                                   // Writing Data to Memory
967
            // Array buffer
968
            case (Bank)
969
                2'b00 : Dq_dqm = Bank0 [{Row, Col}];
970
                2'b01 : Dq_dqm = Bank1 [{Row, Col}];
971
                2'b10 : Dq_dqm = Bank2 [{Row, Col}];
972
                2'b11 : Dq_dqm = Bank3 [{Row, Col}];
973
            endcase
974
 
975
            // Dqm operation
976
            if (Dqm[0] == 1'b0) begin
977
                Dq_dqm [ 7 : 0] = Dq [ 7 : 0];
978
            end
979
            if (Dqm[1] == 1'b0) begin
980
                Dq_dqm [15 : 8] = Dq [15 : 8];
981
            end
982
 
983
            // Write to memory
984
            case (Bank)
985
                2'b00 : Bank0 [{Row, Col}] = Dq_dqm;
986
                2'b01 : Bank1 [{Row, Col}] = Dq_dqm;
987
                2'b10 : Bank2 [{Row, Col}] = Dq_dqm;
988
                2'b11 : Bank3 [{Row, Col}] = Dq_dqm;
989
            endcase
990
 
991
            // Display debug message
992
            if (Dqm !== 2'b11) begin
993
                // Record tWR for manual precharge
994
                WR_chkm [Bank] = $time;
995
 
996
                if (Debug) begin
997
                    $display("%m : at time %t WRITE: Bank = %h Row = %h, Col = %h, Data = %h", $time, Bank, Row, Col, Dq_dqm);
998
                end
999
            end else begin
1000
                if (Debug) begin
1001
                    $display("%m : at time %t WRITE: Bank = %h Row = %h, Col = %h, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
1002
                end
1003
            end
1004
 
1005
            // Advance burst counter subroutine
1006
            #tHZ Burst_decode;
1007
 
1008
        end else if (Data_out_enable == 1'b1) begin                         // Reading Data from Memory
1009
            // Array buffer
1010
            case (Bank)
1011
                2'b00 : Dq_dqm = Bank0[{Row, Col}];
1012
                2'b01 : Dq_dqm = Bank1[{Row, Col}];
1013
                2'b10 : Dq_dqm = Bank2[{Row, Col}];
1014
                2'b11 : Dq_dqm = Bank3[{Row, Col}];
1015
            endcase
1016
 
1017
            // Dqm operation
1018
            if (Dqm_reg0 [0] == 1'b1) begin
1019
                Dq_dqm [ 7 : 0] = 8'bz;
1020
            end
1021
            if (Dqm_reg0 [1] == 1'b1) begin
1022
                Dq_dqm [15 : 8] = 8'bz;
1023
            end
1024
 
1025
            // Display debug message
1026
            if (Dqm_reg0 !== 2'b11) begin
1027
                Dq_reg = #tAC Dq_dqm;
1028
                if (Debug) begin
1029
                    $display("%m : at time %t READ : Bank = %h Row = %h, Col = %h, Data = %h", $time, Bank, Row, Col, Dq_reg);
1030
                end
1031
            end else begin
1032
                Dq_reg = #tHZ {data_bits{1'bz}};
1033
                if (Debug) begin
1034
                    $display("%m : at time %t READ : Bank = %h Row = %h, Col = %h, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
1035
                end
1036
            end
1037
 
1038
            // Advance burst counter subroutine
1039
            Burst_decode;
1040
        end
1041
    end
1042
 
1043
    // Burst counter decode
1044
    task Burst_decode;
1045
        begin
1046
            // Advance Burst Counter
1047
            Burst_counter = Burst_counter + 1;
1048
 
1049
            // Burst Type
1050
            if (Mode_reg[3] == 1'b0) begin                                  // Sequential Burst
1051
                Col_temp = Col + 1;
1052
            end else if (Mode_reg[3] == 1'b1) begin                         // Interleaved Burst
1053
                Col_temp[2] =  Burst_counter[2] ^  Col_brst[2];
1054
                Col_temp[1] =  Burst_counter[1] ^  Col_brst[1];
1055
                Col_temp[0] =  Burst_counter[0] ^  Col_brst[0];
1056
            end
1057
 
1058
            // Burst Length
1059
            if (Burst_length_2) begin                                       // Burst Length = 2
1060
                Col [0] = Col_temp [0];
1061
            end else if (Burst_length_4) begin                              // Burst Length = 4
1062
                Col [1 : 0] = Col_temp [1 : 0];
1063
            end else if (Burst_length_8) begin                              // Burst Length = 8
1064
                Col [2 : 0] = Col_temp [2 : 0];
1065
            end else begin                                                  // Burst Length = FULL
1066
                Col = Col_temp;
1067
            end
1068
 
1069
            // Burst Read Single Write            
1070
            if (Write_burst_mode == 1'b1) begin
1071
                Data_in_enable = 1'b0;
1072
            end
1073
 
1074
            // Data Counter
1075
            if (Burst_length_1 == 1'b1) begin
1076
                if (Burst_counter >= 1) begin
1077
                    Data_in_enable = 1'b0;
1078
                    Data_out_enable = 1'b0;
1079
                end
1080
            end else if (Burst_length_2 == 1'b1) begin
1081
                if (Burst_counter >= 2) begin
1082
                    Data_in_enable = 1'b0;
1083
                    Data_out_enable = 1'b0;
1084
                end
1085
            end else if (Burst_length_4 == 1'b1) begin
1086
                if (Burst_counter >= 4) begin
1087
                    Data_in_enable = 1'b0;
1088
                    Data_out_enable = 1'b0;
1089
                end
1090
            end else if (Burst_length_8 == 1'b1) begin
1091
                if (Burst_counter >= 8) begin
1092
                    Data_in_enable = 1'b0;
1093
                    Data_out_enable = 1'b0;
1094
                end
1095
            end
1096
        end
1097
    endtask
1098
 
1099
    // Timing Parameters for -7E (133 MHz @ CL2)
1100
    specify
1101
        specparam
1102
            tAH  =  0.8,                                        // Addr, Ba Hold Time
1103
            tAS  =  1.5,                                        // Addr, Ba Setup Time
1104
            tCH  =  2.5,                                        // Clock High-Level Width
1105
            tCL  =  2.5,                                        // Clock Low-Level Width
1106
            tCK  =  7.0,                                        // Clock Cycle Time
1107
            tDH  =  0.8,                                        // Data-in Hold Time
1108
            tDS  =  1.5,                                        // Data-in Setup Time
1109
            tCKH =  0.8,                                        // CKE Hold  Time
1110
            tCKS =  1.5,                                        // CKE Setup Time
1111
            tCMH =  0.8,                                        // CS#, RAS#, CAS#, WE#, DQM# Hold  Time
1112
            tCMS =  1.5;                                        // CS#, RAS#, CAS#, WE#, DQM# Setup Time
1113
        $width    (posedge Clk,           tCH);
1114
        $width    (negedge Clk,           tCL);
1115
        $period   (negedge Clk,           tCK);
1116
        $period   (posedge Clk,           tCK);
1117
        $setuphold(posedge Clk,    Cke,   tCKS, tCKH);
1118
        $setuphold(posedge Clk,    Cs_n,  tCMS, tCMH);
1119
        $setuphold(posedge Clk,    Cas_n, tCMS, tCMH);
1120
        $setuphold(posedge Clk,    Ras_n, tCMS, tCMH);
1121
        $setuphold(posedge Clk,    We_n,  tCMS, tCMH);
1122
        $setuphold(posedge Clk,    Addr,  tAS,  tAH);
1123
        $setuphold(posedge Clk,    Ba,    tAS,  tAH);
1124
        $setuphold(posedge Clk,    Dqm,   tCMS, tCMH);
1125
        $setuphold(posedge Dq_chk, Dq,    tDS,  tDH);
1126
    endspecify
1127
 
1128 403 julius
   task get_byte;
1129
      input [31:0] addr;
1130
      output [7:0] data;
1131
      reg [1:0]     bank;
1132
      reg [15:0]   short;
1133
 
1134
      begin
1135
         bank = addr[24:23];
1136
 
1137
         case(bank)
1138
           2'b00:
1139
             short = Bank0[addr[22:1]];
1140
           2'b01:
1141
             short = Bank1[addr[22:1]];
1142
           2'b10:
1143
             short = Bank2[addr[22:1]];
1144
           2'b11:
1145
             short = Bank3[addr[22:1]];
1146
         endcase // case (bank)
1147
 
1148
         // Get the byte from the short
1149
         if (!addr[0])
1150
           data = short[15:8];
1151
         else
1152
           data = short[7:0];
1153
 
1154
         //$display("SDRAM addr 0x%0h, bank %0d, short 0x%0h, byte 0x%0h", addr, bank, short, data);
1155
 
1156
 
1157
      end
1158
   endtask // get_byte
1159
 
1160 6 julius
endmodule

powered by: WebSVN 2.1.0

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