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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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