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

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [verif/] [model/] [mt48lc2m32b2.v] - Blame information for rev 59

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

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

powered by: WebSVN 2.1.0

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