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

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [verif/] [model/] [mt48lc4m16.v] - Blame information for rev 52

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

Line No. Rev Author Line
1 7 dinesha
//////////////////////////////////////////////////////////////////////////////
2
//  File name : mt48lc4m16.v
3
//////////////////////////////////////////////////////////////////////////////
4
//  Copyright (C) 2008 Free Model Foundry; http://www.freemodelfoundry.com
5
//
6
//  This program is free software; you can redistribute it and/or modify
7
//  it under the terms of the GNU General Public License version 2 as
8
//  published by the Free Software Foundation.
9
//
10
//  MODIFICATION HISTORY:
11
//
12
//  version: |  author:       |  mod date:  | changes made:
13
//    V1.0     S.Janevski       08 Feb 27    Initial release
14
//    V1.1     S.Janevski       08 Mar 26    Assertions of wrong DQM settings during powerup removed
15
//////////////////////////////////////////////////////////////////////////////
16
//  PART DESCRIPTION:
17
//
18
//  Library:    RAM
19
//  Technology: LVTTL
20
//  Part:       mt48lc4m16
21
//
22
//  Description: 1M x 16 x 4Banks SDRAM
23
//
24
//////////////////////////////////////////////////////////////////////////////
25
//  Known Bugs:
26
//
27
//////////////////////////////////////////////////////////////////////////////
28
 
29
//////////////////////////////////////////////////////////////////////////////
30
// MODULE DECLARATION                                                       //
31
//////////////////////////////////////////////////////////////////////////////
32
`timescale 1 ns/100 ps
33
 
34
module mt48lc4m16
35
    (
36
     A11      ,
37
     A10      ,
38
     A9       ,
39
     A8       ,
40
     A7       ,
41
     A6       ,
42
     A5       ,
43
     A4       ,
44
     A3       ,
45
     A2       ,
46
     A1       ,
47
     A0       ,
48
 
49
     DQ15      ,
50
     DQ14      ,
51
     DQ13      ,
52
     DQ12      ,
53
     DQ11      ,
54
     DQ10      ,
55
     DQ9       ,
56
     DQ8       ,
57
     DQ7       ,
58
     DQ6       ,
59
     DQ5       ,
60
     DQ4       ,
61
     DQ3       ,
62
     DQ2       ,
63
     DQ1       ,
64
     DQ0       ,
65
 
66
     BA0  ,
67
     BA1  ,
68
     DQMH ,
69
     DQML ,
70
     CLK  ,
71
     CKE  ,
72
     WENeg  ,
73
     RASNeg ,
74
     CSNeg  ,
75
     CASNeg );
76
 
77
    ////////////////////////////////////////////////////////////////////////
78
    // Port / Part Pin Declarations
79
    ////////////////////////////////////////////////////////////////////////
80
    input  A11  ;
81
    input  A10  ;
82
    input  A9   ;
83
    input  A8   ;
84
    input  A7   ;
85
    input  A6   ;
86
    input  A5   ;
87
    input  A4   ;
88
    input  A3   ;
89
    input  A2   ;
90
    input  A1   ;
91
    input  A0   ;
92
 
93
    inout  DQ15   ;
94
    inout  DQ14   ;
95
    inout  DQ13   ;
96
    inout  DQ12   ;
97
    inout  DQ11   ;
98
    inout  DQ10   ;
99
    inout  DQ9   ;
100
    inout  DQ8   ;
101
    inout  DQ7   ;
102
    inout  DQ6   ;
103
    inout  DQ5   ;
104
    inout  DQ4   ;
105
    inout  DQ3   ;
106
    inout  DQ2   ;
107
    inout  DQ1   ;
108
    inout  DQ0   ;
109
 
110
    input  BA0   ;
111
    input  BA1   ;
112
    input  DQMH  ;
113
    input  DQML  ;
114
    input  CLK   ;
115
    input  CKE   ;
116
    input  WENeg  ;
117
    input  RASNeg ;
118
    input  CSNeg  ;
119
    input  CASNeg ;
120
 
121
    // interconnect path delay signals
122
    wire   A11_ipd  ;
123
    wire   A10_ipd  ;
124
    wire   A9_ipd   ;
125
    wire   A8_ipd   ;
126
    wire   A7_ipd   ;
127
    wire   A6_ipd   ;
128
    wire   A5_ipd   ;
129
    wire   A4_ipd   ;
130
    wire   A3_ipd   ;
131
    wire   A2_ipd   ;
132
    wire   A1_ipd   ;
133
    wire   A0_ipd   ;
134
 
135
    wire [11 : 0] A;
136
    assign        A = {A11_ipd,
137
                               A10_ipd,
138
                               A9_ipd,
139
                               A8_ipd,
140
                               A7_ipd,
141
                               A6_ipd,
142
                               A5_ipd,
143
                               A4_ipd,
144
                               A3_ipd,
145
                               A2_ipd,
146
                               A1_ipd,
147
                               A0_ipd };
148
 
149
    wire          DQ15_ipd   ;
150
    wire          DQ14_ipd   ;
151
    wire          DQ13_ipd   ;
152
    wire          DQ12_ipd   ;
153
    wire          DQ11_ipd   ;
154
    wire          DQ10_ipd   ;
155
    wire          DQ9_ipd   ;
156
    wire          DQ8_ipd   ;
157
    wire          DQ7_ipd   ;
158
    wire          DQ6_ipd   ;
159
    wire          DQ5_ipd   ;
160
    wire          DQ4_ipd   ;
161
    wire          DQ3_ipd   ;
162
    wire          DQ2_ipd   ;
163
    wire          DQ1_ipd   ;
164
    wire          DQ0_ipd   ;
165
 
166
    wire [15 : 0 ] DQIn;
167
    assign     DQIn = { DQ15_ipd,
168
                         DQ14_ipd,
169
                         DQ13_ipd,
170
                         DQ12_ipd,
171
                         DQ11_ipd,
172
                         DQ10_ipd,
173
                         DQ9_ipd,
174
                         DQ8_ipd,
175
                         DQ7_ipd,
176
                         DQ6_ipd,
177
                         DQ5_ipd,
178
                         DQ4_ipd,
179
                         DQ3_ipd,
180
                         DQ2_ipd,
181
                         DQ1_ipd,
182
                         DQ0_ipd };
183
 
184
    wire [15 : 0] DQOut;
185
    assign     DQOut = { DQ15,
186
                          DQ14,
187
                          DQ13,
188
                          DQ12,
189
                          DQ11,
190
                          DQ10,
191
                          DQ9,
192
                          DQ8,
193
                          DQ7,
194
                          DQ6,
195
                          DQ5,
196
                          DQ4,
197
                          DQ3,
198
                          DQ2,
199
                          DQ1,
200
                          DQ0 };
201
 
202
    wire  BA0_ipd   ;
203
    wire  BA1_ipd   ;
204
    wire  DQM1_ipd  ;
205
    wire  DQM0_ipd  ;
206
    wire  CLK_ipd   ;
207
    wire  CKE_ipd   ;
208
    wire  WENeg_ipd  ;
209
    wire  RASNeg_ipd ;
210
    wire  CSNeg_ipd  ;
211
    wire  CASNeg_ipd ;
212
 
213
    integer bank;
214
    integer bank_tmp;
215
 
216
    //  internal delays
217
    reg rct_in ;
218
    reg rct_out;
219
    reg [3:0] rcdt_in ;
220
    reg [3:0] rcdt_out;
221
    reg pre_in        ;
222
    reg pre_out       ;
223
    reg refreshed_in  ;
224
    reg refreshed_out ;
225
    reg rcar_out      ;
226
    reg rcar_in       ;
227
    reg [3:0] ras_in  = 1'b0;
228
    reg [3:0] ras_out = 1'b0;
229
 
230
    reg [15 : 0] DQ_zd = 16'bz;
231
    assign {DQ15_zd,
232
            DQ14_zd,
233
            DQ13_zd,
234
            DQ12_zd,
235
            DQ11_zd,
236
            DQ10_zd,
237
            DQ9_zd,
238
            DQ8_zd,
239
            DQ7_zd,
240
            DQ6_zd,
241
            DQ5_zd,
242
            DQ4_zd,
243
            DQ3_zd,
244
            DQ2_zd,
245
            DQ1_zd,
246
            DQ0_zd } = DQ_zd;
247
 
248
    parameter UserPreload   = 1'b1;
249
    parameter mem_file_name = "none";  //"mt48lc4m16.mem";
250
    parameter TimingModel   = "DefaultTimingModel";
251
    parameter PartID        = "mt48lc4m16";
252
    parameter hi_bank       = 3;
253
    parameter depth         = 25'h100000;
254
 
255
    reg PoweredUp = 1'b0;
256
    reg CKEreg    = 1'b0;
257
    reg CAS_Lat ;
258
    reg CAS_Lat2;
259
    reg [15:0] DataDrive = 16'bz ;
260
 
261
    // Memory array declaration
262
    integer Mem [0:(hi_bank+1)*depth*2-1];
263
 
264
    // Type definition for state machine
265
    parameter pwron           = 5'd0;
266
    parameter precharge       = 5'd1;
267
    parameter idle            = 5'd2;
268
    parameter mode_set        = 5'd3;
269
    parameter self_refresh    = 5'd4;
270
    parameter auto_refresh    = 5'd5;
271
    parameter pwrdwn          = 5'd6;
272
    parameter bank_act        = 5'd7;
273
    parameter bank_act_pwrdwn = 5'd8;
274
    parameter write           = 5'd9;
275
    parameter write_suspend   = 5'd10;
276
    parameter read            = 5'd11;
277
    parameter read_suspend    = 5'd12;
278
    parameter write_auto_pre  = 5'd13;
279
    parameter read_auto_pre   = 5'd14;
280
 
281
    reg [4:0] statebank [hi_bank:0];
282
 
283
    // Type definition for commands
284
    parameter desl = 4'd0;
285
    parameter nop  = 4'd1;
286
    parameter bst  = 4'd2;
287
    parameter rd   = 4'd3;
288
    parameter writ = 4'd4;
289
    parameter act  = 4'd5;
290
    parameter pre  = 4'd6;
291
    parameter mrs  = 4'd7;
292
    parameter ref  = 4'd8;
293
 
294
    reg [3:0] command = desl;
295
 
296
    // burst type
297
    parameter sequential = 1'b0;
298
    parameter interleave = 1'b1;
299
    reg Burst ;
300
 
301
    // write burst mode
302
    parameter programmed = 1'b0;
303
    parameter single     = 1'b1;
304
    reg WB ;
305
 
306
    //burst sequences
307
    integer  intab [0:63];
308
 
309
    reg [19:0] MemAddr [hi_bank:0];
310
    integer BurstCnt   [hi_bank:0];
311
    integer StartAddr  [hi_bank:0];
312
    integer BurstInc   [hi_bank:0];
313
    integer BaseLoc    [hi_bank:0];
314
 
315
    integer Loc;
316
    integer BurstLen;
317
    integer Burst_Bits;
318
 
319
    reg written = 1'b0;
320
    reg chip_en = 1'b0;
321
 
322
    integer cur_bank;
323
    reg [11:0] ModeReg ;
324
    integer Ref_Cnt = 0;
325
 
326
    time Next_Ref = 0;
327
    reg [8*8:1] BankString ;
328
 
329
    reg Viol = 1'b0;
330
    reg [15:0] DataDriveOut = 16'bz;
331
    reg [15:0] DataDrive1 = 16'bz;
332
    reg [15:0] DataDrive2 = 16'bz;
333
    reg [15:0] DataDrive3 = 16'bz;
334
 
335
    reg DQM0_reg0 ;
336
    reg DQM0_reg1 ;
337
    reg DQM0_reg2 ;
338
    reg DQM1_reg0 ;
339
    reg DQM1_reg1 ;
340
    reg DQM1_reg2 ;
341
 
342
    // tdevice values: values for internal delays
343
    time tdevice_TRASmin   = 0;
344
    time tdevice_TRASmax   = 0;
345
    time tdevice_TRC   = 0;
346
    time tdevice_TRCAR = 0;
347
    time tdevice_TRCD  = 0;
348
    time tdevice_TRP   = 0;
349
 
350
    ///////////////////////////////////////////////////////////////////////////
351
    //Interconnect Path Delay Section
352
    ///////////////////////////////////////////////////////////////////////////
353
    buf   (A11_ipd, A11);
354
    buf   (A10_ipd, A10);
355
    buf   (A9_ipd , A9 );
356
    buf   (A8_ipd , A8 );
357
    buf   (A7_ipd , A7 );
358
    buf   (A6_ipd , A6 );
359
    buf   (A5_ipd , A5 );
360
    buf   (A4_ipd , A4 );
361
    buf   (A3_ipd , A3 );
362
    buf   (A2_ipd , A2 );
363
    buf   (A1_ipd , A1 );
364
    buf   (A0_ipd , A0 );
365
 
366
    buf   (DQ15_ipd , DQ15 );
367
    buf   (DQ14_ipd , DQ14 );
368
    buf   (DQ13_ipd , DQ13 );
369
    buf   (DQ12_ipd , DQ12 );
370
    buf   (DQ11_ipd , DQ11 );
371
    buf   (DQ10_ipd , DQ10 );
372
    buf   (DQ9_ipd  , DQ9 );
373
    buf   (DQ8_ipd  , DQ8 );
374
    buf   (DQ7_ipd  , DQ7 );
375
    buf   (DQ6_ipd  , DQ6 );
376
    buf   (DQ5_ipd  , DQ5 );
377
    buf   (DQ4_ipd  , DQ4 );
378
    buf   (DQ3_ipd  , DQ3 );
379
    buf   (DQ2_ipd  , DQ2 );
380
    buf   (DQ1_ipd  , DQ1 );
381
    buf   (DQ0_ipd  , DQ0 );
382
 
383
    buf   (CASNeg_ipd, CASNeg);
384
    buf   (RASNeg_ipd, RASNeg);
385
    buf   (BA0_ipd   , BA0   );
386
    buf   (BA1_ipd   , BA1   );
387
    buf   (DQM0_ipd  , DQML  );
388
    buf   (DQM1_ipd  , DQMH  );
389
    buf   (CLK_ipd   , CLK   );
390
    buf   (CKE_ipd   , CKE   );
391
    buf   (WENeg_ipd , WENeg );
392
    buf   (CSNeg_ipd , CSNeg );
393
 
394
    ///////////////////////////////////////////////////////////////////////////
395
    // Propagation  delay Section
396
    ///////////////////////////////////////////////////////////////////////////
397
    nmos   (DQ15 ,   DQ15_zd  , 1);
398
    nmos   (DQ14 ,   DQ14_zd  , 1);
399
    nmos   (DQ13 ,   DQ13_zd  , 1);
400
    nmos   (DQ12 ,   DQ12_zd  , 1);
401
    nmos   (DQ11 ,   DQ11_zd  , 1);
402
    nmos   (DQ10 ,   DQ10_zd  , 1);
403
    nmos   (DQ9  ,   DQ9_zd   , 1);
404
    nmos   (DQ8  ,   DQ8_zd   , 1);
405
    nmos   (DQ7  ,   DQ7_zd   , 1);
406
    nmos   (DQ6  ,   DQ6_zd   , 1);
407
    nmos   (DQ5  ,   DQ5_zd   , 1);
408
    nmos   (DQ4  ,   DQ4_zd   , 1);
409
    nmos   (DQ3  ,   DQ3_zd   , 1);
410
    nmos   (DQ2  ,   DQ2_zd   , 1);
411
    nmos   (DQ1  ,   DQ1_zd   , 1);
412
    nmos   (DQ0  ,   DQ0_zd   , 1);
413
 
414
    wire deg;
415
    wire chip_act;
416
    assign chip_act = chip_en;
417
 
418
    wire chip_act_deg;
419
    assign chip_act_deg = chip_act && deg;
420
 
421
    wire cas_latency2;
422
    wire cas_latency3;
423
 
424
    assign cas_latency2 = ~CAS_Lat && CAS_Lat2;
425
    assign cas_latency3 = CAS_Lat && CAS_Lat2;
426
 
427
    specify
428
        // tipd delays: interconnect path delays, mapped to input port delays.
429
        // In Verilog it is not necessary to declare any tipd delay variables,
430
        // they can be taken from SDF file
431
        // With all the other delays real delays would be taken from SDF file
432
 
433
        // tpd delays
434
        specparam   tpd_CLK_DQ0    = 1;
435
        specparam   tpd_CLK_DQ1    = 1;
436
 
437
        // tpw values: pulse widths
438
        specparam   tpw_CLK_posedge = 1;
439
        specparam   tpw_CLK_negedge = 1;
440
 
441
        // tsetup values: setup times
442
        specparam   tsetup_DQ0_CLK  = 1;  // tDS
443
 
444
        // thold values: hold times
445
        specparam   thold_DQ0_CLK   = 1;  // tDH
446
 
447
        // tperiod_min: minimum clock period = 1/max freq
448
        specparam    tperiod_CLK_cl1_eq_1_posedge        = 1;
449
        specparam    tperiod_CLK_cl2_eq_1_posedge        = 1;
450
 
451
        // tdevice values: values for internal delays
452
        specparam         tdevice_REF      = 15625 ;
453
 
454
        ///////////////////////////////////////////////////////////////////////
455
        // Input Port Delays don't require Verilog description
456
        ///////////////////////////////////////////////////////////////////////
457
        // Path delays                                                       //
458
        ///////////////////////////////////////////////////////////////////////
459
 
460
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ0;
461
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ0;
462
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ0;
463
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ0;
464
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ0;
465
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ0;
466
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ0;
467
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ0;
468
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ0;
469
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ0;
470
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ0;
471
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ0;
472
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ0;
473
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ0;
474
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ0;
475
        if (~CAS_Lat && CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ0;
476
 
477
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ0) = tpd_CLK_DQ1;
478
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ1) = tpd_CLK_DQ1;
479
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ2) = tpd_CLK_DQ1;
480
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ3) = tpd_CLK_DQ1;
481
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ4) = tpd_CLK_DQ1;
482
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ5) = tpd_CLK_DQ1;
483
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ6) = tpd_CLK_DQ1;
484
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ7) = tpd_CLK_DQ1;
485
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ8) = tpd_CLK_DQ1;
486
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ9) = tpd_CLK_DQ1;
487
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ10) = tpd_CLK_DQ1;
488
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ11) = tpd_CLK_DQ1;
489
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ12) = tpd_CLK_DQ1;
490
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ13) = tpd_CLK_DQ1;
491
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ14) = tpd_CLK_DQ1;
492
        if (CAS_Lat && CAS_Lat2) (CLK *> DQ15) = tpd_CLK_DQ1;
493
 
494
        ////////////////////////////////////////////////////////////////////////
495
        // Timing Check Section
496
        ////////////////////////////////////////////////////////////////////////
497
        $setup (BA0 , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
498
        $setup (BA1 , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
499
        $setup (DQML, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
500
        $setup (DQMH, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
501
        $setup (CKE  , posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
502
        $setup (WENeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
503
        $setup (CSNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
504
        $setup (CASNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
505
        $setup (RASNeg, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
506
 
507
        $setup (DQ0 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
508
        $setup (DQ1 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
509
        $setup (DQ2 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
510
        $setup (DQ3 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
511
        $setup (DQ4 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
512
        $setup (DQ5 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
513
        $setup (DQ6 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
514
        $setup (DQ7 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
515
        $setup (DQ8 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
516
        $setup (DQ9 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
517
        $setup (DQ10 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
518
        $setup (DQ11 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
519
        $setup (DQ12 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
520
        $setup (DQ13 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
521
        $setup (DQ14 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
522
        $setup (DQ15 ,posedge CLK &&& chip_act_deg, tsetup_DQ0_CLK, Viol);
523
 
524
        $setup (A0, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
525
        $setup (A1, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
526
        $setup (A2, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
527
        $setup (A3, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
528
        $setup (A4, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
529
        $setup (A5, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
530
        $setup (A6, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
531
        $setup (A7, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
532
        $setup (A8, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
533
        $setup (A9, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
534
        $setup (A10, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
535
        $setup (A11, posedge CLK &&& chip_act, tsetup_DQ0_CLK, Viol);
536
 
537
        $hold (posedge CLK &&& chip_act, BA0, thold_DQ0_CLK, Viol);
538
        $hold (posedge CLK &&& chip_act, BA1, thold_DQ0_CLK, Viol);
539
        $hold (posedge CLK &&& chip_act, DQML, thold_DQ0_CLK, Viol);
540
        $hold (posedge CLK &&& chip_act, DQMH, thold_DQ0_CLK, Viol);
541
        $hold (posedge CLK &&& chip_act, CKE , thold_DQ0_CLK, Viol);
542
        $hold (posedge CLK &&& chip_act, CASNeg, thold_DQ0_CLK, Viol);
543
        $hold (posedge CLK &&& chip_act, RASNeg, thold_DQ0_CLK, Viol);
544
        $hold (posedge CLK &&& chip_act, WENeg, thold_DQ0_CLK, Viol);
545
        $hold (posedge CLK &&& chip_act, CSNeg, thold_DQ0_CLK, Viol);
546
 
547
        $hold (posedge CLK &&& chip_act, A0, thold_DQ0_CLK, Viol);
548
        $hold (posedge CLK &&& chip_act, A1, thold_DQ0_CLK, Viol);
549
        $hold (posedge CLK &&& chip_act, A2, thold_DQ0_CLK, Viol);
550
        $hold (posedge CLK &&& chip_act, A3, thold_DQ0_CLK, Viol);
551
        $hold (posedge CLK &&& chip_act, A4, thold_DQ0_CLK, Viol);
552
        $hold (posedge CLK &&& chip_act, A5, thold_DQ0_CLK, Viol);
553
        $hold (posedge CLK &&& chip_act, A6, thold_DQ0_CLK, Viol);
554
        $hold (posedge CLK &&& chip_act, A7, thold_DQ0_CLK, Viol);
555
        $hold (posedge CLK &&& chip_act, A8, thold_DQ0_CLK, Viol);
556
        $hold (posedge CLK &&& chip_act, A9, thold_DQ0_CLK, Viol);
557
        $hold (posedge CLK &&& chip_act, A10, thold_DQ0_CLK, Viol);
558
        $hold (posedge CLK &&& chip_act, A11, thold_DQ0_CLK, Viol);
559
 
560
        $hold (posedge CLK &&& chip_act_deg, DQ0, thold_DQ0_CLK, Viol);
561
        $hold (posedge CLK &&& chip_act_deg, DQ1, thold_DQ0_CLK, Viol);
562
        $hold (posedge CLK &&& chip_act_deg, DQ2, thold_DQ0_CLK, Viol);
563
        $hold (posedge CLK &&& chip_act_deg, DQ3, thold_DQ0_CLK, Viol);
564
        $hold (posedge CLK &&& chip_act_deg, DQ4, thold_DQ0_CLK, Viol);
565
        $hold (posedge CLK &&& chip_act_deg, DQ5, thold_DQ0_CLK, Viol);
566
        $hold (posedge CLK &&& chip_act_deg, DQ6, thold_DQ0_CLK, Viol);
567
        $hold (posedge CLK &&& chip_act_deg, DQ7, thold_DQ0_CLK, Viol);
568
        $hold (posedge CLK &&& chip_act_deg, DQ8, thold_DQ0_CLK, Viol);
569
        $hold (posedge CLK &&& chip_act_deg, DQ9, thold_DQ0_CLK, Viol);
570
        $hold (posedge CLK &&& chip_act_deg, DQ10, thold_DQ0_CLK, Viol);
571
        $hold (posedge CLK &&& chip_act_deg, DQ11, thold_DQ0_CLK, Viol);
572
        $hold (posedge CLK &&& chip_act_deg, DQ12, thold_DQ0_CLK, Viol);
573
        $hold (posedge CLK &&& chip_act_deg, DQ13, thold_DQ0_CLK, Viol);
574
        $hold (posedge CLK &&& chip_act_deg, DQ14, thold_DQ0_CLK, Viol);
575
        $hold (posedge CLK &&& chip_act_deg, DQ15, thold_DQ0_CLK, Viol);
576
 
577
        $width (posedge CLK &&& chip_act, tpw_CLK_posedge);
578
        $width (negedge CLK &&& chip_act, tpw_CLK_negedge);
579
 
580
        $period (posedge CLK &&& cas_latency2, tperiod_CLK_cl1_eq_1_posedge);
581
        $period (posedge CLK &&& cas_latency3, tperiod_CLK_cl2_eq_1_posedge);
582
 
583
    endspecify
584
 
585
    task generate_out ;
586
        output [15:0] DataDrive;
587
        input Bank;
588
        integer Bank;
589
        integer location;
590
    begin
591
        location = Bank * depth * 2 + Loc;
592
 
593
        DataDrive[7:0] = 8'bx;
594
        if (Mem[location] > -1)
595
            DataDrive[7:0] = Mem[location];
596
 
597
        DataDrive[15:8] = 8'bx;
598
        if (Mem[location+1] > -1)
599
            DataDrive[15:8] = Mem[location+1];
600
 
601
    end
602
    endtask
603
 
604
    task MemWrite;
605
        input Bank;
606
        integer Bank;
607
        integer location;
608
    begin
609
        location = Bank * depth * 2 + Loc;
610
 
611
        if (~DQM0_ipd)
612
        begin
613
            Mem[location] = -1;
614
            if (~Viol)
615
                Mem[location] = DQIn[7:0];
616
        end
617
 
618
        if (~DQM1_ipd)
619
        begin
620
            Mem[location+1] = -1;
621
            if (~Viol)
622
                Mem[location+1] = DQIn[15:8];
623
        end
624
 
625
    end
626
    endtask
627
 
628
    task BurstIncProc;
629
        input Bank;
630
        integer Bank;
631
    begin
632
        BurstInc[Bank] = 0;
633
        if (Burst_Bits == 1)
634
            BurstInc[Bank] = A[0:0];
635
        if (Burst_Bits == 2)
636
            BurstInc[Bank] = A[1:0];
637
        if (Burst_Bits == 3)
638
            BurstInc[Bank] = A[2:0];
639
        if (Burst_Bits == 7)
640
            BurstInc[Bank] = A[6:0];
641
    end
642
    endtask
643
 
644
    task NextStateAuto;
645
        input Bank;
646
        input state;
647
        integer Bank;
648
        reg [4:0] state;
649
    begin
650
        if (~A[10])
651
            statebank[Bank] = state;
652
        else if (A[10])
653
            if (state == write)
654
                statebank[Bank] = write_auto_pre;
655
            else
656
                statebank[Bank] = read_auto_pre;
657
    end
658
    endtask
659
 
660
    //////////////////////////////////////////////////////////////////////////
661
    // Main Behavior Block                                                  //
662
    //////////////////////////////////////////////////////////////////////////
663
 
664
    // chech when data is generated from model to avoid setup/hold check in
665
    // those occasion
666
    reg   deq;
667
    always @(DQIn, DQOut)
668
        begin
669
            if (DQIn==DQOut)
670
                deq=1'b1;
671
            else
672
                deq=1'b0;
673
        end
674
    assign deg=deq;
675
 
676
    // initialize burst sequences
677
    initial
678
    begin
679
        intab[0] = 0;
680
        intab[1] = 1;
681
        intab[2] = 2;
682
        intab[3] = 3;
683
        intab[4] = 4;
684
        intab[5] = 5;
685
        intab[6] = 6;
686
        intab[7] = 7;
687
        intab[8] = 1;
688
        intab[9] = 0;
689
        intab[10] = 3;
690
        intab[11] = 2;
691
        intab[12] = 5;
692
        intab[13] = 4;
693
        intab[14] = 7;
694
        intab[15] = 6;
695
        intab[16] = 2;
696
        intab[17] = 3;
697
        intab[18] = 0;
698
        intab[19] = 1;
699
        intab[20] = 6;
700
        intab[21] = 7;
701
        intab[22] = 4;
702
        intab[23] = 5;
703
        intab[24] = 3;
704
        intab[25] = 2;
705
        intab[26] = 1;
706
        intab[27] = 0;
707
        intab[28] = 7;
708
        intab[29] = 6;
709
        intab[30] = 5;
710
        intab[31] = 4;
711
        intab[32] = 4;
712
        intab[33] = 5;
713
        intab[34] = 6;
714
        intab[35] = 7;
715
        intab[36] = 0;
716
        intab[37] = 1;
717
        intab[38] = 2;
718
        intab[39] = 3;
719
        intab[40] = 5;
720
        intab[41] = 4;
721
        intab[42] = 7;
722
        intab[43] = 6;
723
        intab[44] = 1;
724
        intab[45] = 0;
725
        intab[46] = 3;
726
        intab[47] = 2;
727
        intab[48] = 6;
728
        intab[49] = 7;
729
        intab[50] = 4;
730
        intab[51] = 5;
731
        intab[52] = 2;
732
        intab[53] = 3;
733
        intab[54] = 0;
734
        intab[55] = 1;
735
        intab[56] = 7;
736
        intab[57] = 6;
737
        intab[58] = 5;
738
        intab[59] = 4;
739
        intab[60] = 3;
740
        intab[61] = 2;
741
        intab[62] = 1;
742
        intab[63] = 0;
743
    end
744
 
745
    // initialize memory and load preload files if any
746
    initial
747
    begin: InitMemory
748
    integer i;
749
        for (i=0; i<=((hi_bank+1)*depth*2 - 1); i=i+1)
750
        begin
751
            Mem[i] = -1;
752
        end
753
        // Memory preload file
754
        // mt48lc4m16.mem file
755
        //   @bbbbbb - <bbbbbb> stands for address within memory,
756
        //   dd      - <dd> is word to be written at Mem(bbbbbb++)
757
        //              (bbbbbb is incremented at every load)
758
        if (UserPreload && !(mem_file_name == "none"))
759
            $readmemh(mem_file_name,Mem);
760
    end
761
 
762
    //Power Up time 100 us;
763
    initial
764
    begin
765
        PoweredUp = 1'b0;
766
        statebank[0] = pwron;
767
        statebank[1] = pwron;
768
        statebank[2] = pwron;
769
        statebank[3] = pwron;
770
        #100000 PoweredUp = 1'b1;
771
    end
772
 
773
    always @(posedge ras_in[0])
774
    begin:TRASrise0
775
        ras_out[0] <= #tdevice_TRASmin ras_in[0];
776
    end
777
 
778
    always @(negedge ras_in[0])
779
    begin:TRASfall0
780
        ras_out[0] <= #tdevice_TRASmax ras_in[0];
781
    end
782
 
783
    always @(posedge ras_in[1])
784
    begin:TRASrise1
785
        ras_out[1] <= #tdevice_TRASmin ras_in[1];
786
    end
787
 
788
    always @(negedge ras_in[1])
789
    begin:TRASfall1
790
        ras_out[1] <= #tdevice_TRASmax ras_in[1];
791
    end
792
 
793
    always @(posedge ras_in[2])
794
    begin:TRASrise2
795
        ras_out[2] <= #tdevice_TRASmin ras_in[2];
796
    end
797
    always @(negedge ras_in[2])
798
    begin:TRASfall2
799
        ras_out[2] <= #tdevice_TRASmax ras_in[2];
800
    end
801
 
802
    always @(posedge ras_in[3])
803
    begin:TRASrise3
804
        ras_out[3] <= #tdevice_TRASmin ras_in[3];
805
    end
806
 
807
    always @(negedge ras_in[3])
808
    begin:TRASfall3
809
        ras_out[3] <= #tdevice_TRASmax ras_in[3];
810
    end
811
 
812
    always @(posedge rcdt_in[0])
813
    begin:TRCDrise0
814
        rcdt_out[0] <= #5 1'b1;
815
    end
816
    always @(negedge rcdt_in[0])
817
    begin:TRCDfall0
818
        rcdt_out[0] <= #tdevice_TRCD 1'b0;
819
    end
820
 
821
    always @(posedge rcdt_in[1])
822
    begin:TRCDrise1
823
        rcdt_out[1] <= #5 1'b1;
824
    end
825
    always @(negedge rcdt_in[1])
826
    begin:TRCDfall1
827
        rcdt_out[1] <= #tdevice_TRCD 1'b0;
828
    end
829
 
830
    always @(posedge rcdt_in[2])
831
    begin:TRCDrise2
832
        rcdt_out[2] <= #5 1'b1;
833
    end
834
    always @(negedge rcdt_in[2])
835
    begin:TRCDfall2
836
        rcdt_out[2] <= #tdevice_TRCD 1'b0;
837
    end
838
 
839
    always @(posedge rcdt_in[3])
840
    begin:TRCDrise3
841
        rcdt_out[3] <= #5 1'b1;
842
    end
843
    always @(negedge rcdt_in[3])
844
    begin:TRCDfall3
845
        rcdt_out[3] <= #tdevice_TRCD 1'b0;
846
    end
847
 
848
    /////////////////////////////////////////////////////////////////////////
849
    // Functional Section
850
    /////////////////////////////////////////////////////////////////////////
851
    always @(posedge CLK)
852
    begin
853
        if ($time > Next_Ref && PoweredUp && Ref_Cnt > 0)
854
        begin
855
            Ref_Cnt = Ref_Cnt - 1;
856
            Next_Ref = $time + tdevice_REF;
857
        end
858
        if (CKEreg)
859
        begin
860
            if (~CSNeg_ipd)
861
                chip_en = 1;
862
            else
863
                chip_en = 0;
864
        end
865
 
866
        if (CKEreg && ~CSNeg_ipd)
867
        begin
868
            if (WENeg_ipd == 1'bx)
869
                $display(" Unusable value for WENeg ");
870
            if (RASNeg_ipd == 1'bx)
871
                $display(" Unusable value for RASNeg ");
872
            if (CASNeg_ipd == 1'bx)
873
                $display(" Unusable value for CASNeg ");
874
 
875
            // Command Decode
876
            if (RASNeg_ipd && CASNeg_ipd && WENeg_ipd)
877
                command = nop;
878
            else if (~RASNeg_ipd && CASNeg_ipd && WENeg_ipd)
879
                command = act;
880
            else if (RASNeg_ipd && ~CASNeg_ipd && WENeg_ipd)
881
                command = rd;
882
            else if (RASNeg_ipd && ~CASNeg_ipd && ~WENeg_ipd)
883
                command = writ;
884
            else if (RASNeg_ipd && CASNeg_ipd && ~WENeg_ipd)
885
                command = bst;
886
            else if (~RASNeg_ipd && CASNeg_ipd && ~WENeg_ipd)
887
                command = pre;
888
            else if (~RASNeg_ipd && ~CASNeg_ipd && WENeg_ipd)
889
                command = ref;
890
            else if (~RASNeg_ipd && ~CASNeg_ipd && ~WENeg_ipd)
891
                command = mrs;
892
 
893
            //  PowerUp Check
894
            if (~(PoweredUp) && command != nop)
895
            begin
896
                $display (" Incorrect power up. Command issued before ");
897
                $display (" power up complete. ");
898
            end
899
 
900
            //  Bank Decode
901
            if (~BA0_ipd && ~BA1_ipd)
902
                cur_bank = 0;
903
            else if (BA0_ipd && ~BA1_ipd)
904
                cur_bank = 1;
905
            else if (~BA0_ipd && BA1_ipd)
906
                cur_bank = 2;
907
            else if (BA0_ipd && BA1_ipd)
908
                cur_bank = 3;
909
            else
910
            begin
911
                $display ("Could not decode bank selection - results");
912
                $display ("may be incorrect.");
913
            end
914
        end
915
 
916
        // The Big State Machine
917
        if (CKEreg)
918
        begin
919
            if (CSNeg_ipd == 1'bx)
920
                $display ("Unusable value for CSNeg");
921
 
922
            if (CSNeg_ipd)
923
                command = nop;
924
 
925
            // DQM pipeline
926
            DQM0_reg2 = DQM0_reg1;
927
            DQM0_reg1 = DQM0_reg0;
928
            DQM0_reg0 = DQM0_ipd;
929
            DQM1_reg2 = DQM1_reg1;
930
            DQM1_reg1 = DQM1_reg0;
931
            DQM1_reg0 = DQM1_ipd;
932
 
933
            // by default data drive is Z, might get over written in one
934
            // of the passes below
935
            DataDrive = 16'bz;
936
 
937
            for (bank = 0; bank <= hi_bank; bank = bank + 1)
938
            begin
939
                case (statebank[bank])
940
                pwron :
941
                begin
942
                    if (~PoweredUp)
943
                    begin
944
                        if (command != nop)
945
                            $display ("Only NOPs allowed during power up.");
946
                        DataDrive = 16'bz;
947
                    end
948
                    else if (command == pre && (cur_bank == bank || A[10]))
949
                    begin
950
                        statebank[bank] = precharge;
951
                        statebank[bank] <= #tdevice_TRP idle;
952
                    end
953
                end
954
 
955
                precharge :
956
                begin
957
                    if (cur_bank == bank)
958
                    // It is only an error if this bank is selected
959
                        if (command != nop && command != pre)
960
                        begin
961
                            $display ("Illegal command received ");
962
                            $display ("during precharge.",$time);
963
                        end
964
                end
965
 
966
                idle :
967
                begin
968
                    if (command == nop || command == bst || command == pre
969
                        || cur_bank != bank)
970
                    begin
971
                    end
972
                    else if (command == mrs)
973
                    begin
974
                        if (statebank[0] == idle && statebank[1] == idle &&
975
                            statebank[2] == idle && statebank[3] == idle)
976
                        begin
977
                            ModeReg = A;
978
                            statebank[bank] = mode_set;
979
                        end
980
                    end
981
                    else if (command == ref)
982
                    begin
983
                        if (statebank[0] == idle && statebank[1] == idle &&
984
                            statebank[2] == idle && statebank[3] == idle)
985
                            if (CKE)
986
                            begin
987
                                statebank[bank] = auto_refresh;
988
                                statebank[bank] <= #tdevice_TRCAR idle;
989
                            end
990
                            else
991
                            begin
992
                                statebank[0] = self_refresh;
993
                                statebank[1] = self_refresh;
994
                                statebank[2] = self_refresh;
995
                                statebank[3] = self_refresh;
996
                            end
997
                    end
998
                    else if (command == act)
999
                    begin
1000
                        statebank[bank] = bank_act;
1001
                        ras_in[bank] = 1'b1;
1002
                        ras_in [bank] <= #70 1'b0;
1003
                        rct_in = 1'b1;
1004
                        rct_in <= #1 1'b0;
1005
                        rcdt_in[bank] = 1'b1;
1006
                        rcdt_in[bank] <= #1 1'b0;
1007
                        MemAddr[bank][19:8] = A; // latch row addr
1008
                    end
1009
                    else
1010
               $display ("Illegal command received in idle state.",$time);
1011
                end
1012
 
1013
                mode_set :
1014
                begin
1015
                    if (ModeReg[7] != 0 || ModeReg[8] != 0)
1016
                        $display ("Illegal operating mode set.");
1017
                    if (command != nop)
1018
                    begin
1019
                        $display ("Illegal command received during mode");
1020
                        $display ("set.",$time);
1021
                    end
1022
 
1023
                    // read burst length
1024
                    if (ModeReg[2:0] == 3'b000)
1025
                    begin
1026
                        BurstLen = 1;
1027
                        Burst_Bits = 0;
1028
                    end
1029
                    else if (ModeReg[2:0] == 3'b001)
1030
                    begin
1031
                        BurstLen = 2;
1032
                        Burst_Bits = 1;
1033
                    end
1034
                    else if (ModeReg[2:0] == 3'b010)
1035
                    begin
1036
                        BurstLen = 4;
1037
                        Burst_Bits = 2;
1038
                    end
1039
                    else if (ModeReg[2:0] == 3'b011)
1040
                    begin
1041
                        BurstLen = 8;
1042
                        Burst_Bits = 3;
1043
                    end
1044
                    else if (ModeReg[2:0] == 3'b111)
1045
                    begin
1046
                        BurstLen = 256;
1047
                        Burst_Bits = 7;
1048
                    end
1049
                    else
1050
                        $display ("Invalid burst length specified.");
1051
 
1052
                    // read burst type
1053
                    if (~ModeReg[3])
1054
                        Burst = sequential;
1055
                    else if (ModeReg[3])
1056
                        Burst = interleave;
1057
                    else
1058
                        $display ("Invalid burst type specified.");
1059
 
1060
                    // read CAS latency
1061
                    if (ModeReg[6:4] == 3'b010)
1062
                    begin
1063
                        CAS_Lat = 1'b0;
1064
                        CAS_Lat2 = 1'b1;
1065
                    end
1066
                    else if (ModeReg[6:4] == 3'b011)
1067
                    begin
1068
                        CAS_Lat = 1'b1;
1069
                        CAS_Lat2 = 1'b1;
1070
                    end
1071
                    else
1072
                        $display ("CAS Latency set incorrecty");
1073
 
1074
                    // write burst mode
1075
                    if (~ModeReg[9])
1076
                        WB = programmed;
1077
                    else if (ModeReg[9])
1078
                        WB = single;
1079
                    else
1080
                        $display ("Invalid burst type specified.");
1081
 
1082
                    statebank[bank] = idle;
1083
                end
1084
 
1085
                auto_refresh :
1086
                begin
1087
                    if (Ref_Cnt < 8192)
1088
                        Ref_Cnt = Ref_Cnt + 1;
1089
                    if (command != nop)
1090
                    begin
1091
                        $display ("Illegal command received during");
1092
                        $display ("auto_refresh.",$time);
1093
                    end
1094
                end
1095
 
1096
                bank_act :
1097
                begin
1098
                    if (command == pre && (cur_bank == bank || A[10]))
1099
                    begin
1100
                        if (~ras_out[bank])
1101
                        begin
1102
                            $display ("precharge command does not meet tRAS");
1103
                            $display ("time", $time);
1104
                        end
1105
                        statebank[bank] = precharge;
1106
                        statebank[bank] <= #tdevice_TRP idle;
1107
                    end
1108
                    else if (command == nop || command == bst
1109
                        || cur_bank != bank)
1110
                    begin
1111
                    end
1112
                    else if (command == rd)
1113
                    begin
1114
                        if (rcdt_out[bank])
1115
                        begin
1116
                            $display ("read command received too soon");
1117
                            $display ("after active",$time);
1118
                        end
1119
                        if (A[10] == 1'bx)
1120
                        begin
1121
                            $display ("A(10) = X during read command.");
1122
                            $display ("Next state unknown.");
1123
                        end
1124
                        MemAddr[bank][7:0] = 8'b0;// clr old addr
1125
                        // latch col addr
1126
                        if (Burst_Bits == 0)
1127
                            MemAddr[bank][7:0] = A[7:0];
1128
                        if (Burst_Bits == 1)
1129
                            MemAddr[bank][7:1] = A[7:1];
1130
                        if (Burst_Bits == 2)
1131
                            MemAddr[bank][7:2] = A[7:2];
1132
                        if (Burst_Bits == 3)
1133
                            MemAddr[bank][7:3] = A[7:3];
1134
                        if (Burst_Bits == 7)
1135
                            MemAddr[bank][7:7] = A[7:7];
1136
                        BurstIncProc(bank);
1137
                        StartAddr[bank] = BurstInc[bank] % 8;
1138
                        BaseLoc[bank] = MemAddr[bank];
1139
                        Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1140
                        generate_out(DataDrive,bank);
1141
                        BurstCnt[bank] = 1;
1142
                        NextStateAuto(bank, read);
1143
                        bank_tmp = bank;
1144
                    end
1145
                    else if (command == writ)
1146
                    begin
1147
                        if (rcdt_out[bank])
1148
                        begin
1149
                            $display ("write command received too soon");
1150
                            $display ("after active",$time);
1151
                        end
1152
                        if (A[10] == 1'bx)
1153
                        begin
1154
                            $display ("A(10) = X during write command.");
1155
                            $display ("Next state unknown.");
1156
                        end
1157
                        MemAddr[bank][7:0] = 8'b0; // clr old addr
1158
                        BurstIncProc(bank);
1159
                        // latch col addr
1160
                        if (Burst_Bits == 0)
1161
                            MemAddr[bank][7:0] = A[7:0];
1162
                        if (Burst_Bits == 1)
1163
                            MemAddr[bank][7:1] = A[7:1];
1164
                        if (Burst_Bits == 2)
1165
                            MemAddr[bank][7:2] = A[7:2];
1166
                        if (Burst_Bits == 3)
1167
                            MemAddr[bank][7:3] = A[7:3];
1168
                        if (Burst_Bits == 7)
1169
                            MemAddr[bank][7:7] = A[7:7];
1170
                        StartAddr[bank] = BurstInc[bank] % 8;
1171
                        BaseLoc[bank] = MemAddr[bank];
1172
                        Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1173
                        MemWrite(bank);
1174
                        BurstCnt[bank] = 1'b1;
1175
                        NextStateAuto(bank, write);
1176
                        written = 1'b1;
1177
                    end
1178
                    else if (cur_bank == bank || command == mrs)
1179
                    begin
1180
                        $display ("Illegal command received in");
1181
                        $display ("active state",$time);
1182
                    end
1183
                end
1184
 
1185
                write :
1186
                begin
1187
                    if (command == bst)
1188
                    begin
1189
                        statebank[bank] = bank_act;
1190
                        BurstCnt[bank] = 1'b0;
1191
                    end
1192
                    else if (command == rd)
1193
                        if (cur_bank == bank)
1194
                        begin
1195
                            MemAddr[bank][7:0] = 8'b0;// clr old addr
1196
                            BurstIncProc(bank);
1197
                            // latch col addr
1198
                            if (Burst_Bits == 0)
1199
                                MemAddr[bank][7:0] = A[7:0];
1200
                            if (Burst_Bits == 1)
1201
                                MemAddr[bank][7:1] = A[7:1];
1202
                            if (Burst_Bits == 2)
1203
                                MemAddr[bank][7:2] = A[7:2];
1204
                            if (Burst_Bits == 3)
1205
                                MemAddr[bank][7:3] = A[7:3];
1206
                            if (Burst_Bits == 7)
1207
                                MemAddr[bank][7:7] = A[7:7];
1208
                            StartAddr[bank] = BurstInc[bank] % 8;
1209
                            BaseLoc[bank] = MemAddr[bank];
1210
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1211
                            generate_out(DataDrive, bank);
1212
                            BurstCnt[bank] = 1'b1;
1213
                            NextStateAuto(bank, read);
1214
                        end
1215
                        else
1216
                            statebank[bank] = bank_act;
1217
                    else if (command == writ)
1218
                        if (cur_bank == bank)
1219
                        begin
1220
                            MemAddr[bank][7:0] = 8'b0;// clr old addr
1221
                            BurstIncProc(bank);
1222
                            // latch col addr
1223
                            if (Burst_Bits == 0)
1224
                                MemAddr[bank][7:0] = A[7:0];
1225
                            if (Burst_Bits == 1)
1226
                                MemAddr[bank][7:1] = A[7:1];
1227
                            if (Burst_Bits == 2)
1228
                                MemAddr[bank][7:2] = A[7:2];
1229
                            if (Burst_Bits == 3)
1230
                                MemAddr[bank][7:3] = A[7:3];
1231
                            if (Burst_Bits == 7)
1232
                                MemAddr[bank][7:7] = A[7:7];
1233
                            StartAddr[bank] = BurstInc[bank] % 8;
1234
                            BaseLoc[bank] = MemAddr[bank];
1235
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1236
                            MemWrite(bank);
1237
                            BurstCnt[bank] = 1'b1;
1238
                            if (A[10])
1239
                                statebank[bank] = write_auto_pre;
1240
                        end
1241
                        else
1242
                            statebank[bank] = bank_act;
1243
                    else if (command == pre && (cur_bank == bank || A[10]))
1244
                    begin
1245
                        if (~ras_out[bank])
1246
                        begin
1247
                $display ("precharge command does not meet tRAS time",$time);
1248
                        end
1249
                        if (~DQM0_ipd)
1250
                        begin
1251
                            $display ("DQM0 should be held high, data is");
1252
                            $display ("lost.",$time);
1253
                        end
1254
                        if (~DQM1_ipd)
1255
                        begin
1256
                            $display ("DQM1 should be held high, data is");
1257
                            $display ("lost.",$time);
1258
                        end
1259
                        statebank[bank] = precharge;
1260
                        statebank[bank] <= #tdevice_TRP idle;
1261
                    end
1262
                    else if (command == nop || cur_bank != bank)
1263
                        if (BurstCnt[bank] == BurstLen || WB == single)
1264
                        begin
1265
                            statebank[bank] = bank_act;
1266
                            BurstCnt[bank] = 1'b0;
1267
                            ras_in[bank] = 1'b1;
1268
                        end
1269
                        else
1270
                        begin
1271
                            if (Burst == sequential)
1272
                                BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
1273
                            else
1274
                                BurstInc[bank] =
1275
                                intab[StartAddr[bank]*8 + BurstCnt[bank]];
1276
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1277
                            MemWrite(bank);
1278
                            BurstCnt[bank] = BurstCnt[bank] + 1;
1279
                        end
1280
                    else if (cur_bank == bank)
1281
                    $display ("Illegal command received in write state",$time);
1282
                end
1283
 
1284
                read :
1285
                begin
1286
                    if (command == bst)
1287
                    begin
1288
                        statebank[bank] = bank_act;
1289
                        BurstCnt[bank] = 1'b0;
1290
                    end
1291
                    else if (command == rd)
1292
                        if (cur_bank == bank)
1293
                        begin
1294
                            MemAddr[bank][7:0] = 8'b0;// clr old addr
1295
                            BurstIncProc(bank);
1296
                            // latch col addr
1297
                            if (Burst_Bits == 0)
1298
                                MemAddr[bank][7:0] = A[7:0];
1299
                            if (Burst_Bits == 1)
1300
                                MemAddr[bank][7:1] = A[7:1];
1301
                            if (Burst_Bits == 2)
1302
                                MemAddr[bank][7:2] = A[7:2];
1303
                            if (Burst_Bits == 3)
1304
                                MemAddr[bank][7:3] = A[7:3];
1305
                            if (Burst_Bits == 7)
1306
                                MemAddr[bank][7:7] = A[7:7];
1307
                            StartAddr[bank] = BurstInc[bank] % 8;
1308
                            BaseLoc[bank] = MemAddr[bank];
1309
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1310
                            generate_out(DataDrive, bank);
1311
                            BurstCnt[bank] = 1'b1;
1312
                            NextStateAuto(bank, read);
1313
                        end
1314
                        else
1315
                            statebank[bank] = bank_act;
1316
                    else if (command == writ)
1317
                        if (cur_bank == bank)
1318
                        begin
1319
                            if (rcdt_out[bank])
1320
                            begin
1321
                $display ("write command received too soon after active",$time);
1322
                            end
1323
                            if (A[10] == 1'bx)
1324
                            begin
1325
                                $display ("A(10) = X during write command.");
1326
                                $display ("Next state unknown.");
1327
                            end
1328
 
1329
                            MemAddr[bank][7:0] = 8'b0;// clr old addr
1330
                            BurstIncProc(bank);
1331
                            // latch col addr
1332
                            if (Burst_Bits == 0)
1333
                                MemAddr[bank][7:0] = A[7:0];
1334
                            if (Burst_Bits == 1)
1335
                                MemAddr[bank][7:1] = A[7:1];
1336
                            if (Burst_Bits == 2)
1337
                                MemAddr[bank][7:2] = A[7:2];
1338
                            if (Burst_Bits == 3)
1339
                                MemAddr[bank][7:3] = A[7:3];
1340
                            if (Burst_Bits == 7)
1341
                                MemAddr[bank][7:7] = A[7:7];
1342
                            StartAddr[bank] = BurstInc[bank] % 8;
1343
                            BaseLoc[bank] = MemAddr[bank];
1344
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1345
                            MemWrite(bank);
1346
                            BurstCnt[bank] = 1'b1;
1347
                            NextStateAuto(bank,write);
1348
                        end
1349
                        else
1350
                            statebank[bank] = bank_act;
1351
 
1352
                    else if (command == pre && (cur_bank == bank || A[10]))
1353
                    begin
1354
                        if (~ras_out[bank])
1355
                        begin
1356
                  $display ("Precharge command does not meet tRAS time",$time);
1357
                        end
1358
                        statebank[bank] = precharge;
1359
                        statebank[bank] <= #tdevice_TRP idle;
1360
                    end
1361
 
1362
                    else if (command == nop || cur_bank != bank)
1363
                    begin
1364
                        if (BurstCnt[bank] == BurstLen)
1365
                        begin
1366
                            statebank[bank] = bank_act;
1367
                            BurstCnt[bank] = 1'b0;
1368
                            ras_in[bank] = 1'b1;
1369
                        end
1370
                        else
1371
                        begin
1372
                            if (Burst == sequential)
1373
                                BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
1374
                            else
1375
                                BurstInc[bank] =
1376
                                intab[StartAddr[bank]*8 + BurstCnt[bank]];
1377
 
1378
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1379
                            generate_out(DataDrive, bank);
1380
                            BurstCnt[bank] = BurstCnt[bank] + 1;
1381
                        end
1382
                    end
1383
                    else if (cur_bank == bank)
1384
                    $display ("Illegal command received in read state",$time);
1385
                end
1386
 
1387
                write_auto_pre :
1388
                begin
1389
                    if (command == nop || cur_bank != bank)
1390
                        if (BurstCnt[bank] == BurstLen || WB == single)
1391
                        begin
1392
                            statebank[bank] = precharge;
1393
                            statebank[bank] <= #tdevice_TRP idle;
1394
                            BurstCnt[bank] = 1'b0;
1395
                            ras_in[bank] = 1'b1;
1396
                        end
1397
                        else
1398
                        begin
1399
                            if (Burst == sequential)
1400
                                BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
1401
                            else
1402
                                BurstInc[bank] =
1403
                                intab[StartAddr[bank]*8 + BurstCnt[bank]];
1404
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1405
                            MemWrite(bank);
1406
                            BurstCnt[bank] = BurstCnt[bank] + 1;
1407
                        end
1408
                    else
1409
                    $display ("Illegal command received in write state.",$time);
1410
                end
1411
 
1412
                read_auto_pre :
1413
                begin
1414
                    if (command == nop || (cur_bank != bank && command != rd
1415
                        && command != writ))
1416
                        if (BurstCnt[bank] == BurstLen)
1417
                        begin
1418
                            statebank[bank] = precharge;
1419
                            statebank[bank] <= #tdevice_TRP idle;
1420
                            BurstCnt[bank] = 1'b0;
1421
                            ras_in[bank] = 1'b1;
1422
                        end
1423
                        else
1424
                        begin
1425
                            if (Burst == sequential)
1426
                                BurstInc[bank] = (BurstInc[bank]+1) % BurstLen;
1427
                            else
1428
                                BurstInc[bank] =
1429
                                intab[StartAddr[bank]*8 + BurstCnt[bank]];
1430
                            Loc = 2*(BaseLoc[bank] + BurstInc[bank]);
1431
                            generate_out(DataDrive, bank);
1432
                            BurstCnt[bank] = BurstCnt[bank] + 1;
1433
                        end
1434
                    else if ((command == rd || command == writ) && cur_bank
1435
                        != bank)
1436
                    begin
1437
                        statebank[bank] = precharge;
1438
                        statebank[bank] <= #tdevice_TRP idle;
1439
                    end
1440
                    else
1441
                    $display ("Illegal command received in read state",$time);
1442
                end
1443
                endcase
1444
            end
1445
 
1446
            // Check Refresh Status
1447
            if (written && (Ref_Cnt == 0))
1448
                $display ("memory not refreshed (by ref_cnt)", $time);
1449
 
1450
            DataDrive3 = DataDrive2;
1451
            DataDrive2 = DataDrive1;
1452
            DataDrive1 = DataDrive;
1453
 
1454
        end
1455
 
1456
        //  Latency adjustments and DQM read masking
1457
        if (~DQM0_reg1)
1458
            if (CAS_Lat && CAS_Lat2)
1459
                DataDriveOut[7:0] = DataDrive3[7:0];
1460
            else
1461
                DataDriveOut[7:0] = DataDrive2[7:0];
1462
        else
1463
            DataDriveOut[7:0] = 8'bz;
1464
 
1465
        if (~DQM1_reg1)
1466
            if (CAS_Lat && CAS_Lat2)
1467
                DataDriveOut[15:8] = DataDrive3[15:8];
1468
            else
1469
                DataDriveOut[15:8] = DataDrive2[15:8];
1470
        else
1471
            DataDriveOut[15:8] = 8'bz;
1472
 
1473
        // The Powering-up State Machine
1474
        if (~CKEreg && CKE_ipd)
1475
        begin
1476
            if (CSNeg_ipd == 1'bx)
1477
                $display ("Unusable value for CSNeg");
1478
            if (CSNeg_ipd)
1479
                command = nop;
1480
 
1481
            case (statebank[cur_bank])
1482
            write_suspend :
1483
            begin
1484
                statebank[cur_bank] = write;
1485
            end
1486
 
1487
            read_suspend :
1488
            begin
1489
                statebank[cur_bank] = read;
1490
            end
1491
 
1492
            self_refresh :
1493
            begin
1494
                statebank[0] <= #tdevice_TRP idle;
1495
                statebank[1] <= #tdevice_TRP idle;
1496
                statebank[2] <= #tdevice_TRP idle;
1497
                statebank[3] <= #tdevice_TRP idle;
1498
                Ref_Cnt = 8192;
1499
                if (command != nop)
1500
                begin
1501
                    $display ("Illegal command received during self");
1502
                    $display ("refresh",$time);
1503
                end
1504
            end
1505
 
1506
            pwrdwn :
1507
            begin
1508
                statebank[0] = idle;
1509
                statebank[1] = idle;
1510
                statebank[2] = idle;
1511
                statebank[3] = idle;
1512
            end
1513
 
1514
            bank_act_pwrdwn :
1515
            begin
1516
                statebank[cur_bank] = bank_act;
1517
            end
1518
            endcase
1519
        end
1520
 
1521
        // The Powering-down State Machine
1522
        if (CKEreg && ~CKE_ipd)
1523
        begin
1524
            if (CSNeg_ipd == 1'bx)
1525
                $display ("Unusable value for CSNeg");
1526
            if (CSNeg_ipd)
1527
                command = nop;
1528
 
1529
            case (statebank[cur_bank])
1530
            idle :
1531
            begin
1532
                if (command == nop)
1533
                begin
1534
                    statebank[0] = pwrdwn;
1535
                    statebank[1] = pwrdwn;
1536
                    statebank[2] = pwrdwn;
1537
                    statebank[3] = pwrdwn;
1538
                end
1539
            end
1540
 
1541
            write :
1542
            begin
1543
                statebank[cur_bank] = write_suspend;
1544
            end
1545
 
1546
            read :
1547
            begin
1548
                statebank[cur_bank] = read_suspend;
1549
            end
1550
 
1551
            bank_act :
1552
            begin
1553
                statebank[cur_bank] = bank_act_pwrdwn;
1554
            end
1555
            endcase
1556
        end
1557
 
1558
        CKEreg = CKE_ipd;
1559
    end
1560
 
1561
    always @(DataDriveOut)
1562
    begin
1563
        DQ_zd = DataDriveOut;
1564
    end
1565
 
1566
    reg TRASMIN_In, TRASMAX_In, TRC_In , TRCAR_In;
1567
    reg TRCD_In , TRP_In , TWR_In;
1568
    wire TRASMIN_Out,TRASMAX_Out,TRC_Out,TRCAR_Out, TRCD_Out, TRP_Out, TWR_Out;
1569
 
1570
    BUFFER    BUF_TRASMIN    (TRASMIN_Out  , TRASMIN_In);
1571
    BUFFER    BUF_TRASMAX    (TRASMAX_Out  , TRASMAX_In);
1572
    BUFFER    BUF_TRC    (TRC_Out  , TRC_In);
1573
    BUFFER    BUF_TRCAR  (TRCAR_Out, TRCAR_In);
1574
    BUFFER    BUF_TRCD   (TRCD_Out , TRCD_In);
1575
    BUFFER    BUF_TRP    (TRP_Out  , TRP_In);
1576
 
1577
    initial
1578
    begin
1579
        TRASMIN_In = 1;
1580
        TRASMAX_In = 1;
1581
        TRC_In   = 1;
1582
        TRCAR_In = 1;
1583
        TRCD_In  = 1'b1;
1584
        TRP_In   = 1;
1585
        TWR_In   = 1;
1586
    end
1587
 
1588
    always @(posedge TRC_Out)
1589
    begin
1590
        tdevice_TRC = $time;
1591
    end
1592
 
1593
    always @(posedge TRASMIN_Out)
1594
    begin
1595
        tdevice_TRASmin = $time;
1596
    end
1597
 
1598
    always @(posedge TRASMAX_Out)
1599
    begin
1600
        tdevice_TRASmax = $time;
1601
    end
1602
 
1603
    always @(posedge TRCAR_Out)
1604
    begin
1605
        tdevice_TRCAR = $time;
1606
    end
1607
 
1608
    always @(posedge TRCD_Out)
1609
    begin
1610
        tdevice_TRCD = $time;
1611
    end
1612
 
1613
    always @(posedge TRP_Out)
1614
    begin
1615
        tdevice_TRP = $time;
1616
    end
1617
 
1618
endmodule
1619
 
1620
module BUFFER (OUT,IN);
1621
    input IN;
1622
    output OUT;
1623
        buf (OUT, IN);
1624
endmodule

powered by: WebSVN 2.1.0

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