Date:2010-12-19 02:38:43 (13 years 3 months ago)
Author:Wolfgang Spraul
Commit:29e7ceda7ccbe5fc20a262feae254b0c9fcd679f
Message:unzipped 2 files

Files: sim/verilog/micron/2048Mb_ddr2.zip (0 diffs)
sim/verilog/micron/mobile_ddr.zip (0 diffs)
sim/verilog/micron_2048Mb_ddr2/ddr2.v (1 diff)
sim/verilog/micron_2048Mb_ddr2/ddr2_mcp.v (1 diff)
sim/verilog/micron_2048Mb_ddr2/ddr2_module.v (1 diff)
sim/verilog/micron_2048Mb_ddr2/ddr2_parameters.vh (1 diff)
sim/verilog/micron_2048Mb_ddr2/readme.txt (1 diff)
sim/verilog/micron_2048Mb_ddr2/subtest.vh (1 diff)
sim/verilog/micron_2048Mb_ddr2/tb.do (1 diff)
sim/verilog/micron_2048Mb_ddr2/tb.v (1 diff)
sim/verilog/micron_mobile_ddr/1024Mb_mobile_ddr_parameters.vh (1 diff)
sim/verilog/micron_mobile_ddr/128Mb_mobile_ddr_parameters.vh (1 diff)
sim/verilog/micron_mobile_ddr/2048Mb_mobile_ddr_parameters.vh (1 diff)
sim/verilog/micron_mobile_ddr/256Mb_mobile_ddr_parameters.vh (1 diff)
sim/verilog/micron_mobile_ddr/512Mb_mobile_ddr_parameters.vh (1 diff)
sim/verilog/micron_mobile_ddr/mobile_ddr.v (1 diff)
sim/verilog/micron_mobile_ddr/mobile_ddr_mcp.v (1 diff)
sim/verilog/micron_mobile_ddr/readme.txt (1 diff)
sim/verilog/micron_mobile_ddr/subtest.vh (1 diff)
sim/verilog/micron_mobile_ddr/tb.do (1 diff)
sim/verilog/micron_mobile_ddr/tb.v (1 diff)

Change Details

sim/verilog/micron/2048Mb_ddr2.zip
sim/verilog/micron/mobile_ddr.zip
sim/verilog/micron_2048Mb_ddr2/ddr2.v
1/****************************************************************************************
2*
3* File Name: ddr2.v
4* Version: 5.83
5* Model: BUS Functional
6*
7* Dependencies: ddr2_parameters.vh
8*
9* Description: Micron SDRAM DDR2 (Double Data Rate 2)
10*
11* Limitation: - doesn't check for average refresh timings
12* - positive ck and ck_n edges are used to form internal clock
13* - positive dqs and dqs_n edges are used to latch data
14* - test mode is not modeled
15*
16* Note: - Set simulator resolution to "ps" accuracy
17* - Set Debug = 0 to disable $display messages
18*
19* Disclaimer This software code and all associated documentation, comments or other
20* of Warranty: information (collectively "Software") is provided "AS IS" without
21* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
22* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
23* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
24* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
25* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
26* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
27* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
28* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
29* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
30* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
31* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
32* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
33* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
34* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
35* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
36* DAMAGES. Because some jurisdictions prohibit the exclusion or
37* limitation of liability for consequential or incidental damages, the
38* above limitation may not apply to you.
39*
40* Copyright 2003 Micron Technology, Inc. All rights reserved.
41*
42* Rev Author Date Changes
43* ---------------------------------------------------------------------------------------
44* 1.00 JMK 07/29/03 Initial Release
45* 1.10 JMK 08/09/03 Timing Parameter updates to tIS, tIH, tDS, tDH
46* 2.20 JMK 08/07/03 General cleanup
47* 2.30 JMK 11/26/03 Added CL_MIN, CL_MAX, wl_min and wl_max parameters.
48* Added AL_MIN and AL_MAX parameters.
49* Removed support for OCD.
50* 2.40 JMK 01/15/04 Removed verilog 2001 constructs.
51* 2.50 JMK 01/29/04 Removed tRP checks during Precharge command.
52* 2.60 JMK 04/20/04 Fixed tWTR check.
53* 2.70 JMK 04/30/04 Added tRFC maximum check.
54* Combined Self Refresh and Power Down always blocks.
55* Added Reset Function (CKE LOW Anytime).
56* 2.80 JMK 08/19/04 Precharge is treated as NOP when bank is not active.
57* Added checks for tRAS, tWR, tRTP to any bank during Pre-All.
58* tRFC maximum violation will only display one time.
59* 2.90 JMK 11/05/04 Fixed DQS checking during write.
60* Fixed false tRFC max assertion during power up and self ref.
61* Added warning for 200us CKE low time during initialization.
62* Added -3, -3E, and -37V speed grades to ddr2_parameters.v
63* 3.00 JMK 04/22/05 Removed ODT off requirement during power down.
64* Added tAOND, tAOFD, tANPD, tAXPD, tAONPD, and tAOFPD parameters.
65* Added ODT status messages.
66* Updated the initialization sequence.
67* Disable ODT and CLK pins during self refresh.
68* Disable cmd and addr pins during power down and self refresh.
69* 3.10 JMK 06/07/05 Disable trpa checking if the part does not have 8 banks.
70* Changed tAXPD message from error to a warning.
71* Added tDSS checking.
72* Removed tDQSL checking during tWPRE and tWPST.
73* Fixed a burst order error during writes.
74* Renamed parameters file with .vh extension.
75* 3.20 JMK 07/18/05 Removed 14 tCK requirement from LMR to READ.
76* 3.30 JMK 08/03/05 Added check for interrupting a burst with auto precharge.
77* 4.00 JMK 11/21/05 Parameter names all UPPERCASE, signal names all lowercase.
78* Clock jitter can be tolerated within specification range.
79* Clock frequency is sampled from the CK pin.
80* Scaleable up to 64 DQ and 16 DQS bits.
81* Read data can be randomly skewed using RANDOM_OUT_DELAY.
82* Parameterized read and write DQS, and read DQ.
83* Initialization can be bypassed using initialize task.
84* 4.10 JMK 11/30/05 Fixed compile errors when `MAX_MEM was defined.
85* 4.20 JMK 12/09/05 Fixed memory addressing error when `MAX_MEM was defined.
86* 4.30 JMK 02/15/06 Added dummy write to initialization sequence.
87* Removed tWPST maximum checking.
88* Rising dqs_n edge latches data when enabled in EMR.
89* Fixed a sign error in the tJIT(cc) calculation.
90* 4.40 JMK 02/16/06 Fixed dummy write when`MAX_MEM was defined.
91* 4.50 JMK 02/27/06 Fixed extra tDQSS assertions.
92* Fixed tRCD and tWTR checking.
93* Errors entering Power Down or Self Refresh will cause reset.
94* Ignore dqs_n when disabled in EMR.
95* 5.00 JMK 04/24/06 Test stimulus now included from external file (subtest.vh)
96* Fixed tRFC max assertion during self refresh.
97* Fixed tANPD checking during Power Down.
98* Removed dummy write from initialization sequence.
99* 5.01 JMK 04/28/06 Fixed Auto Precharge to Load Mode, Refresh and Self Refresh.
100* Removed Auto Precharge error message during Power Down Enter.
101* 5.10 JMK 07/26/06 Created internal clock using ck and ck_n.
102* RDQS can only be enabled in EMR for x8 configurations.
103* CAS latency is checked vs frequency when DLL locks.
104* tMOD changed from tCK units to ns units.
105* Added 50 Ohm setting for Rtt in EMR.
106* Improved checking of DQS during writes.
107* 5.20 JMK 10/02/06 Fixed DQS checking for interrupting write to write and x16.
108* 5.30 JMK 05/25/07 Fixed checking for 0-Z transition on write postamble.
109* 5.50 JMK 05/30/08 Renamed ddr2_dimm.v to ddr2_module.v and added SODIMM support.
110* Added a register delay to ddr2_module.v when RDIMM is defined.
111* Added multi-chip package model support in ddr2_mcp.v
112* Added High Temp Self Refresh rate setting in EMRS2[7]
113* 5.70 JMK 04/23/09 Updated tRPA definition
114* Increased internal width to 72 bit DQ bus
115* 5.80 SPH 08/12/09 Fixed tRAS maximum violation (only check if bank still open)
116* 5.81 SPH 12/08/09 Only check tIH for cmd_addr if CS# LOW
117* 5.82 SPH 04/08/10 Correct debug message for SRT in EMR2
118* 5.83 SPH 04/29/10 Correct tDQSS check on valid DQS group
119****************************************************************************************/
120
121// DO NOT CHANGE THE TIMESCALE
122// MAKE SURE YOUR SIMULATOR USES "PS" RESOLUTION
123`timescale 1ps / 1ps
124
125module ddr2 (
126    ck,
127    ck_n,
128    cke,
129    cs_n,
130    ras_n,
131    cas_n,
132    we_n,
133    dm_rdqs,
134    ba,
135    addr,
136    dq,
137    dqs,
138    dqs_n,
139    rdqs_n,
140    odt
141);
142
143    `include "ddr2_parameters.vh"
144
145    // text macros
146    `define DQ_PER_DQS DQ_BITS/DQS_BITS
147    `define BANKS (1<<BA_BITS)
148    `define MAX_BITS (BA_BITS+ROW_BITS+COL_BITS-BL_BITS)
149    `define MAX_SIZE (1<<(BA_BITS+ROW_BITS+COL_BITS-BL_BITS))
150    `define MEM_SIZE (1<<MEM_BITS)
151    `define MAX_PIPE 2*(AL_MAX + CL_MAX)
152
153    // Declare Ports
154    input ck;
155    input ck_n;
156    input cke;
157    input cs_n;
158    input ras_n;
159    input cas_n;
160    input we_n;
161    inout [DM_BITS-1:0] dm_rdqs;
162    input [BA_BITS-1:0] ba;
163    input [ADDR_BITS-1:0] addr;
164    inout [DQ_BITS-1:0] dq;
165    inout [DQS_BITS-1:0] dqs;
166    inout [DQS_BITS-1:0] dqs_n;
167    output [DQS_BITS-1:0] rdqs_n;
168    input odt;
169
170    // clock jitter
171    real tck_avg;
172    time tck_sample [TDLLK-1:0];
173    time tch_sample [TDLLK-1:0];
174    time tcl_sample [TDLLK-1:0];
175    time tck_i;
176    time tch_i;
177    time tcl_i;
178    real tch_avg;
179    real tcl_avg;
180    time tm_ck_pos;
181    time tm_ck_neg;
182    real tjit_per_rtime;
183    integer tjit_cc_time;
184    real terr_nper_rtime;
185
186    // clock skew
187    real out_delay;
188    integer dqsck [DQS_BITS-1:0];
189    integer dqsck_min;
190    integer dqsck_max;
191    integer dqsq_min;
192    integer dqsq_max;
193    integer seed;
194
195    // Mode Registers
196    reg burst_order;
197    reg [BL_BITS:0] burst_length;
198    integer cas_latency;
199    integer additive_latency;
200    reg dll_reset;
201    reg dll_locked;
202    reg dll_en;
203    integer write_recovery;
204    reg low_power;
205    reg [1:0] odt_rtt;
206    reg odt_en;
207    reg [2:0] ocd;
208    reg dqs_n_en;
209    reg rdqs_en;
210    reg out_en;
211    integer read_latency;
212    integer write_latency;
213
214    // cmd encoding
215    parameter
216        LOAD_MODE = 4'b0000,
217        REFRESH = 4'b0001,
218        PRECHARGE = 4'b0010,
219        ACTIVATE = 4'b0011,
220        WRITE = 4'b0100,
221        READ = 4'b0101,
222        NOP = 4'b0111,
223        PWR_DOWN = 4'b1000,
224        SELF_REF = 4'b1001
225    ;
226
227    reg [8*9-1:0] cmd_string [9:0];
228    initial begin
229        cmd_string[LOAD_MODE] = "Load Mode";
230        cmd_string[REFRESH ] = "Refresh ";
231        cmd_string[PRECHARGE] = "Precharge";
232        cmd_string[ACTIVATE ] = "Activate ";
233        cmd_string[WRITE ] = "Write ";
234        cmd_string[READ ] = "Read ";
235        cmd_string[NOP ] = "No Op ";
236        cmd_string[PWR_DOWN ] = "Pwr Down ";
237        cmd_string[SELF_REF ] = "Self Ref ";
238    end
239
240    // command state
241    reg [`BANKS-1:0] active_bank;
242    reg [`BANKS-1:0] auto_precharge_bank;
243    reg [`BANKS-1:0] write_precharge_bank;
244    reg [`BANKS-1:0] read_precharge_bank;
245    reg [ROW_BITS-1:0] active_row [`BANKS-1:0];
246    reg in_power_down;
247    reg in_self_refresh;
248    reg [3:0] init_mode_reg;
249    reg init_done;
250    integer init_step;
251    reg er_trfc_max;
252    reg odt_state;
253    reg prev_odt;
254
255    // cmd timers/counters
256    integer ref_cntr;
257    integer ck_cntr;
258    integer ck_load_mode;
259    integer ck_write;
260    integer ck_read;
261    integer ck_write_ap;
262    integer ck_power_down;
263    integer ck_slow_exit_pd;
264    integer ck_self_refresh;
265    integer ck_cke;
266    integer ck_odt;
267    integer ck_dll_reset;
268    integer ck_bank_write [`BANKS-1:0];
269    integer ck_bank_read [`BANKS-1:0];
270    time tm_refresh;
271    time tm_precharge;
272    time tm_precharge_all;
273    time tm_activate;
274    time tm_write_end;
275    time tm_self_refresh;
276    time tm_odt_en;
277    time tm_bank_precharge [`BANKS-1:0];
278    time tm_bank_activate [`BANKS-1:0];
279    time tm_bank_write_end [`BANKS-1:0];
280    time tm_bank_read_end [`BANKS-1:0];
281
282    // pipelines
283    reg [`MAX_PIPE:0] al_pipeline;
284    reg [`MAX_PIPE:0] wr_pipeline;
285    reg [`MAX_PIPE:0] rd_pipeline;
286    reg [`MAX_PIPE:0] odt_pipeline;
287    reg [BA_BITS-1:0] ba_pipeline [`MAX_PIPE:0];
288    reg [ROW_BITS-1:0] row_pipeline [`MAX_PIPE:0];
289    reg [COL_BITS-1:0] col_pipeline [`MAX_PIPE:0];
290    reg prev_cke;
291
292    // data state
293    reg [BL_MAX*DQ_BITS-1:0] memory_data;
294    reg [BL_MAX*DQ_BITS-1:0] bit_mask;
295    reg [BL_BITS-1:0] burst_position;
296    reg [BL_BITS:0] burst_cntr;
297    reg [DQ_BITS-1:0] dq_temp;
298    reg [35:0] check_write_postamble;
299    reg [35:0] check_write_preamble;
300    reg [35:0] check_write_dqs_high;
301    reg [35:0] check_write_dqs_low;
302    reg [17:0] check_dm_tdipw;
303    reg [71:0] check_dq_tdipw;
304
305    // data timers/counters
306    time tm_cke;
307    time tm_odt;
308    time tm_tdqss;
309    time tm_dm [17:0];
310    time tm_dqs [17:0];
311    time tm_dqs_pos [35:0];
312    time tm_dqss_pos [35:0];
313    time tm_dqs_neg [35:0];
314    time tm_dq [71:0];
315    time tm_cmd_addr [22:0];
316    reg [8*7-1:0] cmd_addr_string [22:0];
317    initial begin
318        cmd_addr_string[ 0] = "CS_N ";
319        cmd_addr_string[ 1] = "RAS_N ";
320        cmd_addr_string[ 2] = "CAS_N ";
321        cmd_addr_string[ 3] = "WE_N ";
322        cmd_addr_string[ 4] = "BA 0 ";
323        cmd_addr_string[ 5] = "BA 1 ";
324        cmd_addr_string[ 6] = "BA 2 ";
325        cmd_addr_string[ 7] = "ADDR 0";
326        cmd_addr_string[ 8] = "ADDR 1";
327        cmd_addr_string[ 9] = "ADDR 2";
328        cmd_addr_string[10] = "ADDR 3";
329        cmd_addr_string[11] = "ADDR 4";
330        cmd_addr_string[12] = "ADDR 5";
331        cmd_addr_string[13] = "ADDR 6";
332        cmd_addr_string[14] = "ADDR 7";
333        cmd_addr_string[15] = "ADDR 8";
334        cmd_addr_string[16] = "ADDR 9";
335        cmd_addr_string[17] = "ADDR 10";
336        cmd_addr_string[18] = "ADDR 11";
337        cmd_addr_string[19] = "ADDR 12";
338        cmd_addr_string[20] = "ADDR 13";
339        cmd_addr_string[21] = "ADDR 14";
340        cmd_addr_string[22] = "ADDR 15";
341    end
342
343    reg [8*5-1:0] dqs_string [1:0];
344    initial begin
345        dqs_string[0] = "DQS ";
346        dqs_string[1] = "DQS_N";
347    end
348
349    // Memory Storage
350`ifdef MAX_MEM
351    reg [BL_MAX*DQ_BITS-1:0] memory [0:`MAX_SIZE-1];
352`else
353    reg [BL_MAX*DQ_BITS-1:0] memory [0:`MEM_SIZE-1];
354    reg [`MAX_BITS-1:0] address [0:`MEM_SIZE-1];
355    reg [MEM_BITS:0] memory_index;
356    reg [MEM_BITS:0] memory_used;
357`endif
358
359    // receive
360    reg ck_in;
361    reg ck_n_in;
362    reg cke_in;
363    reg cs_n_in;
364    reg ras_n_in;
365    reg cas_n_in;
366    reg we_n_in;
367    reg [17:0] dm_in;
368    reg [2:0] ba_in;
369    reg [15:0] addr_in;
370    reg [71:0] dq_in;
371    reg [35:0] dqs_in;
372    reg odt_in;
373
374    reg [17:0] dm_in_pos;
375    reg [17:0] dm_in_neg;
376    reg [71:0] dq_in_pos;
377    reg [71:0] dq_in_neg;
378    reg dq_in_valid;
379    reg dqs_in_valid;
380    integer wdqs_cntr;
381    integer wdq_cntr;
382    integer wdqs_pos_cntr [35:0];
383    reg b2b_write;
384    reg [35:0] prev_dqs_in;
385    reg diff_ck;
386
387    always @(ck ) ck_in <= #BUS_DELAY ck;
388    always @(ck_n ) ck_n_in <= #BUS_DELAY ck_n;
389    always @(cke ) cke_in <= #BUS_DELAY cke;
390    always @(cs_n ) cs_n_in <= #BUS_DELAY cs_n;
391    always @(ras_n ) ras_n_in <= #BUS_DELAY ras_n;
392    always @(cas_n ) cas_n_in <= #BUS_DELAY cas_n;
393    always @(we_n ) we_n_in <= #BUS_DELAY we_n;
394    always @(dm_rdqs) dm_in <= #BUS_DELAY dm_rdqs;
395    always @(ba ) ba_in <= #BUS_DELAY ba;
396    always @(addr ) addr_in <= #BUS_DELAY addr;
397    always @(dq ) dq_in <= #BUS_DELAY dq;
398    always @(dqs or dqs_n) dqs_in <= #BUS_DELAY (dqs_n<<18) | dqs;
399    always @(odt ) odt_in <= #BUS_DELAY odt;
400    // create internal clock
401    always @(posedge ck_in) diff_ck <= ck_in;
402    always @(posedge ck_n_in) diff_ck <= ~ck_n_in;
403
404    wire [17:0] dqs_even = dqs_in[17:0];
405    wire [17:0] dqs_odd = dqs_n_en ? dqs_in[35:18] : ~dqs_in[17:0];
406    wire [3:0] cmd_n_in = !cs_n_in ? {ras_n_in, cas_n_in, we_n_in} : NOP; //deselect = nop
407
408    // transmit
409    reg dqs_out_en;
410    reg [DQS_BITS-1:0] dqs_out_en_dly;
411    reg dqs_out;
412    reg [DQS_BITS-1:0] dqs_out_dly;
413    reg dq_out_en;
414    reg [DQ_BITS-1:0] dq_out_en_dly;
415    reg [DQ_BITS-1:0] dq_out;
416    reg [DQ_BITS-1:0] dq_out_dly;
417    integer rdqsen_cntr;
418    integer rdqs_cntr;
419    integer rdqen_cntr;
420    integer rdq_cntr;
421
422    bufif1 buf_dqs [DQS_BITS-1:0] (dqs, dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}});
423    bufif1 buf_dm [DM_BITS-1:0] (dm_rdqs, dqs_out_dly, dqs_out_en_dly & {DM_BITS {out_en}} & {DM_BITS{rdqs_en}});
424    bufif1 buf_dqs_n [DQS_BITS-1:0] (dqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}} & {DQS_BITS{dqs_n_en}});
425    bufif1 buf_rdqs_n [DQS_BITS-1:0] (rdqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}} & {DQS_BITS{dqs_n_en}} & {DQS_BITS{rdqs_en}});
426    bufif1 buf_dq [DQ_BITS-1:0] (dq, dq_out_dly, dq_out_en_dly & {DQ_BITS {out_en}});
427
428    initial begin
429        if (BL_MAX < 2)
430            $display("%m ERROR: BL_MAX parameter must be >= 2. \nBL_MAX = %d", BL_MAX);
431        if ((1<<BO_BITS) > BL_MAX)
432            $display("%m ERROR: 2^BO_BITS cannot be greater than BL_MAX parameter.");
433        $timeformat (-12, 1, " ps", 1);
434        reset_task;
435        seed = RANDOM_SEED;
436        ck_cntr = 0;
437    end
438
439    // calculate the absolute value of a real number
440    function real abs_value;
441    input arg;
442    real arg;
443    begin
444        if (arg < 0.0)
445            abs_value = -1.0 * arg;
446        else
447            abs_value = arg;
448    end
449    endfunction
450
451`ifdef MAX_MEM
452`else
453    function get_index;
454        input [`MAX_BITS-1:0] addr;
455        begin : index
456            get_index = 0;
457            for (memory_index=0; memory_index<memory_used; memory_index=memory_index+1) begin
458                if (address[memory_index] == addr) begin
459                    get_index = 1;
460                    disable index;
461                end
462            end
463        end
464    endfunction
465`endif
466
467    task memory_write;
468        input [BA_BITS-1:0] bank;
469        input [ROW_BITS-1:0] row;
470        input [COL_BITS-1:0] col;
471        input [BL_MAX*DQ_BITS-1:0] data;
472        reg [`MAX_BITS-1:0] addr;
473        begin
474            // chop off the lowest address bits
475            addr = {bank, row, col}/BL_MAX;
476`ifdef MAX_MEM
477            memory[addr] = data;
478`else
479            if (get_index(addr)) begin
480                address[memory_index] = addr;
481                memory[memory_index] = data;
482            end else if (memory_used == `MEM_SIZE) begin
483                $display ("%m: at time %t ERROR: Memory overflow. Write to Address %h with Data %h will be lost.\nYou must increase the MEM_BITS parameter or define MAX_MEM.", $time, addr, data);
484                if (STOP_ON_ERROR) $stop(0);
485            end else begin
486                address[memory_used] = addr;
487                memory[memory_used] = data;
488                memory_used = memory_used + 1;
489            end
490`endif
491        end
492    endtask
493
494    task memory_read;
495        input [BA_BITS-1:0] bank;
496        input [ROW_BITS-1:0] row;
497        input [COL_BITS-1:0] col;
498        output [BL_MAX*DQ_BITS-1:0] data;
499        reg [`MAX_BITS-1:0] addr;
500        begin
501            // chop off the lowest address bits
502            addr = {bank, row, col}/BL_MAX;
503`ifdef MAX_MEM
504            data = memory[addr];
505`else
506            if (get_index(addr)) begin
507                data = memory[memory_index];
508            end else begin
509                data = {BL_MAX*DQ_BITS{1'bx}};
510            end
511`endif
512        end
513    endtask
514
515    // Before this task runs, the model must be in a valid state for precharge power down.
516    // After this task runs, NOP commands must be issued until tRFC has been met
517    task initialize;
518        input [ADDR_BITS-1:0] mode_reg0;
519        input [ADDR_BITS-1:0] mode_reg1;
520        input [ADDR_BITS-1:0] mode_reg2;
521        input [ADDR_BITS-1:0] mode_reg3;
522        begin
523            if (DEBUG) $display ("%m: at time %t INFO: Performing Initialization Sequence", $time);
524            cmd_task(1, NOP, 'bx, 'bx);
525            cmd_task(1, PRECHARGE, 'bx, 1<<AP); // Precharege ALL
526            cmd_task(1, LOAD_MODE, 3, mode_reg3);
527            cmd_task(1, LOAD_MODE, 2, mode_reg2);
528            cmd_task(1, LOAD_MODE, 1, mode_reg1);
529            cmd_task(1, LOAD_MODE, 0, mode_reg0 | 'h100); // DLL Reset
530            cmd_task(1, PRECHARGE, 'bx, 1<<AP); // Precharege ALL
531            cmd_task(1, REFRESH, 'bx, 'bx);
532            cmd_task(1, REFRESH, 'bx, 'bx);
533            cmd_task(1, LOAD_MODE, 0, mode_reg0);
534            cmd_task(1, LOAD_MODE, 1, mode_reg1 | 'h380); // OCD Default
535            cmd_task(1, LOAD_MODE, 1, mode_reg1);
536            cmd_task(0, NOP, 'bx, 'bx);
537        end
538    endtask
539
540    task reset_task;
541        integer i;
542        begin
543            // disable inputs
544            dq_in_valid = 0;
545            dqs_in_valid <= 0;
546            wdqs_cntr = 0;
547            wdq_cntr = 0;
548            for (i=0; i<36; i=i+1) begin
549                wdqs_pos_cntr[i] <= 0;
550            end
551            b2b_write <= 0;
552            // disable outputs
553            out_en = 0;
554            dqs_n_en = 0;
555            rdqs_en = 0;
556            dq_out_en = 0;
557            rdq_cntr = 0;
558            dqs_out_en = 0;
559            rdqs_cntr = 0;
560            // disable ODT
561            odt_en = 0;
562            odt_state = 0;
563            // reset bank state
564            active_bank = {`BANKS{1'b1}};
565            auto_precharge_bank = 0;
566            read_precharge_bank = 0;
567            write_precharge_bank = 0;
568            // require initialization sequence
569            init_done = 0;
570            init_step = 0;
571            init_mode_reg = 0;
572            // reset DLL
573            dll_en = 0;
574            dll_reset = 0;
575            dll_locked = 0;
576            ocd = 0;
577            // exit power down and self refresh
578            in_power_down = 0;
579            in_self_refresh = 0;
580            // clear pipelines
581            al_pipeline = 0;
582            wr_pipeline = 0;
583            rd_pipeline = 0;
584            odt_pipeline = 0;
585            // clear memory
586`ifdef MAX_MEM
587            for (i=0; i<=`MAX_SIZE; i=i+1) begin //erase memory ... one address at a time
588                memory[i] <= 'bx;
589            end
590`else
591            memory_used <= 0; //erase memory
592`endif
593            // clear maximum timing checks
594            tm_refresh <= 'bx;
595            for (i=0; i<`BANKS; i=i+1) begin
596                tm_bank_activate[i] <= 'bx;
597            end
598        end
599    endtask
600
601    task chk_err;
602        input samebank;
603        input [BA_BITS-1:0] bank;
604        input [3:0] fromcmd;
605        input [3:0] cmd;
606        reg err;
607    begin
608        // all matching case expressions will be evaluated
609        casex ({samebank, fromcmd, cmd})
610            {1'b0, LOAD_MODE, 4'b0xxx } : begin if (ck_cntr - ck_load_mode < TMRD) $display ("%m: at time %t ERROR: tMRD violation during %s", $time, cmd_string[cmd]); end
611            {1'b0, LOAD_MODE, 4'b100x } : begin if (ck_cntr - ck_load_mode < TMRD) begin $display ("%m: at time %t INFO: Load Mode to Reset condition.", $time); init_done = 0; end end
612            {1'b0, REFRESH , 4'b0xxx } : begin if ($time - tm_refresh < TRFC_MIN) $display ("%m: at time %t ERROR: tRFC violation during %s", $time, cmd_string[cmd]); end
613            {1'b0, REFRESH , PWR_DOWN } : ; // 1 tCK
614            {1'b0, REFRESH , SELF_REF } : begin if ($time - tm_refresh < TRFC_MIN) begin $display ("%m: at time %t INFO: Refresh to Reset condition", $time); init_done = 0; end end
615            {1'b0, PRECHARGE, 4'b000x } : begin if ($time - tm_precharge_all < TRPA) $display ("%m: at time %t ERROR: tRPA violation during %s", $time, cmd_string[cmd]);
616                                                 if ($time - tm_precharge < TRP) $display ("%m: at time %t ERROR: tRP violation during %s", $time, cmd_string[cmd]); end
617            {1'b1, PRECHARGE, PRECHARGE} : begin if (DEBUG && ($time - tm_precharge_all < TRPA)) $display ("%m: at time %t INFO: Precharge All interruption during %s", $time, cmd_string[cmd]);
618                                                 if (DEBUG && ($time - tm_bank_precharge[bank] < TRP)) $display ("%m: at time %t INFO: Precharge bank %d interruption during %s", $time, cmd_string[cmd], bank); end
619            {1'b1, PRECHARGE, ACTIVATE } : begin if ($time - tm_precharge_all < TRPA) $display ("%m: at time %t ERROR: tRPA violation during %s", $time, cmd_string[cmd]);
620                                                 if ($time - tm_bank_precharge[bank] < TRP) $display ("%m: at time %t ERROR: tRP violation during %s to bank %d", $time, cmd_string[cmd], bank); end
621            {1'b0, PRECHARGE, PWR_DOWN } : ; //1 tCK, can be concurrent with auto precharge
622            {1'b0, PRECHARGE, SELF_REF } : begin if (($time - tm_precharge_all < TRPA) || ($time - tm_precharge < TRP)) begin $display ("%m: at time %t INFO: Precharge to Reset condition", $time); init_done = 0; end end
623            {1'b0, ACTIVATE , REFRESH } : begin if ($time - tm_activate < TRC) $display ("%m: at time %t ERROR: tRC violation during %s", $time, cmd_string[cmd]); end
624            {1'b1, ACTIVATE , PRECHARGE} : begin if (($time - tm_bank_activate[bank] > TRAS_MAX) && (active_bank[bank] === 1'b1)) $display ("%m: at time %t ERROR: tRAS maximum violation during %s to bank %d", $time, cmd_string[cmd], bank);
625                                                 if ($time - tm_bank_activate[bank] < TRAS_MIN) $display ("%m: at time %t ERROR: tRAS minimum violation during %s to bank %d", $time, cmd_string[cmd], bank);end
626            {1'b0, ACTIVATE , ACTIVATE } : begin if ($time - tm_activate < TRRD) $display ("%m: at time %t ERROR: tRRD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
627            {1'b1, ACTIVATE , ACTIVATE } : begin if ($time - tm_bank_activate[bank] < TRC) $display ("%m: at time %t ERROR: tRC violation during %s to bank %d", $time, cmd_string[cmd], bank); end
628            {1'b1, ACTIVATE , 4'b010x } : ; // tRCD is checked outside this task
629            {1'b1, ACTIVATE , PWR_DOWN } : ; // 1 tCK
630            {1'b1, WRITE , PRECHARGE} : begin if ((ck_cntr - ck_bank_write[bank] <= write_latency + burst_length/2) || ($time - tm_bank_write_end[bank] < TWR)) $display ("%m: at time %t ERROR: tWR violation during %s to bank %d", $time, cmd_string[cmd], bank); end
631            {1'b0, WRITE , WRITE } : begin if (ck_cntr - ck_write < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
632            {1'b0, WRITE , READ } : begin if ((ck_load_mode < ck_write) && (ck_cntr - ck_write < write_latency + burst_length/2 + 2 - additive_latency)) $display ("%m: at time %t ERROR: tWTR violation during %s to bank %d", $time, cmd_string[cmd], bank); end
633            {1'b0, WRITE , PWR_DOWN } : begin if ((ck_load_mode < ck_write) && (
634                                                    |write_precharge_bank
635                                                 || (ck_cntr - ck_write_ap < 1)
636                                                 || (ck_cntr - ck_write < write_latency + burst_length/2 + 2)
637                                                 || ($time - tm_write_end < TWTR))) begin $display ("%m: at time %t INFO: Write to Reset condition", $time); init_done = 0; end end
638            {1'b1, READ , PRECHARGE} : begin if ((ck_cntr - ck_bank_read[bank] < additive_latency + burst_length/2) || ($time - tm_bank_read_end[bank] < TRTP)) $display ("%m: at time %t ERROR: tRTP violation during %s to bank %d", $time, cmd_string[cmd], bank); end
639            {1'b0, READ , WRITE } : begin if ((ck_load_mode < ck_read) && (ck_cntr - ck_read < read_latency + burst_length/2 + 1 - write_latency)) $display ("%m: at time %t ERROR: tRTW violation during %s to bank %d", $time, cmd_string[cmd], bank); end
640            {1'b0, READ , READ } : begin if (ck_cntr - ck_read < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
641            {1'b0, READ , PWR_DOWN } : begin if ((ck_load_mode < ck_read) && (ck_cntr - ck_read < read_latency + burst_length/2 + 1)) begin $display ("%m: at time %t INFO: Read to Reset condition", $time); init_done = 0; end end
642            {1'b0, PWR_DOWN , 4'b00xx } : begin if (ck_cntr - ck_power_down < TXP) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]); end
643            {1'b0, PWR_DOWN , WRITE } : begin if (ck_cntr - ck_power_down < TXP) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]); end
644            {1'b0, PWR_DOWN , READ } : begin if (ck_cntr - ck_slow_exit_pd < TXARDS - additive_latency) $display ("%m: at time %t ERROR: tXARDS violation during %s", $time, cmd_string[cmd]);
645                                            else if (ck_cntr - ck_power_down < TXARD) $display ("%m: at time %t ERROR: tXARD violation during %s", $time, cmd_string[cmd]); end
646            {1'b0, SELF_REF , 4'b00xx } : begin if ($time - tm_self_refresh < TXSNR) $display ("%m: at time %t ERROR: tXSNR violation during %s", $time, cmd_string[cmd]); end
647            {1'b0, SELF_REF , WRITE } : begin if ($time - tm_self_refresh < TXSNR) $display ("%m: at time %t ERROR: tXSNR violation during %s", $time, cmd_string[cmd]); end
648            {1'b0, SELF_REF , READ } : begin if (ck_cntr - ck_self_refresh < TXSRD) $display ("%m: at time %t ERROR: tXSRD violation during %s", $time, cmd_string[cmd]); end
649            {1'b0, 4'b100x , 4'b100x } : begin if (ck_cntr - ck_cke < TCKE) begin $display ("%m: at time %t ERROR: tCKE violation on CKE", $time); init_done = 0; end end
650        endcase
651    end
652    endtask
653
654    task cmd_task;
655        input cke;
656        input [2:0] cmd;
657        input [BA_BITS-1:0] bank;
658        input [ADDR_BITS-1:0] addr;
659        reg [`BANKS:0] i;
660        integer j;
661        reg [`BANKS:0] tfaw_cntr;
662        reg [COL_BITS-1:0] col;
663        begin
664
665            // tRFC max check
666            if (!er_trfc_max && !in_self_refresh) begin
667                if ($time - tm_refresh > TRFC_MAX) begin
668                    $display ("%m: at time %t ERROR: tRFC maximum violation during %s", $time, cmd_string[cmd]);
669                    er_trfc_max = 1;
670                end
671            end
672            if (cke) begin
673                if ((cmd < NOP) && ((cmd != PRECHARGE) || !addr[AP])) begin
674                    for (j=0; j<NOP; j=j+1) begin
675                        chk_err(1'b0, bank, j, cmd);
676                        chk_err(1'b1, bank, j, cmd);
677                    end
678                    chk_err(1'b0, bank, PWR_DOWN, cmd);
679                    chk_err(1'b0, bank, SELF_REF, cmd);
680                end
681
682                case (cmd)
683                    LOAD_MODE : begin
684                        if (|active_bank) begin
685                            $display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]);
686                            if (STOP_ON_ERROR) $stop(0);
687                        end else begin
688                            if (DEBUG) $display ("%m: at time %t INFO: %s %d", $time, cmd_string[cmd], bank);
689                            case (bank)
690                                0 : begin
691                                    // Burst Length
692                                    burst_length = 1<<addr[2:0];
693                                    if ((burst_length >= BL_MIN) && (burst_length <= BL_MAX)) begin
694                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Length = %d", $time, cmd_string[cmd], bank, burst_length);
695                                    end else begin
696                                        $display ("%m: at time %t ERROR: %s %d Illegal Burst Length = %d", $time, cmd_string[cmd], bank, burst_length);
697                                    end
698                                    // Burst Order
699                                    burst_order = addr[3];
700                                    if (!burst_order) begin
701                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Order = Sequential", $time, cmd_string[cmd], bank);
702                                    end else if (burst_order) begin
703                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Order = Interleaved", $time, cmd_string[cmd], bank);
704                                    end else begin
705                                        $display ("%m: at time %t ERROR: %s %d Illegal Burst Order = %d", $time, cmd_string[cmd], bank, burst_order);
706                                    end
707                                    // CAS Latency
708                                    cas_latency = addr[6:4];
709                                    read_latency = cas_latency + additive_latency;
710                                    write_latency = read_latency - 1;
711                                    if ((cas_latency >= CL_MIN) && (cas_latency <= CL_MAX)) begin
712                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d CAS Latency = %d", $time, cmd_string[cmd], bank, cas_latency);
713                                    end else begin
714                                        $display ("%m: at time %t ERROR: %s %d Illegal CAS Latency = %d", $time, cmd_string[cmd], bank, cas_latency);
715                                    end
716                                    // Test Mode
717                                    if (!addr[7]) begin
718                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Test Mode = Normal", $time, cmd_string[cmd], bank);
719                                    end else begin
720                                        $display ("%m: at time %t ERROR: %s %d Illegal Test Mode = %d", $time, cmd_string[cmd], bank, addr[7]);
721                                    end
722                                    // DLL Reset
723                                    dll_reset = addr[8];
724                                    if (!dll_reset) begin
725                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Reset = Normal", $time, cmd_string[cmd], bank);
726                                    end else if (dll_reset) begin
727                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Reset = Reset DLL", $time, cmd_string[cmd], bank);
728                                        dll_locked = 0;
729                                        ck_dll_reset <= ck_cntr;
730                                    end else begin
731                                        $display ("%m: at time %t ERROR: %s %d Illegal DLL Reset = %d", $time, cmd_string[cmd], bank, dll_reset);
732                                    end
733                                    // Write Recovery
734                                    write_recovery = addr[11:9] + 1;
735                                    if ((write_recovery >= WR_MIN) && (write_recovery <= WR_MAX)) begin
736                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Write Recovery = %d", $time, cmd_string[cmd], bank, write_recovery);
737                                    end else begin
738                                        $display ("%m: at time %t ERROR: %s %d Illegal Write Recovery = %d", $time, cmd_string[cmd], bank, write_recovery);
739                                    end
740                                    // Power Down Mode
741                                    low_power = addr[12];
742                                    if (!low_power) begin
743                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Power Down Mode = Fast Exit", $time, cmd_string[cmd], bank);
744                                    end else if (low_power) begin
745                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Power Down Mode = Slow Exit", $time, cmd_string[cmd], bank);
746                                    end else begin
747                                        $display ("%m: at time %t ERROR: %s %d Illegal Power Down Mode = %d", $time, cmd_string[cmd], bank, low_power);
748                                    end
749                                end
750                                1 : begin
751                                    // DLL Enable
752                                    dll_en = !addr[0];
753                                    if (!dll_en) begin
754                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Enable = Disabled", $time, cmd_string[cmd], bank);
755                                    end else if (dll_en) begin
756                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Enable = Enabled", $time, cmd_string[cmd], bank);
757                                    end else begin
758                                        $display ("%m: at time %t ERROR: %s %d Illegal DLL Enable = %d", $time, cmd_string[cmd], bank, dll_en);
759                                    end
760                                    // Output Drive Strength
761                                    if (!addr[1]) begin
762                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = Full", $time, cmd_string[cmd], bank);
763                                    end else if (addr[1]) begin
764                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = Reduced", $time, cmd_string[cmd], bank);
765                                    end else begin
766                                        $display ("%m: at time %t ERROR: %s %d Illegal Output Drive Strength = %d", $time, cmd_string[cmd], bank, addr[1]);
767                                    end
768                                    // ODT Rtt
769                                    odt_rtt = {addr[6], addr[2]};
770                                    if (odt_rtt == 2'b00) begin
771                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = Disabled", $time, cmd_string[cmd], bank);
772                                        odt_en = 0;
773                                    end else if (odt_rtt == 2'b01) begin
774                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = 75 Ohm", $time, cmd_string[cmd], bank);
775                                        odt_en = 1;
776                                        tm_odt_en <= $time;
777                                    end else if (odt_rtt == 2'b10) begin
778                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = 150 Ohm", $time, cmd_string[cmd], bank);
779                                        odt_en = 1;
780                                        tm_odt_en <= $time;
781                                    end else if (odt_rtt == 2'b11) begin
782                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = 50 Ohm", $time, cmd_string[cmd], bank);
783                                        odt_en = 1;
784                                        tm_odt_en <= $time;
785                                    end else begin
786                                        $display ("%m: at time %t ERROR: %s %d Illegal ODT Rtt = %d", $time, cmd_string[cmd], bank, odt_rtt);
787                                        odt_en = 0;
788                                    end
789                                    // Additive Latency
790                                    additive_latency = addr[5:3];
791                                    read_latency = cas_latency + additive_latency;
792                                    write_latency = read_latency - 1;
793                                    if ((additive_latency >= AL_MIN) && (additive_latency <= AL_MAX)) begin
794                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Additive Latency = %d", $time, cmd_string[cmd], bank, additive_latency);
795                                    end else begin
796                                        $display ("%m: at time %t ERROR: %s %d Illegal Additive Latency = %d", $time, cmd_string[cmd], bank, additive_latency);
797                                    end
798                                    // OCD Program
799                                    ocd = addr[9:7];
800                                    if (ocd == 3'b000) begin
801                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d OCD Program = OCD Exit", $time, cmd_string[cmd], bank);
802                                    end else if (ocd == 3'b111) begin
803                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d OCD Program = OCD Default", $time, cmd_string[cmd], bank);
804                                    end else begin
805                                        $display ("%m: at time %t ERROR: %s %d Illegal OCD Program = %b", $time, cmd_string[cmd], bank, ocd);
806                                    end
807
808                                    // DQS_N Enable
809                                    dqs_n_en = !addr[10];
810                                    if (!dqs_n_en) begin
811                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d DQS_N Enable = Disabled", $time, cmd_string[cmd], bank);
812                                    end else if (dqs_n_en) begin
813                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d DQS_N Enable = Enabled", $time, cmd_string[cmd], bank);
814                                    end else begin
815                                        $display ("%m: at time %t ERROR: %s %d Illegal DQS_N Enable = %d", $time, cmd_string[cmd], bank, dqs_n_en);
816                                    end
817                                    // RDQS Enable
818                                    rdqs_en = addr[11];
819                                    if (!rdqs_en) begin
820                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d RDQS Enable = Disabled", $time, cmd_string[cmd], bank);
821                                    end else if (rdqs_en) begin
822`ifdef x8
823                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d RDQS Enable = Enabled", $time, cmd_string[cmd], bank);
824`else
825                                        $display ("%m: at time %t WARNING: %s %d Illegal RDQS Enable. RDQS only exists on a x8 part", $time, cmd_string[cmd], bank);
826                                        rdqs_en = 0;
827`endif
828                                    end else begin
829                                        $display ("%m: at time %t ERROR: %s %d Illegal RDQS Enable = %d", $time, cmd_string[cmd], bank, rdqs_en);
830                                    end
831                                    // Output Enable
832                                    out_en = !addr[12];
833                                    if (!out_en) begin
834                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Enable = Disabled", $time, cmd_string[cmd], bank);
835                                    end else if (out_en) begin
836                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Enable = Enabled", $time, cmd_string[cmd], bank);
837                                    end else begin
838                                        $display ("%m: at time %t ERROR: %s %d Illegal Output Enable = %d", $time, cmd_string[cmd], bank, out_en);
839                                    end
840                                end
841                                2 : begin
842                                    // High Temperature Self Refresh rate
843                                    if (!addr[7]) begin
844                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d High Temperature Self Refresh rate = 1X (0C-85C)", $time, cmd_string[cmd], bank);
845                                    end else if (addr[7]) begin
846                                        if (DEBUG) $display ("%m: at time %t INFO: %s %d High Temperature Self Refresh rate = 2X (>85C)", $time, cmd_string[cmd], bank);
847                                    end else begin
848                                        $display ("%m: at time %t ERROR: %s %d Illegal High Temperature Self Refresh rate = %d", $time, cmd_string[cmd], bank, addr[7]);
849                                    end
850                                    if ((addr & ~(1<<7)) !== 0) begin
851                                        $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved bits must be programmed to zero", $time, cmd_string[cmd], bank);
852                                    end
853                                end
854                                3 : begin
855                                    if (addr !== 0) begin
856                                        $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved bits must be programmed to zero", $time, cmd_string[cmd], bank);
857                                    end
858                                end
859                            endcase
860                            init_mode_reg[bank] = 1;
861                            ck_load_mode <= ck_cntr;
862                        end
863                    end
864                    REFRESH : begin
865                        if (|active_bank) begin
866                            $display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]);
867                            if (STOP_ON_ERROR) $stop(0);
868                        end else begin
869                            if (DEBUG) $display ("%m: at time %t INFO: %s", $time, cmd_string[cmd]);
870                            er_trfc_max = 0;
871                            ref_cntr = ref_cntr + 1;
872                            tm_refresh <= $time;
873                        end
874                    end
875                    PRECHARGE : begin
876                        if (addr[AP]) begin
877                            // tRPA timing applies when the PRECHARGE (ALL) command is issued, regardless of
878                            // the number of banks already open or closed.
879                            for (i=0; i<`BANKS; i=i+1) begin
880                                for (j=0; j<NOP; j=j+1) begin
881                                    chk_err(1'b0, i, j, cmd);
882                                    chk_err(1'b1, i, j, cmd);
883                                end
884                                chk_err(1'b0, i, PWR_DOWN, cmd);
885                                chk_err(1'b0, i, SELF_REF, cmd);
886                            end
887                            if (|auto_precharge_bank) begin
888                                $display ("%m: at time %t ERROR: %s All Failure. Auto Precharge is scheduled.", $time, cmd_string[cmd]);
889                                if (STOP_ON_ERROR) $stop(0);
890                            end else begin
891                                if (DEBUG) $display ("%m: at time %t INFO: %s All", $time, cmd_string[cmd]);
892                                active_bank = 0;
893                                tm_precharge_all <= $time;
894                            end
895                        end else begin
896                            // A PRECHARGE command is allowed if there is no open row in that bank (idle state)
897                            // or if the previously open row is already in the process of precharging.
898                            // However, the precharge period will be determined by the last PRECHARGE command issued to the bank.
899                            if (auto_precharge_bank[bank]) begin
900                                $display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank);
901                                if (STOP_ON_ERROR) $stop(0);
902                            end else begin
903                                if (DEBUG) $display ("%m: at time %t INFO: %s bank %d", $time, cmd_string[cmd], bank);
904                                active_bank[bank] = 1'b0;
905                                tm_bank_precharge[bank] <= $time;
906                                tm_precharge <= $time;
907                            end
908                        end
909                    end
910                    ACTIVATE : begin
911                        if (`BANKS == 8) begin
912                            tfaw_cntr = 0;
913                            for (i=0; i<`BANKS; i=i+1) begin
914                                if ($time - tm_bank_activate[i] < TFAW) begin
915                                    tfaw_cntr = tfaw_cntr + 1;
916                                end
917                            end
918                            if (tfaw_cntr > 3) begin
919                                $display ("%m: at time %t ERROR: tFAW violation during %s to bank %d", $time, cmd_string[cmd], bank);
920                            end
921                        end
922
923                        if (!init_done) begin
924                            $display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]);
925                            if (STOP_ON_ERROR) $stop(0);
926                        end else if (active_bank[bank]) begin
927                            $display ("%m: at time %t ERROR: %s Failure. Bank %d must be Precharged.", $time, cmd_string[cmd], bank);
928                            if (STOP_ON_ERROR) $stop(0);
929                        end else begin
930                            if (addr >= 1<<ROW_BITS) begin
931                                $display ("%m: at time %t WARNING: row = %h does not exist. Maximum row = %h", $time, addr, (1<<ROW_BITS)-1);
932                            end
933                            if (DEBUG) $display ("%m: at time %t INFO: %s bank %d row %h", $time, cmd_string[cmd], bank, addr);
934                            active_bank[bank] = 1'b1;
935                            active_row[bank] = addr;
936                            tm_bank_activate[bank] <= $time;
937                            tm_activate <= $time;
938                        end
939
940                    end
941                    WRITE : begin
942                        if (!init_done) begin
943                            $display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]);
944                            if (STOP_ON_ERROR) $stop(0);
945                        end else if (!active_bank[bank]) begin
946                            $display ("%m: at time %t ERROR: %s Failure. Bank %d must be Activated.", $time, cmd_string[cmd], bank);
947                            if (STOP_ON_ERROR) $stop(0);
948                        end else if (auto_precharge_bank[bank]) begin
949                            $display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank);
950                            if (STOP_ON_ERROR) $stop(0);
951                        end else if ((ck_cntr - ck_write < burst_length/2) && (ck_cntr - ck_write)%2) begin
952                            $display ("%m: at time %t ERROR: %s Failure. Illegal burst interruption.", $time, cmd_string[cmd]);
953                            if (STOP_ON_ERROR) $stop(0);
954                        end else begin
955                            if (addr[AP]) begin
956                                auto_precharge_bank[bank] = 1'b1;
957                                write_precharge_bank[bank] = 1'b1;
958                            end
959                            col = ((addr>>1) & -1*(1<<AP)) | (addr & {AP{1'b1}});
960                            if (col >= 1<<COL_BITS) begin
961                                $display ("%m: at time %t WARNING: col = %h does not exist. Maximum col = %h", $time, col, (1<<COL_BITS)-1);
962                            end
963                            if (DEBUG) $display ("%m: at time %t INFO: %s bank %d col %h, auto precharge %d", $time, cmd_string[cmd], bank, col, addr[AP]);
964                            wr_pipeline[2*write_latency + 1] = 1;
965                            ba_pipeline[2*write_latency + 1] = bank;
966                            row_pipeline[2*write_latency + 1] = active_row[bank];
967                            col_pipeline[2*write_latency + 1] = col;
968                            ck_bank_write[bank] <= ck_cntr;
969                            ck_write <= ck_cntr;
970                        end
971                    end
972                    READ : begin
973                        if (!dll_locked)
974                            $display ("%m: at time %t WARNING: %s prior to DLL locked. Failing to wait for synchronization to occur may result in a violation of the tAC or tDQSCK parameters.", $time, cmd_string[cmd]);
975                        if (!init_done) begin
976                            $display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]);
977                            if (STOP_ON_ERROR) $stop(0);
978                        end else if (!active_bank[bank]) begin
979                            $display ("%m: at time %t ERROR: %s Failure. Bank %d must be Activated.", $time, cmd_string[cmd], bank);
980                            if (STOP_ON_ERROR) $stop(0);
981                        end else if (auto_precharge_bank[bank]) begin
982                            $display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank);
983                            if (STOP_ON_ERROR) $stop(0);
984                        end else if ((ck_cntr - ck_read < burst_length/2) && (ck_cntr - ck_read)%2) begin
985                            $display ("%m: at time %t ERROR: %s Failure. Illegal burst interruption.", $time, cmd_string[cmd]);
986                            if (STOP_ON_ERROR) $stop(0);
987                        end else begin
988                            if (addr[AP]) begin
989                                auto_precharge_bank[bank] = 1'b1;
990                                read_precharge_bank[bank] = 1'b1;
991                            end
992                            col = ((addr>>1) & -1*(1<<AP)) | (addr & {AP{1'b1}});
993                            if (col >= 1<<COL_BITS) begin
994                                $display ("%m: at time %t WARNING: col = %h does not exist. Maximum col = %h", $time, col, (1<<COL_BITS)-1);
995                            end
996                            if (DEBUG) $display ("%m: at time %t INFO: %s bank %d col %h, auto precharge %d", $time, cmd_string[cmd], bank, col, addr[AP]);
997                            rd_pipeline[2*read_latency - 1] = 1;
998                            ba_pipeline[2*read_latency - 1] = bank;
999                            row_pipeline[2*read_latency - 1] = active_row[bank];
1000                            col_pipeline[2*read_latency - 1] = col;
1001                            ck_bank_read[bank] <= ck_cntr;
1002                            ck_read <= ck_cntr;
1003                        end
1004                    end
1005                    NOP: begin
1006                        if (in_power_down) begin
1007                            if (DEBUG) $display ("%m: at time %t INFO: Power Down Exit", $time);
1008                            in_power_down = 0;
1009                            if (|active_bank & low_power) begin // slow exit active power down
1010                                ck_slow_exit_pd <= ck_cntr;
1011                            end
1012                            ck_power_down <= ck_cntr;
1013                        end
1014                        if (in_self_refresh) begin
1015                            if ($time - tm_cke < TISXR)
1016                                $display ("%m: at time %t ERROR: tISXR violation during Self Refresh Exit", $time);
1017                            if (DEBUG) $display ("%m: at time %t INFO: Self Refresh Exit", $time);
1018                            in_self_refresh = 0;
1019                            ck_dll_reset <= ck_cntr;
1020                            ck_self_refresh <= ck_cntr;
1021                            tm_self_refresh <= $time;
1022                            tm_refresh <= $time;
1023                        end
1024                    end
1025                endcase
1026                if ((prev_cke !== 1) && (cmd !== NOP)) begin
1027                    $display ("%m: at time %t ERROR: NOP or Deselect is required when CKE goes active.", $time);
1028                end
1029                if (!init_done) begin
1030                    case (init_step)
1031                        0 : begin
1032                            if ($time < 200000000)
1033                                $display ("%m: at time %t WARNING: 200 us is required before CKE goes active.", $time);
1034// if (cmd_chk + 200000000 > $time)
1035// $display("%m: at time %t WARNING: NOP or DESELECT is required for 200 us before CKE is brought high", $time);
1036                            init_step = init_step + 1;
1037                        end
1038                        1 : if (dll_en) init_step = init_step + 1;
1039                        2 : begin
1040                            if (&init_mode_reg && dll_reset) begin
1041                                active_bank = {`BANKS{1'b1}}; // require Precharge All or bank Precharges
1042                                ref_cntr = 0; // require refresh
1043                                init_step = init_step + 1;
1044                            end
1045                        end
1046                        3 : if (ref_cntr == 2) begin
1047                            init_step = init_step + 1;
1048                        end
1049                        4 : if (!dll_reset) init_step = init_step + 1;
1050                        5 : if (ocd == 3'b111) init_step = init_step + 1;
1051                        6 : begin
1052                            if (ocd == 3'b000) begin
1053                                if (DEBUG) $display ("%m: at time %t INFO: Initialization Sequence is complete", $time);
1054                                init_done = 1;
1055                            end
1056                        end
1057                    endcase
1058                end
1059            end else if (prev_cke) begin
1060                if ((!init_done) && (init_step > 1)) begin
1061                    $display ("%m: at time %t ERROR: CKE must remain active until the initialization sequence is complete.", $time);
1062                    if (STOP_ON_ERROR) $stop(0);
1063                end
1064                case (cmd)
1065                    REFRESH : begin
1066                        for (j=0; j<NOP; j=j+1) begin
1067                            chk_err(1'b0, bank, j, SELF_REF);
1068                        end
1069                        chk_err(1'b0, bank, PWR_DOWN, SELF_REF);
1070                        chk_err(1'b0, bank, SELF_REF, SELF_REF);
1071                        if (|active_bank) begin
1072                            $display ("%m: at time %t ERROR: Self Refresh Failure. All banks must be Precharged.", $time);
1073                            if (STOP_ON_ERROR) $stop(0);
1074                            init_done = 0;
1075                        end else if (odt_en && odt_state) begin
1076                            $display ("%m: at time %t ERROR: ODT must be off prior to entering Self Refresh", $time);
1077                            if (STOP_ON_ERROR) $stop(0);
1078                            init_done = 0;
1079                        end else if (!init_done) begin
1080                            $display ("%m: at time %t ERROR: Self Refresh Failure. Initialization sequence is not complete.", $time);
1081                            if (STOP_ON_ERROR) $stop(0);
1082                        end else begin
1083                            if (DEBUG) $display ("%m: at time %t INFO: Self Refresh Enter", $time);
1084                            in_self_refresh = 1;
1085                            dll_locked = 0;
1086                        end
1087                    end
1088                    NOP : begin
1089                        // entering slow_exit or precharge power down and tANPD has not been satisfied
1090                        if ((low_power || (active_bank == 0)) && (ck_cntr - ck_odt < TANPD))
1091                            $display ("%m: at time %t WARNING: tANPD violation during %s. Synchronous or asynchronous change in termination resistance is possible.", $time, cmd_string[PWR_DOWN]);
1092                        for (j=0; j<NOP; j=j+1) begin
1093                            chk_err(1'b0, bank, j, PWR_DOWN);
1094                        end
1095                        chk_err(1'b0, bank, PWR_DOWN, PWR_DOWN);
1096                        chk_err(1'b0, bank, SELF_REF, PWR_DOWN);
1097
1098                        if (!init_done) begin
1099                            $display ("%m: at time %t ERROR: Power Down Failure. Initialization sequence is not complete.", $time);
1100                            if (STOP_ON_ERROR) $stop(0);
1101                        end else begin
1102                            if (DEBUG) begin
1103                                if (|active_bank) begin
1104                                    $display ("%m: at time %t INFO: Active Power Down Enter", $time);
1105                                end else begin
1106                                    $display ("%m: at time %t INFO: Precharge Power Down Enter", $time);
1107                                end
1108                            end
1109                            in_power_down = 1;
1110                        end
1111                    end
1112                    default : begin
1113                        $display ("%m: at time %t ERROR: NOP, Deselect, or Refresh is required when CKE goes inactive.", $time);
1114                        init_done = 0;
1115                    end
1116                endcase
1117                if (!init_done) begin
1118                    if (DEBUG) $display ("%m: at time %t WARNING: Reset has occurred. Device must be re-initialized.", $time);
1119                    reset_task;
1120                end
1121            end
1122            prev_cke = cke;
1123        end
1124    endtask
1125
1126    task data_task;
1127        reg [BA_BITS-1:0] bank;
1128        reg [ROW_BITS-1:0] row;
1129        reg [COL_BITS-1:0] col;
1130        integer i;
1131        integer j;
1132        begin
1133
1134            if (diff_ck) begin
1135                for (i=0; i<36; i=i+1) begin
1136                    if (dq_in_valid && dll_locked && ($time - tm_dqs_neg[i] < $rtoi(TDSS*tck_avg)))
1137                        $display ("%m: at time %t ERROR: tDSS violation on %s bit %d", $time, dqs_string[i/18], i%18);
1138                    if (check_write_dqs_high[i])
1139                        $display ("%m: at time %t ERROR: %s bit %d latching edge required during the preceding clock period.", $time, dqs_string[i/18], i%18);
1140                end
1141                check_write_dqs_high <= 0;
1142            end else begin
1143                for (i=0; i<36; i=i+1) begin
1144                    if (dll_locked && dq_in_valid && (i % 18 < DQS_BITS)) begin // Only check valid DQS group
1145                        tm_tdqss = abs_value($itor(tm_ck_pos) - tm_dqss_pos[i]);
1146                        //$display ("at time %t, tm_tdqss = %0d, tm_ck_pos = %0d, tm_dqss_pos [%0d] = %0d", $time, tm_tdqss, tm_ck_pos, i, tm_dqss_pos[i]);
1147                        if ((tm_tdqss < tck_avg/2.0) && (tm_tdqss > TDQSS*tck_avg))
1148                            $display ("%m: at time %t ERROR: tDQSS violation on %s bit %d", $time, dqs_string[i/18], i%18);
1149                    end
1150                    if (check_write_dqs_low[i])
1151                        $display ("%m: at time %t ERROR: %s bit %d latching edge required during the preceding clock period", $time, dqs_string[i/18], i%18);
1152                end
1153                check_write_preamble <= 0;
1154                check_write_postamble <= 0;
1155                check_write_dqs_low <= 0;
1156            end
1157
1158            if (wr_pipeline[0] || rd_pipeline[0]) begin
1159                bank = ba_pipeline[0];
1160                row = row_pipeline[0];
1161                col = col_pipeline[0];
1162                burst_cntr = 0;
1163                memory_read(bank, row, col, memory_data);
1164            end
1165
1166            // burst counter
1167            if (burst_cntr < burst_length) begin
1168                burst_position = col ^ burst_cntr;
1169                if (!burst_order) begin
1170                    burst_position[BO_BITS-1:0] = col + burst_cntr;
1171                end
1172                burst_cntr = burst_cntr + 1;
1173            end
1174
1175            // write dqs counter
1176            if (wr_pipeline[WDQS_PRE + 1]) begin
1177                wdqs_cntr = WDQS_PRE + burst_length + WDQS_PST - 1;
1178            end
1179            // write dqs
1180            if ((wdqs_cntr == burst_length + WDQS_PST) && (wdq_cntr == 0)) begin //write preamble
1181                check_write_preamble <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}};
1182            end
1183            if (wdqs_cntr > 1) begin // write data
1184                if ((wdqs_cntr - WDQS_PST)%2) begin
1185                    check_write_dqs_high <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}};
1186                end else begin
1187                    check_write_dqs_low <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}};
1188                end
1189            end
1190            if (wdqs_cntr == WDQS_PST) begin // write postamble
1191                check_write_postamble <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}};
1192            end
1193            if (wdqs_cntr > 0) begin
1194                wdqs_cntr = wdqs_cntr - 1;
1195            end
1196
1197            // write dq
1198            if (dq_in_valid) begin // write data
1199                bit_mask = 0;
1200                if (diff_ck) begin
1201                    for (i=0; i<DM_BITS; i=i+1) begin
1202                        bit_mask = bit_mask | ({`DQ_PER_DQS{~dm_in_neg[i]}}<<(burst_position*DQ_BITS + i*`DQ_PER_DQS));
1203                    end
1204                    memory_data = (dq_in_neg<<(burst_position*DQ_BITS) & bit_mask) | (memory_data & ~bit_mask);
1205                end else begin
1206                    for (i=0; i<DM_BITS; i=i+1) begin
1207                        bit_mask = bit_mask | ({`DQ_PER_DQS{~dm_in_pos[i]}}<<(burst_position*DQ_BITS + i*`DQ_PER_DQS));
1208                    end
1209                    memory_data = (dq_in_pos<<(burst_position*DQ_BITS) & bit_mask) | (memory_data & ~bit_mask);
1210                end
1211                dq_temp = memory_data>>(burst_position*DQ_BITS);
1212                if (DEBUG) $display ("%m: at time %t INFO: WRITE @ DQS= bank = %h row = %h col = %h data = %h",$time, bank, row, (-1*BL_MAX & col) + burst_position, dq_temp);
1213                if (burst_cntr%BL_MIN == 0) begin
1214                    memory_write(bank, row, col, memory_data);
1215                end
1216            end
1217            if (wr_pipeline[1]) begin
1218                wdq_cntr = burst_length;
1219            end
1220            if (wdq_cntr > 0) begin
1221                wdq_cntr = wdq_cntr - 1;
1222                dq_in_valid = 1'b1;
1223            end else begin
1224                dq_in_valid = 1'b0;
1225                dqs_in_valid <= 1'b0;
1226                for (i=0; i<36; i=i+1) begin
1227                    wdqs_pos_cntr[i] <= 0;
1228                end
1229            end
1230            if (wr_pipeline[0]) begin
1231                b2b_write <= 1'b0;
1232            end
1233            if (wr_pipeline[2]) begin
1234                if (dqs_in_valid) begin
1235                    b2b_write <= 1'b1;
1236                end
1237                dqs_in_valid <= 1'b1;
1238            end
1239            // read dqs enable counter
1240            if (rd_pipeline[RDQSEN_PRE]) begin
1241                rdqsen_cntr = RDQSEN_PRE + burst_length + RDQSEN_PST - 1;
1242            end
1243            if (rdqsen_cntr > 0) begin
1244                rdqsen_cntr = rdqsen_cntr - 1;
1245                dqs_out_en = 1'b1;
1246            end else begin
1247                dqs_out_en = 1'b0;
1248            end
1249
1250            // read dqs counter
1251            if (rd_pipeline[RDQS_PRE]) begin
1252                rdqs_cntr = RDQS_PRE + burst_length + RDQS_PST - 1;
1253            end
1254            // read dqs
1255            if ((rdqs_cntr >= burst_length + RDQS_PST) && (rdq_cntr == 0)) begin //read preamble
1256                dqs_out = 1'b0;
1257            end else if (rdqs_cntr > RDQS_PST) begin // read data
1258                dqs_out = rdqs_cntr - RDQS_PST;
1259            end else if (rdqs_cntr > 0) begin // read postamble
1260                dqs_out = 1'b0;
1261            end else begin
1262                dqs_out = 1'b1;
1263            end
1264            if (rdqs_cntr > 0) begin
1265                rdqs_cntr = rdqs_cntr - 1;
1266            end
1267
1268            // read dq enable counter
1269            if (rd_pipeline[RDQEN_PRE]) begin
1270                rdqen_cntr = RDQEN_PRE + burst_length + RDQEN_PST;
1271            end
1272            if (rdqen_cntr > 0) begin
1273                rdqen_cntr = rdqen_cntr - 1;
1274                dq_out_en = 1'b1;
1275            end else begin
1276                dq_out_en = 1'b0;
1277            end
1278            // read dq
1279            if (rd_pipeline[0]) begin
1280                rdq_cntr = burst_length;
1281            end
1282            if (rdq_cntr > 0) begin // read data
1283                dq_temp = memory_data>>(burst_position*DQ_BITS);
1284                dq_out = dq_temp;
1285                if (DEBUG) $display ("%m: at time %t INFO: READ @ DQS= bank = %h row = %h col = %h data = %h",$time, bank, row, (-1*BL_MAX & col) + burst_position, dq_temp);
1286                rdq_cntr = rdq_cntr - 1;
1287            end else begin
1288                dq_out = {DQ_BITS{1'b1}};
1289            end
1290
1291            // delay signals prior to output
1292            if (RANDOM_OUT_DELAY && (dqs_out_en || |dqs_out_en_dly || dq_out_en || |dq_out_en_dly)) begin
1293                for (i=0; i<DQS_BITS; i=i+1) begin
1294                    // DQSCK requirements
1295                    // 1.) less than tDQSCK
1296                    // 2.) greater than -tDQSCK
1297                    // 3.) cannot change more than tQHS + tDQSQ from previous DQS edge
1298                    dqsck_max = TDQSCK;
1299                    if (dqsck_max > dqsck[i] + TQHS + TDQSQ) begin
1300                        dqsck_max = dqsck[i] + TQHS + TDQSQ;
1301                    end
1302                    dqsck_min = -1*TDQSCK;
1303                    if (dqsck_min < dqsck[i] - TQHS - TDQSQ) begin
1304                        dqsck_min = dqsck[i] - TQHS - TDQSQ;
1305                    end
1306
1307                    // DQSQ requirements
1308                    // 1.) less than tAC - DQSCK
1309                    // 2.) less than tDQSQ
1310                    // 3.) greater than -tAC
1311                    // 4.) greater than tQH from previous DQS edge
1312                    dqsq_min = -1*TAC;
1313                    if (dqsq_min < dqsck[i] - TQHS) begin
1314                        dqsq_min = dqsck[i] - TQHS;
1315                    end
1316                    if (dqsck_min == dqsck_max) begin
1317                        dqsck[i] = dqsck_min;
1318                    end else begin
1319                        dqsck[i] = $dist_uniform(seed, dqsck_min, dqsck_max);
1320                    end
1321                    dqsq_max = TAC;
1322                    if (dqsq_max > TDQSQ + dqsck[i]) begin
1323                        dqsq_max = TDQSQ + dqsck[i];
1324                    end
1325
1326                    dqs_out_en_dly[i] <= #(tck_avg/2.0 + ($random % TAC)) dqs_out_en;
1327                    dqs_out_dly[i] <= #(tck_avg/2.0 + dqsck[i]) dqs_out;
1328                    for (j=0; j<`DQ_PER_DQS; j=j+1) begin
1329                        if (dq_out_en) begin // tLZ2
1330                            dq_out_en_dly[i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + $dist_uniform(seed, -2*TAC, dqsq_max)) dq_out_en;
1331                        end else begin // tHZ
1332                            dq_out_en_dly[i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + ($random % TAC)) dq_out_en;
1333                        end
1334                        if (dqsq_min == dqsq_max) begin
1335                            dq_out_dly [i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + dqsq_min) dq_out[i*`DQ_PER_DQS + j];
1336                        end else begin
1337                            dq_out_dly [i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + $dist_uniform(seed, dqsq_min, dqsq_max)) dq_out[i*`DQ_PER_DQS + j];
1338                        end
1339                    end
1340                end
1341            end else begin
1342                out_delay = tck_avg/2.0;
1343                dqs_out_en_dly <= #(out_delay) {DQS_BITS{dqs_out_en}};
1344                dqs_out_dly <= #(out_delay) {DQS_BITS{dqs_out }};
1345                dq_out_en_dly <= #(out_delay) {DQ_BITS {dq_out_en }};
1346                dq_out_dly <= #(out_delay) {DQ_BITS {dq_out }};
1347            end
1348        end
1349    endtask
1350
1351    always @(diff_ck) begin : main
1352        integer i;
1353
1354        if (!in_self_refresh && (diff_ck !== 1'b0) && (diff_ck !== 1'b1))
1355            $display ("%m: at time %t ERROR: CK and CK_N are not allowed to go to an unknown state.", $time);
1356        data_task;
1357        if (diff_ck) begin
1358            // check setup of command signals
1359            if ($time > TIS) begin
1360                if ($time - tm_cke < TIS)
1361                    $display ("%m: at time %t ERROR: tIS violation on CKE by %t", $time, tm_cke + TIS - $time);
1362                if (cke_in) begin
1363                    for (i=0; i<22; i=i+1) begin
1364                        if ($time - tm_cmd_addr[i] < TIS)
1365                            $display ("%m: at time %t ERROR: tIS violation on %s by %t", $time, cmd_addr_string[i], tm_cmd_addr[i] + TIS - $time);
1366                    end
1367                end
1368            end
1369
1370            // update current state
1371            if (!dll_locked && !in_self_refresh && (ck_cntr - ck_dll_reset == TDLLK)) begin
1372                // check CL value against the clock frequency
1373                if (cas_latency*tck_avg < CL_TIME)
1374                    $display ("%m: at time %t ERROR: CAS Latency = %d is illegal @tCK(avg) = %f", $time, cas_latency, tck_avg);
1375                // check WR value against the clock frequency
1376                if (write_recovery*tck_avg < TWR)
1377                    $display ("%m: at time %t ERROR: Write Recovery = %d is illegal @tCK(avg) = %f", $time, write_recovery, tck_avg);
1378                dll_locked = 1;
1379            end
1380            if (|auto_precharge_bank) begin
1381                for (i=0; i<`BANKS; i=i+1) begin
1382                    // Write with Auto Precharge Calculation
1383                    // 1. Meet minimum tRAS requirement
1384                    // 2. Write Latency PLUS BL/2 cycles PLUS WR after Write command
1385                    if (write_precharge_bank[i]
1386                        && ($time - tm_bank_activate[i] >= TRAS_MIN)
1387                        && (ck_cntr - ck_bank_write[i] >= write_latency + burst_length/2 + write_recovery)) begin
1388
1389                        if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", $time, i);
1390                        write_precharge_bank[i] = 0;
1391                        active_bank[i] = 0;
1392                        auto_precharge_bank[i] = 0;
1393                        ck_write_ap = ck_cntr;
1394                        tm_bank_precharge[i] = $time;
1395                        tm_precharge = $time;
1396                    end
1397                    // Read with Auto Precharge Calculation
1398                    // 1. Meet minimum tRAS requirement
1399                    // 2. Additive Latency plus BL/2 cycles after Read command
1400                    // 3. tRTP after the last 4-bit prefetch
1401                    if (read_precharge_bank[i]
1402                        && ($time - tm_bank_activate[i] >= TRAS_MIN)
1403                        && (ck_cntr - ck_bank_read[i] >= additive_latency + burst_length/2)) begin
1404
1405                        read_precharge_bank[i] = 0;
1406                        // In case the internal precharge is pushed out by tRTP, tRP starts at the point where
1407                        // the internal precharge happens (not at the next rising clock edge after this event).
1408                        if ($time - tm_bank_read_end[i] < TRTP) begin
1409                            if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", tm_bank_read_end[i] + TRTP, i);
1410                            active_bank[i] <= #(tm_bank_read_end[i] + TRTP - $time) 0;
1411                            auto_precharge_bank[i] <= #(tm_bank_read_end[i] + TRTP - $time) 0;
1412                            tm_bank_precharge[i] <= #(tm_bank_read_end[i] + TRTP - $time) tm_bank_read_end[i] + TRTP;
1413                            tm_precharge <= #(tm_bank_read_end[i] + TRTP - $time) tm_bank_read_end[i] + TRTP;
1414                        end else begin
1415                            if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", $time, i);
1416                            active_bank[i] = 0;
1417                            auto_precharge_bank[i] = 0;
1418                            tm_bank_precharge[i] = $time;
1419                            tm_precharge = $time;
1420                        end
1421                    end
1422                end
1423            end
1424
1425            // respond to incoming command
1426            if (cke_in ^ prev_cke) begin
1427                ck_cke <= ck_cntr;
1428            end
1429
1430            cmd_task(cke_in, cmd_n_in, ba_in, addr_in);
1431            if ((cmd_n_in == WRITE) || (cmd_n_in == READ)) begin
1432                al_pipeline[2*additive_latency] = 1'b1;
1433            end
1434            if (al_pipeline[0]) begin
1435                // check tRCD after additive latency
1436                if ($time - tm_bank_activate[ba_pipeline[2*cas_latency - 1]] < TRCD) begin
1437                    if (rd_pipeline[2*cas_latency - 1]) begin
1438                        $display ("%m: at time %t ERROR: tRCD violation during %s", $time, cmd_string[READ]);
1439                    end else begin
1440                        $display ("%m: at time %t ERROR: tRCD violation during %s", $time, cmd_string[WRITE]);
1441                    end
1442                end
1443                // check tWTR after additive latency
1444                if (rd_pipeline[2*cas_latency - 1]) begin
1445                    if ($time - tm_write_end < TWTR)
1446                        $display ("%m: at time %t ERROR: tWTR violation during %s", $time, cmd_string[READ]);
1447                end
1448            end
1449            if (rd_pipeline[2*(cas_latency - burst_length/2 + 2) - 1]) begin
1450                tm_bank_read_end[ba_pipeline[2*(cas_latency - burst_length/2 + 2) - 1]] <= $time;
1451            end
1452            for (i=0; i<`BANKS; i=i+1) begin
1453                if ((ck_cntr - ck_bank_write[i] > write_latency) && (ck_cntr - ck_bank_write[i] <= write_latency + burst_length/2)) begin
1454                    tm_bank_write_end[i] <= $time;
1455                    tm_write_end <= $time;
1456                end
1457            end
1458
1459            // clk pin is disabled during self refresh
1460            if (!in_self_refresh) begin
1461                tjit_cc_time = $time - tm_ck_pos - tck_i;
1462                tck_i = $time - tm_ck_pos;
1463                tck_avg = tck_avg - tck_sample[ck_cntr%TDLLK]/$itor(TDLLK);
1464                tck_avg = tck_avg + tck_i/$itor(TDLLK);
1465                tck_sample[ck_cntr%TDLLK] = tck_i;
1466                tjit_per_rtime = tck_i - tck_avg;
1467
1468                if (dll_locked) begin
1469                    // check accumulated error
1470                    terr_nper_rtime = 0;
1471                    for (i=0; i<50; i=i+1) begin
1472                        terr_nper_rtime = terr_nper_rtime + tck_sample[i] - tck_avg;
1473                        terr_nper_rtime = abs_value(terr_nper_rtime);
1474                        case (i)
1475                                  0 :;
1476                                  1 : if (terr_nper_rtime - TERR_2PER >= 1.0) $display ("%m: at time %t ERROR: tERR(2per) violation by %f ps.", $time, terr_nper_rtime - TERR_2PER);
1477                                  2 : if (terr_nper_rtime - TERR_3PER >= 1.0) $display ("%m: at time %t ERROR: tERR(3per) violation by %f ps.", $time, terr_nper_rtime - TERR_3PER);
1478                                  3 : if (terr_nper_rtime - TERR_4PER >= 1.0) $display ("%m: at time %t ERROR: tERR(4per) violation by %f ps.", $time, terr_nper_rtime - TERR_4PER);
1479                                  4 : if (terr_nper_rtime - TERR_5PER >= 1.0) $display ("%m: at time %t ERROR: tERR(5per) violation by %f ps.", $time, terr_nper_rtime - TERR_5PER);
1480                          5,6,7,8,9 : if (terr_nper_rtime - TERR_N1PER >= 1.0) $display ("%m: at time %t ERROR: tERR(n1per) violation by %f ps.", $time, terr_nper_rtime - TERR_N1PER);
1481                            default : if (terr_nper_rtime - TERR_N2PER >= 1.0) $display ("%m: at time %t ERROR: tERR(n2per) violation by %f ps.", $time, terr_nper_rtime - TERR_N2PER);
1482                        endcase
1483                    end
1484
1485                    // check tCK min/max/jitter
1486                    if (abs_value(tjit_per_rtime) - TJIT_PER >= 1.0)
1487                        $display ("%m: at time %t ERROR: tJIT(per) violation by %f ps.", $time, abs_value(tjit_per_rtime) - TJIT_PER);
1488                    if (abs_value(tjit_cc_time) - TJIT_CC >= 1.0)
1489                        $display ("%m: at time %t ERROR: tJIT(cc) violation by %f ps.", $time, abs_value(tjit_cc_time) - TJIT_CC);
1490                    if (TCK_MIN - tck_avg >= 1.0)
1491                        $display ("%m: at time %t ERROR: tCK(avg) minimum violation by %f ps.", $time, TCK_MIN - tck_avg);
1492                    if (tck_avg - TCK_MAX >= 1.0)
1493                        $display ("%m: at time %t ERROR: tCK(avg) maximum violation by %f ps.", $time, tck_avg - TCK_MAX);
1494                    if (tm_ck_pos + TCK_MIN - TJIT_PER > $time)
1495                        $display ("%m: at time %t ERROR: tCK(abs) minimum violation by %t", $time, tm_ck_pos + TCK_MIN - TJIT_PER - $time);
1496                    if (tm_ck_pos + TCK_MAX + TJIT_PER < $time)
1497                        $display ("%m: at time %t ERROR: tCK(abs) maximum violation by %t", $time, $time - tm_ck_pos - TCK_MAX - TJIT_PER);
1498
1499                    // check tCL
1500                    if (tm_ck_neg + TCL_MIN*tck_avg - TJIT_DUTY > $time)
1501                        $display ("%m: at time %t ERROR: tCL(abs) minimum violation on CLK by %t", $time, tm_ck_neg + TCL_MIN*tck_avg - TJIT_DUTY - $time);
1502                    if (tm_ck_neg + TCL_MAX*tck_avg + TJIT_DUTY < $time)
1503                        $display ("%m: at time %t ERROR: tCL(abs) maximum violation on CLK by %t", $time, $time - tm_ck_neg - TCL_MAX*tck_avg - TJIT_DUTY);
1504                    if (tcl_avg < TCL_MIN*tck_avg)
1505                        $display ("%m: at time %t ERROR: tCL(avg) minimum violation on CLK by %t", $time, TCL_MIN*tck_avg - tcl_avg);
1506                    if (tcl_avg > TCL_MAX*tck_avg)
1507                        $display ("%m: at time %t ERROR: tCL(avg) maximum violation on CLK by %t", $time, tcl_avg - TCL_MAX*tck_avg);
1508                end
1509
1510                // calculate the tch avg jitter
1511                tch_avg = tch_avg - tch_sample[ck_cntr%TDLLK]/$itor(TDLLK);
1512                tch_avg = tch_avg + tch_i/$itor(TDLLK);
1513                tch_sample[ck_cntr%TDLLK] = tch_i;
1514
1515                // update timers/counters
1516                tcl_i <= $time - tm_ck_neg;
1517            end
1518
1519            prev_odt <= odt_in;
1520            // update timers/counters
1521            ck_cntr <= ck_cntr + 1;
1522            tm_ck_pos <= $time;
1523        end else begin
1524            // clk pin is disabled during self refresh
1525            if (!in_self_refresh) begin
1526                if (dll_locked) begin
1527                    if (tm_ck_pos + TCH_MIN*tck_avg - TJIT_DUTY > $time)
1528                        $display ("%m: at time %t ERROR: tCH(abs) minimum violation on CLK by %t", $time, tm_ck_pos + TCH_MIN*tck_avg - TJIT_DUTY + $time);
1529                    if (tm_ck_pos + TCH_MAX*tck_avg + TJIT_DUTY < $time)
1530                        $display ("%m: at time %t ERROR: tCH(abs) maximum violation on CLK by %t", $time, $time - tm_ck_pos - TCH_MAX*tck_avg - TJIT_DUTY);
1531                    if (tch_avg < TCH_MIN*tck_avg)
1532                        $display ("%m: at time %t ERROR: tCH(avg) minimum violation on CLK by %t", $time, TCH_MIN*tck_avg - tch_avg);
1533                    if (tch_avg > TCH_MAX*tck_avg)
1534                        $display ("%m: at time %t ERROR: tCH(avg) maximum violation on CLK by %t", $time, tch_avg - TCH_MAX*tck_avg);
1535                end
1536
1537                // calculate the tcl avg jitter
1538                tcl_avg = tcl_avg - tcl_sample[ck_cntr%TDLLK]/$itor(TDLLK);
1539                tcl_avg = tcl_avg + tcl_i/$itor(TDLLK);
1540                tcl_sample[ck_cntr%TDLLK] = tcl_i;
1541
1542                // update timers/counters
1543                tch_i <= $time - tm_ck_pos;
1544            end
1545            tm_ck_neg <= $time;
1546        end
1547
1548        // on die termination
1549        if (odt_en) begin
1550            // clk pin is disabled during self refresh
1551            if (!in_self_refresh && diff_ck) begin
1552                if ($time - tm_odt < TIS) begin
1553                    $display ("%m: at time %t ERROR: tIS violation on ODT by %t", $time, tm_odt + TIS - $time);
1554                end
1555                if (prev_odt ^ odt_in) begin
1556                    if (!dll_locked)
1557                        $display ("%m: at time %t WARNING: tDLLK violation during ODT transition.", $time);
1558                    if (odt_in && ($time - tm_odt_en < TMOD))
1559                        $display ("%m: at time %t ERROR: tMOD violation during ODT transition", $time);
1560                    if ($time - tm_self_refresh < TXSNR)
1561                        $display ("%m: at time %t ERROR: tXSNR violation during ODT transition", $time);
1562                    if (in_self_refresh)
1563                        $display ("%m: at time %t ERROR: Illegal ODT transition during Self Refresh.", $time);
1564
1565                    // async ODT mode applies:
1566                    // 1.) during active power down with slow exit
1567                    // 2.) during precharge power down
1568                    // 3.) if tANPD has not been satisfied
1569                    // 4.) until tAXPD has been satisfied
1570                    if ((in_power_down && (low_power || (active_bank == 0))) || (ck_cntr - ck_slow_exit_pd < TAXPD)) begin
1571                        if (ck_cntr - ck_slow_exit_pd < TAXPD)
1572                            $display ("%m: at time %t WARNING: tAXPD violation during ODT transition. Synchronous or asynchronous change in termination resistance is possible.", $time);
1573                        if (odt_in) begin
1574                            if (DEBUG) $display ("%m: at time %t INFO: Async On Die Termination = %d", $time + TAONPD, 1'b1);
1575                            odt_state <= #(TAONPD) 1'b1;
1576                        end else begin
1577                            if (DEBUG) $display ("%m: at time %t INFO: Async On Die Termination = %d", $time + TAOFPD, 1'b0);
1578                            odt_state <= #(TAOFPD) 1'b0;
1579                        end
1580                    // sync ODT mode applies:
1581                    // 1.) during normal operation
1582                    // 2.) during active power down with fast exit
1583                    end else begin
1584                        if (odt_in) begin
1585                            i = TAOND*2;
1586                            odt_pipeline[i] = 1'b1;
1587                        end else begin
1588                            i = TAOFD*2;
1589                            odt_pipeline[i] = 1'b1;
1590                        end
1591                    end
1592                    ck_odt <= ck_cntr;
1593                end
1594            end
1595            if (odt_pipeline[0]) begin
1596                odt_state = ~odt_state;
1597                if (DEBUG) $display ("%m: at time %t INFO: Sync On Die Termination = %d", $time, odt_state);
1598            end
1599        end
1600
1601        // shift pipelines
1602        if (|wr_pipeline || |rd_pipeline || |al_pipeline) begin
1603            al_pipeline = al_pipeline>>1;
1604            wr_pipeline = wr_pipeline>>1;
1605            rd_pipeline = rd_pipeline>>1;
1606            for (i=0; i<`MAX_PIPE; i=i+1) begin
1607                ba_pipeline[i] = ba_pipeline[i+1];
1608                row_pipeline[i] = row_pipeline[i+1];
1609                col_pipeline[i] = col_pipeline[i+1];
1610            end
1611        end
1612        if (|odt_pipeline) begin
1613            odt_pipeline = odt_pipeline>>1;
1614        end
1615    end
1616
1617    // receiver(s)
1618    task dqs_even_receiver;
1619        input [4:0] i;
1620        reg [71:0] bit_mask;
1621        begin
1622            bit_mask = {`DQ_PER_DQS{1'b1}}<<(i*`DQ_PER_DQS);
1623            if (dqs_even[i]) begin
1624                if (rdqs_en) begin // rdqs disables dm
1625                    dm_in_pos[i] = 1'b0;
1626                end else begin
1627                    dm_in_pos[i] = dm_in[i];
1628                end
1629                dq_in_pos = (dq_in & bit_mask) | (dq_in_pos & ~bit_mask);
1630            end
1631        end
1632    endtask
1633
1634    always @(posedge dqs_even[ 0]) dqs_even_receiver( 0);
1635    always @(posedge dqs_even[ 1]) dqs_even_receiver( 1);
1636    always @(posedge dqs_even[ 2]) dqs_even_receiver( 2);
1637    always @(posedge dqs_even[ 3]) dqs_even_receiver( 3);
1638    always @(posedge dqs_even[ 4]) dqs_even_receiver( 4);
1639    always @(posedge dqs_even[ 5]) dqs_even_receiver( 5);
1640    always @(posedge dqs_even[ 6]) dqs_even_receiver( 6);
1641    always @(posedge dqs_even[ 7]) dqs_even_receiver( 7);
1642    always @(posedge dqs_even[ 8]) dqs_even_receiver( 8);
1643    always @(posedge dqs_even[ 9]) dqs_even_receiver( 9);
1644    always @(posedge dqs_even[10]) dqs_even_receiver(10);
1645    always @(posedge dqs_even[11]) dqs_even_receiver(11);
1646    always @(posedge dqs_even[12]) dqs_even_receiver(12);
1647    always @(posedge dqs_even[13]) dqs_even_receiver(13);
1648    always @(posedge dqs_even[14]) dqs_even_receiver(14);
1649    always @(posedge dqs_even[15]) dqs_even_receiver(15);
1650    always @(posedge dqs_even[16]) dqs_even_receiver(16);
1651    always @(posedge dqs_even[17]) dqs_even_receiver(17);
1652
1653    task dqs_odd_receiver;
1654        input [4:0] i;
1655        reg [71:0] bit_mask;
1656        begin
1657            bit_mask = {`DQ_PER_DQS{1'b1}}<<(i*`DQ_PER_DQS);
1658            if (dqs_odd[i]) begin
1659                if (rdqs_en) begin // rdqs disables dm
1660                    dm_in_neg[i] = 1'b0;
1661                end else begin
1662                    dm_in_neg[i] = dm_in[i];
1663                end
1664                dq_in_neg = (dq_in & bit_mask) | (dq_in_neg & ~bit_mask);
1665            end
1666        end
1667    endtask
1668
1669    always @(posedge dqs_odd[ 0]) dqs_odd_receiver( 0);
1670    always @(posedge dqs_odd[ 1]) dqs_odd_receiver( 1);
1671    always @(posedge dqs_odd[ 2]) dqs_odd_receiver( 2);
1672    always @(posedge dqs_odd[ 3]) dqs_odd_receiver( 3);
1673    always @(posedge dqs_odd[ 4]) dqs_odd_receiver( 4);
1674    always @(posedge dqs_odd[ 5]) dqs_odd_receiver( 5);
1675    always @(posedge dqs_odd[ 6]) dqs_odd_receiver( 6);
1676    always @(posedge dqs_odd[ 7]) dqs_odd_receiver( 7);
1677    always @(posedge dqs_odd[ 8]) dqs_odd_receiver( 8);
1678    always @(posedge dqs_odd[ 9]) dqs_odd_receiver( 9);
1679    always @(posedge dqs_odd[10]) dqs_odd_receiver(10);
1680    always @(posedge dqs_odd[11]) dqs_odd_receiver(11);
1681    always @(posedge dqs_odd[12]) dqs_odd_receiver(12);
1682    always @(posedge dqs_odd[13]) dqs_odd_receiver(13);
1683    always @(posedge dqs_odd[14]) dqs_odd_receiver(14);
1684    always @(posedge dqs_odd[15]) dqs_odd_receiver(15);
1685    always @(posedge dqs_odd[16]) dqs_odd_receiver(16);
1686    always @(posedge dqs_odd[17]) dqs_odd_receiver(17);
1687
1688    // Processes to check hold and pulse width of control signals
1689    always @(cke_in) begin
1690        if ($time > TIH) begin
1691            if ($time - tm_ck_pos < TIH)
1692                $display ("%m: at time %t ERROR: tIH violation on CKE by %t", $time, tm_ck_pos + TIH - $time);
1693        end
1694        if (dll_locked && ($time - tm_cke < $rtoi(TIPW*tck_avg)))
1695            $display ("%m: at time %t ERROR: tIPW violation on CKE by %t", $time, tm_cke + TIPW*tck_avg - $time);
1696        tm_cke = $time;
1697    end
1698    always @(odt_in) begin
1699        if (odt_en && !in_self_refresh) begin
1700            if ($time - tm_ck_pos < TIH)
1701                $display ("%m: at time %t ERROR: tIH violation on ODT by %t", $time, tm_ck_pos + TIH - $time);
1702            if (dll_locked && ($time - tm_odt < $rtoi(TIPW*tck_avg)))
1703                $display ("%m: at time %t ERROR: tIPW violation on ODT by %t", $time, tm_odt + TIPW*tck_avg - $time);
1704        end
1705        tm_odt = $time;
1706    end
1707
1708    task cmd_addr_timing_check;
1709    input i;
1710    reg [4:0] i;
1711    begin
1712        if (prev_cke) begin
1713            if ((i == 0) && ($time - tm_ck_pos < TIH)) // Always check tIH for CS#
1714                $display ("%m: at time %t ERROR: tIH violation on %s by %t", $time, cmd_addr_string[i], tm_ck_pos + TIH - $time);
1715            if ((i > 0) && (cs_n_in == 1'b0) && ($time - tm_ck_pos < TIH)) // Only check tIH for cmd_addr if CS# low
1716                $display ("%m: at time %t ERROR: tIH violation on %s by %t", $time, cmd_addr_string[i], tm_ck_pos + TIH - $time);
1717            if (dll_locked && ($time - tm_cmd_addr[i] < $rtoi(TIPW*tck_avg)))
1718                $display ("%m: at time %t ERROR: tIPW violation on %s by %t", $time, cmd_addr_string[i], tm_cmd_addr[i] + TIPW*tck_avg - $time);
1719        end
1720        tm_cmd_addr[i] = $time;
1721    end
1722    endtask
1723
1724    always @(cs_n_in ) cmd_addr_timing_check( 0);
1725    always @(ras_n_in ) cmd_addr_timing_check( 1);
1726    always @(cas_n_in ) cmd_addr_timing_check( 2);
1727    always @(we_n_in ) cmd_addr_timing_check( 3);
1728    always @(ba_in [ 0]) cmd_addr_timing_check( 4);
1729    always @(ba_in [ 1]) cmd_addr_timing_check( 5);
1730    always @(ba_in [ 2]) cmd_addr_timing_check( 6);
1731    always @(addr_in[ 0]) cmd_addr_timing_check( 7);
1732    always @(addr_in[ 1]) cmd_addr_timing_check( 8);
1733    always @(addr_in[ 2]) cmd_addr_timing_check( 9);
1734    always @(addr_in[ 3]) cmd_addr_timing_check(10);
1735    always @(addr_in[ 4]) cmd_addr_timing_check(11);
1736    always @(addr_in[ 5]) cmd_addr_timing_check(12);
1737    always @(addr_in[ 6]) cmd_addr_timing_check(13);
1738    always @(addr_in[ 7]) cmd_addr_timing_check(14);
1739    always @(addr_in[ 8]) cmd_addr_timing_check(15);
1740    always @(addr_in[ 9]) cmd_addr_timing_check(16);
1741    always @(addr_in[10]) cmd_addr_timing_check(17);
1742    always @(addr_in[11]) cmd_addr_timing_check(18);
1743    always @(addr_in[12]) cmd_addr_timing_check(19);
1744    always @(addr_in[13]) cmd_addr_timing_check(20);
1745    always @(addr_in[14]) cmd_addr_timing_check(21);
1746    always @(addr_in[15]) cmd_addr_timing_check(22);
1747
1748    // Processes to check setup and hold of data signals
1749    task dm_timing_check;
1750    input i;
1751    reg [4:0] i;
1752    begin
1753        if (dqs_in_valid) begin
1754            if ($time - tm_dqs[i] < TDH)
1755                $display ("%m: at time %t ERROR: tDH violation on DM bit %d by %t", $time, i, tm_dqs[i] + TDH - $time);
1756            if (check_dm_tdipw[i]) begin
1757                if (dll_locked && ($time - tm_dm[i] < $rtoi(TDIPW*tck_avg)))
1758                    $display ("%m: at time %t ERROR: tDIPW violation on DM bit %d by %t", $time, i, tm_dm[i] + TDIPW*tck_avg - $time);
1759            end
1760        end
1761        check_dm_tdipw[i] <= 1'b0;
1762        tm_dm[i] = $time;
1763    end
1764    endtask
1765
1766    always @(dm_in[ 0]) dm_timing_check( 0);
1767    always @(dm_in[ 1]) dm_timing_check( 1);
1768    always @(dm_in[ 2]) dm_timing_check( 2);
1769    always @(dm_in[ 3]) dm_timing_check( 3);
1770    always @(dm_in[ 4]) dm_timing_check( 4);
1771    always @(dm_in[ 5]) dm_timing_check( 5);
1772    always @(dm_in[ 6]) dm_timing_check( 6);
1773    always @(dm_in[ 7]) dm_timing_check( 7);
1774    always @(dm_in[ 8]) dm_timing_check( 8);
1775    always @(dm_in[ 9]) dm_timing_check( 9);
1776    always @(dm_in[10]) dm_timing_check(10);
1777    always @(dm_in[11]) dm_timing_check(11);
1778    always @(dm_in[12]) dm_timing_check(12);
1779    always @(dm_in[13]) dm_timing_check(13);
1780    always @(dm_in[14]) dm_timing_check(14);
1781    always @(dm_in[15]) dm_timing_check(15);
1782    always @(dm_in[16]) dm_timing_check(16);
1783    always @(dm_in[17]) dm_timing_check(17);
1784
1785    task dq_timing_check;
1786    input i;
1787    reg [6:0] i;
1788    begin
1789        if (dqs_in_valid) begin
1790            if ($time - tm_dqs[i/`DQ_PER_DQS] < TDH)
1791                $display ("%m: at time %t ERROR: tDH violation on DQ bit %d by %t", $time, i, tm_dqs[i/`DQ_PER_DQS] + TDH - $time);
1792            if (check_dq_tdipw[i]) begin
1793                if (dll_locked && ($time - tm_dq[i] < $rtoi(TDIPW*tck_avg)))
1794                    $display ("%m: at time %t ERROR: tDIPW violation on DQ bit %d by %t", $time, i, tm_dq[i] + TDIPW*tck_avg - $time);
1795            end
1796        end
1797        check_dq_tdipw[i] <= 1'b0;
1798        tm_dq[i] = $time;
1799    end
1800    endtask
1801
1802    always @(dq_in[ 0]) dq_timing_check( 0);
1803    always @(dq_in[ 1]) dq_timing_check( 1);
1804    always @(dq_in[ 2]) dq_timing_check( 2);
1805    always @(dq_in[ 3]) dq_timing_check( 3);
1806    always @(dq_in[ 4]) dq_timing_check( 4);
1807    always @(dq_in[ 5]) dq_timing_check( 5);
1808    always @(dq_in[ 6]) dq_timing_check( 6);
1809    always @(dq_in[ 7]) dq_timing_check( 7);
1810    always @(dq_in[ 8]) dq_timing_check( 8);
1811    always @(dq_in[ 9]) dq_timing_check( 9);
1812    always @(dq_in[10]) dq_timing_check(10);
1813    always @(dq_in[11]) dq_timing_check(11);
1814    always @(dq_in[12]) dq_timing_check(12);
1815    always @(dq_in[13]) dq_timing_check(13);
1816    always @(dq_in[14]) dq_timing_check(14);
1817    always @(dq_in[15]) dq_timing_check(15);
1818    always @(dq_in[16]) dq_timing_check(16);
1819    always @(dq_in[17]) dq_timing_check(17);
1820    always @(dq_in[18]) dq_timing_check(18);
1821    always @(dq_in[19]) dq_timing_check(19);
1822    always @(dq_in[20]) dq_timing_check(20);
1823    always @(dq_in[21]) dq_timing_check(21);
1824    always @(dq_in[22]) dq_timing_check(22);
1825    always @(dq_in[23]) dq_timing_check(23);
1826    always @(dq_in[24]) dq_timing_check(24);
1827    always @(dq_in[25]) dq_timing_check(25);
1828    always @(dq_in[26]) dq_timing_check(26);
1829    always @(dq_in[27]) dq_timing_check(27);
1830    always @(dq_in[28]) dq_timing_check(28);
1831    always @(dq_in[29]) dq_timing_check(29);
1832    always @(dq_in[30]) dq_timing_check(30);
1833    always @(dq_in[31]) dq_timing_check(31);
1834    always @(dq_in[32]) dq_timing_check(32);
1835    always @(dq_in[33]) dq_timing_check(33);
1836    always @(dq_in[34]) dq_timing_check(34);
1837    always @(dq_in[35]) dq_timing_check(35);
1838    always @(dq_in[36]) dq_timing_check(36);
1839    always @(dq_in[37]) dq_timing_check(37);
1840    always @(dq_in[38]) dq_timing_check(38);
1841    always @(dq_in[39]) dq_timing_check(39);
1842    always @(dq_in[40]) dq_timing_check(40);
1843    always @(dq_in[41]) dq_timing_check(41);
1844    always @(dq_in[42]) dq_timing_check(42);
1845    always @(dq_in[43]) dq_timing_check(43);
1846    always @(dq_in[44]) dq_timing_check(44);
1847    always @(dq_in[45]) dq_timing_check(45);
1848    always @(dq_in[46]) dq_timing_check(46);
1849    always @(dq_in[47]) dq_timing_check(47);
1850    always @(dq_in[48]) dq_timing_check(48);
1851    always @(dq_in[49]) dq_timing_check(49);
1852    always @(dq_in[50]) dq_timing_check(50);
1853    always @(dq_in[51]) dq_timing_check(51);
1854    always @(dq_in[52]) dq_timing_check(52);
1855    always @(dq_in[53]) dq_timing_check(53);
1856    always @(dq_in[54]) dq_timing_check(54);
1857    always @(dq_in[55]) dq_timing_check(55);
1858    always @(dq_in[56]) dq_timing_check(56);
1859    always @(dq_in[57]) dq_timing_check(57);
1860    always @(dq_in[58]) dq_timing_check(58);
1861    always @(dq_in[59]) dq_timing_check(59);
1862    always @(dq_in[60]) dq_timing_check(60);
1863    always @(dq_in[61]) dq_timing_check(61);
1864    always @(dq_in[62]) dq_timing_check(62);
1865    always @(dq_in[63]) dq_timing_check(63);
1866    always @(dq_in[64]) dq_timing_check(64);
1867    always @(dq_in[65]) dq_timing_check(65);
1868    always @(dq_in[66]) dq_timing_check(66);
1869    always @(dq_in[67]) dq_timing_check(67);
1870    always @(dq_in[68]) dq_timing_check(68);
1871    always @(dq_in[69]) dq_timing_check(69);
1872    always @(dq_in[70]) dq_timing_check(70);
1873    always @(dq_in[71]) dq_timing_check(71);
1874
1875    task dqs_pos_timing_check;
1876    input i;
1877    reg [5:0] i;
1878    reg [3:0] j;
1879    begin
1880        if (dqs_in_valid && ((wdqs_pos_cntr[i] < burst_length/2) || b2b_write) && (dqs_n_en || i<18)) begin
1881            if (dqs_in[i] ^ prev_dqs_in[i]) begin
1882                if (dll_locked) begin
1883                    if (check_write_preamble[i]) begin
1884                        if ($time - tm_dqs_neg[i] < $rtoi(TWPRE*tck_avg))
1885                            $display ("%m: at time %t ERROR: tWPRE violation on &s bit %d", $time, dqs_string[i/18], i%18);
1886                    end else if (check_write_postamble[i]) begin
1887                        if ($time - tm_dqs_neg[i] < $rtoi(TWPST*tck_avg))
1888                            $display ("%m: at time %t ERROR: tWPST violation on %s bit %d", $time, dqs_string[i/18], i%18);
1889                    end else begin
1890                        if ($time - tm_dqs_neg[i] < $rtoi(TDQSL*tck_avg))
1891                            $display ("%m: at time %t ERROR: tDQSL violation on %s bit %d", $time, dqs_string[i/18], i%18);
1892                    end
1893                end
1894                if ($time - tm_dm[i%18] < TDS)
1895                    $display ("%m: at time %t ERROR: tDS violation on DM bit %d by %t", $time, i, tm_dm[i%18] + TDS - $time);
1896                if (!dq_out_en) begin
1897                    for (j=0; j<`DQ_PER_DQS; j=j+1) begin
1898                        if ($time - tm_dq[i*`DQ_PER_DQS+j] < TDS)
1899                            $display ("%m: at time %t ERROR: tDS violation on DQ bit %d by %t", $time, i*`DQ_PER_DQS+j, tm_dq[i*`DQ_PER_DQS+j] + TDS - $time);
1900                        check_dq_tdipw[i*`DQ_PER_DQS+j] <= 1'b1;
1901                    end
1902                end
1903                if ((wdqs_pos_cntr[i] < burst_length/2) && !b2b_write) begin
1904                    wdqs_pos_cntr[i] <= wdqs_pos_cntr[i] + 1;
1905                end else begin
1906                    wdqs_pos_cntr[i] <= 1;
1907                end
1908                check_dm_tdipw[i%18] <= 1'b1;
1909                check_write_preamble[i] <= 1'b0;
1910                check_write_postamble[i] <= 1'b0;
1911                check_write_dqs_low[i] <= 1'b0;
1912                tm_dqs[i%18] <= $time;
1913            end else begin
1914                $display ("%m: at time %t ERROR: Invalid latching edge on %s bit %d", $time, dqs_string[i/18], i%18);
1915            end
1916        end
1917        tm_dqss_pos[i] <= $time;
1918        tm_dqs_pos[i] = $time;
1919        prev_dqs_in[i] <= dqs_in[i];
1920    end
1921    endtask
1922
1923    always @(posedge dqs_in[ 0]) dqs_pos_timing_check( 0);
1924    always @(posedge dqs_in[ 1]) dqs_pos_timing_check( 1);
1925    always @(posedge dqs_in[ 2]) dqs_pos_timing_check( 2);
1926    always @(posedge dqs_in[ 3]) dqs_pos_timing_check( 3);
1927    always @(posedge dqs_in[ 4]) dqs_pos_timing_check( 4);
1928    always @(posedge dqs_in[ 5]) dqs_pos_timing_check( 5);
1929    always @(posedge dqs_in[ 6]) dqs_pos_timing_check( 6);
1930    always @(posedge dqs_in[ 7]) dqs_pos_timing_check( 7);
1931    always @(posedge dqs_in[ 8]) dqs_pos_timing_check( 8);
1932    always @(posedge dqs_in[ 9]) dqs_pos_timing_check( 9);
1933    always @(posedge dqs_in[10]) dqs_pos_timing_check(10);
1934    always @(posedge dqs_in[11]) dqs_pos_timing_check(11);
1935    always @(posedge dqs_in[12]) dqs_pos_timing_check(12);
1936    always @(posedge dqs_in[13]) dqs_pos_timing_check(13);
1937    always @(posedge dqs_in[14]) dqs_pos_timing_check(14);
1938    always @(posedge dqs_in[15]) dqs_pos_timing_check(15);
1939    always @(posedge dqs_in[16]) dqs_pos_timing_check(16);
1940    always @(posedge dqs_in[17]) dqs_pos_timing_check(17);
1941    always @(negedge dqs_in[18]) dqs_pos_timing_check(18);
1942    always @(negedge dqs_in[19]) dqs_pos_timing_check(19);
1943    always @(negedge dqs_in[20]) dqs_pos_timing_check(20);
1944    always @(negedge dqs_in[21]) dqs_pos_timing_check(21);
1945    always @(negedge dqs_in[22]) dqs_pos_timing_check(22);
1946    always @(negedge dqs_in[23]) dqs_pos_timing_check(23);
1947    always @(negedge dqs_in[24]) dqs_pos_timing_check(24);
1948    always @(negedge dqs_in[25]) dqs_pos_timing_check(25);
1949    always @(negedge dqs_in[26]) dqs_pos_timing_check(26);
1950    always @(negedge dqs_in[27]) dqs_pos_timing_check(27);
1951    always @(negedge dqs_in[28]) dqs_pos_timing_check(28);
1952    always @(negedge dqs_in[29]) dqs_pos_timing_check(29);
1953    always @(negedge dqs_in[30]) dqs_pos_timing_check(30);
1954    always @(negedge dqs_in[31]) dqs_pos_timing_check(31);
1955    always @(negedge dqs_in[32]) dqs_neg_timing_check(32);
1956    always @(negedge dqs_in[33]) dqs_neg_timing_check(33);
1957    always @(negedge dqs_in[34]) dqs_neg_timing_check(34);
1958    always @(negedge dqs_in[35]) dqs_neg_timing_check(35);
1959
1960    task dqs_neg_timing_check;
1961    input i;
1962    reg [5:0] i;
1963    reg [3:0] j;
1964    begin
1965        if (dqs_in_valid && (wdqs_pos_cntr[i] > 0) && check_write_dqs_high[i] && (dqs_n_en || i < 18)) begin
1966            if (dqs_in[i] ^ prev_dqs_in[i]) begin
1967                if (dll_locked) begin
1968                    if ($time - tm_dqs_pos[i] < $rtoi(TDQSH*tck_avg))
1969                        $display ("%m: at time %t ERROR: tDQSH violation on %s bit %d", $time, dqs_string[i/18], i%18);
1970                    if ($time - tm_ck_pos < $rtoi(TDSH*tck_avg))
1971                        $display ("%m: at time %t ERROR: tDSH violation on %s bit %d", $time, dqs_string[i/18], i%18);
1972                end
1973                if ($time - tm_dm[i%18] < TDS)
1974                    $display ("%m: at time %t ERROR: tDS violation on DM bit %d by %t", $time, i, tm_dm[i%18] + TDS - $time);
1975                if (!dq_out_en) begin
1976                    for (j=0; j<`DQ_PER_DQS; j=j+1) begin
1977                        if ($time - tm_dq[i*`DQ_PER_DQS+j] < TDS)
1978                            $display ("%m: at time %t ERROR: tDS violation on DQ bit %d by %t", $time, i*`DQ_PER_DQS+j, tm_dq[i*`DQ_PER_DQS+j] + TDS - $time);
1979                        check_dq_tdipw[i*`DQ_PER_DQS+j] <= 1'b1;
1980                    end
1981                end
1982                check_dm_tdipw[i%18] <= 1'b1;
1983                check_write_dqs_high[i] <= 1'b0;
1984                tm_dqs[i%18] <= $time;
1985            end else begin
1986                $display ("%m: at time %t ERROR: Invalid latching edge on %s bit %d", $time, dqs_string[i/18], i%18);
1987            end
1988        end
1989        tm_dqs_neg[i] = $time;
1990        prev_dqs_in[i] <= dqs_in[i];
1991    end
1992    endtask
1993
1994    always @(negedge dqs_in[ 0]) dqs_neg_timing_check( 0);
1995    always @(negedge dqs_in[ 1]) dqs_neg_timing_check( 1);
1996    always @(negedge dqs_in[ 2]) dqs_neg_timing_check( 2);
1997    always @(negedge dqs_in[ 3]) dqs_neg_timing_check( 3);
1998    always @(negedge dqs_in[ 4]) dqs_neg_timing_check( 4);
1999    always @(negedge dqs_in[ 5]) dqs_neg_timing_check( 5);
2000    always @(negedge dqs_in[ 6]) dqs_neg_timing_check( 6);
2001    always @(negedge dqs_in[ 7]) dqs_neg_timing_check( 7);
2002    always @(negedge dqs_in[ 8]) dqs_neg_timing_check( 8);
2003    always @(negedge dqs_in[ 9]) dqs_neg_timing_check( 9);
2004    always @(negedge dqs_in[10]) dqs_neg_timing_check(10);
2005    always @(negedge dqs_in[11]) dqs_neg_timing_check(11);
2006    always @(negedge dqs_in[12]) dqs_neg_timing_check(12);
2007    always @(negedge dqs_in[13]) dqs_neg_timing_check(13);
2008    always @(negedge dqs_in[14]) dqs_neg_timing_check(14);
2009    always @(negedge dqs_in[15]) dqs_neg_timing_check(15);
2010    always @(negedge dqs_in[16]) dqs_neg_timing_check(16);
2011    always @(negedge dqs_in[17]) dqs_neg_timing_check(17);
2012    always @(posedge dqs_in[18]) dqs_neg_timing_check(18);
2013    always @(posedge dqs_in[19]) dqs_neg_timing_check(19);
2014    always @(posedge dqs_in[20]) dqs_neg_timing_check(20);
2015    always @(posedge dqs_in[21]) dqs_neg_timing_check(21);
2016    always @(posedge dqs_in[22]) dqs_neg_timing_check(22);
2017    always @(posedge dqs_in[23]) dqs_neg_timing_check(23);
2018    always @(posedge dqs_in[24]) dqs_neg_timing_check(24);
2019    always @(posedge dqs_in[25]) dqs_neg_timing_check(25);
2020    always @(posedge dqs_in[26]) dqs_neg_timing_check(26);
2021    always @(posedge dqs_in[27]) dqs_neg_timing_check(27);
2022    always @(posedge dqs_in[28]) dqs_neg_timing_check(28);
2023    always @(posedge dqs_in[29]) dqs_neg_timing_check(29);
2024    always @(posedge dqs_in[30]) dqs_neg_timing_check(30);
2025    always @(posedge dqs_in[31]) dqs_neg_timing_check(31);
2026    always @(posedge dqs_in[32]) dqs_neg_timing_check(32);
2027    always @(posedge dqs_in[33]) dqs_neg_timing_check(33);
2028    always @(posedge dqs_in[34]) dqs_neg_timing_check(34);
2029    always @(posedge dqs_in[35]) dqs_neg_timing_check(35);
2030
2031endmodule
sim/verilog/micron_2048Mb_ddr2/ddr2_mcp.v
1/****************************************************************************************
2*
3* File Name: ddr2_mcp.v
4*
5* Dependencies: ddr2.v, ddr2_parameters.vh
6*
7* Description: Micron SDRAM DDR2 (Double Data Rate 2) multi-chip package model
8*
9* Disclaimer This software code and all associated documentation, comments or other
10* of Warranty: information (collectively "Software") is provided "AS IS" without
11* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
12* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
13* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
14* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
15* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
16* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
17* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
18* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
19* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
20* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
21* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
22* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
23* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
24* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
25* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
26* DAMAGES. Because some jurisdictions prohibit the exclusion or
27* limitation of liability for consequential or incidental damages, the
28* above limitation may not apply to you.
29*
30* Copyright 2003 Micron Technology, Inc. All rights reserved.
31*
32****************************************************************************************/
33 `timescale 1ps / 1ps
34
35module ddr2_mcp (
36    ck,
37    ck_n,
38    cke,
39    cs_n,
40    ras_n,
41    cas_n,
42    we_n,
43    dm_rdqs,
44    ba,
45    addr,
46    dq,
47    dqs,
48    dqs_n,
49    rdqs_n,
50    odt
51);
52
53    `include "ddr2_parameters.vh"
54
55    // Declare Ports
56    input ck;
57    input ck_n;
58    input [CS_BITS-1:0] cke;
59    input [CS_BITS-1:0] cs_n;
60    input ras_n;
61    input cas_n;
62    input we_n;
63    inout [DM_BITS-1:0] dm_rdqs;
64    input [BA_BITS-1:0] ba;
65    input [ADDR_BITS-1:0] addr;
66    inout [DQ_BITS-1:0] dq;
67    inout [DQS_BITS-1:0] dqs;
68    inout [DQS_BITS-1:0] dqs_n;
69    output [DQS_BITS-1:0] rdqs_n;
70    input [CS_BITS-1:0] odt;
71
72    wire [RANKS-1:0] cke_mcp = cke;
73    wire [RANKS-1:0] cs_n_mcp = cs_n;
74    wire [RANKS-1:0] odt_mcp = odt;
75
76    ddr2 rank [RANKS-1:0] (
77        ck,
78        ck_n,
79        cke_mcp,
80        cs_n_mcp,
81        ras_n,
82        cas_n,
83        we_n,
84        dm_rdqs,
85        ba,
86        addr,
87        dq,
88        dqs,
89        dqs_n,
90        rdqs_n,
91        odt_mcp
92    );
93
94endmodule
sim/verilog/micron_2048Mb_ddr2/ddr2_module.v
1/****************************************************************************************
2*
3* File Name: ddr2_module.v
4*
5* Dependencies: ddr2.v, ddr2.v, ddr2_parameters.vh
6*
7* Description: Micron SDRAM DDR2 (Double Data Rate 2) module model
8*
9* Limitation: - SPD (Serial Presence-Detect) is not modeled
10*
11* Disclaimer This software code and all associated documentation, comments or other
12* of Warranty: information (collectively "Software") is provided "AS IS" without
13* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
14* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
16* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
17* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
18* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
19* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
20* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
21* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
22* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
23* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
24* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
25* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
26* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
27* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
28* DAMAGES. Because some jurisdictions prohibit the exclusion or
29* limitation of liability for consequential or incidental damages, the
30* above limitation may not apply to you.
31*
32* Copyright 2003 Micron Technology, Inc. All rights reserved.
33*
34* Rev Author Date Changes
35* ---------------------------------------------------------------------------------------
36* 1.00 SPH 09/18/09 Fixed cb connection in ECC mode
37* Added invalid ECC mode error message in x16 configuration
38****************************************************************************************/
39 `timescale 1ps / 1ps
40
41module ddr2_module (
42`ifdef SODIMM
43`else
44    reset_n,
45    cb ,
46`endif
47    ck ,
48    ck_n ,
49    cke ,
50    s_n ,
51    ras_n ,
52    cas_n ,
53    we_n ,
54    ba ,
55    addr ,
56    odt ,
57    dqs ,
58    dqs_n ,
59    dq ,
60    scl ,
61    sa ,
62    sda
63);
64
65`include "ddr2_parameters.vh"
66
67    input [1:0] cke ;
68    input ras_n ;
69    input cas_n ;
70    input we_n ;
71    input [2:0] ba ;
72    input [15:0] addr ;
73    input [1:0] odt ;
74    inout [17:0] dqs ;
75    inout [17:0] dqs_n ;
76    inout [63:0] dq ;
77    input scl ; // no connect
78    inout sda ; // no connect
79
80`ifdef QUAD_RANK
81    initial if (DEBUG) $display("%m: Quad Rank");
82`else `ifdef DUAL_RANK
83    initial if (DEBUG) $display("%m: Dual Rank");
84`else
85    initial if (DEBUG) $display("%m: Single Rank");
86`endif `endif
87
88`ifdef ECC
89    initial if (DEBUG) $display("%m: ECC");
90    `ifdef SODIMM
91    initial begin
92        $display("%m ERROR: ECC is not available on SODIMM configurations");
93        if (STOP_ON_ERROR) $stop(0);
94    end
95    `endif
96    `ifdef x16
97    initial begin
98        $display("%m ERROR: ECC is not available on x16 configurations");
99        if (STOP_ON_ERROR) $stop(0);
100    end
101    `endif
102`else
103    initial if (DEBUG) $display("%m: non ECC");
104`endif
105
106`ifdef RDIMM
107    initial if (DEBUG) $display("%m: RDIMM");
108    input reset_n;
109    input ck ;
110    input ck_n ;
111    input [3:0] s_n ;
112    inout [7:0] cb ;
113    input [2:0] sa ; // no connect
114
115    wire [5:0] rck = {6{ck}};
116    wire [5:0] rck_n = {6{ck_n}};
117    reg [3:0] rs_n ;
118    reg rras_n ;
119    reg rcas_n ;
120    reg rwe_n ;
121    reg [2:0] rba ;
122    reg [15:0] raddr ;
123    reg [3:0] rcke ;
124    reg [3:0] rodt ;
125
126    always @(negedge reset_n or posedge ck) begin
127        if (!reset_n) begin
128            rs_n <= #(500) 0;
129            rras_n <= #(500) 0;
130            rcas_n <= #(500) 0;
131            rwe_n <= #(500) 0;
132            rba <= #(500) 0;
133            raddr <= #(500) 0;
134            rcke <= #(500) 0;
135            rodt <= #(500) 0;
136        end else begin
137            rs_n <= #(500) s_n ;
138            rras_n <= #(500) ras_n;
139            rcas_n <= #(500) cas_n;
140            rwe_n <= #(500) we_n ;
141            rba <= #(500) ba ;
142            raddr <= #(500) addr ;
143    `ifdef QUAD_RANK
144            rcke <= #(500) {{2{cke[1]}}, {2{cke[0]}}};
145            rodt <= #(500) {{2{odt[1]}}, {2{odt[0]}}};
146    `else
147            rcke <= #(500) {2'b00, cke};
148            rodt <= #(500) {2'b00, odt};
149    `endif
150
151        end
152    end
153`else
154    `ifdef SODIMM
155    initial if (DEBUG) $display("%m: SODIMM");
156    input [1:0] ck ;
157    input [1:0] ck_n ;
158    input [1:0] s_n ;
159    input [1:0] sa ; // no connect
160
161    wire [7:0] cb;
162    wire [5:0] rck = {{3{ck[1]}}, {3{ck[0]}}};
163    wire [5:0] rck_n = {{3{ck_n[1]}}, {3{ck_n[0]}}};
164    `else
165    initial if (DEBUG) $display("%m: UDIMM");
166    input reset_n;
167    input [2:0] ck ;
168    input [2:0] ck_n ;
169    input [1:0] s_n ;
170    inout [7:0] cb ;
171    input [2:0] sa ; // no connect
172
173    wire [5:0] rck = {2{ck}};
174    wire [5:0] rck_n = {2{ck_n}};
175    `endif
176
177    wire [2:0] rba = ba ;
178    wire [15:0] raddr = addr ;
179    wire rras_n = ras_n;
180    wire rcas_n = cas_n;
181    wire rwe_n = we_n ;
182    `ifdef QUAD_RANK
183    wire [3:0] rs_n = {{2{s_n[1]}}, {2{s_n[0]}}};
184    wire [3:0] rcke = {{2{cke[1]}}, {2{cke[0]}}};
185    wire [3:0] rodt = {{2{odt[1]}}, {2{odt[0]}}};
186    `else
187    wire [3:0] rs_n = {2'b00, s_n};
188    wire [3:0] rcke = {2'b00, cke};
189    wire [3:0] rodt = {2'b00, odt};
190    `endif
191`endif
192    wire [15:0] rcb = {8'b0, cb};
193    wire zero = 1'b0;
194    wire one = 1'b1;
195
196  //ddr2 (ck , ck_n , cke , cs_n , ras_n , cas_n , we_n , dm_rdqs , ba , addr , dq , dqs , dqs_n , rdqs_n , odt );
197`ifdef x4
198    initial if (DEBUG) $display("%m: Component Width = x4");
199    ddr2 U1R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0], , rodt[0]);
200    ddr2 U2R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1], , rodt[0]);
201    ddr2 U3R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2], , rodt[0]);
202    ddr2 U4R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3], , rodt[0]);
203    ddr2 U6R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4], , rodt[0]);
204    ddr2 U7R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5], , rodt[0]);
205    ddr2 U8R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6], , rodt[0]);
206    ddr2 U9R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7], , rodt[0]);
207    `ifdef ECC
208    ddr2 U5R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 3: 0], dqs[ 8] , dqs_n[ 8], , rodt[0]);
209    `endif
210    ddr2 U18R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9], , rodt[0]);
211    ddr2 U17R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10], , rodt[0]);
212    ddr2 U16R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11], , rodt[0]);
213    ddr2 U15R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12], , rodt[0]);
214    ddr2 U13R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13], , rodt[0]);
215    ddr2 U12R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14], , rodt[0]);
216    ddr2 U11R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15], , rodt[0]);
217    ddr2 U10R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16], , rodt[0]);
218    `ifdef ECC
219    ddr2 U14R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 7: 4], dqs[ 17] , dqs_n[ 17], , rodt[0]);
220    `endif
221    `ifdef DUAL_RANK
222    ddr2 U1R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0], , rodt[1]);
223    ddr2 U2R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1], , rodt[1]);
224    ddr2 U3R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2], , rodt[1]);
225    ddr2 U4R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3], , rodt[1]);
226    ddr2 U6R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4], , rodt[1]);
227    ddr2 U7R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5], , rodt[1]);
228    ddr2 U8R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6], , rodt[1]);
229    ddr2 U9R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7], , rodt[1]);
230        `ifdef ECC
231    ddr2 U5R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 3: 0], dqs[ 8] , dqs_n[ 8], , rodt[1]);
232        `endif
233    ddr2 U18R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9], , rodt[1]);
234    ddr2 U17R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10], , rodt[1]);
235    ddr2 U16R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11], , rodt[1]);
236    ddr2 U15R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12], , rodt[1]);
237    ddr2 U13R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13], , rodt[1]);
238    ddr2 U12R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14], , rodt[1]);
239    ddr2 U11R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15], , rodt[1]);
240    ddr2 U10R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16], , rodt[1]);
241        `ifdef ECC
242    ddr2 U14R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 7: 4], dqs[ 17] , dqs_n[ 17], , rodt[1]);
243        `endif
244    `endif
245    `ifdef QUAD_RANK
246    ddr2 U1R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0], , rodt[2]);
247    ddr2 U2R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1], , rodt[2]);
248    ddr2 U3R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2], , rodt[2]);
249    ddr2 U4R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3], , rodt[2]);
250    ddr2 U6R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4], , rodt[2]);
251    ddr2 U7R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5], , rodt[2]);
252    ddr2 U8R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6], , rodt[2]);
253    ddr2 U9R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7], , rodt[2]);
254        `ifdef ECC
255    ddr2 U5R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 3: 0], dqs[ 8] , dqs_n[ 8], , rodt[2]);
256        `endif
257    ddr2 U18R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9], , rodt[2]);
258    ddr2 U17R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10], , rodt[2]);
259    ddr2 U16R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11], , rodt[2]);
260    ddr2 U15R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12], , rodt[2]);
261    ddr2 U13R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13], , rodt[2]);
262    ddr2 U12R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14], , rodt[2]);
263    ddr2 U11R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15], , rodt[2]);
264    ddr2 U10R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16], , rodt[2]);
265        `ifdef ECC
266    ddr2 U14R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 7: 4], dqs[ 17] , dqs_n[ 17], , rodt[2]);
267        `endif
268    ddr2 U1R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0], , rodt[3]);
269    ddr2 U2R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1], , rodt[3]);
270    ddr2 U3R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2], , rodt[3]);
271    ddr2 U4R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3], , rodt[3]);
272    ddr2 U6R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4], , rodt[3]);
273    ddr2 U7R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5], , rodt[3]);
274    ddr2 U8R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6], , rodt[3]);
275    ddr2 U9R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7], , rodt[3]);
276        `ifdef ECC
277    ddr2 U5R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 3: 0], dqs[ 8] , dqs_n[ 8], , rodt[3]);
278        `endif
279    ddr2 U18R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9], , rodt[3]);
280    ddr2 U17R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10], , rodt[3]);
281    ddr2 U16R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11], , rodt[3]);
282    ddr2 U15R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12], , rodt[3]);
283    ddr2 U13R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13], , rodt[3]);
284    ddr2 U12R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14], , rodt[3]);
285    ddr2 U11R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15], , rodt[3]);
286    ddr2 U10R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16], , rodt[3]);
287        `ifdef ECC
288    ddr2 U14R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb [ 7: 4], dqs[ 17] , dqs_n[ 17], , rodt[3]);
289        `endif
290    `endif
291`else `ifdef x8
292    initial if (DEBUG) $display("%m: Component Width = x8");
293    ddr2 U1R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0], dqs_n[ 9], rodt[0]);
294    ddr2 U2R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1], dqs_n[10], rodt[0]);
295    ddr2 U3R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2], dqs_n[11], rodt[0]);
296    ddr2 U4R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3], dqs_n[12], rodt[0]);
297    ddr2 U6R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4], dqs_n[13], rodt[0]);
298    ddr2 U7R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5], dqs_n[14], rodt[0]);
299    ddr2 U8R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6], dqs_n[15], rodt[0]);
300    ddr2 U9R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7], dqs_n[16], rodt[0]);
301    `ifdef ECC
302    ddr2 U5R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb [ 7: 0], dqs[ 8] , dqs_n[ 8], dqs_n[17], rodt[0]);
303    `endif
304    `ifdef DUAL_RANK
305    ddr2 U1R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0], dqs_n[ 9], rodt[1]);
306    ddr2 U2R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1], dqs_n[10], rodt[1]);
307    ddr2 U3R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2], dqs_n[11], rodt[1]);
308    ddr2 U4R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3], dqs_n[12], rodt[1]);
309    ddr2 U6R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4], dqs_n[13], rodt[1]);
310    ddr2 U7R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5], dqs_n[14], rodt[1]);
311    ddr2 U8R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6], dqs_n[15], rodt[1]);
312    ddr2 U9R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7], dqs_n[16], rodt[1]);
313        `ifdef ECC
314    ddr2 U5R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb [ 7: 0], dqs[ 8] , dqs_n[ 8], dqs_n[17], rodt[1]);
315        `endif
316    `endif
317    `ifdef QUAD_RANK
318    ddr2 U1R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0], dqs_n[ 9], rodt[2]);
319    ddr2 U2R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1], dqs_n[10], rodt[2]);
320    ddr2 U3R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2], dqs_n[11], rodt[2]);
321    ddr2 U4R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3], dqs_n[12], rodt[2]);
322    ddr2 U6R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4], dqs_n[13], rodt[2]);
323    ddr2 U7R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5], dqs_n[14], rodt[2]);
324    ddr2 U8R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6], dqs_n[15], rodt[2]);
325    ddr2 U9R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7], dqs_n[16], rodt[2]);
326        `ifdef ECC
327    ddr2 U5R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb [ 7: 0], dqs[ 8] , dqs_n[ 8], dqs_n[17], rodt[2]);
328        `endif
329    ddr2 U1R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0], dqs_n[ 9], rodt[3]);
330    ddr2 U2R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1], dqs_n[10], rodt[3]);
331    ddr2 U3R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2], dqs_n[11], rodt[3]);
332    ddr2 U4R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3], dqs_n[12], rodt[3]);
333    ddr2 U6R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4], dqs_n[13], rodt[3]);
334    ddr2 U7R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5], dqs_n[14], rodt[3]);
335    ddr2 U8R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6], dqs_n[15], rodt[3]);
336    ddr2 U9R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7], dqs_n[16], rodt[3]);
337        `ifdef ECC
338    ddr2 U5R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb [ 7: 0], dqs[ 8] , dqs_n[ 8], dqs_n[17], rodt[3]);
339        `endif
340    `endif
341`else `ifdef x16
342    initial if (DEBUG) $display("%m: Component Width = x16");
343    ddr2 U1R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0], , rodt[0]);
344    ddr2 U2R0 (rck[1], rck_n[1], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2], , rodt[0]);
345    ddr2 U4R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4], , rodt[0]);
346    ddr2 U5R0 (rck[2], rck_n[2], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6], , rodt[0]);
347    `ifdef ECC
348    ddr2 U3R0 (rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[0]);
349    `endif
350    `ifdef DUAL_RANK
351    ddr2 U1R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0], , rodt[1]);
352    ddr2 U2R1 (rck[4], rck_n[4], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2], , rodt[1]);
353    ddr2 U4R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4], , rodt[1]);
354    ddr2 U5R1 (rck[5], rck_n[5], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6], , rodt[1]);
355        `ifdef ECC
356    ddr2 U3R1 (rck[3], rck_n[3], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[1]);
357        `endif
358    `endif
359    `ifdef QUAD_RANK
360    ddr2 U1R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0], , rodt[2]);
361    ddr2 U2R2 (rck[1], rck_n[1], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2], , rodt[2]);
362    ddr2 U4R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4], , rodt[2]);
363    ddr2 U5R2 (rck[2], rck_n[2], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6], , rodt[2]);
364        `ifdef ECC
365    ddr2 U3R2 (rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[2]);
366        `endif
367    ddr2 U1R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0], , rodt[3]);
368    ddr2 U2R3 (rck[4], rck_n[4], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2], , rodt[3]);
369    ddr2 U4R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4], , rodt[3]);
370    ddr2 U5R3 (rck[5], rck_n[5], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6], , rodt[3]);
371        `ifdef ECC
372    ddr2 U3R3 (rck[3], rck_n[3], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[3]);
373        `endif
374    `endif
375`endif `endif `endif
376
377endmodule
sim/verilog/micron_2048Mb_ddr2/ddr2_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2003 Micron Technology, Inc. All rights reserved.
25*
26****************************************************************************************/
27
28    // Parameters current with 2Gb datasheet rev B
29
30    // Timing parameters based on Speed Grade
31
32                                          // SYMBOL UNITS DESCRIPTION
33                                          // ------ ----- -----------
34`ifdef sg187E
35    parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
36    parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
37    parameter TJIT_DUTY = 75; // tJIT(duty) ps Half Period Jitter
38    parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
39    parameter TERR_2PER = 132; // tERR(nper) ps Accumulated Error (2-cycle)
40    parameter TERR_3PER = 157; // tERR(nper) ps Accumulated Error (3-cycle)
41    parameter TERR_4PER = 175; // tERR(nper) ps Accumulated Error (4-cycle)
42    parameter TERR_5PER = 188; // tERR(nper) ps Accumulated Error (5-cycle)
43    parameter TERR_N1PER = 250; // tERR(nper) ps Accumulated Error (6-10-cycle)
44    parameter TERR_N2PER = 425; // tERR(nper) ps Accumulated Error (11-50-cycle)
45    parameter TQHS = 250; // tQHS ps Data hold skew factor
46    parameter TAC = 350; // tAC ps DQ output access time from CK/CK#
47    parameter TDS = 0; // tDS ps DQ and DM input setup time relative to DQS
48    parameter TDH = 75; // tDH ps DQ and DM input hold time relative to DQS
49    parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
50    parameter TDQSQ = 175; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
51    parameter TIS = 125; // tIS ps Input Setup Time
52    parameter TIH = 200; // tIH ps Input Hold Time
53    parameter TRC = 54000; // tRC ps Active to Active/Auto Refresh command time
54    parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
55    parameter TWTR = 7500; // tWTR ps Write to Read command delay
56    parameter TRP = 13125; // tRP ps Precharge command period
57    parameter TRPA = 15000; // tRPA ps Precharge All period
58    parameter TXARDS = 10; // tXARDS tCK Exit low power active power down to a read command
59    parameter TXARD = 3; // tXARD tCK Exit active power down to a read command
60    parameter TXP = 3; // tXP tCK Exit power down to a non-read command
61    parameter TANPD = 4; // tANPD tCK ODT to power-down entry latency
62    parameter TAXPD = 11; // tAXPD tCK ODT power-down exit latency
63    parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
64`else `ifdef sg25E
65    parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
66    parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
67    parameter TJIT_DUTY = 100; // tJIT(duty) ps Half Period Jitter
68    parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
69    parameter TERR_2PER = 150; // tERR(nper) ps Accumulated Error (2-cycle)
70    parameter TERR_3PER = 175; // tERR(nper) ps Accumulated Error (3-cycle)
71    parameter TERR_4PER = 200; // tERR(nper) ps Accumulated Error (4-cycle)
72    parameter TERR_5PER = 200; // tERR(nper) ps Accumulated Error (5-cycle)
73    parameter TERR_N1PER = 300; // tERR(nper) ps Accumulated Error (6-10-cycle)
74    parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle)
75    parameter TQHS = 300; // tQHS ps Data hold skew factor
76    parameter TAC = 400; // tAC ps DQ output access time from CK/CK#
77    parameter TDS = 50; // tDS ps DQ and DM input setup time relative to DQS
78    parameter TDH = 125; // tDH ps DQ and DM input hold time relative to DQS
79    parameter TDQSCK = 350; // tDQSCK ps DQS output access time from CK/CK#
80    parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
81    parameter TIS = 175; // tIS ps Input Setup Time
82    parameter TIH = 250; // tIH ps Input Hold Time
83    parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time
84    parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
85    parameter TWTR = 7500; // tWTR ps Write to Read command delay
86    parameter TRP = 12500; // tRP ps Precharge command period
87    parameter TRPA = 15000; // tRPA ps Precharge All period
88    parameter TXARDS = 8; // tXARDS tCK Exit low power active power down to a read command
89    parameter TXARD = 2; // tXARD tCK Exit active power down to a read command
90    parameter TXP = 2; // tXP tCK Exit power down to a non-read command
91    parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency
92    parameter TAXPD = 10; // tAXPD tCK ODT power-down exit latency
93    parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
94`else `ifdef sg25
95    parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
96    parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
97    parameter TJIT_DUTY = 100; // tJIT(duty) ps Half Period Jitter
98    parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
99    parameter TERR_2PER = 150; // tERR(nper) ps Accumulated Error (2-cycle)
100    parameter TERR_3PER = 175; // tERR(nper) ps Accumulated Error (3-cycle)
101    parameter TERR_4PER = 200; // tERR(nper) ps Accumulated Error (4-cycle)
102    parameter TERR_5PER = 200; // tERR(nper) ps Accumulated Error (5-cycle)
103    parameter TERR_N1PER = 300; // tERR(nper) ps Accumulated Error (6-10-cycle)
104    parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle)
105    parameter TQHS = 300; // tQHS ps Data hold skew factor
106    parameter TAC = 400; // tAC ps DQ output access time from CK/CK#
107    parameter TDS = 50; // tDS ps DQ and DM input setup time relative to DQS
108    parameter TDH = 125; // tDH ps DQ and DM input hold time relative to DQS
109    parameter TDQSCK = 350; // tDQSCK ps DQS output access time from CK/CK#
110    parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
111    parameter TIS = 175; // tIS ps Input Setup Time
112    parameter TIH = 250; // tIH ps Input Hold Time
113    parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time
114    parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
115    parameter TWTR = 7500; // tWTR ps Write to Read command delay
116    parameter TRP = 15000; // tRP ps Precharge command period
117    parameter TRPA = 17500; // tRPA ps Precharge All period
118    parameter TXARDS = 8; // tXARDS tCK Exit low power active power down to a read command
119    parameter TXARD = 2; // tXARD tCK Exit active power down to a read command
120    parameter TXP = 2; // tXP tCK Exit power down to a non-read command
121    parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency
122    parameter TAXPD = 10; // tAXPD tCK ODT power-down exit latency
123    parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
124`else `ifdef sg3E
125    parameter TCK_MIN = 3000; // tCK ps Minimum Clock Cycle Time
126    parameter TJIT_PER = 125; // tJIT(per) ps Period JItter
127    parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter
128    parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter
129    parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle)
130    parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle)
131    parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle)
132    parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle)
133    parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle)
134    parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle)
135    parameter TQHS = 340; // tQHS ps Data hold skew factor
136    parameter TAC = 450; // tAC ps DQ output access time from CK/CK#
137    parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS
138    parameter TDH = 175; // tDH ps DQ and DM input hold time relative to DQS
139    parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
140    parameter TDQSQ = 240; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
141    parameter TIS = 200; // tIS ps Input Setup Time
142    parameter TIH = 275; // tIH ps Input Hold Time
143    parameter TRC = 54000; // tRC ps Active to Active/Auto Refresh command time
144    parameter TRCD = 12000; // tRCD ps Active to Read/Write command time
145    parameter TWTR = 7500; // tWTR ps Write to Read command delay
146    parameter TRP = 12000; // tRP ps Precharge command period
147    parameter TRPA = 15000; // tRPA ps Precharge All period
148    parameter TXARDS = 7; // tXARDS tCK Exit low power active power down to a read command
149    parameter TXARD = 2; // tXARD tCK Exit active power down to a read command
150    parameter TXP = 2; // tXP tCK Exit power down to a non-read command
151    parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency
152    parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency
153    parameter CL_TIME = 12000; // CL ps Minimum CAS Latency
154`else `ifdef sg3
155    parameter TCK_MIN = 3000; // tCK ps Minimum Clock Cycle Time
156    parameter TJIT_PER = 125; // tJIT(per) ps Period JItter
157    parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter
158    parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter
159    parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle)
160    parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle)
161    parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle)
162    parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle)
163    parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle)
164    parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle)
165    parameter TQHS = 340; // tQHS ps Data hold skew factor
166    parameter TAC = 450; // tAC ps DQ output access time from CK/CK#
167    parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS
168    parameter TDH = 175; // tDH ps DQ and DM input hold time relative to DQS
169    parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
170    parameter TDQSQ = 240; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
171    parameter TIS = 200; // tIS ps Input Setup Time
172    parameter TIH = 275; // tIH ps Input Hold Time
173    parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time
174    parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
175    parameter TWTR = 7500; // tWTR ps Write to Read command delay
176    parameter TRP = 15000; // tRP ps Precharge command period
177    parameter TRPA = 18000; // tRPA ps Precharge All period
178    parameter TXARDS = 7; // tXARDS tCK Exit low power active power down to a read command
179    parameter TXARD = 2; // tXARD tCK Exit active power down to a read command
180    parameter TXP = 2; // tXP tCK Exit power down to a non-read command
181    parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency
182    parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency
183    parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
184`else `ifdef sg37E
185    parameter TCK_MIN = 3750; // tCK ps Minimum Clock Cycle Time
186    parameter TJIT_PER = 125; // tJIT(per) ps Period JItter
187    parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter
188    parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter
189    parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle)
190    parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle)
191    parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle)
192    parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle)
193    parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle)
194    parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle)
195    parameter TQHS = 400; // tQHS ps Data hold skew factor
196    parameter TAC = 500; // tAC ps DQ output access time from CK/CK#
197    parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS
198    parameter TDH = 225; // tDH ps DQ and DM input hold time relative to DQS
199    parameter TDQSCK = 450; // tDQSCK ps DQS output access time from CK/CK#
200    parameter TDQSQ = 300; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
201    parameter TIS = 250; // tIS ps Input Setup Time
202    parameter TIH = 375; // tIH ps Input Hold Time
203    parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time
204    parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
205    parameter TWTR = 7500; // tWTR ps Write to Read command delay
206    parameter TRP = 15000; // tRP ps Precharge command period
207    parameter TRPA = 18750; // tRPA ps Precharge All period
208    parameter TXARDS = 6; // tXARDS tCK Exit low power active power down to a read command
209    parameter TXARD = 2; // tXARD tCK Exit active power down to a read command
210    parameter TXP = 2; // tXP tCK Exit power down to a non-read command
211    parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency
212    parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency
213    parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
214`else `define sg5E
215    parameter TCK_MIN = 5000; // tCK ps Minimum Clock Cycle Time
216    parameter TJIT_PER = 125; // tJIT(per) ps Period JItter
217    parameter TJIT_DUTY = 150; // tJIT(duty) ps Half Period Jitter
218    parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter
219    parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle)
220    parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle)
221    parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle)
222    parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle)
223    parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle)
224    parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle)
225    parameter TQHS = 450; // tQHS ps Data hold skew factor
226    parameter TAC = 600; // tAC ps DQ output access time from CK/CK#
227    parameter TDS = 150; // tDS ps DQ and DM input setup time relative to DQS
228    parameter TDH = 275; // tDH ps DQ and DM input hold time relative to DQS
229    parameter TDQSCK = 500; // tDQSCK ps DQS output access time from CK/CK#
230    parameter TDQSQ = 350; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
231    parameter TIS = 350; // tIS ps Input Setup Time
232    parameter TIH = 475; // tIH ps Input Hold Time
233    parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time
234    parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
235    parameter TWTR = 10000; // tWTR ps Write to Read command delay
236    parameter TRP = 15000; // tRP ps Precharge command period
237    parameter TRPA = 20000; // tRPA ps Precharge All period
238    parameter TXARDS = 6; // tXARDS tCK Exit low power active power down to a read command
239    parameter TXARD = 2; // tXARD tCK Exit active power down to a read command
240    parameter TXP = 2; // tXP tCK Exit power down to a non-read command
241    parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency
242    parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency
243    parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
244`endif `endif `endif `endif `endif `endif
245
246`ifdef x16
247  `ifdef sg187E
248    parameter TFAW = 45000; // tFAW ps Four Bank Activate window
249  `else `ifdef sg25E
250    parameter TFAW = 45000; // tFAW ps Four Bank Activate window
251  `else `ifdef sg25
252    parameter TFAW = 45000; // tFAW ps Four Bank Activate window
253  `else // sg3E, sg3, sg37E, sg5E
254    parameter TFAW = 50000; // tFAW ps Four Bank Activate window
255  `endif `endif `endif
256`else // x4, x8
257  `ifdef sg187E
258    parameter TFAW = 35000; // tFAW ps Four Bank Activate window
259  `else `ifdef sg25E
260    parameter TFAW = 35000; // tFAW ps Four Bank Activate window
261  `else `ifdef sg25
262    parameter TFAW = 35000; // tFAW ps Four Bank Activate window
263  `else // sg3E, sg3, sg37E, sg5E
264    parameter TFAW = 37500; // tFAW ps Four Bank Activate window
265  `endif `endif `endif
266`endif
267
268    // Timing Parameters
269
270    // Mode Register
271    parameter AL_MIN = 0; // AL tCK Minimum Additive Latency
272    parameter AL_MAX = 6; // AL tCK Maximum Additive Latency
273    parameter CL_MIN = 3; // CL tCK Minimum CAS Latency
274    parameter CL_MAX = 7; // CL tCK Maximum CAS Latency
275    parameter WR_MIN = 2; // WR tCK Minimum Write Recovery
276    parameter WR_MAX = 8; // WR tCK Maximum Write Recovery
277    parameter BL_MIN = 4; // BL tCK Minimum Burst Length
278    parameter BL_MAX = 8; // BL tCK Minimum Burst Length
279    // Clock
280    parameter TCK_MAX = 8000; // tCK ps Maximum Clock Cycle Time
281    parameter TCH_MIN = 0.48; // tCH tCK Minimum Clock High-Level Pulse Width
282    parameter TCH_MAX = 0.52; // tCH tCK Maximum Clock High-Level Pulse Width
283    parameter TCL_MIN = 0.48; // tCL tCK Minimum Clock Low-Level Pulse Width
284    parameter TCL_MAX = 0.52; // tCL tCK Maximum Clock Low-Level Pulse Width
285    // Data
286    parameter TLZ = TAC; // tLZ ps Data-out low-impedance window from CK/CK#
287    parameter THZ = TAC; // tHZ ps Data-out high impedance window from CK/CK#
288    parameter TDIPW = 0.35; // tDIPW tCK DQ and DM input Pulse Width
289    // Data Strobe
290    parameter TDQSH = 0.35; // tDQSH tCK DQS input High Pulse Width
291    parameter TDQSL = 0.35; // tDQSL tCK DQS input Low Pulse Width
292    parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
293    parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
294    parameter TWPRE = 0.35; // tWPRE tCK DQS Write Preamble
295    parameter TWPST = 0.40; // tWPST tCK DQS Write Postamble
296    parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
297    // Command and Address
298    parameter TIPW = 0.6; // tIPW tCK Control and Address input Pulse Width
299    parameter TCCD = 2; // tCCD tCK Cas to Cas command delay
300    parameter TRAS_MIN = 40000; // tRAS ps Minimum Active to Precharge command time
301    parameter TRAS_MAX =70000000; // tRAS ps Maximum Active to Precharge command time
302    parameter TRTP = 7500; // tRTP ps Read to Precharge command delay
303    parameter TWR = 15000; // tWR ps Write recovery time
304    parameter TMRD = 2; // tMRD tCK Load Mode Register command cycle time
305    parameter TDLLK = 200; // tDLLK tCK DLL locking time
306    // Refresh
307    parameter TRFC_MIN = 197500; // tRFC ps Refresh to Refresh Command interval minimum value
308    parameter TRFC_MAX =70000000; // tRFC ps Refresh to Refresh Command Interval maximum value
309    // Self Refresh
310    parameter TXSNR = TRFC_MIN + 10000; // tXSNR ps Exit self refesh to a non-read command
311    parameter TXSRD = 200; // tXSRD tCK Exit self refresh to a read command
312    parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit.
313    // ODT
314    parameter TAOND = 2; // tAOND tCK ODT turn-on delay
315    parameter TAOFD = 2.5; // tAOFD tCK ODT turn-off delay
316    parameter TAONPD = 2000; // tAONPD ps ODT turn-on (precharge power-down mode)
317    parameter TAOFPD = 2000; // tAOFPD ps ODT turn-off (precharge power-down mode)
318    parameter TMOD = 12000; // tMOD ps ODT enable in EMR to ODT pin transition
319    // Power Down
320    parameter TCKE = 3; // tCKE tCK CKE minimum high or low pulse width
321
322    // Size Parameters based on Part Width
323
324`ifdef x4
325    parameter ADDR_BITS = 15; // Address Bits
326    parameter ROW_BITS = 15; // Number of Address bits
327    parameter COL_BITS = 11; // Number of Column bits
328    parameter DM_BITS = 1; // Number of Data Mask bits
329    parameter DQ_BITS = 4; // Number of Data bits
330    parameter DQS_BITS = 1; // Number of Dqs bits
331    parameter TRRD = 7500; // tRRD Active bank a to Active bank b command time
332`else `ifdef x8
333    parameter ADDR_BITS = 15; // Address Bits
334    parameter ROW_BITS = 15; // Number of Address bits
335    parameter COL_BITS = 10; // Number of Column bits
336    parameter DM_BITS = 1; // Number of Data Mask bits
337    parameter DQ_BITS = 8; // Number of Data bits
338    parameter DQS_BITS = 1; // Number of Dqs bits
339    parameter TRRD = 7500; // tRRD Active bank a to Active bank b command time
340`else `define x16
341    parameter ADDR_BITS = 14; // Address Bits
342    parameter ROW_BITS = 14; // Number of Address bits
343    parameter COL_BITS = 10; // Number of Column bits
344    parameter DM_BITS = 2; // Number of Data Mask bits
345    parameter DQ_BITS = 16; // Number of Data bits
346    parameter DQS_BITS = 2; // Number of Dqs bits
347    parameter TRRD = 10000; // tRRD Active bank a to Active bank b command time
348`endif `endif
349
350`ifdef QUAD_RANK
351    `define DUAL_RANK // also define DUAL_RANK
352    parameter CS_BITS = 4; // Number of Chip Select Bits
353    parameter RANKS = 4; // Number of Chip Select Bits
354`else `ifdef DUAL_RANK
355    parameter CS_BITS = 2; // Number of Chip Select Bits
356    parameter RANKS = 2; // Number of Chip Select Bits
357`else
358    parameter CS_BITS = 2; // Number of Chip Select Bits
359    parameter RANKS = 1; // Number of Chip Select Bits
360`endif `endif
361
362    // Size Parameters
363    parameter BA_BITS = 3; // Set this parmaeter to control how many Bank Address bits
364    parameter MEM_BITS = 10; // Number of write data bursts can be stored in memory. The default is 2^10=1024.
365    parameter AP = 10; // the address bit that controls auto-precharge and precharge-all
366    parameter BL_BITS = 3; // the number of bits required to count to MAX_BL
367    parameter BO_BITS = 2; // the number of Burst Order Bits
368
369    // Simulation parameters
370    parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors
371    parameter DEBUG = 1; // Turn on Debug messages
372    parameter BUS_DELAY = 0; // delay in nanoseconds
373    parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads
374    parameter RANDOM_SEED = 711689044; //seed value for random generator.
375
376    parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe
377    parameter RDQSEN_PST = 1; // DQS driving time after last read strobe
378    parameter RDQS_PRE = 2; // DQS low time prior to first read strobe
379    parameter RDQS_PST = 1; // DQS low time after last valid read strobe
380    parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data
381    parameter RDQEN_PST = 0; // DQ/DM driving time after last read data
382    parameter WDQS_PRE = 1; // DQS half clock periods prior to first write strobe
383    parameter WDQS_PST = 1; // DQS half clock periods after last valid write strobe
sim/verilog/micron_2048Mb_ddr2/readme.txt
1Disclaimer of Warranty:
2-----------------------
3This software code and all associated documentation, comments or other
4information (collectively "Software") is provided "AS IS" without
5warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20DAMAGES. Because some jurisdictions prohibit the exclusion or
21limitation of liability for consequential or incidental damages, the
22above limitation may not apply to you.
23
24Copyright 2003 Micron Technology, Inc. All rights reserved.
25
26Getting Started:
27----------------
28Unzip the included files to a folder.
29Compile ddr2.v, ddr2_mcp.v, and tb.v using a verilog simulator.
30Simulate the top level test bench tb.
31Or, if you are using the ModelSim simulator, type "do tb.do" at the prompt.
32
33File Descriptions:
34------------------
35ddr2.v -ddr2 model
36ddr2_mcp.v -structural wrapper for ddr2 - multi-chip package model
37ddr2_module.v -structural wrapper for ddr2 - module model
38ddr2_parameters.vh -file that contains all parameters used by the model
39readme.txt -this file
40tb.v -ddr2 model test bench
41subtest.vh -example test included by the test bench.
42tb.do -compiles and runs the ddr2 model and test bench
43
44Defining the Speed Grade:
45-------------------------
46The verilog compiler directive "`define" may be used to choose between
47multiple speed grades supported by the ddr2 model. Allowable speed
48grades are listed in the ddr2_parameters.vh file and begin with the
49letters "sg". The speed grade is used to select a set of timing
50parameters for the ddr2 model. The following are examples of defining
51the speed grade.
52
53    simulator command line
54    --------- ------------
55    ModelSim vlog +define+sg5 ddr2.v
56    NC-Verilog ncverilog +define+sg5 ddr2.v
57    VCS vcs +define+sg5 ddr2.v
58
59Defining the Organization:
60--------------------------
61The verilog compiler directive "`define" may be used to choose between
62multiple organizations supported by the ddr2 model. Valid
63organizations include "x4", "x8", and x16, and are listed in the
64ddr2_parameters.vh file. The organization is used to select the amount
65of memory and the port sizes of the ddr2 model. The following are
66examples of defining the organization.
67
68    simulator command line
69    --------- ------------
70    ModelSim vlog +define+x8 ddr2.v
71    NC-Verilog ncverilog +define+x8 ddr2.v
72    VCS vcs +define+x8 ddr2.v
73
74All combinations of speed grade and organization are considered valid
75by the ddr2 model even though a Micron part may not exist for every
76combination.
77
78Allocating Memory:
79------------------
80An associative array has been implemented to reduce the amount of
81static memory allocated by the ddr2 model. Each entry in the
82associative array is a burst length of eight in size. The number of
83entries in the associative array is controlled by the MEM_BITS
84parameter, and is equal to 2^MEM_BITS. For example, if the MEM_BITS
85parameter is equal to 10, the associative array will be large enough
86to store 1024 writes of burst length 8 to unique addresses. The
87following are examples of setting the MEM_BITS parameter to 8.
88
89    simulator command line
90    --------- ------------
91    ModelSim vsim -GMEM_BITS=8 ddr2
92    NC-Verilog ncverilog +defparam+ddr2.MEM_BITS=8 ddr2.v
93    VCS vcs -pvalue+MEM_BITS=8 ddr2.v
94
95It is possible to allocate memory for every address supported by the
96ddr2 model by using the verilog compiler directive "`define MAX_MEM".
97This procedure will improve simulation performance at the expense of
98system memory. The following are examples of allocating memory for
99every address.
100
101    Simulator command line
102    --------- ------------
103    ModelSim vlog +define+MAX_MEM ddr2.v
104    NC-Verilog ncverilog +define+MAX_MEM ddr2.v
105    VCS vcs +define+MAX_MEM ddr2.v
106
107
108**********************************************************************
109The following information is provided to assist the modeling engineer
110in creating multi-chip package (mcp) models. ddr2_mcp.v is a
111structural wrapper that instantiates ddr2 models. This wrapper can be
112used to create single, dual, or quad rank mcp models. From the
113perspective of the model, the only item that needs to be defined is the
114number of ranks.
115**********************************************************************
116
117Defining the Number of Ranks in a multi-chip package:
118----------------------------------------------------
119The verilog compiler directive "`define" may be used to choose between
120single, dual, and quad rank mcp configurations. The default is single
121rank if nothing is defined. Dual rank configuration can be selected by
122defining "DUAL_RANK" when the ddr2_mcp is compiled. Quad rank
123configuration can be selected by defining "QUAD_RANK" when the ddr2_mcp
124is compiled. The following are examples of defining a dual rank mcp
125configuration.
126
127    simulator command line
128    --------- ------------
129    ModelSim vlog +define+DUAL_RANK ddr2.v ddr2_mcp.v
130    NC-Verilog ncverilog +define+DUAL_RANK ddr2.v ddr2_mcp.v
131    VCS vcs +define+DUAL_RANK ddr2.v ddr2_mcp.v
132
133
134**********************************************************************
135The following information is provided to assist the modeling engineer
136in creating DIMM models. ddr2_module.v is a structural wrapper that
137instantiates ddr2 models. This wrapper can be used to create UDIMM,
138RDIMM or SODIMM models. Other form factors are not supported
139(MiniDIMM, VLP DIMM, etc.). From the perspective of the model, the
140items that need to be defined are the number of ranks, the module
141type, and the presence of ECC. All combinations of ranks, module
142type, and ECC are considered valid by the ddr2_module model even
143though a Micron part may not exist for every combination.
144**********************************************************************
145
146Defining the Number of Ranks on a module:
147----------------------------------------
148The verilog compiler directive "`define" may be used to choose between
149single, dual, and quad rank module configurations. The default is single
150rank if nothing is defined. Dual rank configuration can be selected by
151defining "DUAL_RANK" when the ddr2_module is compiled. Quad rank
152configuration can be selected by defining "QUAD_RANK" when the ddr2_module
153is compiled. The following are examples of defining a dual rank module
154configuration.
155
156    simulator command line
157    --------- ------------
158    ModelSim vlog +define+DUAL_RANK ddr2.v ddr2_module.v
159    NC-Verilog ncverilog +define+DUAL_RANK ddr2.v ddr2_module.v
160    VCS vcs +define+DUAL_RANK ddr2.v ddr2_module.v
161
162Defining the Module Type:
163-----------------------------------
164The verilog compiler directive "`define" may be used to choose between
165UDIMM, RDIMM, and SODIMM module configurations. The default is
166unregistered (UDIMM) if nothing is defined. SODIMM configuration can be
167selected by defining "SODIMM" when the ddr2_module is compiled. Registered
168configuration can be selected by defining "RDIMM" when the ddr2_module is
169compiled. The following are examples of defining a registered module
170configuration.
171
172    simulator command line
173    --------- ------------
174    ModelSim vlog +define+RDIMM ddr2.v ddr2_module.v
175    NC-Verilog ncverilog +define+RDIMM ddr2.v ddr2_module.v
176    VCS vcs +define+RDIMM ddr2.v ddr2_module.v
177
178Defining the ECC for a module:
179-----------------------------
180The verilog compiler directive "`define" may be used to choose between
181ECC and nonECC module configurations. The default is nonECC if nothing
182is defined. ECC configuration can be selected by defining "ECC" when
183the ddr2_module is compiled. The following are examples of defining an
184ECC module configuration.
185
186    simulator command line
187    --------- ------------
188    ModelSim vlog +define+ECC ddr2.v ddr2_module.v
189    NC-Verilog ncverilog +define+ECC ddr2.v ddr2_module.v
190    VCS vcs +define+ECC ddr2.v ddr2_module.v
sim/verilog/micron_2048Mb_ddr2/subtest.vh
1/****************************************************************************************
2*
3* File Name: subtest.vh
4*
5* Description: Micron SDRAM DDR2 (Double Data Rate 2)
6* This file is included by tb.v
7*
8* Disclaimer This software code and all associated documentation, comments or other
9* of Warranty: information (collectively "Software") is provided "AS IS" without
10* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
11* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
12* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
13* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
14* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
15* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
16* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
17* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
18* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
19* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
20* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
21* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
22* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
23* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
24* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
25* DAMAGES. Because some jurisdictions prohibit the exclusion or
26* limitation of liability for consequential or incidental damages, the
27* above limitation may not apply to you.
28*
29* Copyright 2003 Micron Technology, Inc. All rights reserved.
30*
31****************************************************************************************/
32
33    initial begin : test
34        cke <= 1'b0;
35        cs_n <= 1'b1;
36        ras_n <= 1'b1;
37        cas_n <= 1'b1;
38        we_n <= 1'b1;
39        ba <= {BA_BITS{1'bz}};
40        a <= {ADDR_BITS{1'bz}};
41        odt <= 1'b0;
42        dq_en <= 1'b0;
43        dqs_en <= 1'b0;
44
45        cke <= 1'b1;
46
47        // POWERUP SECTION
48        power_up;
49
50        // INITIALIZE SECTION
51        precharge (0, 1); // Precharge all banks
52        nop (trp);
53
54        load_mode (2, 0); // Extended Mode Register (2)
55        nop (tmrd-1);
56
57        load_mode (3, 0); // Extended Mode Register (3)
58        nop (tmrd-1);
59
60        load_mode (1, 13'b0_0_0_000_0_000_1_0_0); // Extended Mode Register with DLL Enable
61        nop (tmrd-1);
62
63        load_mode (0, 13'b0_000_1_0_000_0_011 | (twr-1)<<9 | taa<<4); // Mode Register without DLL Reset (bl=8)
64        nop (tmrd-1);
65
66        precharge (0, 1); // Precharge all banks
67        nop (trp);
68
69        refresh;
70        nop (trfc-1);
71
72        refresh;
73        nop (trfc-1);
74
75        load_mode (0, 13'b0_000_0_0_000_0_011 | (twr-1)<<9 | taa<<4); // Mode Register without DLL Reset (bl=8)
76        nop (tmrd-1);
77
78        load_mode (1, 13'b0_0_0_111_0_000_1_0_0); // Extended Mode Register with OCD Default
79        nop (tmrd-1);
80
81        load_mode (1, 13'b0_0_0_000_0_000_1_0_0); // Extended Mode Register with OCD Exit
82        nop (tmrd-1);
83
84        // DLL RESET ENABLE - you will need 200 TCK before any read command.
85        nop (200);
86
87        // WRITE SECTION
88        activate (0, 0); // Activate Bank 0, Row 0
89        nop (trcd-1);
90        write (0, 4, 0, 0, 'h3210); // Write Bank 0, Col 0
91        nop (tccd-1);
92        write (0, 0, 1, 0, 'h0123); // Write Bank 0, Col 0
93
94        activate (1, 0); // Activate Bank 1, Row 0
95        nop (trcd-1);
96        write (1, 0, 1, 0, 'h4567); // Write Bank 1, Col 0
97
98        activate (2, 0); // Activate Bank 2, Row 0
99        nop (trcd-1);
100        write (2, 0, 1, 0, 'h89AB); // Write Bank 2, Col 0
101
102        activate (3, 0); // Activate Bank 3, Row 0
103        nop (trcd-1);
104        write (3, 0, 1, 0, 'hCDEF); // Write Bank 3, Col 0
105
106        nop (cl - 1 + bl/2 + twtr-1);
107
108        nop (tras);
109
110        // READ SECTION
111        activate (0, 0); // Activate Bank 0, Row 0
112        nop (trrd-1);
113        activate (1, 0); // Activate Bank 1, Row 0
114        nop (trrd-1);
115        activate (2, 0); // Activate Bank 2, Row 0
116        nop (trrd-1);
117        activate (3, 0); // Activate Bank 3, Row 0
118        read (0, 0, 1); // Read Bank 0, Col 0
119        nop (bl/2);
120        read (1, 1, 1); // Read Bank 1, Col 1
121        nop (bl/2);
122        read (2, 2, 1); // Read Bank 2, Col 2
123        nop (bl/2);
124        read (3, 3, 1); // Read Bank 3, Col 3
125        nop (rl + bl/2);
126
127        activate (0, 0); // Activate Bank 0, Row 0
128        nop (trrd-1);
129        activate (1, 0); // Activate Bank 1, Row 0
130        nop (trcd-1);
131        $display ("%m at time %t: Figure 22: Consecutive READ Bursts", $time);
132        read (0, 0, 0); // Read Bank 0, Col 0
133        nop (bl/2-1);
134        read (0, 4, 0); // Read Bank 0, Col 4
135        nop (rl + bl/2);
136
137        $display ("%m at time %t: Figure 23: Nonconsecutive READ Bursts", $time);
138        read (0, 0, 0); // Read Bank 0, Col 0
139        nop (bl/2);
140        read (0, 4, 0); // Read Bank 0, Col 4
141        nop (rl + bl/2);
142
143        $display ("%m at time %t: Figure 24: READ Interrupted by READ", $time);
144        read (0, 0, 0); // Read Bank 0, Col 0
145        nop (tccd-1);
146        read (1, 0, 0); // Read Bank 0, Col 0
147        nop (rl + bl/2);
148
149        $display ("%m at time %t: Figure 25 & 26: READ to PRECHARGE", $time);
150        read (0, 0, 0); // Read Bank 0, Col 0
151        nop (al + bl/2 + trtp - 2);
152        precharge (0, 0); // Precharge Bank 0
153        nop (trp-1);
154
155        activate (0, 0); // Activate Bank 0, Row 0
156        nop (trcd-1);
157        $display ("%m at time %t: Figure 27: READ to WRITE", $time);
158        read (0, 0, 0); // Read Bank 0, Col 0
159        nop (rl + bl/2 - wl);
160        write (0, 0, 1, 0, 'h0123); // Write Bank 0, Col 0
161        nop (wl + bl/2 + twr + trp-1);
162
163        activate (0, 0); // Activate Bank 0, Row 0
164        nop (trcd-1);
165        $display ("%m at time %t: Figure 36: Nonconsecutive WRITE to WRITE", $time);
166        write (0, 0, 0, 0, 'h0123); // Write Bank 0, Col 0
167        nop (bl/2);
168        write (0, 4, 0, 0, 'h0123); // Write Bank 0, Col 0
169        nop (wl + bl/2);
170
171        $display ("%m at time %t: Figure 37: Random WRITE Cycles", $time);
172        write (0, 0, 0, 0, 'h0123); // Write Bank 0, Col 0
173        nop (bl/2-1);
174        write (0, 4, 0, 0, 'h0123); // Write Bank 0, Col 0
175        nop (wl + bl/2);
176
177        $display ("%m at time %t: Figure 37: Figure 38: WRITE Interrupted by WRITE", $time);
178        write (0, 0, 0, 0, 'h0123); // Write Bank 0, Col 0
179        nop (tccd-1);
180        write (1, 4, 0, 0, 'h0123); // Write Bank 0, Col 0
181        nop (wl + bl/2);
182
183        $display ("%m at time %t: Figure 39: WRITE to READ", $time);
184        write (0, 0, 0, 0, 'h0123); // Write Bank 0, Col 0
185        nop (wl + bl/2 + twtr-1);
186        read_verify (0, 0, 0, 0, 'h0123); // Read Bank 0, Col 0
187        nop (rl + bl/2);
188
189        $display ("%m at time %t: Figure 40: WRITE to PRECHARGE", $time);
190        write (0, 0, 0, 0, 'h0123); // Write Bank 0, Col 0
191        nop (wl + bl/2 + twr-1);
192        precharge (0, 1); // Precharge all banks
193        nop (trp-1);
194
195        // odt Section
196        $display ("%m at time %t: Figure 60: odt Timing for Active or Fast-Exit Power-Down Mode", $time);
197        odt = 1'b1;
198        nop (1);
199        odt = 1'b0;
200        nop (tanpd);
201
202        $display ("%m at time %t: Figure 61: odt timing for Slow-Exit or Precharge Power-Down Modes", $time);
203        cke = 1'b0;
204        @(negedge ck);
205        odt = 1'b1;
206        @(negedge ck);
207        odt = 1'b0;
208        repeat(tanpd)@(negedge ck);
209        nop (taxpd);
210
211        $display ("%m at time %t: Figure 62 & 63: odt Transition Timings when Entering Power-Down Mode", $time);
212        odt = 1'b1;
213        nop (tanpd);
214        power_down (tcke);
215
216        // Self Refresh Section
217        nop (taxpd);
218        odt = 1'b0;
219        nop (3); // taofd
220        self_refresh (tcke);
221        nop (tdllk);
222        nop (tcke);
223
224        test_done;
225    end
sim/verilog/micron_2048Mb_ddr2/tb.do
1#########################################################################################
2#
3# Disclaimer This software code and all associated documentation, comments or other
4# of Warranty: information (collectively "Software") is provided "AS IS" without
5# warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6# DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7# TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8# OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9# WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10# OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11# FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12# THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13# ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14# OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15# ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16# INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17# WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18# OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19# THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20# DAMAGES. Because some jurisdictions prohibit the exclusion or
21# limitation of liability for consequential or incidental damages, the
22# above limitation may not apply to you.
23#
24# Copyright 2003 Micron Technology, Inc. All rights reserved.
25#
26#########################################################################################
27
28vlog -novopt ddr2.v tb.v
29vsim -novopt tb
30add wave -p sdramddr2/*
31run -all
sim/verilog/micron_2048Mb_ddr2/tb.v
1/****************************************************************************************
2*
3* File Name: tb.v
4*
5* Dependencies: ddr2.v, ddr2_parameters.vh
6*
7* Description: Micron SDRAM DDR2 (Double Data Rate 2) test bench
8*
9* Note: -Set simulator resolution to "ps" accuracy
10* -Set Debug = 0 to disable $display messages
11*
12* Disclaimer This software code and all associated documentation, comments or other
13* of Warranty: information (collectively "Software") is provided "AS IS" without
14* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
15* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
16* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
17* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
18* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
19* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
20* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
21* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
22* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
23* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
24* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
25* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
26* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
27* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
28* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
29* DAMAGES. Because some jurisdictions prohibit the exclusion or
30* limitation of liability for consequential or incidental damages, the
31* above limitation may not apply to you.
32*
33* Copyright 2003 Micron Technology, Inc. All rights reserved.
34*
35****************************************************************************************/
36
37// DO NOT CHANGE THE TIMESCALE
38
39`timescale 1ps / 1ps
40
41module tb;
42
43`include "ddr2_parameters.vh"
44
45    // ports
46    reg ck;
47    wire ck_n = ~ck;
48    reg cke;
49    reg cs_n;
50    reg ras_n;
51    reg cas_n;
52    reg we_n;
53    reg [BA_BITS-1:0] ba;
54    reg [ADDR_BITS-1:0] a;
55    wire [DM_BITS-1:0] dm;
56    wire [DQ_BITS-1:0] dq;
57    wire [DQS_BITS-1:0] dqs;
58    wire [DQS_BITS-1:0] dqs_n;
59    wire [DQS_BITS-1:0] rdqs_n;
60    reg odt;
61
62    // mode registers
63    reg [ADDR_BITS-1:0] mode_reg0; //Mode Register
64    reg [ADDR_BITS-1:0] mode_reg1; //Extended Mode Register
65    wire [2:0] cl = mode_reg0[6:4]; //CAS Latency
66    wire bo = mode_reg0[3]; //Burst Order
67    wire [7:0] bl = (1<<mode_reg0[2:0]); //Burst Length
68    wire rdqs_en = mode_reg1[11]; //RDQS Enable
69    wire dqs_n_en = ~mode_reg1[10]; //dqs# Enable
70    wire [2:0] al = mode_reg1[5:3]; //Additive Latency
71    wire [3:0] rl = al + cl; //Read Latency
72    wire [3:0] wl = al + cl-1'b1; //Write Latency
73
74    // dq transmit
75    reg dq_en;
76    reg [DM_BITS-1:0] dm_out;
77    reg [DQ_BITS-1:0] dq_out;
78    reg dqs_en;
79    reg [DQS_BITS-1:0] dqs_out;
80    assign dm = dq_en ? dm_out : {DM_BITS{1'bz}};
81    assign dq = dq_en ? dq_out : {DQ_BITS{1'bz}};
82    assign dqs = dqs_en ? dqs_out : {DQS_BITS{1'bz}};
83    assign dqs_n = (dqs_en & dqs_n_en) ? ~dqs_out : {DQS_BITS{1'bz}};
84
85    // dq receive
86    reg [DM_BITS-1:0] dm_fifo [2*(AL_MAX+CL_MAX)+BL_MAX:0];
87    reg [DQ_BITS-1:0] dq_fifo [2*(AL_MAX+CL_MAX)+BL_MAX:0];
88    wire [DQ_BITS-1:0] q0, q1, q2, q3;
89    reg [1:0] burst_cntr;
90    assign rdqs_n = {DQS_BITS{1'bz}};
91
92    // timing definition in tCK units
93    real tck;
94    wire [11:0] taa = ceil(CL_TIME/tck);
95    wire [11:0] tanpd = TANPD;
96    wire [11:0] taond = TAOND;
97    wire [11:0] taofd = ceil(TAOFD);
98    wire [11:0] taxpd = TAXPD;
99    wire [11:0] tccd = TCCD;
100    wire [11:0] tcke = TCKE;
101    wire [11:0] tdllk = TDLLK;
102    wire [11:0] tfaw = ceil(TFAW/tck);
103    wire [11:0] tmod = ceil(TMOD/tck);
104    wire [11:0] tmrd = TMRD;
105    wire [11:0] tras = ceil(TRAS_MIN/tck);
106    wire [11:0] trc = TRC;
107    wire [11:0] trcd = ceil(TRCD/tck);
108    wire [11:0] trfc = ceil(TRFC_MIN/tck);
109    wire [11:0] trp = ceil(TRP/tck);
110    wire [11:0] trrd = ceil(TRRD/tck);
111    wire [11:0] trtp = ceil(TRTP/tck);
112    wire [11:0] twr = ceil(TWR/tck);
113    wire [11:0] twtr = ceil(TWTR/tck);
114    wire [11:0] txard = TXARD;
115    wire [11:0] txards = TXARDS;
116    wire [11:0] txp = TXP;
117    wire [11:0] txsnr = ceil(TXSNR/tck);
118    wire [11:0] txsrd = TXSRD;
119
120    initial begin
121        $timeformat (-9, 1, " ns", 1);
122`ifdef period
123        tck <= `period;
124`else
125        tck <= TCK_MIN;
126`endif
127        ck <= 1'b1;
128    end
129
130    // component instantiation
131    ddr2 sdramddr2 (
132        ck,
133        ck_n,
134        cke,
135        cs_n,
136        ras_n,
137        cas_n,
138        we_n,
139        dm,
140        ba,
141        a,
142        dq,
143        dqs,
144        dqs_n,
145        rdqs_n,
146        odt
147    );
148
149    // clock generator
150    always @(posedge ck) begin
151      ck <= #(tck/2) 1'b0;
152      ck <= #(tck) 1'b1;
153    end
154
155    function integer ceil;
156        input number;
157        real number;
158        if (number > $rtoi(number))
159            ceil = $rtoi(number) + 1;
160        else
161            ceil = number;
162    endfunction
163
164    function integer max;
165        input arg1;
166        input arg2;
167        integer arg1;
168        integer arg2;
169        if (arg1 > arg2)
170            max = arg1;
171        else
172            max = arg2;
173    endfunction
174
175    task power_up;
176        begin
177            cke <= 1'b0;
178            odt <= 1'b0;
179            repeat(10) @(negedge ck);
180            cke <= 1'b1;
181            nop (400000/tck+1);
182        end
183    endtask
184
185    task load_mode;
186        input [BA_BITS-1:0] bank;
187        input [ADDR_BITS-1:0] addr;
188        begin
189            case (bank)
190                0: mode_reg0 = addr;
191                1: mode_reg1 = addr;
192            endcase
193            cke <= 1'b1;
194            cs_n <= 1'b0;
195            ras_n <= 1'b0;
196            cas_n <= 1'b0;
197            we_n <= 1'b0;
198            ba <= bank;
199            a <= addr;
200            @(negedge ck);
201        end
202    endtask
203
204    task refresh;
205        begin
206            cke <= 1'b1;
207            cs_n <= 1'b0;
208            ras_n <= 1'b0;
209            cas_n <= 1'b0;
210            we_n <= 1'b1;
211            @(negedge ck);
212        end
213    endtask
214
215    task precharge;
216        input [BA_BITS-1:0] bank;
217        input ap; //precharge all
218        begin
219            cke <= 1'b1;
220            cs_n <= 1'b0;
221            ras_n <= 1'b0;
222            cas_n <= 1'b1;
223            we_n <= 1'b0;
224            ba <= bank;
225            a <= (ap<<10);
226            @(negedge ck);
227        end
228    endtask
229
230    task activate;
231        input [BA_BITS-1:0] bank;
232        input [ROW_BITS-1:0] row;
233        begin
234            cke <= 1'b1;
235            cs_n <= 1'b0;
236            ras_n <= 1'b0;
237            cas_n <= 1'b1;
238            we_n <= 1'b1;
239            ba <= bank;
240            a <= row;
241            @(negedge ck);
242        end
243    endtask
244
245    //write task supports burst lengths <= 8
246    task write;
247        input [BA_BITS-1:0] bank;
248        input [COL_BITS-1:0] col;
249        input ap; //Auto Precharge
250        input [8*DM_BITS-1:0] dm;
251        input [8*DQ_BITS-1:0] dq;
252        reg [ADDR_BITS-1:0] atemp [1:0];
253        integer i;
254        begin
255            cke <= 1'b1;
256            cs_n <= 1'b0;
257            ras_n <= 1'b1;
258            cas_n <= 1'b0;
259            we_n <= 1'b0;
260            ba <= bank;
261            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
262            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
263            a <= atemp[0] | atemp[1] | (ap<<10);
264            for (i=0; i<=bl; i=i+1) begin
265
266                dqs_en <= #(wl*tck + i*tck/2) 1'b1;
267                if (i%2 == 0) begin
268                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b0}};
269                end else begin
270                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b1}};
271                end
272
273                dq_en <= #(wl*tck + i*tck/2 + tck/4) 1'b1;
274                dm_out <= #(wl*tck + i*tck/2 + tck/4) dm>>i*DM_BITS;
275                dq_out <= #(wl*tck + i*tck/2 + tck/4) dq>>i*DQ_BITS;
276            end
277            dqs_en <= #(wl*tck + bl*tck/2 + tck/2) 1'b0;
278            dq_en <= #(wl*tck + bl*tck/2 + tck/4) 1'b0;
279            @(negedge ck);
280        end
281    endtask
282
283    // read without data verification
284    task read;
285        input [BA_BITS-1:0] bank;
286        input [COL_BITS-1:0] col;
287        input ap; //Auto Precharge
288        reg [ADDR_BITS-1:0] atemp [1:0];
289        begin
290            cke <= 1'b1;
291            cs_n <= 1'b0;
292            ras_n <= 1'b1;
293            cas_n <= 1'b0;
294            we_n <= 1'b1;
295            ba <= bank;
296            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
297            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
298            a <= atemp[0] | atemp[1] | (ap<<10);
299            @(negedge ck);
300        end
301    endtask
302
303    task nop;
304        input [31:0] count;
305        begin
306            cke <= 1'b1;
307            cs_n <= 1'b0;
308            ras_n <= 1'b1;
309            cas_n <= 1'b1;
310            we_n <= 1'b1;
311            repeat(count) @(negedge ck);
312        end
313    endtask
314
315    task deselect;
316        input [31:0] count;
317        begin
318            cke <= 1'b1;
319            cs_n <= 1'b1;
320            ras_n <= 1'b1;
321            cas_n <= 1'b1;
322            we_n <= 1'b1;
323            repeat(count) @(negedge ck);
324        end
325    endtask
326
327    task power_down;
328        input [31:0] count;
329        begin
330            cke <= 1'b0;
331            cs_n <= 1'b1;
332            ras_n <= 1'b1;
333            cas_n <= 1'b1;
334            we_n <= 1'b1;
335            repeat(count) @(negedge ck);
336        end
337    endtask
338
339    task self_refresh;
340        input [31:0] count;
341        begin
342            cke <= 1'b0;
343            cs_n <= 1'b0;
344            ras_n <= 1'b0;
345            cas_n <= 1'b0;
346            we_n <= 1'b1;
347            cs_n <= #(tck) 1'b1;
348            ras_n <= #(tck) 1'b1;
349            cas_n <= #(tck) 1'b1;
350            we_n <= #(tck) 1'b1;
351            repeat(count) @(negedge ck);
352        end
353    endtask
354
355    // read with data verification
356    task read_verify;
357        input [BA_BITS-1:0] bank;
358        input [COL_BITS-1:0] col;
359        input ap; //Auto Precharge
360        input [8*DM_BITS-1:0] dm; //Expected Data Mask
361        input [8*DQ_BITS-1:0] dq; //Expected Data
362        integer i;
363        begin
364            read (bank, col, ap);
365            for (i=0; i<bl; i=i+1) begin
366                dm_fifo[2*rl + i] = dm >> (i*DM_BITS);
367                dq_fifo[2*rl + i] = dq >> (i*DQ_BITS);
368            end
369        end
370    endtask
371
372    // receiver(s) for data_verify process
373    dqrx dqrx[DQS_BITS-1:0] (dqs, dq, q0, q1, q2, q3);
374
375    // perform data verification as a result of read_verify task call
376    always @(ck) begin:data_verify
377        integer i;
378        integer j;
379        reg [DQ_BITS-1:0] bit_mask;
380        reg [DM_BITS-1:0] dm_temp;
381        reg [DQ_BITS-1:0] dq_temp;
382
383        for (i = !ck; (i < 2/(2.0 - !ck)); i=i+1) begin
384            if (dm_fifo[i] === {DM_BITS{1'bx}}) begin
385                burst_cntr = 0;
386            end else begin
387
388                dm_temp = dm_fifo[i];
389                for (j=0; j<DQ_BITS; j=j+1) begin
390                    bit_mask[j] = !dm_temp[j/8];
391                end
392
393                case (burst_cntr)
394                    0: dq_temp = q0;
395                    1: dq_temp = q1;
396                    2: dq_temp = q2;
397                    3: dq_temp = q3;
398                endcase
399                //if ( ((dq_temp & bit_mask) === (dq_fifo[i] & bit_mask)))
400                // $display ("%m at time %t: INFO: Successful read data compare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
401                if ((dq_temp & bit_mask) !== (dq_fifo[i] & bit_mask))
402                    $display ("%m at time %t: ERROR: Read data miscompare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
403
404                burst_cntr = burst_cntr + 1;
405            end
406        end
407
408        if (ck) begin
409            if (dm_fifo[2] === {DM_BITS{1'bx}}) begin
410                dqrx[0%DQS_BITS].ptr <= 0; // v2k syntax
411                dqrx[1%DQS_BITS].ptr <= 0; // v2k syntax
412                dqrx[2%DQS_BITS].ptr <= 0; // v2k syntax
413                dqrx[3%DQS_BITS].ptr <= 0; // v2k syntax
414            end
415        end else begin
416            for (i=0; i<=(2*(AL_MAX+CL_MAX)+BL_MAX); i=i+1) begin
417                dm_fifo[i] = dm_fifo[i+2];
418                dq_fifo[i] = dq_fifo[i+2];
419            end
420        end
421    end
422
423    // End-of-test triggered in 'subtest.vh'
424    task test_done;
425        begin
426            $display ("%m at time %t: INFO: Simulation is Complete", $time);
427            $stop(0);
428        end
429    endtask
430
431    // Test included from external file
432    `include "subtest.vh"
433
434endmodule
435
436module dqrx (
437    dqs, dq, q0, q1, q2, q3
438);
439
440    `include "ddr2_parameters.vh"
441
442    input dqs;
443    input [DQ_BITS/DQS_BITS-1:0] dq;
444    output [DQ_BITS/DQS_BITS-1:0] q0;
445    output [DQ_BITS/DQS_BITS-1:0] q1;
446    output [DQ_BITS/DQS_BITS-1:0] q2;
447    output [DQ_BITS/DQS_BITS-1:0] q3;
448
449    reg [DQ_BITS/DQS_BITS-1:0] q [3:0];
450
451    assign q0 = q[0];
452    assign q1 = q[1];
453    assign q2 = q[2];
454    assign q3 = q[3];
455
456    reg [1:0] ptr;
457    reg dqs_q;
458
459    always @(dqs) begin
460        if (dqs ^ dqs_q) begin
461            #(TDQSQ + 1);
462            q[ptr] <= dq;
463            ptr <= (ptr + 1)%4;
464        end
465        dqs_q <= dqs;
466    end
467
468endmodule
sim/verilog/micron_mobile_ddr/1024Mb_mobile_ddr_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2005 Micron Technology, Inc. All rights reserved.
25*
26*
27* Revisions: baaab - 06/20/06 - tMRD was set to 2.0 ns but should be 2 * tCK. Fixed.
28* Added ROW_BITS & BA_BITS for compatibility w/our system.
29* Removed part size parameter.
30*
31****************************************************************************************/
32
33    // Parameters current with 1024Mb datasheet rev C (10/02/07)
34    // 04.17.08 - Consolidated 1024Mb and T48M designs; Updated to rev E (03/08)
35    // 12.10.08 - Updated to datasheet rev G (07/08)
36
37
38                                          // SYMBOL UNITS DESCRIPTION
39                                          // ------ ----- -----------
40`ifdef sg5 // Timing Parameters for -5 (CL = 3)
41    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
42    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
43    parameter tCK = 5.0; // tCK ns Nominal Clock Cycle Time
44    parameter tCK3_min = 5.0; // tCK ns Nominal Clock Cycle Time
45    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
46    parameter tDQSQ = 0.40; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
47    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
48    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
49    parameter tRAS = 40.0; // tRAS ns Active to Precharge command time
50    parameter tRC = 55.0; // tRC ns Active to Active/Auto Refresh command time
51    parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time
52    parameter tRP = 15.0; // tRP ns Precharge command period
53    parameter tRRD = 10.0; // tRRD ns Active bank a to Active bank b command time
54    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
55    parameter tXP = 10.0; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
56`else `ifdef sg54 // Timing Parameters for -6 (CL = 3)
57    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
58    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
59    parameter tCK = 5.4; // tCK ns Nominal Clock Cycle Time
60    parameter tCK3_min = 5.4; // tCK ns Nominal Clock Cycle Time
61    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
62    parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
63    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
64    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
65    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
66    parameter tRC = 58.2; // tRC ns Active to Active/Auto Refresh command time
67    parameter tRCD = 16.2; // tRCD ns Active to Read/Write command time
68    parameter tRP = 16.2; // tRP ns Precharge command period
69    parameter tRRD = 10.8; // tRRD ns Active bank a to Active bank b command time
70    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
71    parameter tXP = 10.8; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
72`else `ifdef sg6 // Timing Parameters for -6 (CL = 3)
73    parameter tAC3_max = 5.5; // tAC ns Access window of DQ from CK/CK#
74    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
75    parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
76    parameter tCK3_min = 6.0; // tCK ns Nominal Clock Cycle Time
77    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
78    parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
79    parameter tHZ3_max = 5.5; // tHZ ns Data-out high Z window from CK/CK#
80    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
81    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
82    parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
83    parameter tRCD = 18.0; // tRCD ns Active to Read/Write command time
84    parameter tRP = 18.0; // tRP ns Precharge command period
85    parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
86    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
87    parameter tXP = 12.0; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
88`else `define sg75 // Timing Parameters for -75 (CL = 3)
89    parameter tAC3_max = 6.0; // tAC ns Access window of DQ from CK/CK#
90    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
91    parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time
92    parameter tCK3_min = 7.5; // tCK ns Nominal Clock Cycle Time
93    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
94    parameter tDQSQ = 0.60; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
95    parameter tHZ3_max = 6.0; // tHZ ns Data-out high Z window from CK/CK#
96    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
97    parameter tRAS = 45.0; // tRAS ns Active to Precharge command time
98    parameter tRC = 75.0; // tRC ns Active to Active/Auto Refresh command time
99    parameter tRCD = 22.5; // tRCD ns Active to Read/Write command time
100    parameter tRP = 22.5; // tRP ns Precharge command period
101    parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time
102    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
103    parameter tXP = 15.0; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
104`endif `endif `endif
105
106    parameter tAC2_min = 2.0; // tAC ns Access window of DQ from CK/CK#
107    parameter tAC3_min = 2.0; // tAC ns Access window of DQ from CK/CK#
108    parameter tLZ = 1.0; // tLZ ns Data-out low Z window from CK/CK#
109    parameter tMRD = 2.0; // tMRD tCK Load Mode Register command cycle time
110    parameter tRFC = 110.0; // tRFC ns Refresh to Refresh Command interval time
111    parameter tSRC = 1.0; // tSRC tCK SRR READ command to first valid command Note: model adds CL to this value
112    parameter tSRR = 2.0; // tSRR tCK SRR command to SRR READ command
113    parameter tWR = 15.0; // tWR ns Write recovery time
114    parameter tCH_MAX = 0.55; // Clk high level width
115    parameter tCH_MIN = 0.45; // Clk high level width
116    parameter tCL_MAX = 0.55; // Clk low level width
117    parameter tCL_MIN = 0.45; // Clk low level width
118    parameter tCKE = 1.0 ; // Minimum tCKE High/Low time (in tCK's)
119    parameter CL_MAX = 3 ; // Maximum CAS Latency
120    parameter BL_MAX = 16 ;
121
122
123
124
125     // Size Parameters based on Part Width
126`ifdef x16
127    parameter ADDR_BITS = 14; // Set this parameter to control how many Address bits are used
128    parameter ROW_BITS = 14; // Set this parameter to control how many Row bits are used
129    parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
130    parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
131    parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
132    parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
133    parameter BA_BITS = 2; // Set this parameter to control how many Bank bits are used
134`else `define x32
135  `ifdef RP // reduced page mode
136    parameter ADDR_BITS = 14; // Set this parameter to control how many Address bits are used
137    parameter ROW_BITS = 14; // Set this parameter to control how many Row bits are used
138    parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
139    parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
140    parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
141    parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used
142    parameter BA_BITS = 2; // Bank bits
143  `else
144    parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
145    parameter ROW_BITS = 13; // Set this parameter to control how many Row bits are used
146    parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
147    parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
148    parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
149    parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
150    parameter BA_BITS = 2; // Bank bits
151  `endif
152`endif
153
154    // For use with the Multi Chip Package
155`ifdef DUAL_RANK
156    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
157    parameter RANKS = 2; // Set this parameter to control how many Ranks on the mcp are used
158`else
159    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
160    parameter RANKS = 1; // Set this parameter to control how many Ranks on the mcp are used
161`endif
162
163    parameter full_mem_bits = BA_BITS+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
164    parameter part_mem_bits = 10; // Set this parameter to control how many unique addresses are used
165    parameter part_size = 1024; // Set this parameter to indicate part size(1024Mb, 512Mb, 256Mb, 128Mb)
166
167
sim/verilog/micron_mobile_ddr/128Mb_mobile_ddr_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2005 - 2006 Micron Technology, Inc. All rights reserved.
25*
26*
27* Revisions: baaab - 06/20/06 - tMRD was set to 2.0 ns but should be 2 * tCK - fixed.
28* Added ROW_BITS & BA_BITS for compatibility w/our system.
29* Also changed Col bits from 10 to 9 per spec.
30* Removed x32 option and part size parameter.
31*
32****************************************************************************************/
33
34    // Parameters current with 128Mb datasheet rev J (11/05)
35    // 04.17.08 - Parameters current with 128Mb Data sheet rev A (04/08)
36
37    // Timing parameters based on Speed Grade
38
39                                          // SYMBOL UNITS DESCRIPTION
40                                          // ------ ----- -----------
41`ifdef sg5 // Timing Parameters for -5 (CL = 3)
42    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
43    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
44    parameter tCK = 5.0; // tCK ns Nominal Clock Cycle Time
45    parameter tCK3_min = 5.0; // tCK ns Nominal Clock Cycle Time
46    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
47    parameter tDQSQ = 0.40; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
48    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
49    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
50    parameter tRAS = 40.0; // tRAS ns Active to Precharge command time
51    parameter tRC = 55.0; // tRC ns Active to Active/Auto Refresh command time
52    parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time
53    parameter tRP = 15.0; // tRP ns Precharge command period
54    parameter tRRD = 10.0; // tRRD ns Active bank a to Active bank b command time
55    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
56    parameter tXP = 5.0; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
57`else `ifdef sg54 // Timing Parameters for -6 (CL = 3)
58    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
59    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
60    parameter tCK = 5.4; // tCK ns Nominal Clock Cycle Time
61    parameter tCK3_min = 5.4; // tCK ns Nominal Clock Cycle Time
62    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
63    parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
64    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
65    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
66    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
67    parameter tRC = 58.2; // tRC ns Active to Active/Auto Refresh command time
68    parameter tRCD = 16.2; // tRCD ns Active to Read/Write command time
69    parameter tRP = 16.2; // tRP ns Precharge command period
70    parameter tRRD = 10.8; // tRRD ns Active bank a to Active bank b command time
71    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
72    parameter tXP = 5.4; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
73`else `ifdef sg6 // Timing Parameters for -6 (CL = 3)
74    parameter tAC3_max = 5.5; // tAC ns Access window of DQ from CK/CK#
75    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
76    parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
77    parameter tCK3_min = 6.0; // tCK ns Nominal Clock Cycle Time
78    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
79    parameter tDQSQ = 0.50; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
80    parameter tHZ3_max = 5.5; // tHZ ns Data-out high Z window from CK/CK#
81    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
82    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
83    parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
84    parameter tRCD = 18.0; // tRCD ns Active to Read/Write command time
85    parameter tRP = 18.0; // tRP ns Precharge command period
86    parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
87    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
88    parameter tXP = 6.0; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
89`else `define sg75 // Timing Parameters for -75 (CL = 3)
90    parameter tAC3_max = 6.0; // tAC ns Access window of DQ from CK/CK#
91    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
92    parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time
93    parameter tCK3_min = 7.5; // tCK ns Nominal Clock Cycle Time
94    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
95    parameter tDQSQ = 0.60; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
96    parameter tHZ3_max = 6.0; // tHZ ns Data-out high Z window from CK/CK#
97    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
98    parameter tRAS = 45.0; // tRAS ns Active to Precharge command time
99    parameter tRC = 75.0; // tRC ns Active to Active/Auto Refresh command time
100    parameter tRCD = 22.5; // tRCD ns Active to Read/Write command time
101    parameter tRP = 22.5; // tRP ns Precharge command period
102    parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time
103    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
104    parameter tXP = 7.5; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
105`endif `endif `endif
106
107    parameter tAC2_min = 2.0; // tAC ns Access window of DQ from CK/CK#
108    parameter tAC3_min = 2.0; // tAC ns Access window of DQ from CK/CK#
109    parameter tLZ = 1.0; // tLZ ns Data-out low Z window from CK/CK#
110    parameter tMRD = 2.0; // tMRD tCK Load Mode Register command cycle time
111    parameter tRFC = 80.0; // tRFC ns Refresh to Refresh Command interval time
112    parameter tSRC = 1.0; // tSRC tCK SRR READ command to first valid command (Not Applicable for 128Mb, 256Mb Parts)
113    parameter tSRR = 2.0; // tSRR tCK SRR command to SRR READ command (Not Applicable for 128Mb, 256Mb Parts)
114    parameter tWR = 15.0; // tWR ns Write recovery time
115
116    // Size Parameters based on Part Width
117`ifdef x16
118    parameter ADDR_BITS = 12; // Set this parameter to control how many Address bits are used
119    parameter ROW_BITS = 12; // Set this parameter to control how many Row bits are used
120    parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
121    parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
122    parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
123    parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used
124    parameter BA_BITS = 2; // Bank bits
125`else `define x32
126    parameter ADDR_BITS = 12; // Set this parameter to control how many Address bits are used
127    parameter ROW_BITS = 12; // Set this parameter to control how many Row bits are used
128    parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
129    parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
130    parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
131    parameter COL_BITS = 8; // Set this parameter to control how many Column bits are used
132    parameter BA_BITS = 2; // Bank bits
133`endif
134
135    // For use with the Multi Chip Package
136`ifdef DUAL_RANK
137    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
138    parameter RANKS = 2; // Set this parameter to control how many Ranks on the mcp are used
139`else
140    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
141    parameter RANKS = 1; // Set this parameter to control how many Ranks on the mcp are used
142`endif
143
144    parameter full_mem_bits = BA_BITS+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
145    parameter part_mem_bits = 10; // Set this parameter to control how many unique addresses are used
146    parameter part_size = 128; // Set this parameter to indicate part size(512Mb, 256Mb, 128Mb)
147    parameter tCH_MAX = 0.55; // Clk high level width
148    parameter tCH_MIN = 0.45; // Clk high level width
149    parameter tCL_MAX = 0.55; // Clk low level width
150    parameter tCL_MIN = 0.45; // Clk low level width
151    parameter tCKE = 2.0; // Minimum tCKE High/Low time (in tCK's)
152    parameter CL_MAX = 3; // Maximum CAS Latency
153    parameter BL_MAX = 16 ;
sim/verilog/micron_mobile_ddr/2048Mb_mobile_ddr_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2005 Micron Technology, Inc. All rights reserved.
25*
26*
27* Revisions: baaab - 06/20/06 - tMRD was set to 2.0 ns but should be 2 * tCK. Fixed.
28* Added ROW_BITS & BA_BITS for compatibility w/our system.
29* Removed part size parameter.
30*
31****************************************************************************************/
32
33    // Parameters current with 2048Mb LPDDR SDRAM
34    // 04.26.10 - Based on Rev 0.7 04/09EN (DDS)
35
36
37                                          // SYMBOL UNITS DESCRIPTION
38                                          // ------ ----- -----------
39`ifdef sg5 // Timing Parameters for -5 (CL = 3)
40    parameter tAC3_max = 4.8; // tAC ns Access window of DQ from CK/CK#
41    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
42    parameter tCK = 4.8; // tCK ns Nominal Clock Cycle Time
43    parameter tCK3_min = 4.8; // tCK ns Nominal Clock Cycle Time
44    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
45    parameter tDQSQ = 0.40; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
46    parameter tHZ3_max = 4.8; // tHZ ns Data-out high Z window from CK/CK#
47    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
48    parameter tRAS = 40.0; // tRAS ns Active to Precharge command time
49    parameter tRC = 55.0; // tRC ns Active to Active/Auto Refresh command time
50    parameter tRCD = 14.4; // tRCD ns Active to Read/Write command time
51    parameter tRP = 14.4; // tRP ns Precharge command period
52    parameter tRRD = 10.0; // tRRD ns Active bank a to Active bank b command time
53    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
54    parameter tXP = 6.0; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
55    parameter tWR = 14.4; // tWR ns Write recovery time
56`else `ifdef sg54 // Timing Parameters for -6 (CL = 3)
57    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
58    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
59    parameter tCK = 5.4; // tCK ns Nominal Clock Cycle Time
60    parameter tCK3_min = 5.4; // tCK ns Nominal Clock Cycle Time
61    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
62    parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
63    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
64    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
65    parameter tRAS = 41.8; // tRAS ns Active to Precharge command time
66    parameter tRC = 58.2; // tRC ns Active to Active/Auto Refresh command time
67    parameter tRCD = 16.2; // tRCD ns Active to Read/Write command time
68    parameter tRP = 16.2; // tRP ns Precharge command period
69    parameter tRRD = 10.8; // tRRD ns Active bank a to Active bank b command time
70    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
71    parameter tXP = 6.0; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
72    parameter tWR = 15.0; // tWR ns Write recovery time
73`else `ifdef sg6 // Timing Parameters for -6 (CL = 3)
74    parameter tAC3_max = 5.5; // tAC ns Access window of DQ from CK/CK#
75    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
76    parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
77    parameter tCK3_min = 6.0; // tCK ns Nominal Clock Cycle Time
78    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
79    parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
80    parameter tHZ3_max = 5.5; // tHZ ns Data-out high Z window from CK/CK#
81    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
82    parameter tRAS = 41.8; // tRAS ns Active to Precharge command time
83    parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
84    parameter tRCD = 18.0; // tRCD ns Active to Read/Write command time
85    parameter tRP = 18.0; // tRP ns Precharge command period
86    parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
87    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
88    parameter tXP = 6.0; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
89    parameter tWR = 15.0; // tWR ns Write recovery time
90`else `define sg75 // Timing Parameters for -75 (CL = 3)
91    parameter tAC3_max = 6.0; // tAC ns Access window of DQ from CK/CK#
92    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
93    parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time
94    parameter tCK3_min = 7.5; // tCK ns Nominal Clock Cycle Time
95    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
96    parameter tDQSQ = 0.60; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
97    parameter tHZ3_max = 6.0; // tHZ ns Data-out high Z window from CK/CK#
98    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
99    parameter tRAS = 45.0; // tRAS ns Active to Precharge command time
100    parameter tRC = 67.5; // tRC ns Active to Active/Auto Refresh command time
101    parameter tRCD = 22.5; // tRCD ns Active to Read/Write command time
102    parameter tRP = 22.5; // tRP ns Precharge command period
103    parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time
104    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
105    parameter tXP = 7.50; // tXP ns Exit power-down to first valid cmd Note: spec'd as 2 * tCK
106    parameter tWR = 15.0; // tWR ns Write recovery time
107`endif `endif `endif
108
109    parameter tAC2_min = 2.0; // tAC ns Access window of DQ from CK/CK#
110    parameter tAC3_min = 2.0; // tAC ns Access window of DQ from CK/CK#
111    parameter tLZ = 1.0; // tLZ ns Data-out low Z window from CK/CK#
112    parameter tMRD = 2.0; // tMRD tCK Load Mode Register command cycle time
113    parameter tRFC = 72.0; // tRFC ns Refresh to Refresh Command interval time
114    parameter tSRC = 1.0; // tSRC tCK SRR READ command to first valid command Note: model adds CL to this value
115    parameter tSRR = 2.0; // tSRR tCK SRR command to SRR READ command
116    parameter tCH_MAX = 0.55; // Clk high level width
117    parameter tCH_MIN = 0.45; // Clk high level width
118    parameter tCL_MAX = 0.55; // Clk low level width
119    parameter tCL_MIN = 0.45; // Clk low level width
120    parameter tCKE = 1.0 ; // Minimum tCKE High/Low time (in tCK's)
121    parameter CL_MAX = 3 ; // Maximum CAS Latency
122    parameter BL_MAX = 16 ;
123
124
125
126
127     // Size Parameters based on Part Width
128`ifdef x16
129    `ifdef RP
130        parameter ADDR_BITS = 15; // Set this parameter to control how many Address bits are used
131        parameter ROW_BITS = 15; // Set this parameter to control how many Row bits are used
132        parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
133        parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
134        parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
135        parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
136        parameter BA_BITS = 2; // Set this parameter to control how many Bank bits are used
137    `else
138        parameter ADDR_BITS = 14; // Set this parameter to control how many Address bits are used
139        parameter ROW_BITS = 14; // Set this parameter to control how many Row bits are used
140        parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
141        parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
142        parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
143        parameter COL_BITS = 11; // Set this parameter to control how many Column bits are used
144        parameter BA_BITS = 2; // Set this parameter to control how many Bank bits are used
145    `endif
146`else `define x32
147    `ifdef RP // reduced page mode
148        parameter ADDR_BITS = 15; // Set this parameter to control how many Address bits are used
149        parameter ROW_BITS = 15; // Set this parameter to control how many Row bits are used
150        parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
151        parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
152        parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
153        parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used
154        parameter BA_BITS = 2; // Bank bits
155    `else
156        parameter ADDR_BITS = 14; // Set this parameter to control how many Address bits are used
157        parameter ROW_BITS = 14; // Set this parameter to control how many Row bits are used
158        parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
159        parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
160        parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
161        parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
162        parameter BA_BITS = 2; // Bank bits
163    `endif
164`endif
165
166    // For use with the Multi Chip Package
167`ifdef DUAL_RANK
168    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
169    parameter RANKS = 2; // Set this parameter to control how many Ranks on the mcp are used
170`else
171    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
172    parameter RANKS = 1; // Set this parameter to control how many Ranks on the mcp are used
173`endif
174
175    parameter full_mem_bits = BA_BITS+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
176    parameter part_mem_bits = 10; // Set this parameter to control how many unique addresses are used
177    parameter part_size = 2048; // Set this parameter to indicate part size(1024Mb, 512Mb, 256Mb, 128Mb)
178
179
sim/verilog/micron_mobile_ddr/256Mb_mobile_ddr_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2005 Micron Technology, Inc. All rights reserved.
25*
26*
27* Revisions: baaab - 06/20/06 - tMRD was set to 2.0 ns but should be 2 * tCK. Fixed.
28* Added ROW_BITS & BA_BITS for compatibility w/our system.
29* Also changed x16 Col bits from 8 to 9 per spec.
30* Removed part size parameter.
31*
32****************************************************************************************/
33
34    // Parameters current with 256Mb datasheet rev E (05/07)
35    // 04.17.08 - Parameters current with 256Mb Data sheet rev H (03/08)
36
37    // Timing parameters based on Speed Grade
38
39                                          // SYMBOL UNITS DESCRIPTION
40                                          // ------ ----- -----------
41`ifdef sg6 // Timing Parameters for -6 (CL = 3)
42    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
43    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
44    parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
45    parameter tCK3_min = 6.0; // tCK ns Nominal Clock Cycle Time
46    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
47    parameter tDQSQ = 0.50; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
48    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
49    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
50    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
51    parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
52    parameter tRCD = 18.0; // tRCD ns Active to Read/Write command time
53    parameter tRP = 18.0; // tRP ns Precharge command period
54    parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
55    parameter tWR = 12.0; // tWR ns Write recovery time
56    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
57    parameter tXP = 6.0; // tXP ns Exit power-down to first valid cmd
58`else `define sg75 // Timing Parameters for -75 (CL = 3)
59    parameter tAC3_max = 6.0; // tAC ns Access window of DQ from CK/CK#
60    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
61    parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time
62    parameter tCK3_min = 7.5; // tCK ns Nominal Clock Cycle Time
63    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
64    parameter tDQSQ = 0.60; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
65    parameter tHZ3_max = 6.0; // tHZ ns Data-out high Z window from CK/CK#
66    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
67    parameter tRAS = 45.0; // tRAS ns Active to Precharge command time
68    parameter tRC = 75.0; // tRC ns Active to Active/Auto Refresh command time
69    parameter tRCD = 22.5; // tRCD ns Active to Read/Write command time
70    parameter tRP = 22.5; // tRP ns Precharge command period
71    parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time
72    parameter tWR = 15.0; // tWR ns Write recovery time
73    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
74    parameter tXP = 7.5; // tXP ns Exit power-down to first valid cmd
75`endif
76
77    parameter tAC2_min = 2.0; // tAC ns Access window of DQ from CK/CK#
78    parameter tAC3_min = 2.0; // tAC ns Access window of DQ from CK/CK#
79    parameter tLZ = 1.0; // tLZ ns Data-out low Z window from CK/CK#
80    parameter tMRD = 2.0; // tMRD tCK Load Mode Register command cycle time
81    parameter tRFC = 70.0; // tRFC ns Refresh to Refresh Command interval time
82    parameter tSRC = 1.0; // tSRC tCK SRR READ command to first valid command (Not Applicable for 128Mb, 256Mb, and 512Mb Parts)
83    parameter tSRR = 2.0; // tSRR tCK SRR command to SRR READ command (Not Applicable for 128Mb, 256Mb, and 512Mb Parts)
84
85    // Size Parameters based on Part Width
86`ifdef x16
87    parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
88    parameter ROW_BITS = 13; // Set this parameter to control how many Row bits are used
89    parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
90    parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
91    parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
92    parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used
93    parameter BA_BITS = 2; // Bank bits
94`else `define x32
95    `ifdef RP
96    parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
97    parameter ROW_BITS = 13; // Set this parameter to control how many Row bits are used
98    parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
99    parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
100    parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
101    parameter COL_BITS = 8; // Set this parameter to control how many Column bits are used
102    parameter BA_BITS = 2; // Bank bits
103    `else
104    parameter ADDR_BITS = 12; // Set this parameter to control how many Address bits are used
105    parameter ROW_BITS = 12; // Set this parameter to control how many Row bits are used
106    parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
107    parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
108    parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
109    parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used
110    parameter BA_BITS = 2; // Bank bits
111    `endif
112`endif
113
114    // For use with the Multi Chip Package
115`ifdef DUAL_RANK
116    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
117    parameter RANKS = 2; // Set this parameter to control how many Ranks on the mcp are used
118`else
119    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
120    parameter RANKS = 1; // Set this parameter to control how many Ranks on the mcp are used
121`endif
122
123    parameter full_mem_bits = BA_BITS+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
124    parameter part_mem_bits = 10; // For fast sim load
125    parameter part_size = 256; // Set this parameter to indicate part size(512Mb, 256Mb, 128Mb)
126    parameter tCH_MAX = 0.55; // Clk high level width
127    parameter tCH_MIN = 0.45; // Clk high level width
128    parameter tCL_MAX = 0.55; // Clk low level width
129    parameter tCL_MIN = 0.45; // Clk low level width
130    parameter tCKE = 2.0; // Minimum tCKE High/Low time (in tCK's)
131    parameter CL_MAX = 3; // Maximum CAS Latency
132    parameter BL_MAX = 16;
133
134
sim/verilog/micron_mobile_ddr/512Mb_mobile_ddr_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2005 Micron Technology, Inc. All rights reserved.
25*
26*
27* Revisions: baaab - 06/20/06 - tMRD was set to 2.0 ns but should be 2 * tCK. Fixed.
28* Added ROW_BITS & BA_BITS for compatibility w/our system.
29* Removed part size parameter.
30*
31****************************************************************************************/
32
33    // Parameters current with T47M datasheet rev M (07/07)
34    // 04.17.08 - Paramters current with 512Mb Data sheet rev C (03/08)
35    // Timing parameters based on Speed Grade
36
37
38                                          // SYMBOL UNITS DESCRIPTION
39                                          // ------ ----- -----------
40`ifdef sg5 // Timing Parameters for -5 (CL = 3)
41    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
42    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
43    parameter tCK = 5.0; // tCK ns Nominal Clock Cycle Time
44    parameter tCK3_min = 5.0; // tCK ns Nominal Clock Cycle Time
45    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
46    parameter tDQSQ = 0.40; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
47    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
48    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
49    parameter tRAS = 40.0; // tRAS ns Active to Precharge command time
50    parameter tRC = 55.0; // tRC ns Active to Active/Auto Refresh command time
51    parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time
52    parameter tRP = 15.0; // tRP ns Precharge command period
53    parameter tRRD = 10.0; // tRRD ns Active bank a to Active bank b command time
54    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
55    parameter tXP = 10.0; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
56`else `ifdef sg54 // Timing Parameters for -6 (CL = 3)
57    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
58    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
59    parameter tCK = 5.4; // tCK ns Nominal Clock Cycle Time
60    parameter tCK3_min = 5.4; // tCK ns Nominal Clock Cycle Time
61    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
62    parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
63    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
64    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
65    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
66    parameter tRC = 59.4; // tRC ns Active to Active/Auto Refresh command time
67    parameter tRCD = 16.2; // tRCD ns Active to Read/Write command time
68    parameter tRP = 16.2; // tRP ns Precharge command period
69    parameter tRRD = 10.8; // tRRD ns Active bank a to Active bank b command time
70    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
71    parameter tXP = 10.8; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
72`else `ifdef sg6 // Timing Parameters for -6 (CL = 3)
73    parameter tAC3_max = 5.0; // tAC ns Access window of DQ from CK/CK#
74    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
75    parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
76    parameter tCK3_min = 6.0; // tCK ns Nominal Clock Cycle Time
77    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
78    parameter tDQSQ = 0.50; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
79    parameter tHZ3_max = 5.0; // tHZ ns Data-out high Z window from CK/CK#
80    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
81    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
82    parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
83    parameter tRCD = 18.0; // tRCD ns Active to Read/Write command time
84    parameter tRP = 18.0; // tRP ns Precharge command period
85    parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
86    parameter tWTR = 2.0; // tWTR tCK Internal Write-to-Read command delay
87    parameter tXP = 6.0; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
88`else `define sg75 // Timing Parameters for -75 (CL = 3)
89    parameter tAC3_max = 6.0; // tAC ns Access window of DQ from CK/CK#
90    parameter tAC2_max = 6.5; // tAC ns Access window of DQ from CK/CK#
91    parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time
92    parameter tCK3_min = 7.5; // tCK ns Nominal Clock Cycle Time
93    parameter tCK2_min = 12.0; // tCK ns Nominal Clock Cycle Time
94    parameter tDQSQ = 0.60; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access
95    parameter tHZ3_max = 6.0; // tHZ ns Data-out high Z window from CK/CK#
96    parameter tHZ2_max = 6.5; // tHZ ns Data-out high Z window from CK/CK#
97    parameter tRAS = 45.0; // tRAS ns Active to Precharge command time
98    parameter tRC = 75.0; // tRC ns Active to Active/Auto Refresh command time
99    parameter tRCD = 22.5; // tRCD ns Active to Read/Write command time
100    parameter tRP = 22.5; // tRP ns Precharge command period
101    parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time
102    parameter tWTR = 1.0; // tWTR tCK Internal Write-to-Read command delay
103    parameter tXP = 7.5; // tXP ns Exit power-down to first valid cmd *note: In data sheet this is specified as one clk, but min tck fails before tXP on the actual part
104`endif `endif `endif
105
106    parameter tAC2_min = 2.0; // tAC ns Access window of DQ from CK/CK#
107    parameter tAC3_min = 2.0; // tAC ns Access window of DQ from CK/CK#
108    parameter tLZ = 1.0; // tLZ ns Data-out low Z window from CK/CK#
109    parameter tMRD = 2.0; // tMRD tCK Load Mode Register command cycle time
110    parameter tRFC = 97.5; // tRFC ns Refresh to Refresh Command interval time
111    parameter tSRC = 1.0; // tSRC tCK SRR READ command to first valid command (Not Applicable for 128Mb, 256Mb Parts)
112    parameter tSRR = 2.0; // tSRR tCK SRR command to SRR READ command (Not Applicable for 128Mb, 256Mb Parts)
113    parameter tWR = 15.0; // tWR ns Write recovery time
114
115     // Size Parameters based on Part Width
116 `ifdef x16
117     parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
118     parameter ROW_BITS = 13; // Set this parameter to control how many Row bits are used
119     parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
120     parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
121     parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
122     parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
123     parameter BA_BITS = 2; // Bank bits
124 `else `define x32
125     `ifdef RP
126     parameter ADDR_BITS = 14; // Set this parameter to control how many Address bits are used
127     parameter ROW_BITS = 14; // Set this parameter to control how many Row bits are used
128     parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
129     parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
130     parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
131     parameter COL_BITS = 8; // Set this parameter to control how many Column bits are used
132     parameter BA_BITS = 2; // Bank bits
133     `else
134     parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
135     parameter ROW_BITS = 13; // Set this parameter to control how many Row bits are used
136     parameter DQ_BITS = 32; // Set this parameter to control how many Data bits are used
137     parameter DQS_BITS = 4; // Set this parameter to control how many DQS bits are used
138     parameter DM_BITS = 4; // Set this parameter to control how many DM bits are used
139     parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used
140     parameter BA_BITS = 2; // Bank bits
141     `endif
142`endif
143
144    // For use with the Multi Chip Package
145`ifdef DUAL_RANK
146    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
147    parameter RANKS = 2; // Set this parameter to control how many Ranks on the mcp are used
148`else
149    parameter CS_BITS = 2; // Set this parameter to control how many Chip Select bits are used
150    parameter RANKS = 1; // Set this parameter to control how many Ranks on the mcp are used
151`endif
152
153    parameter full_mem_bits = BA_BITS+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
154    parameter part_mem_bits = 10; // Set this parameter to control how many unique addresses are used
155    parameter part_size = 512; // Set this parameter to indicate part size(512Mb, 256Mb, 128Mb)
156    parameter tCH_MAX = 0.55; // Clk high level width
157    parameter tCH_MIN = 0.45; // Clk high level width
158    parameter tCL_MAX = 0.55; // Clk low level width
159    parameter tCL_MIN = 0.45; // Clk low level width
160    parameter tCKE = 1.0; // Minimum tCKE High/Low time (in tCK's)
161    parameter CL_MAX = 3; // Maximum CAS Latency
162    parameter BL_MAX = 16 ;
sim/verilog/micron_mobile_ddr/mobile_ddr.v
1/****************************************************************************************
2*
3* File Name: mobile_ddr.v
4* Version: 6.03
5* Model: BUS Functional
6*
7* Dependencies: mobile_ddr_parameters.vh
8*
9* Description: Micron MOBILE DDR SDRAM
10*
11* Limitation: - Doesn't check for 8K-cycle refresh
12*
13* Note: - Set simulator resolution to "ps" accuracy
14* - Set Debug = 0 to disable $display messages
15* - Model assume Clk and Clk# crossing at both edge
16*
17* Disclaimer This software code and all associated documentation, comments or other
18* of Warranty: information (collectively "Software") is provided "AS IS" without
19* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
20* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
21* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
22* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
23* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
24* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
25* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
26* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
27* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
28* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
29* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
30* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
31* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
32* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
33* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
34* DAMAGES. Because some jurisdictions prohibit the exclusion or
35* limitation of liability for consequential or incidental damages, the
36* above limitation may not apply to you.
37*
38* Copyright 2008 Micron Technology, Inc. All rights reserved.
39*
40* Rev Author Date Changes
41* --- ------ ---------- ---------------------------------------
42* 1.0 NMB 03/19/02 - Initial Release of Mobile DDR model
43* based off of version 5.0 of DDR model
44* 1.1 ritz 12/03/04 - New feature: 1/8th strength driver in Drive Strength (Ext Mode Reg).
45* Bugfix - ba[0] ba[1] were swapped for determening ext_mode_enable
46* thus ext_mode_reg wasnt being programmed.
47* 1.2 ritz 12/07/04 - Logging transactions in transcript for automated testing
48* 1.3 ritz 01/31/05 - updated to SMG DDR model version 5.2 (dqs edge checking errors fix)
49* 1.4 ritz 02/15/05 - Fixed display.*WRITE to use hex for "data".
50* 1.5 ritz 03/22/05 - Fixed read latency (#0.5 and 2*Read_latency-1) for MMG latency
51* 2.0 bas 07/19/06 - Added PASR support and clk_n checking
52* 3.0 bas 08/07/06 - Added tXP check, tCke check, Power-down/Deep power down enter/exit messages
53                            FULL_MEM fix
54* 3.11 bas 10/18/06 - Added clk spd chk, added RP support, added T48M part, added SRR functionality, changed tMRD checker to measure in tck pos edge, DPD optimization for FULL_MEM mode
55* 3.12 bas 10/19/06 - Fixed PASR in FULL_MEM mode
56* 3.20 bas 10/23/06 - changed tXP check to tPDX check for T25L, Initial release to web
57* 3.30 bas 01/15/07 - Updated T48M Parameters (updated as of 12/06)
58* 3.35 bas 02/28/07 - Model uses tAC correctly to calculate strobe/data launch
59* 3.36 bas 03/05/07 - fixed error messages for different banks interrupting
60                            reads/writes w/autoprecharge
61* 3.37 bas 03/21/07 - Added T47M Part to 512Mb parameter file
62* 3.40 bas 06/25/07 - Removed RP options from 1024Mb
63                          - Updated 128Mb, 256Mb, and 512Mb parts to 05/07 datasheet
64                          - Updated 1024Mb part to 02/07
65                          - Added illegal Cas Latency check per speed grade
66* 3.40 jwm 08/02/07 - Support for 512Mb T47M
67* 3.80 clk 10/29/07 - Support for 1024Mb T48M
68* 4.00 clk 12/30/07 - Fixed Read terminated by precharge testcase
69* 4.70 clk 03/30/08 - Fixed typo in SRR code
70* 4.80 clk 04/03/08 - Disable clk checking during initialization
71* 4.90 clk 04/16/08 - Fixed tInit, added mpc support, updated t35m timing
72* 5.00 clk 05/14/08 - Fixed back to back auto precharge commands
73* 5.20 clk 05/21/08 - Fixed read interrupt by pre (BL8), fixed 1024Mb parameter file
74* 5.30 clk 05/22/08 - Fixed DM signal which cause false tWTR errors
75              05/27/08 - Rewrote write and read pipelines, strobes
76* 5.40 clk 05/28/08 - Fixed Addressing problem in Burst Order logic
77* 5.50 clk 07/25/08 - Added T36N part type
78* 5.60 clk 09/05/08 - Fixed tXP in 256Mb part type
79* 5.70 clk 09/17/08 - Fixed burst term check for write w/ all DM active
80* 5.80 clk 11/18/08 - Fixed internally latched dq & mask widths
81* 5.90 clk 12/10/08 - Updated T36N parameters to latest datasheet
82* 6.00 clk 03/05/09 - Fixed DQS problem w/ CL = 2, Fix Wr Pipeline during Rd interrupt
83* 6.01 sph 01/20/10 - Added clock stop detection to fix tCH/tCL timing violation
84* 6.02 sph 01/22/10 - Added check for nop/des is used when enter/exit stop clock mode
85* 6.03 sph 06/07/10 - Include all the mobile_ddr_parameters.vh into a single package
86****************************************************************************************/
87
88// DO NOT CHANGE THE TIMESCALE
89// MAKE SURE YOUR SIMULATOR USES "PS" RESOLUTION
90`timescale 1ns / 1ps
91
92module mobile_ddr (Dq, Dqs, Addr, Ba, Clk, Clk_n, Cke, Cs_n, Ras_n, Cas_n, We_n, Dm);
93
94`ifdef den128Mb
95    `include "128Mb_mobile_ddr_parameters.vh"
96`elsif den256Mb
97    `include "256Mb_mobile_ddr_parameters.vh"
98`elsif den512Mb
99    `include "512Mb_mobile_ddr_parameters.vh"
100`elsif den1024Mb
101    `include "1024Mb_mobile_ddr_parameters.vh"
102`elsif den2048Mb
103    `include "2048Mb_mobile_ddr_parameters.vh"
104`else
105    // NOTE: Intentionally cause a compile fail here to force the users
106    // to select the correct component density before continuing
107    ERROR: You must specify component density with +define+den____Mb.
108`endif
109
110    `define MAX_PIPE 2*(CL_MAX + BL_MAX)
111
112    // Port Declarations
113    input Clk;
114    input Clk_n;
115    input Cke;
116    input Cs_n;
117    input Ras_n;
118    input Cas_n;
119    input We_n;
120    input [ADDR_BITS - 1 : 0] Addr;
121    input [1 : 0] Ba;
122    inout [DQ_BITS - 1 : 0] Dq;
123    inout [DQS_BITS - 1 : 0] Dqs;
124    input [DM_BITS - 1 : 0] Dm;
125
126    //time variables
127    realtime tXP_chk ;
128    reg enter_DPD ;
129    reg enter_PD ;
130    reg enter_APD ;
131
132    //integer clk checks
133
134    // Internal Wires (fixed width)
135    wire [31 : 0] Dq_in;
136    wire [3 : 0] Dqs_in;
137    wire [3 : 0] Dm_in;
138
139    assign Dq_in [DQ_BITS - 1 : 0] = Dq;
140    assign Dqs_in [DQS_BITS - 1 : 0] = Dqs;
141    assign Dm_in [DM_BITS - 1 : 0] = Dm;
142
143    // Data pair
144    reg [DQ_BITS-1 : 0] dq_rise;
145    reg [DM_BITS-1 : 0] dm_rise;
146    reg [DQ_BITS-1 : 0] dq_fall;
147    reg [DM_BITS-1 : 0] dm_fall;
148    reg [DM_BITS*2-1 : 0] dm_pair;
149    reg [DQ_BITS-1 : 0] Dq_buf;
150
151    // Power-down cycle counter
152    reg [03:00] PD_cntr ;
153
154    // prev cmd value
155
156    reg prev_Cs_n ;
157    reg prev_Ras_n ;
158    reg prev_Cas_n ;
159    reg prev_We_n ;
160    reg [01:00] prev_Ba ;
161    reg prev_cke ;
162
163    wire prev_nop = ~prev_Cs_n & prev_Ras_n & prev_Cas_n & prev_We_n ;
164    wire prev_des = prev_Cs_n ;
165    wire prev_bt = ~prev_Cs_n & prev_Ras_n & prev_Cas_n & ~prev_We_n ;
166    wire prev_rd = ~prev_Cs_n & prev_Ras_n & ~prev_Cas_n & prev_We_n ;
167    reg Clk_Chk_enable = 1'b0 ;
168
169    //differential clk
170    reg diff_ck;
171    always @(posedge Clk) diff_ck <= Clk;
172    always @(posedge Clk_n) diff_ck <= ~Clk_n;
173
174    //measure clock period
175    realtime clk_period ;
176    realtime pos_clk_edge ;
177    integer clk_pos_edge_cnt ;
178    always @(posedge diff_ck) begin
179        clk_period = $realtime - pos_clk_edge ;
180        pos_clk_edge = $realtime ;
181        if ((Cke == 1'b1) && (clk_pos_edge_cnt < 2)) begin
182            clk_pos_edge_cnt = clk_pos_edge_cnt + 1 ;
183        end else if (Cke == 1'b0) begin
184            clk_pos_edge_cnt = 2'b00 ;
185        end
186    end
187
188    //measure duty cycle
189    realtime neg_clk_edge ;
190    always @(negedge diff_ck) begin
191        neg_clk_edge = $realtime ;
192    end
193    realtime pos_clk_time ;
194    realtime neg_clk_time ;
195    reg clock_stop = 0;
196
197    // Mode Register
198    reg [ADDR_BITS - 1 : 0] Mode_reg;
199    reg [ADDR_BITS - 1 : 0] Ext_Mode_reg;
200    reg [2*DQ_BITS - 1 : 0] Srr_reg;
201
202
203    // SRR Registers
204    reg SRR_read;
205
206    // Internal System Clock
207    reg CkeZ, Sys_clk;
208
209    // Internal Dqs initialize
210// reg Dqs_int;
211
212    // Dqs buffer
213    reg Dqs_out;
214// reg [DQS_BITS - 1 : 0] Dqs_gen;
215    reg Dqs_out_en;
216    // Dq buffer
217    reg [DQ_BITS - 1 : 0] Dq_out_temp;
218    reg [DQ_BITS - 1 : 0] Dq_out;
219    reg Dq_out_en;
220
221    // Read pipeline variables
222    reg [`MAX_PIPE : 0] Read_pipeline ;
223    reg [1 : 0] Read_bank [0 : 6];
224    reg [COL_BITS - 1 : 0] Read_cols [0 : 6];
225
226    // Write pipeline variables
227    reg [`MAX_PIPE :-2] Write_pipeline;
228    reg [BA_BITS-1 : 0] Write_bank_pipeline [`MAX_PIPE :-2];
229    reg [COL_BITS - 1 : 0] Write_col_pipeline [`MAX_PIPE :-2];
230
231    // Auto precharge variables
232    reg [3:0] Read_precharge_access ;
233    reg [3:0] Read_precharge_pre ;
234    reg [3:0] Write_precharge_access ;
235    reg [3:0] Write_precharge_pre ;
236    integer Count_precharge [0:3];
237    reg SelfRefresh;
238    reg [3:0] Read_precharge_count [3:0] ;
239    reg [3:0] Write_precharge_count [3:0];
240
241
242    reg wr_ap_display_msg ;
243    reg rd_ap_display_msg ;
244
245    // Manual precharge variables
246// reg [0 : 6] A10_precharge ;
247// reg [1 : 0] Bank_precharge [0 : 6];
248// reg [0 : 6] Cmnd_precharge ;
249
250    // Burst terminate variables
251// reg Cmnd_bst [0 : 6];
252
253    // tMRD counter
254    integer MRD_cntr ;
255    integer SRR_cntr ;
256    integer SRC_cntr ;
257    integer tWTR_cntr ;
258
259    // Memory Banks
260    `ifdef FULL_MEM
261        reg [DQ_BITS - 1 : 0] mem_array [0 : (1<<full_mem_bits)-1];
262    `else
263        reg [DQ_BITS - 1 : 0] mem_array [0 : (1<<part_mem_bits)-1];
264        reg [full_mem_bits - 1 : 0] addr_array [0 : (1<<part_mem_bits)-1];
265        reg [part_mem_bits : 0] mem_used;
266        reg [part_mem_bits : 0] memory_index;
267        initial mem_used = 0;
268    `endif
269
270    // Dqs edge checking
271    integer i;
272    reg [3:0] expect_pos_dqs;
273    reg [3:0] expect_neg_dqs;
274
275    // Burst counter
276    reg [COL_BITS - 1 : 0] Burst_counter;
277
278    // Burst counter delay
279    reg [COL_BITS - 1 : 0] Burst_counter_dly;
280    always @(Mode_reg or Burst_counter) begin
281       if (Mode_reg[6:4] == 3'b010) begin
282// Burst_counter_dly <= #tAC2_max Burst_counter;
283       end else if (Mode_reg[6:4] == 3'b011) begin
284// Burst_counter_dly <= #tAC3_max Burst_counter;
285       end
286    end
287
288    // Precharge variables
289    reg Pc_b0, Pc_b1, Pc_b2, Pc_b3;
290
291    // Activate variables
292    reg Act_b0, Act_b1, Act_b2, Act_b3;
293
294    // Data IO variables
295// reg Data_in_enable;
296    wire Data_in_enable = Write_pipeline[-2];
297// reg Data_out_enable;
298    wire Data_out_enable = Read_pipeline[0];
299    wire tWTR_en = ((|Write_pipeline[`MAX_PIPE : 0]) & ~(&Dm));
300
301    // Data Out Enable delay
302// reg Data_out_enable_dly;
303// always @(Mode_reg or Data_out_enable) begin
304// if (Mode_reg[6:4] == 3'b010) begin
305// Data_out_enable_dly <= #tAC2_max Data_out_enable;
306// end else if (Mode_reg[6:4] == 3'b011) begin
307// Data_out_enable_dly <= #tAC3_max Data_out_enable;
308// end
309// end
310
311    // Internal address mux variables
312    reg [1 : 0] Prev_bank;
313    reg [1 : 0] Bank_addr;
314    reg [COL_BITS - 1 : 0] Cols_addr, Cols_brst, Cols_temp;
315    reg [ADDR_BITS - 1 : 0] Rows_addr;
316    reg [ADDR_BITS - 1 : 0] B0_row_addr;
317    reg [ADDR_BITS - 1 : 0] B1_row_addr;
318    reg [ADDR_BITS - 1 : 0] B2_row_addr;
319    reg [ADDR_BITS - 1 : 0] B3_row_addr;
320
321    integer aref_count;
322    reg ext_mode_load_done;
323    reg mode_load_done;
324    reg power_up_done;
325
326    // Write DQS for tDSS , tDSH, tDQSH, tDQSL checks
327    wire wdqs_valid = Write_pipeline[`MAX_PIPE:0];
328
329    // Commands Decode
330    wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
331    wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n & Cke;
332    wire Sref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n & ~Cke;
333    wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
334    wire Ext_mode_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & Ba[1] & ~Ba[0];
335    wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & ~Ba[1] & ~Ba[0];
336    wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
337    wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
338    wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
339    wire DPD_enable = ~Cs_n & Ras_n & Cas_n & ~We_n & ~Cke;
340    wire PD_enable = ((~Cs_n & Ras_n & Cas_n & We_n) | Cs_n) & ~Cke;
341    wire nop_enable = ~Cs_n & Ras_n & Cas_n & We_n ;
342    wire des_enable = Cs_n ;
343    wire srr_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & ~Ba[1] & Ba[0] & ((part_size==128)|(part_size==512)|(part_size==1024)) ;
344
345    reg Cke_Chk = 0 ;
346    parameter tInit = 200000 ;
347    reg Cke_Print = 1'b0 ;
348    real Init_Cmd_Chk ;
349
350
351    // Burst Length Decode
352// reg [4:0] burst_length = 1 << (Mode_reg[2:0]);
353    reg [4:0] burst_length ;
354    reg read_precharge_truncation;
355
356    // CAS Latency Decode
357    wire [2:0] cas_latency = Mode_reg[6:4] ;
358    wire [2:0] cas_latency_x2 = ((2*Mode_reg[6:4])-1);
359
360    real tAC_max ;
361    always @ (Mode_reg)
362    begin
363        if (Mode_reg[6:4] == 3'b011)
364            tAC_max = tAC3_max ;
365        else if (Mode_reg[6:4] == 3'b010)
366            tAC_max = tAC2_max ;
367    end
368
369    // DQS Buffer
370    reg [DQS_BITS - 1 : 0] dqs_delayed ;
371// always@* begin
372// dqs_delayed <= Dqs_out ;
373// end
374
375    assign Dqs = (Dqs_out_en) ? {DQS_BITS{Dqs_out}} : 'bz;
376    assign Dq = (Dq_out_en ) ? Dq_out : 'bz;
377
378    // Debug message
379    wire Debug = 1'b0;
380
381    // Timing Check
382// realtime MRD_chk;
383    realtime RFC_chk;
384    realtime RRD_chk;
385    realtime RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
386    realtime RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3;
387    realtime RC_chk0, RC_chk1, RC_chk2, RC_chk3;
388    realtime RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
389    realtime RP_chk0, RP_chk1, RP_chk2, RP_chk3;
390    realtime WR_chk0, WR_chk1, WR_chk2, WR_chk3;
391    realtime SRR_chk;
392
393    //
394    reg [2:0] current_init_state ;
395    parameter [2:0] begin_init = 3'b000 ;
396    parameter [2:0] cke_init = 3'b001 ;
397    parameter [2:0] prech_init = 3'b010 ;
398    parameter [2:0] begin_mode_init = 3'b011 ;
399    parameter [2:0] mode_init = 3'b100 ;
400    parameter [2:0] ext_mode_init = 3'b101 ;
401    parameter [2:0] mode_done_init = 3'b110 ;
402
403    initial begin
404        CkeZ = 1'b0;
405        Sys_clk = 1'b0;
406        {Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b0000;
407        {Act_b0, Act_b1, Act_b2, Act_b3} = 4'b1111;
408// Dqs_int = 1'b0;
409        Dqs_out_en = {DQS_BITS{1'b0}};
410        Dqs_out = {DQS_BITS{1'bz}};
411// Dqs_gen = {DQS_BITS{1'bz}};
412        Dq_out = {DQ_BITS{1'bz}};
413        Dq_out_en = {DQ_BITS{1'b0}};
414// dq_delayed = {DQ_BITS{1'bz}};
415// Data_in_enable = 1'b0;
416// Data_out_enable = 1'b0;
417        aref_count = 0;
418        SelfRefresh = 1'b0;
419        power_up_done = 0;
420        ext_mode_load_done = 0;
421        mode_load_done = 0;
422// MRD_chk = 0;
423        RFC_chk = 0;
424        RRD_chk = 0;
425        RAS_chk0 = 0;
426        RAS_chk1 = 0;
427        RAS_chk2 = 0;
428        RAS_chk3 = 0;
429        RAP_chk0 = 0;
430        RAP_chk1 = 0;
431        RAP_chk2 = 0;
432        RAP_chk3 = 0;
433        RC_chk0 = 0;
434        RC_chk1 = 0;
435        RC_chk2 = 0;
436        RC_chk3 = 0;
437        RCD_chk0 = 0;
438        RCD_chk1 = 0;
439        RCD_chk2 = 0;
440        RCD_chk3 = 0;
441        RP_chk0 = 0;
442        RP_chk1 = 0;
443        RP_chk2 = 0;
444        RP_chk3 = 0;
445        WR_chk0 = 0;
446        WR_chk1 = 0;
447        WR_chk2 = 0;
448        WR_chk3 = 0;
449        SRR_chk = 0;
450        $timeformat (-9, 3, " ns", 12);
451        pos_clk_time = 0;
452        neg_clk_time = 0;
453        enter_DPD = 0;
454        enter_PD = 0;
455        enter_APD = 0;
456        current_init_state = begin_init ;
457        SRR_read = 1'b0;
458        MRD_cntr = 8;
459        SRR_cntr = 8;
460        SRC_cntr = 8;
461        tWTR_cntr = 8;
462        Read_precharge_access[0] = 1'b0 ;
463        Read_precharge_access[1] = 1'b0 ;
464        Read_precharge_access[2] = 1'b0 ;
465        Read_precharge_access[3] = 1'b0 ;
466        Read_precharge_pre[0] = 1'b0 ;
467        Read_precharge_pre[1] = 1'b0 ;
468        Read_precharge_pre[2] = 1'b0 ;
469        Read_precharge_pre[3] = 1'b0 ;
470        Write_precharge_access[0] = 1'b0 ;
471        Write_precharge_access[1] = 1'b0 ;
472        Write_precharge_access[2] = 1'b0 ;
473        Write_precharge_access[3] = 1'b0 ;
474        Write_precharge_pre[0] = 1'b0 ;
475        Write_precharge_pre[1] = 1'b0 ;
476        Write_precharge_pre[2] = 1'b0 ;
477        Write_precharge_pre[3] = 1'b0 ;
478        wr_ap_display_msg = 1'b0 ;
479        rd_ap_display_msg = 1'b0 ;
480        Read_precharge_count[0] = 4'hf;
481        Read_precharge_count[1] = 4'hf;
482        Read_precharge_count[2] = 4'hf;
483        Read_precharge_count[3] = 4'hf;
484        Write_precharge_count[0] = 4'hf;
485        Write_precharge_count[1] = 4'hf;
486        Write_precharge_count[2] = 4'hf;
487        Write_precharge_count[3] = 4'hf;
488    end
489
490    // make sure 200 us has passed since cke for first command
491    always @ (Clk_Chk_enable or nop_enable or des_enable)
492    begin
493        if (~Clk_Chk_enable) begin
494            if (~nop_enable & ~des_enable) begin
495                Clk_Chk_enable = 1'b1 ;
496                if (~Cke_Chk) begin
497                    if (($realtime - Init_Cmd_Chk < tInit - 0.001) & ~Cke_Print) begin
498                        $display("Warning: You must wait 200 us from CKE assertion before you perform a command. Current wait time: %3.0f ns", $realtime - (Init_Cmd_Chk));
499                        Cke_Print = 1'b1 ;
500                    end
501                end
502            end
503        end
504    end
505
506    // Check for tCH, tCK, and clock stop mode
507    always @(diff_ck) begin
508        if (diff_ck) begin
509            neg_clk_time = $realtime - neg_clk_edge ;
510        end
511        if (~diff_ck) begin
512            pos_clk_time = $realtime - pos_clk_edge ;
513        end
514        if (Cke & Clk_Chk_enable) begin
515            // clock stop mode when either pulse width is 2x bigger than the other (reasonable assumption???)
516            clock_stop = ((pos_clk_time / neg_clk_time > 2) | (neg_clk_time / pos_clk_time > 2));
517
518            // Check if NOP/DES when enter/exit clock stop mode
519            if ((clock_stop && diff_ck) && (~(prev_nop || prev_des) || ~(nop_enable || des_enable))) begin
520                $display ("%m: at time %t ERROR: Nop or Deselect is required when enter or exit Stop Clock Mode", $time);
521            end
522
523            if ((pos_clk_time / clk_period < tCH_MIN) && ~clock_stop) begin
524                $display ("%m: at time %t ERROR: tCH minimum violation on CLK by %t", $time, tCH_MIN*clk_period - pos_clk_time);
525            end
526            if ((pos_clk_time / clk_period > tCH_MAX) && ~clock_stop) begin
527                $display ("%m: at time %t ERROR: tCH maximum violation on CLK by %t", $time, pos_clk_time - tCH_MAX*clk_period);
528            end
529            if ((neg_clk_time / clk_period < tCL_MIN) && ~clock_stop) begin
530                $display ("%m: at time %t ERROR: tCL minimum violation on CLK by %t", $time, tCL_MIN*clk_period - pos_clk_time);
531            end
532            if ((neg_clk_time / clk_period > tCL_MAX) && ~clock_stop) begin
533                $display ("%m: at time %t ERROR: tCL maximum violation on CLK by %t", $time, pos_clk_time - tCL_MAX*clk_period);
534            end
535        end
536    end
537
538    //clock Frequency Check
539    always @(posedge diff_ck) begin
540        if (clk_pos_edge_cnt > 1) begin
541            if (Mode_reg[6:4] == 3'b011) begin
542                if (clk_period < (tCK3_min-0.001)) begin
543                    $display ("%m : at time %t ERROR : Illegal clk period for CAS Latency 3", $realtime);
544                    $display ("%m : at time %t CLK PERIOD = %t", $realtime, clk_period);
545                end
546            end
547            if (Mode_reg[6:4] == 3'b010) begin
548                if (clk_period < (tCK2_min-0.001)) begin
549                    $display ("%m : at time %t ERROR : Illegal clk period for CAS Latency 2", $realtime);
550                    $display ("%m : at time %t CLK PERIOD = %t", $realtime, clk_period);
551                end
552            end
553        end
554    end
555
556    //SRR reg settings
557    always @(posedge power_up_done) begin
558        Srr_reg = 'b0 ;
559        Srr_reg[3:0] = 4'b1111 ; //Manufacturer(Micron)
560        Srr_reg[7:4] = 4'b0000 ; //Revision ID(Default to 0 in model)
561        Srr_reg[10:8] = 3'b100 ; //Refresh Rate(based on temp sensor - will default to 1x in model)
562        Srr_reg[11] = (DQ_BITS == 32)? 1'b1 : 1'b0 ; //Part width(x32 or x16)
563        Srr_reg[12] = 1'b0 ; //Device Type (LP DDR)
564        Srr_reg[15:13] = (part_size == 1024)? 3'b011 :
565                         (part_size == 512 )? 3'b010 :
566                         (part_size == 256 )? 3'b001 :
567                                              3'b000 ; //Density(1024Mb, 512Mb, 256Mb, 128Mb)
568    end
569
570    // System Clock
571    always begin
572        @ (posedge diff_ck) begin
573            Sys_clk = CkeZ;
574            CkeZ = Cke;
575        end
576        @ (negedge diff_ck) begin
577            Sys_clk = 1'b0;
578        end
579    end
580
581    task store_prev_cmd;
582    begin
583        prev_Cs_n <= Cs_n ;
584        prev_Ras_n <= Ras_n ;
585        prev_Cas_n <= Cas_n ;
586        prev_We_n <= We_n ;
587        prev_Ba[1] <= Ba[1] ;
588        prev_Ba[0] <= Ba[0] ;
589        prev_cke <= Cke ;
590    end
591    endtask
592
593    task MRD_counter;
594    begin
595        if (Cke) begin
596            if (MRD_cntr < tMRD) begin
597                MRD_cntr = MRD_cntr + 1'b1;
598            end
599        end
600    end
601    endtask
602
603    task SRR_counter;
604    begin
605        if (Cke) begin
606            if (SRR_cntr < tSRR) begin
607                SRR_cntr = SRR_cntr + 1'b1;
608            end
609        end
610    end
611    endtask
612
613    task SRC_counter;
614    begin
615        if (Cke) begin
616            if (SRC_cntr < ((Mode_reg[6:4])+1)) begin
617                SRC_cntr = SRC_cntr + 1'b1;
618            end
619        end
620    end
621    endtask
622
623    task tWTR_counter;
624    begin
625        if (Cke) begin
626            if (tWTR_en) begin
627                tWTR_cntr = 0 ;
628            end else begin
629                tWTR_cntr = tWTR_cntr + 1'b1;
630            end
631        end
632    end
633    endtask
634
635    task command_counter;
636    begin
637        if (Cke) begin
638            for (i=0; i<4;i=i+1) begin
639                if (Read_precharge_count[i] < 4'hf) begin
640                    Read_precharge_count[i] = Read_precharge_count[i] + 1'b1;
641                end
642            end
643            for (i=0; i<4;i=i+1) begin
644                if (Write_precharge_count[i] < 4'hf) begin
645                    Write_precharge_count[i] = Write_precharge_count[i] + 1'b1;
646                end
647            end
648        end
649    end
650    endtask
651
652
653    task PD_counter;
654    begin
655        if (~Cke) begin
656            if (PD_cntr < tCKE) begin
657                PD_cntr = PD_cntr + (enter_DPD | enter_PD | DPD_enable | PD_enable);
658            end
659        end else begin
660            PD_cntr = 4'h0 ;
661        end
662    end
663    endtask
664
665    task tXP_check;
666    begin
667        if (Cke == 1'b1 && prev_cke == 1'b0) begin
668            tXP_chk = $realtime ;
669        end
670        if (Cke) begin
671            if (~nop_enable && ~des_enable) begin
672                if ($realtime-tXP_chk < tXP - 0.001) begin
673`ifdef T25L
674                    $display ("%m: At time %t ERROR: tPDX violation", $realtime);
675`else
676                    $display ("%m: At time %t ERROR: tXP violation", $realtime);
677`endif
678                end
679            end
680        end
681    end
682    endtask
683
684    // DPD pos edge clk cntr
685    always begin
686        @ (posedge diff_ck) begin
687            tXP_check ;
688            Power_down_chk ;
689            PD_counter ;
690            store_prev_cmd ;
691        end
692    end
693
694    // Check to make sure that we have a Deselect or NOP command on the bus when CKE is brought high
695    always @(Cke) begin
696        if (Cke === 1'b1) begin
697            Init_Cmd_Chk = $realtime ;
698            if (SelfRefresh === 1'b1) begin
699                SelfRefresh = 1'b0;
700            end
701            if (!((Cs_n) || (~Cs_n & Ras_n & Cas_n & We_n))) begin
702                $display ("%m: At time %t MEMORY ERROR: You must have a Deselect or NOP command applied", $realtime);
703                $display ("%m: when the Clock Enable is brought High.");
704            end
705        end
706    end
707
708    //BL Mode Reg settings
709    always@(Mode_reg[2:0] or mode_load_done) begin
710        if (mode_load_done) begin
711            case (Mode_reg[2:0])
712                3'b001 : burst_length = 5'b00010;
713                3'b010 : burst_length = 5'b00100;
714                3'b011 : burst_length = 5'b01000;
715                3'b100 : burst_length = 5'b10000;
716                default : burst_length = 5'bxxxxx;
717            endcase
718        end
719    end
720
721// Init sequence
722always @(current_init_state or Cke or Prech_enable or ext_mode_load_done or mode_load_done or aref_count) begin
723    if (current_init_state == begin_init) begin
724        if (Cke) begin
725            current_init_state = cke_init ;
726            power_up_done = 1'b0 ;
727        end
728    end
729    if (current_init_state == cke_init) begin
730        if (Prech_enable) begin
731            current_init_state = prech_init ;
732            aref_count = 0 ;
733        end
734    end
735    if (current_init_state == prech_init) begin
736        if (~Prech_enable) begin
737            current_init_state = begin_mode_init ;
738        end
739    end
740    if (current_init_state == begin_mode_init) begin
741        if (ext_mode_load_done) begin
742            current_init_state = ext_mode_init ;
743        end
744        if (mode_load_done) begin
745            current_init_state = mode_init ;
746        end
747    end
748    if (current_init_state == mode_init) begin
749        if (ext_mode_load_done) begin
750            current_init_state = mode_done_init ;
751        end
752    end
753    if (current_init_state == ext_mode_init) begin
754        if (mode_load_done) begin
755            current_init_state = mode_done_init ;
756        end
757    end
758    if (current_init_state == mode_done_init && aref_count >= 2) begin
759        power_up_done = 1'b1;
760    end
761end
762
763
764    // this task will erase the contents of 0 or more banks
765    task erase_mem;
766        input [BA_BITS+1:0] bank_MSB_row; //bank bits + 2 row MSB
767        input DPD_mode ; //erase all memory locations
768        integer i;
769        begin
770
771            if (DPD_mode) begin
772`ifdef FULL_MEM
773                for (i=0; i<{(BA_BITS+ROW_BITS+COL_BITS){1'b1}}; i=i+1) begin
774                    mem_array[i] = 'bx;
775                end
776`else
777                memory_index = 0;
778                i = 0;
779                // remove the selected banks
780                for (memory_index=0; memory_index<mem_used; memory_index=memory_index+1) begin
781                    addr_array[i] = 'bx;
782                    mem_array[i] = 'bx;
783                    i = i + 1;
784                end
785`endif
786            end else begin
787`ifdef FULL_MEM
788                for (i={bank_MSB_row, {(ROW_BITS+COL_BITS-2){1'b1}}}; i<={1'b0, {(BA_BITS+ROW_BITS+COL_BITS){1'b1}}}; i=i+1) begin
789                    mem_array[i] = 'bx;
790                end
791`else
792                memory_index = 0;
793                i = 0;
794                // remove the selected banks
795                for (memory_index=0; memory_index<mem_used; memory_index=memory_index+1) begin
796                    if (addr_array[memory_index]>({bank_MSB_row, {(ROW_BITS+COL_BITS-2){1'b1}}})) begin
797                        addr_array[i] = 'bx;
798                        mem_array[i] = 'bx;
799                        i = i + 1;
800                    end else begin
801                        i = i + 1;
802                    end
803                end
804`endif
805            end
806        end
807    endtask
808
809    // Write Memory
810    task write_mem;
811        input [full_mem_bits - 1 : 0] addr;
812        input [DQ_BITS - 1 : 0] data;
813        reg [part_mem_bits : 0] i;
814        begin
815`ifdef FULL_MEM
816            mem_array[addr] = data;
817`else
818            begin : loop
819                for (i = 0; i < mem_used; i = i + 1) begin
820                    if (addr_array[i] === addr) begin
821                        disable loop;
822                    end
823                end
824            end
825            if (i === mem_used) begin
826                if (i === (1<<part_mem_bits)) begin
827                    $display ("%m: At time %t ERROR: Memory overflow.\n Write to Address %d with Data %d will be lost.\n You must increase the part_mem_bits parameter or `define FULL_MEM.", $realtime, addr, data);
828                end else begin
829                    mem_used = mem_used + 1;
830                    addr_array[i] = addr;
831                end
832            end
833            mem_array[i] = data;
834`endif
835        end
836    endtask
837
838    // Read Memory
839    task read_mem;
840        input [full_mem_bits - 1 : 0] addr;
841        output [DQ_BITS - 1 : 0] data;
842        reg [part_mem_bits : 0] i;
843        begin
844`ifdef FULL_MEM
845            data = mem_array[addr];
846`else
847            begin : loop
848                for (i = 0; i < mem_used; i = i + 1) begin
849                    if (addr_array[i] === addr) begin
850                        disable loop;
851                    end
852                end
853            end
854            if (i <= mem_used) begin
855                data = mem_array[i];
856            end else begin
857                data = 'bx;
858            end
859`endif
860        end
861    endtask
862
863    // Burst Decode
864    task Burst_Decode;
865    begin
866
867        // Advance Burst Counter
868// if (Burst_counter < burst_length) begin
869        if (Write_pipeline[-2]) begin
870            Burst_counter = Burst_counter + 1;
871        end
872
873        // Burst Type
874        if (Mode_reg[3] === 1'b0) begin // Sequential Burst
875            Cols_temp = Cols_addr + 1;
876        end else if (Mode_reg[3] === 1'b1) begin // Interleaved Burst
877            Cols_temp[2] = Burst_counter[2] ^ Cols_brst[2];
878            Cols_temp[1] = Burst_counter[1] ^ Cols_brst[1];
879            Cols_temp[0] = Burst_counter[0] ^ Cols_brst[0];
880        end
881
882        // Burst Length
883        if (burst_length === 2) begin
884            Cols_addr [0] = Cols_temp [0];
885        end else if (burst_length === 4) begin
886            Cols_addr [1 : 0] = Cols_temp [1 : 0];
887        end else if (burst_length === 8) begin
888            Cols_addr [2 : 0] = Cols_temp [2 : 0];
889        end else if (burst_length === 16) begin
890            Cols_addr [3 : 0] = Cols_temp [3 : 0];
891        end else begin
892            Cols_addr = Cols_temp;
893        end
894
895        // Data Counter
896// if (Burst_counter >= burst_length) begin
897// Data_in_enable = 1'b0;
898// Data_out_enable = 1'b0;
899// read_precharge_truncation = 1'b0;
900// SRR_read = 1'b0;
901// end
902    end
903    endtask
904
905
906    // SRC check
907    task Timing_chk_SRC;
908    begin
909        if (Active_enable || Aref_enable || Sref_enable || Burst_term ||
910            Ext_mode_enable || Mode_reg_enable || Prech_enable || Read_enable ||
911            Write_enable || DPD_enable || PD_enable || srr_enable) begin
912               if (part_size == 1024) begin
913                   if (SRC_cntr < ((Mode_reg[6:4])+tSRC)) begin
914                       $display ("%m: At time %t ERROR: tSRC Violation", $realtime);
915                   end
916               end
917        end
918    end
919    endtask
920
921    task ShiftPipelines;
922    begin
923        // read command pipeline
924        Read_pipeline = Read_pipeline >> 1;
925        Write_pipeline = Write_pipeline >> 1;
926        for (i = -2; i < `MAX_PIPE-1; i = i + 1)
927        begin
928            Write_col_pipeline [i] = Write_col_pipeline[i+1];
929            Write_bank_pipeline [i] = Write_bank_pipeline[i+1];
930        end
931    end
932    endtask
933
934    // Dq and Dqs Drivers
935    task Dq_Dqs_Drivers;
936    begin
937
938        // Initialize Read command
939        if (Read_pipeline [0] === 1'b1) begin
940// Data_out_enable = 1'b1;
941            Bank_addr = Write_bank_pipeline[0];
942            Cols_addr = Write_col_pipeline [0];
943            Cols_brst = Cols_addr [2 : 0];
944// if (SRR_read == 1'b1) begin
945// Burst_counter = burst_length - 2;
946// end else begin
947// Burst_counter = 0;
948// end
949
950            // Row Address Mux
951            case (Bank_addr)
952                2'd0 : Rows_addr = B0_row_addr;
953                2'd1 : Rows_addr = B1_row_addr;
954                2'd2 : Rows_addr = B2_row_addr;
955                2'd3 : Rows_addr = B3_row_addr;
956                default : $display ("%m: At time %t ERROR: Invalid Bank Address", $realtime);
957            endcase
958        end
959
960        // Read latch
961        if (Read_pipeline[0] === 1'b1) begin
962            // output data
963            if (SRR_read == 1'b1) begin
964                if (Cols_addr == 0) begin
965                    Dq_out_temp = Srr_reg[DQ_BITS-1:0];
966                end else begin
967                    Dq_out_temp = Srr_reg[2*DQ_BITS-1:DQ_BITS];
968                    SRR_read = 1'b0 ;
969                end
970            end else begin
971                read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_out_temp);
972            end
973            if (Debug) begin
974                $display ("At time %t %m:READ: Bank = %d, Row = %d, Col = %d, Data = %d", $realtime, Bank_addr, Rows_addr, Cols_addr, Dq_out);
975            end
976
977        end
978
979        Dq_out <= #(tAC_max) Dq_out_temp ;
980        Dqs_out <= #(tAC_max) ((|Read_pipeline[0]) & Sys_clk) ;
981
982        if (cas_latency == 3)
983            Dqs_out_en <= #(tAC_max) (|Read_pipeline[2:0]);
984        else
985            Dqs_out_en <= #(tAC_max) (|Read_pipeline[1:0]);
986        if (Sys_clk) begin
987            Dq_out_en <= #(tAC_max) (Read_pipeline[0]);
988        end
989
990    end
991    endtask
992
993    // Write FIFO and DM Mask Logic
994    task Write_FIFO_DM_Mask_Logic;
995    begin
996
997        // Initialize Write command
998        if (Write_pipeline [-2] === 1'b1) begin
999// Data_in_enable = 1'b1;
1000            Bank_addr = Write_bank_pipeline [-2];
1001            Cols_addr = Write_col_pipeline [-2];
1002            Cols_brst = Cols_addr [2 : 0];
1003// Burst_counter = 0;
1004
1005            // Row address mux
1006            case (Bank_addr)
1007                2'd0 : Rows_addr = B0_row_addr;
1008                2'd1 : Rows_addr = B1_row_addr;
1009                2'd2 : Rows_addr = B2_row_addr;
1010                2'd3 : Rows_addr = B3_row_addr;
1011                default : $display ("%m: At time %t ERROR: Invalid Row Address", $realtime);
1012            endcase
1013        end
1014
1015        // Write data
1016// if (Data_in_enable === 1'b1) begin
1017        if (Write_pipeline[-2] === 1'b1) begin
1018
1019            // Data Buffer
1020            read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf);
1021
1022            // write negedge Dqs on posedge Sys_clk
1023            if (Sys_clk) begin
1024                if (!dm_fall[0]) begin
1025                    Dq_buf [ 7 : 0] = dq_fall [ 7 : 0];
1026                end
1027                if (!dm_fall[1]) begin
1028                    Dq_buf [15 : 8] = dq_fall [15 : 8];
1029                end
1030`ifdef x32
1031                if (!dm_fall[2]) begin
1032                    Dq_buf [23 : 16] = dq_fall [23 : 16];
1033                end
1034                if (!dm_fall[3]) begin
1035                    Dq_buf [31 : 24] = dq_fall [31 : 24];
1036                end
1037`endif
1038                if (~&dm_fall) begin
1039                    if (Debug) begin
1040                        $display ("At time %t %m:WRITE: Bank = %d, Row = %d, Col = %d, Data = %h", $realtime, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]);
1041                    end
1042                end
1043            // write posedge Dqs on negedge Sys_clk
1044            end else begin
1045                if (!dm_rise[0]) begin
1046                    Dq_buf [ 7 : 0] = dq_rise [ 7 : 0];
1047                end
1048                if (!dm_rise[1]) begin
1049                    Dq_buf [15 : 8] = dq_rise [15 : 8];
1050                end
1051`ifdef x32
1052                if (!dm_rise[2]) begin
1053                    Dq_buf [23 : 16] = dq_rise [23 : 16];
1054                end
1055                if (!dm_rise[3]) begin
1056                    Dq_buf [31 : 24] = dq_rise [31 : 24];
1057                end
1058`endif
1059                if (~&dm_rise) begin
1060                    if (Debug) begin
1061                        $display ("At time %t %m:WRITE: Bank = %d, Row = %d, Col = %d, Data = %h", $realtime, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]);
1062                    end
1063                end
1064            end
1065
1066            // Write Data
1067            write_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf);
1068            // tWR start and tWTR check
1069            if (Sys_clk && &dm_pair === 1'b0) begin
1070                case (Bank_addr)
1071                    2'd0 : WR_chk0 = $realtime;
1072                    2'd1 : WR_chk1 = $realtime;
1073                    2'd2 : WR_chk2 = $realtime;
1074                    2'd3 : WR_chk3 = $realtime;
1075                    default : $display ("%m: At time %t ERROR: Invalid Bank Address (tWR)", $realtime);
1076                endcase
1077
1078// // tWTR check
1079// if (Read_enable === 1'b1) begin
1080// $display ("%m: At time %t ERROR: tWTR violation during Read", $realtime);
1081// end
1082            end
1083        end
1084    end
1085    endtask
1086
1087    // Auto Precharge Calculation
1088    task Auto_Precharge_Calculation;
1089    begin
1090        // Precharge counter
1091        if (Read_precharge_access [0] === 1'b1 || Write_precharge_access [0] === 1'b1) begin
1092            Count_precharge [0] = Count_precharge [0] + 1;
1093        end
1094        if (Read_precharge_access [1] === 1'b1 || Write_precharge_access [1] === 1'b1) begin
1095            Count_precharge [1] = Count_precharge [1] + 1;
1096        end
1097        if (Read_precharge_access [2] === 1'b1 || Write_precharge_access [2] === 1'b1) begin
1098            Count_precharge [2] = Count_precharge [2] + 1;
1099        end
1100        if (Read_precharge_access [3] === 1'b1 || Write_precharge_access [3] === 1'b1) begin
1101            Count_precharge [3] = Count_precharge [3] + 1;
1102        end
1103
1104        // Read with AutoPrecharge Calculation
1105        // The device start internal precharge when:
1106        // 1. BL/2 cycles after command
1107        // 2. Meet tRAS requirement
1108        if (Read_precharge_access[0] & (Count_precharge[0] >= burst_length/2)) begin
1109            Read_precharge_access[0] = 1'b0 ;
1110            Read_precharge_pre[0] = 1'b1 ;
1111        end
1112        if ((Read_precharge_pre[0] === 1'b1) && ($realtime - RAS_chk0 >= tRAS - 0.001)) begin
1113            Pc_b0 = 1'b1;
1114            Act_b0 = 1'b0;
1115            RP_chk0 = $realtime;
1116            Read_precharge_pre[0] = 1'b0;
1117        end
1118
1119        if (Read_precharge_access[1] & (Count_precharge[1] >= burst_length/2)) begin
1120            Read_precharge_access[1] = 1'b0 ;
1121            Read_precharge_pre[1] = 1'b1 ;
1122        end
1123        if ((Read_precharge_pre[1] === 1'b1) && ($realtime - RAS_chk1 >= tRAS - 0.001)) begin
1124            Pc_b1 = 1'b1;
1125            Act_b1 = 1'b0;
1126            RP_chk1 = $realtime;
1127            Read_precharge_pre[1] = 1'b0;
1128        end
1129
1130        if (Read_precharge_access[2] & (Count_precharge[2] >= burst_length/2)) begin
1131            Read_precharge_access[2] = 1'b0 ;
1132            Read_precharge_pre[2] = 1'b1 ;
1133        end
1134        if ((Read_precharge_pre[2] === 1'b1) && ($realtime - RAS_chk2 >= tRAS - 0.001)) begin
1135            Pc_b2 = 1'b1;
1136            Act_b2 = 1'b0;
1137            RP_chk2 = $realtime;
1138            Read_precharge_pre[2] = 1'b0;
1139        end
1140
1141        if (Read_precharge_access[3] & (Count_precharge[3] >= burst_length/2)) begin
1142            Read_precharge_access[3] = 1'b0 ;
1143            Read_precharge_pre[3] = 1'b1 ;
1144        end
1145        if ((Read_precharge_pre[3] === 1'b1) && ($realtime - RAS_chk3 >= tRAS - 0.001)) begin
1146            Pc_b3 = 1'b1;
1147            Act_b3 = 1'b0;
1148            RP_chk3 = $realtime;
1149            Read_precharge_pre[3] = 1'b0;
1150        end
1151
1152        // Write with AutoPrecharge Calculation
1153        // The device start internal precharge when:
1154        // 1. Meet tRAS requirement
1155        // 2. Two clock after last burst
1156        // Since tWR is time base, the model will compensate tRP
1157        if (Write_precharge_access[0] & (Count_precharge[0] >= burst_length/2+3)) begin
1158            Write_precharge_access[0] = 1'b0 ;
1159            Write_precharge_pre[0] = 1'b1 ;
1160        end
1161        if (Write_precharge_pre[0] & ($realtime - RAS_chk0 >= tRAS - 0.001)) begin
1162                Write_precharge_pre[0] = 1'b0;
1163                Pc_b0 = 1'b1;
1164                Act_b0 = 1'b0;
1165                RP_chk0 = $realtime - ((2 * clk_period) - tWR);
1166        end
1167
1168        if (Write_precharge_access[1] & (Count_precharge[1] >= burst_length/2+3)) begin
1169            Write_precharge_access[1] = 1'b0 ;
1170            Write_precharge_pre[1] = 1'b1 ;
1171        end
1172        if (Write_precharge_pre[1] & ($realtime - RAS_chk1 >= tRAS - 0.001)) begin
1173                Write_precharge_pre[1] = 1'b0;
1174                Pc_b1 = 1'b1;
1175                Act_b1 = 1'b0;
1176                RP_chk1 = $realtime - ((2 * clk_period) - tWR);
1177        end
1178
1179        if (Write_precharge_access[2] & (Count_precharge[2] >= burst_length/2+3)) begin
1180            Write_precharge_access[2] = 1'b0 ;
1181            Write_precharge_pre[2] = 1'b1 ;
1182        end
1183        if (Write_precharge_pre[2] & ($realtime - RAS_chk2 >= tRAS - 0.001)) begin
1184                Write_precharge_pre[2] = 1'b0;
1185                Pc_b2 = 1'b1;
1186                Act_b2 = 1'b0;
1187                RP_chk2 = $realtime - ((2 * clk_period) - tWR);
1188        end
1189
1190        if (Write_precharge_access[3] & (Count_precharge[3] >= burst_length/2+3)) begin
1191            Write_precharge_access[3] = 1'b0 ;
1192            Write_precharge_pre[3] = 1'b1 ;
1193        end
1194        if (Write_precharge_pre[3] & ($realtime - RAS_chk3 >= tRAS - 0.001)) begin
1195                Write_precharge_pre[3] = 1'b0;
1196                Pc_b3 = 1'b1;
1197                Act_b3 = 1'b0;
1198                RP_chk3 = $realtime - ((2 * clk_period) - tWR);
1199        end
1200    end
1201    endtask
1202
1203    task Power_down_chk;
1204    begin
1205        if (DPD_enable == 1'b1 && enter_DPD == 1'b0) begin
1206            if (prev_cke & Pc_b0 & Pc_b1 & Pc_b2 & Pc_b3) begin
1207                erase_mem(4'b0000, 1'b1);
1208                current_init_state = begin_init ;
1209                ext_mode_load_done = 1'b0 ;
1210                mode_load_done = 1'b0 ;
1211                enter_DPD = 1'b1;
1212                $display ("%m: at time %t Entering Deep Power-Down Mode", $realtime);
1213            end
1214        end
1215        if (enter_DPD == 1'b1) begin
1216            if (Cke == 1'b1 && prev_cke == 1'b0) begin
1217                if (PD_cntr < tCKE) begin
1218                    $display ("%m: At time %t ERROR: tCKE violation during exiting of Deep Power-Down Mode", $realtime);
1219                end
1220                $display ("%m: at time %t Exiting Deep Power-Down Mode - A 200 us delay is required with either DESELECT or NOP commands present before the initialization sequence may begin", $realtime);
1221                enter_DPD = 1'b0;
1222            end
1223        end
1224        if (PD_enable == 1'b1 && enter_PD == 1'b0) begin
1225            if (prev_cke) begin
1226                if (Pc_b0 & Pc_b1 & Pc_b2 & Pc_b3) begin
1227                    $display ("%m: at time %t Entering Power-Down Mode", $realtime);
1228                    enter_PD = 1'b1;
1229                end else if (~Pc_b0 | ~Pc_b1 | ~Pc_b2 | ~Pc_b3) begin
1230                    $display ("%m: at time %t Entering Active Power-Down Mode", $realtime);
1231                    enter_APD = 1'b1;
1232                end
1233            end
1234        end
1235        if (enter_PD == 1'b1 || enter_APD == 1'b1) begin
1236            if (Cke == 1'b1 && prev_cke == 1'b0) begin
1237                if (PD_cntr < tCKE) begin
1238                    if (enter_PD == 1'b1) begin
1239                        $display ("%m: At time %t ERROR: tCKE violation during exiting of Power-Down Mode", $realtime);
1240                    end else if (enter_APD == 1'b1) begin
1241                        $display ("%m: At time %t ERROR: tCKE violation during exiting of Active Power-Down Mode", $realtime);
1242                    end
1243                end
1244                if (enter_PD == 1'b1) begin
1245                    $display ("%m: at time %t Exiting Power-Down Mode", $realtime);
1246                    enter_PD = 1'b0 ;
1247                end else if (enter_APD == 1'b1) begin
1248                    $display ("%m: at time %t Exiting Active Power-Down Mode", $realtime);
1249                    enter_APD = 1'b0 ;
1250                end
1251            end
1252        end
1253
1254    end
1255    endtask
1256
1257    reg [31:0] xx ;
1258    function [COL_BITS-1:0] Burst_Order;
1259        input [COL_BITS-1:0] Col;
1260        input [31:0] i;
1261    begin
1262        if (Mode_reg[3] == 1'b1) //interleaved
1263            Burst_Order = (Col & -1*burst_length) + (Col%burst_length ^ i);
1264        else // sequential
1265        begin
1266            xx = -1*burst_length;
1267            Burst_Order = (Col & xx) + (Col%burst_length + i) % (burst_length);
1268        end
1269    end
1270    endfunction
1271
1272    // Control Logic
1273    task Control_Logic;
1274    begin
1275
1276      // Self Refresh
1277        if (Sref_enable === 1'b1) begin
1278            // Partial Array Self Refresh
1279            if (part_size == 128) begin
1280                case (Ext_Mode_reg[2:0])
1281                    3'b000 : ;//keep Bank 0-7
1282                    3'b001 : begin $display("%m: at time %t INFO: Banks 2-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0111, 1'b0); end
1283                    3'b010 : begin $display("%m: at time %t INFO: Banks 1-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0011, 1'b0); end
1284                    3'b011 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1285                    3'b100 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1286                    3'b101 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1287                    3'b110 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1288                endcase
1289            end else begin
1290                case (Ext_Mode_reg[2:0])
1291                    3'b000 : ;//keep Bank 0-7
1292                    3'b001 : begin $display("%m: at time %t INFO: Banks 2-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0111, 1'b0); end
1293                    3'b010 : begin $display("%m: at time %t INFO: Banks 1-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0011, 1'b0); end
1294                    3'b011 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1295                    3'b100 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1296                    3'b101 : begin $display("%m: at time %t INFO: Banks 1-3 and 1/2 of bank 0 will be lost due to Partial Array Self Refresh", $realtime); erase_mem(4'b0001, 1'b0); end
1297                    3'b110 : begin $display("%m: at time %t INFO: Banks 1-3 and 3/4 of bank 0 will be lost due to Partial Array Self Refresh", $realtime); erase_mem(4'b0000, 1'b0); end
1298                endcase
1299            end
1300            SelfRefresh = 1'b1;
1301        end
1302        if (Aref_enable === 1'b1) begin
1303            if (Debug) begin
1304                $display ("Debug: At time %t %m:AUTOREFRESH: Auto Refresh", $realtime);
1305            end
1306            // aref_count is to make sure we have met part of the initialization sequence
1307            if (~power_up_done) begin
1308                aref_count = aref_count + 1;
1309            end
1310
1311            // Auto Refresh to Auto Refresh
1312            if ($realtime - RFC_chk < tRFC - 0.001) begin
1313                $display ("%m: At time %t ERROR: tRFC violation during Auto Refresh", $realtime);
1314            end
1315
1316            // Precharge to Auto Refresh
1317            if (($realtime - RP_chk0 < tRP - 0.001) || ($realtime - RP_chk1 < tRP - 0.001) ||
1318                ($realtime - RP_chk2 < tRP - 0.001) || ($realtime - RP_chk3 < tRP - 0.001)) begin
1319                $display ("%m: At time %t ERROR: tRP violation during Auto Refresh", $realtime);
1320            end
1321
1322            // Precharge to Auto Refresh
1323            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
1324                $display ("%m: At time %t ERROR: All banks must be Precharged before Auto Refresh", $realtime);
1325            end
1326
1327            // Record Current tRFC time
1328            RFC_chk = $realtime;
1329        end
1330
1331        // SRR Register
1332        if (srr_enable == 1'b1) begin
1333            if (Pc_b0 === 1'b1 && Pc_b1 === 1'b1 && Pc_b2 === 1'b1 && Pc_b3 === 1'b1 &&
1334                Data_out_enable === 1'b0 && Data_in_enable === 1'b0) begin
1335                SRR_read = 1'b1;
1336                SRR_chk = $realtime;
1337                SRR_cntr = 0;
1338            end
1339        end
1340
1341
1342        // Extended Mode Register
1343        if (Ext_mode_enable == 1'b1) begin
1344            if (Debug) begin
1345                $display ("Debug: At time %t %m:EMR : Extended Mode Register", $realtime);
1346            end
1347
1348            // Register Mode
1349            Ext_Mode_reg = Addr;
1350
1351            if (Pc_b0 === 1'b1 && Pc_b1 === 1'b1 && Pc_b2 === 1'b1 && Pc_b3 === 1'b1) begin
1352                // ensure that power sequence is met properly
1353                if (~power_up_done) begin
1354                    ext_mode_load_done = 1'b1;
1355                end
1356                $display ("At time %t %m:ELMR : Extended Load Mode Register", $realtime);
1357                if (part_size == 128) begin
1358                    // Self Refresh Coverage
1359                    case (Addr[2 : 0])
1360                        3'b000 : $display ("%m : Self Refresh Cov = 4 banks");
1361                        3'b001 : $display ("%m : Self Refresh Cov = 2 banks");
1362                        3'b010 : $display ("%m : Self Refresh Cov = 1 bank");
1363                        3'b101 : $display ("%m : PASR = Reserved");
1364                        3'b110 : $display ("%m : PASR = Reserved");
1365                        default : $display ("%m : PASR = Reserved");
1366                    endcase
1367                end else begin
1368                    // Self Refresh Coverage
1369                    case (Addr[2 : 0])
1370                        3'b000 : $display ("%m : Self Refresh Cov = 4 banks");
1371                        3'b001 : $display ("%m : Self Refresh Cov = 2 banks");
1372                        3'b010 : $display ("%m : Self Refresh Cov = 1 bank");
1373                        3'b101 : $display ("%m : Self Refresh Cov = 1/2 bank");
1374                        3'b110 : $display ("%m : Self Refresh Cov = 1/4 bank");
1375                        default : $display ("%m : PASR = Reserved");
1376                    endcase
1377                end
1378                // Maximum Case Temp
1379// case (Addr[4 : 3])
1380// 2'b11 : $display ("%m : Maximum Case Temp = 85C");
1381// 2'b00 : $display ("%m : Maximum Case Temp = 70C");
1382// 2'b01 : $display ("%m : Maximum Case Temp = 45C");
1383// 2'b10 : $display ("%m : Maximum Case Temp = 15C");
1384// endcase
1385
1386                // Drive Strength
1387                case (Addr[7 : 5])
1388                    3'b000 : $display ("%m : Drive Strength = Full Strength");
1389                    3'b001 : $display ("%m : Drive Strength = Half Strength");
1390                    3'b010 : $display ("%m : Drive Strength = Quarter Strength");
1391                    3'b011 : $display ("%m : Drive Strength = Three Quarter Strength");
1392                    3'b100 : $display ("%m : Drive Strength = Three Quarter Strength");
1393                endcase
1394
1395            end else begin
1396                $display ("%m: At time %t ERROR: all banks must be Precharged before Extended Mode Register", $realtime);
1397            end
1398
1399            // Precharge to EMR
1400            if (($realtime - RP_chk0 < tRP - 0.001) || ($realtime - RP_chk1 < tRP - 0.001) ||
1401                ($realtime - RP_chk2 < tRP - 0.001) || ($realtime - RP_chk3 < tRP - 0.001)) begin
1402                $display ("%m: At time %t ERROR: tRP violation during Extended Mode Register", $realtime);
1403            end
1404
1405            // LMR/EMR to LMR/EMR
1406// if ($realtime - MRD_chk < tMRD) begin
1407// $display ("%m: At time %t ERROR: tMRD violation during Extended Mode Register", $realtime);
1408// end
1409
1410            if (MRD_cntr < tMRD) begin
1411                $display ("%m: At time %t ERROR: tMRD violation during Extended Mode Register", $realtime);
1412            end
1413
1414            // Record current tMRD time
1415// MRD_chk = $realtime;
1416            MRD_cntr = 0;
1417        end
1418
1419        // Load Mode Register
1420        if (Mode_reg_enable === 1'b1) begin
1421            if (Debug) begin
1422                $display ("Debug: At time %t %m:LMR : Load Mode Register", $realtime);
1423            end
1424
1425            // Register Mode
1426            Mode_reg = Addr;
1427
1428            if (Mode_reg[6:4] == 3'b010) begin
1429                if (tCK2_min == 0) begin
1430                    $display ("%m : at time %t ERROR : Illegal CAS Latency of 2 set for current speed grade", $realtime);
1431                end
1432            end
1433
1434            // Precharge to LMR
1435            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
1436                $display ("%m: At time %t ERROR: all banks must be Precharged before Load Mode Register", $realtime);
1437            end
1438
1439            // Precharge to LMR
1440            if (($realtime - RP_chk0 < tRP - 0.001) || ($realtime - RP_chk1 < tRP - 0.001) ||
1441                ($realtime - RP_chk2 < tRP - 0.001) || ($realtime - RP_chk3 < tRP - 0.001)) begin
1442                $display ("%m: At time %t ERROR: tRP violation during Load Mode Register", $realtime);
1443            end
1444
1445            // LMR/EMR to LMR/EMR
1446// if ($realtime - MRD_chk < tMRD) begin
1447// $display ("%m: At time %t ERROR: tMRD violation during Load Mode Register", $realtime);
1448// end
1449            if (MRD_cntr < tMRD) begin
1450                $display ("%m: At time %t ERROR: tMRD violation during Load Mode Register", $realtime);
1451            end
1452
1453            if (Pc_b0 === 1'b1 && Pc_b1 === 1'b1 && Pc_b2 === 1'b1 && Pc_b3 === 1'b1) begin
1454                // ensure that power sequence is met properly
1455                if (~power_up_done) begin
1456                    mode_load_done = 1'b1;
1457                end
1458               // Burst Length
1459               case (Addr [2 : 0])
1460                   3'b001 : $display ("At time %t %m:LMR : Burst Length = 2", $realtime);
1461                   3'b010 : $display ("At time %t %m:LMR : Burst Length = 4", $realtime);
1462                   3'b011 : $display ("At time %t %m:LMR : Burst Length = 8", $realtime);
1463                   3'b100 : $display ("At time %t %m:LMR : Burst Length = 16",$realtime);
1464                   default :
1465                     begin
1466                       $display ("%m: At time %t ERROR: Undefined burst length selection", $realtime);
1467                       $stop;
1468                     end
1469               endcase
1470
1471               // CAS Latency
1472               case (Addr [6 : 4])
1473                   3'b010 : $display ("At time %t %m:LMR : CAS Latency = 2", $realtime);
1474                   3'b011 : $display ("At time %t %m:LMR : CAS Latency = 3", $realtime);
1475                   default : begin
1476                       $display ("%m: At time %t ERROR: CAS Latency not supported", $realtime);
1477                       $stop;
1478                   end
1479               endcase
1480
1481            end
1482            // Record current tMRD time
1483// MRD_chk = $realtime;
1484            MRD_cntr = 0;
1485        end
1486
1487        // Activate Block
1488        if (Active_enable === 1'b1) begin
1489            if (!(power_up_done)) begin
1490                $display ("%m: At time %t ERROR: Power Up and Initialization Sequence not completed before executing Activate command", $realtime);
1491            end
1492            // Display Debug Message
1493            if (Debug) begin
1494                $display ("Debug: At time %t %m:ACTIVATE: Bank = %d, Row = %d", $realtime, Ba, Addr);
1495            end
1496
1497            // Activating an open bank can cause corruption.
1498            if ((Ba === 2'b00 && Pc_b0 === 1'b0) || (Ba === 2'b01 && Pc_b1 === 1'b0) ||
1499                (Ba === 2'b10 && Pc_b2 === 1'b0) || (Ba === 2'b11 && Pc_b3 === 1'b0)) begin
1500                $display ("%m: At time %t ERROR: Bank = %d is already activated - data can be corrupted", $realtime, Ba);
1501            end
1502
1503            // Activate Bank 0
1504            if (Ba === 2'b00 && Pc_b0 === 1'b1) begin
1505                // Activate to Activate (same bank)
1506                if ($realtime - RC_chk0 < tRC - 0.001) begin
1507                    $display ("%m: At time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1508                end
1509
1510                // Precharge to Activate
1511                if ($realtime - RP_chk0 < tRP - 0.001) begin
1512                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1513                end
1514
1515                // Record variables for checking violation
1516                Act_b0 = 1'b1;
1517                Pc_b0 = 1'b0;
1518                B0_row_addr = Addr;
1519                RC_chk0 = $realtime;
1520                RCD_chk0 = $realtime;
1521                RAS_chk0 = $realtime;
1522                RAP_chk0 = $realtime;
1523            end
1524
1525            // Activate Bank 1
1526            if (Ba === 2'b01 && Pc_b1 === 1'b1) begin
1527                // Activate to Activate (same bank)
1528                if ($realtime - RC_chk1 < tRC - 0.001) begin
1529                    $display ("%m: At time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1530                end
1531
1532                // Precharge to Activate
1533                if ($realtime - RP_chk1 < tRP - 0.001) begin
1534                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1535                end
1536
1537                // Record variables for checking violation
1538                Act_b1 = 1'b1;
1539                Pc_b1 = 1'b0;
1540                B1_row_addr = Addr;
1541                RC_chk1 = $realtime;
1542                RCD_chk1 = $realtime;
1543                RAS_chk1 = $realtime;
1544                RAP_chk1 = $realtime;
1545            end
1546
1547            // Activate Bank 2
1548            if (Ba === 2'b10 && Pc_b2 === 1'b1) begin
1549                // Activate to Activate (same bank)
1550                if ($realtime - RC_chk2 < tRC - 0.001) begin
1551                    $display ("%m: At time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1552                end
1553
1554                // Precharge to Activate
1555                if ($realtime - RP_chk2 < tRP - 0.001) begin
1556                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1557                end
1558
1559                // Record variables for checking violation
1560                Act_b2 = 1'b1;
1561                Pc_b2 = 1'b0;
1562                B2_row_addr = Addr;
1563                RC_chk2 = $realtime;
1564                RCD_chk2 = $realtime;
1565                RAS_chk2 = $realtime;
1566                RAP_chk2 = $realtime;
1567            end
1568
1569            // Activate Bank 3
1570            if (Ba === 2'b11 && Pc_b3 === 1'b1) begin
1571                // Activate to Activate (same bank)
1572                if ($realtime - RC_chk3 < tRC - 0.001) begin
1573                    $display ("%m: t time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1574                end
1575
1576                // Precharge to Activate
1577                if ($realtime - RP_chk3 < tRP - 0.001) begin
1578                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1579                end
1580
1581                // Record variables for checking violation
1582                Act_b3 = 1'b1;
1583                Pc_b3 = 1'b0;
1584                B3_row_addr = Addr;
1585                RC_chk3 = $realtime;
1586                RCD_chk3 = $realtime;
1587                RAS_chk3 = $realtime;
1588                RAP_chk3 = $realtime;
1589            end
1590
1591            // Activate to Activate (different bank)
1592            if ((Prev_bank != Ba) && ($realtime - RRD_chk < tRRD - 0.001)) begin
1593                $display ("%m: At time %t ERROR: tRRD violation during Activate bank = %d", $realtime, Ba);
1594            end
1595
1596            // AutoRefresh to Activate
1597            if ($realtime - RFC_chk < tRFC - 0.001) begin
1598                $display ("%m: At time %t ERROR: tRFC violation during Activate bank %d", $realtime, Ba);
1599            end
1600
1601            // Record variable for checking violation
1602            RRD_chk = $realtime;
1603            Prev_bank = Ba;
1604        end
1605
1606        // Precharge Block - consider NOP if bank already precharged or in process of precharging
1607        if (Prech_enable === 1'b1) begin
1608            // Display Debug Message
1609            if (Debug) begin
1610                $display ("Debug: At time %t %m:PRE: Addr[10] = %b, Bank = %b", $realtime, Addr[10], Ba);
1611            end
1612
1613            // EMR or LMR to Precharge
1614// if ($realtime - MRD_chk < tMRD) begin
1615// $display ("%m: At time %t ERROR: tMRD violation during Precharge", $realtime);
1616// end
1617            if (MRD_cntr < tMRD) begin
1618                $display ("%m: At time %t ERROR: tMRD violation during Precharge", $realtime);
1619            end
1620
1621            // Precharge bank 0
1622            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin
1623                Act_b0 = 1'b0;
1624                Pc_b0 = 1'b1;
1625                RP_chk0 = $realtime;
1626
1627                // Activate to Precharge Bank
1628                if ($realtime - RAS_chk0 < tRAS - 0.001) begin
1629                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1630                end
1631
1632                // tWR violation check for Write
1633                if ($realtime - WR_chk0 < tWR - 0.001) begin
1634                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1635                end
1636            end
1637
1638            // Precharge bank 1
1639            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin
1640                Act_b1 = 1'b0;
1641                Pc_b1 = 1'b1;
1642                RP_chk1 = $realtime;
1643
1644                // Activate to Precharge Bank 1
1645                if ($realtime - RAS_chk1 < tRAS - 0.001) begin
1646                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1647                end
1648
1649                // tWR violation check for Write
1650                if ($realtime - WR_chk1 < tWR - 0.001) begin
1651                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1652                end
1653            end
1654
1655            // Precharge bank 2
1656            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin
1657                Act_b2 = 1'b0;
1658                Pc_b2 = 1'b1;
1659                RP_chk2 = $realtime;
1660
1661                // Activate to Precharge Bank 2
1662                if ($realtime - RAS_chk2 < tRAS - 0.001) begin
1663                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1664                end
1665
1666                // tWR violation check for Write
1667                if ($realtime - WR_chk2 < tWR - 0.001) begin
1668                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1669                end
1670            end
1671
1672            // Precharge bank 3
1673            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin
1674                Act_b3 = 1'b0;
1675                Pc_b3 = 1'b1;
1676                RP_chk3 = $realtime;
1677
1678                // Activate to Precharge Bank 3
1679                if ($realtime - RAS_chk3 < tRAS - 0.001) begin
1680                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1681                end
1682
1683                // tWR violation check for Write
1684                if ($realtime - WR_chk3 < tWR - 0.001) begin
1685                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1686                end
1687            end
1688
1689            // Pipeline for READ
1690            if ((Addr[10] === 1'b1) | (Ba == Write_bank_pipeline[4]))
1691                for (i = 4; i < `MAX_PIPE; i = i + 1)
1692                    Read_pipeline[i] = 1'b0 ;
1693
1694        end
1695
1696        // Burst terminate
1697        if (Burst_term === 1'b1) begin
1698            // Display Debug Message
1699            if (Debug) begin
1700                $display ("Debug: %m: At time %t BURST_TERMINATE): Burst Terminate",$realtime);
1701            end
1702
1703            // Burst Terminate Command Pipeline for Read
1704            for (i = cas_latency_x2-1; i < `MAX_PIPE; i = i + 1)
1705                Read_pipeline[i] = 1'b0 ;
1706            // Illegal to burst terminate a Write
1707            if ((Data_in_enable === 1'b1) & ~((&dm_rise) & (&dm_fall))) begin
1708                $display ("%m: At time %t ERROR: It's illegal to burst terminate a Write", $realtime);
1709            end
1710
1711            // Illegal to burst terminate a Read with Auto Precharge
1712            if (|Read_precharge_access) begin
1713                $display ("%m: At time %t ERROR: It's illegal to burst terminate a Read with Auto Precharge", $realtime);
1714            end
1715        end
1716
1717        // Read Command
1718        if (Read_enable === 1'b1) begin
1719            if (!(power_up_done)) begin
1720                $display ("%m: At time %t ERROR: Power Up and Initialization Sequence not completed before executing Read Command", $realtime);
1721            end
1722            // Display Debug Message
1723            if (Debug) begin
1724                $display ("Debug: At time %t %m:READ: Bank = %d, Col = %d", $realtime, Ba, {Addr [11], Addr [9 : 0]});
1725            end
1726            if (part_size == 1024) begin
1727                if (SRR_read == 1'b1) begin
1728                    if (SRR_cntr < tSRR) begin
1729                        $display ("%m: At time %t ERROR: tSRR Violation", $realtime);
1730                    end
1731                    SRC_cntr = 0 ;
1732                end
1733            end else begin
1734                if (SRR_read == 1'b1) begin
1735                    if ($realtime - SRR_chk < tSRR-0.01) begin
1736                        $display ("%m: At time %t ERROR: tSRR Violation", $realtime);
1737                    end
1738                    SRC_cntr = 0;
1739                end
1740            end
1741            // CAS Latency pipeline
1742            if (SRR_read) begin
1743                if ({Ba, Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]} > 0) begin
1744                   $display ("%m: At time %t ERROR: Address must be all 0 during SRR Read", $realtime);
1745                end
1746                for (i=0; i<2; i=i+1)
1747                begin
1748                    Read_pipeline[cas_latency_x2 - 2 + i + 1] = 1'b1;
1749                    Write_col_pipeline [cas_latency_x2 - 2 + i + 1] = i;
1750                    Write_bank_pipeline [cas_latency_x2 - 2 + i + 1] = 0;
1751                end
1752            end else begin
1753                for (i=0; i<burst_length; i=i+1)
1754                begin
1755                    Read_pipeline[cas_latency_x2 - 2 + i + 1] = 1'b1;
1756                    Write_bank_pipeline [cas_latency_x2 - 2 + i + 1] = Ba;
1757                    Write_col_pipeline [cas_latency_x2 - 2 + i + 1] = Burst_Order({Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}, i);
1758                end
1759            end
1760
1761            // Clear out Write Pipeline
1762            Write_pipeline = 64'b0;
1763
1764            // Interrupt a Read with Auto Precharge
1765            if (Read_precharge_access [Ba] === 1'b1) begin
1766                $display ("%m: At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge (same bank)", $realtime);
1767            end else if ((Read_precharge_access [0] === 1'b1) |
1768                         (Read_precharge_access [1] === 1'b1) |
1769                         (Read_precharge_access [2] === 1'b1) |
1770                         (Read_precharge_access [3] === 1'b1) ) begin
1771                $display ("%m: At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge (different banks)", $realtime);
1772            end
1773
1774            // Interrupt a Write with Auto Precharge
1775            if (Write_precharge_access [Ba] === 1'b1) begin
1776// $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge (same banks)", $realtime);
1777            end else if ((Write_precharge_count [0] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1778                         (Write_precharge_count [1] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1779                         (Write_precharge_count [2] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1780                         (Write_precharge_count [3] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1781                         (Write_precharge_count [0] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) |
1782                         (Write_precharge_count [1] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) |
1783                         (Write_precharge_count [2] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) |
1784                         (Write_precharge_count [3] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) ) begin
1785                $display ("%m: At time %t ERROR: It's illegal to interrupt a data transfer on a Write with Auto Precharge (different banks)", $realtime);
1786            end
1787
1788            // Activate to Read
1789            if (((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) ||
1790                 (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) &&
1791                (SRR_read == 1'b0)) begin
1792                $display("%m: At time %t ERROR: Bank is not Activated for Read", $realtime);
1793            end
1794
1795            // Activate to Read without Auto Precharge
1796            if ((Addr [10] === 1'b0 && Ba === 2'b00 && $realtime - RCD_chk0 < tRCD - 0.001) ||
1797                (Addr [10] === 1'b0 && Ba === 2'b01 && $realtime - RCD_chk1 < tRCD - 0.001) ||
1798                (Addr [10] === 1'b0 && Ba === 2'b10 && $realtime - RCD_chk2 < tRCD - 0.001) ||
1799                (Addr [10] === 1'b0 && Ba === 2'b11 && $realtime - RCD_chk3 < tRCD - 0.001)) begin
1800                $display("%m: At time %t ERROR: tRCD violation during Read", $realtime);
1801            end
1802
1803            // Auto Precharge
1804            if (Addr[10] === 1'b1) begin
1805                Read_precharge_access [Ba]= 1'b1;
1806                Count_precharge [Ba]= 0;
1807                Read_precharge_count[Ba] = 4'h0;
1808            end
1809
1810            // tWTR
1811            if (tWTR_cntr < tWTR - 0.001) begin
1812                $display("%m: At time %t ERROR: tWTR violation during Read", $realtime);
1813            end
1814        end
1815
1816        // Write Command
1817        if (Write_enable === 1'b1) begin
1818            if (!(power_up_done)) begin
1819                $display ("%m: At time %t ERROR: Power Up and Initialization Sequence not completed before executing Write Command", $realtime);
1820            end
1821            // display debug message
1822            if (Debug) begin
1823                $display ("Debug: At time %t %m:WRITE: Bank = %d, Col = %d", $realtime, Ba, {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]});
1824            end
1825
1826            // Pipeline for Write
1827// Write_pipeline [3] = 1'b1;
1828            for (i=0; i<burst_length; i=i+1)
1829            begin
1830                Write_pipeline[1 + i] = 1'b1;
1831// Write_col_pipeline [1 + i] = {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]} + i;
1832                Write_col_pipeline [1 + i] = Burst_Order({Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}, i);
1833                Write_bank_pipeline [1 + i] = Ba;
1834
1835            end
1836
1837            // Interrupt a Write with Auto Precharge (same bank only)
1838            if (Write_precharge_access [Ba] === 1'b1) begin
1839                $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge", $realtime);
1840            end
1841
1842            // Activate to Write
1843            if ((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) ||
1844                (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) begin
1845                $display("%m: At time %t ERROR: Bank is not Activated for Write", $realtime);
1846            end
1847
1848            // Activate to Write
1849            if ((Ba === 2'b00 && $realtime - RCD_chk0 < tRCD - 0.001) ||
1850                (Ba === 2'b01 && $realtime - RCD_chk1 < tRCD - 0.001) ||
1851                (Ba === 2'b10 && $realtime - RCD_chk2 < tRCD - 0.001) ||
1852                (Ba === 2'b11 && $realtime - RCD_chk3 < tRCD - 0.001)) begin
1853                $display("%m: At time %t ERROR: tRCD violation during Write to Bank %d", $realtime, Ba);
1854            end
1855
1856            if (Read_pipeline[0]) begin
1857                $display("%m: At time %t ERROR: Read to Write violation", $realtime);
1858            end
1859
1860            // Interrupt a Write with Auto Precharge
1861            if (Write_precharge_access [Ba] === 1'b1) begin
1862                $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge (same bank)", $realtime);
1863            end else if (((Write_precharge_access [0] === 1'b1) & (Count_precharge[0] < (burst_length/2))) |
1864                         ((Write_precharge_access [1] === 1'b1) & (Count_precharge[1] < (burst_length/2))) |
1865                         ((Write_precharge_access [2] === 1'b1) & (Count_precharge[2] < (burst_length/2))) |
1866                         ((Write_precharge_access [3] === 1'b1) & (Count_precharge[3] < (burst_length/2))) ) begin
1867                $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge (different bank)", $realtime);
1868            end
1869
1870            // Interrupt a Read with Auto Precharge
1871            if (((Read_precharge_count [Ba] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1872                ((Read_precharge_count [Ba] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) ) begin
1873// $display ("%m: At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge (same bank)", $realtime);
1874            end else if (((Read_precharge_count [0] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1875                         ((Read_precharge_count [1] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1876                         ((Read_precharge_count [2] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1877                         ((Read_precharge_count [3] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1878                         ((Read_precharge_count [0] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) |
1879                         ((Read_precharge_count [1] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) |
1880                         ((Read_precharge_count [2] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) |
1881                         ((Read_precharge_count [3] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) ) begin
1882                $display ("%m: At time %t ERROR: It's illegal to interrupt a data transfer on a Read with Auto Precharge (different bank)", $realtime);
1883            end
1884
1885            // Auto Precharge
1886            if (Addr[10] === 1'b1) begin
1887                Write_precharge_access [Ba]= 1'b1;
1888                Count_precharge [Ba]= 0;
1889                Write_precharge_count[Ba] = 4'h0;
1890            end
1891        end
1892
1893    end
1894    endtask
1895
1896    // Main Logic
1897    always @ (posedge Sys_clk) begin
1898        ShiftPipelines;
1899// Manual_Precharge_Pipeline;
1900// Burst_Terminate_Pipeline;
1901        Dq_Dqs_Drivers;
1902        Write_FIFO_DM_Mask_Logic;
1903        Burst_Decode;
1904        Auto_Precharge_Calculation;
1905        Timing_chk_SRC;
1906        Control_Logic;
1907        MRD_counter;
1908        SRR_counter;
1909        SRC_counter;
1910        tWTR_counter;
1911        command_counter;
1912    end
1913
1914    always @ (negedge Sys_clk) begin
1915        ShiftPipelines;
1916// Manual_Precharge_Pipeline;
1917// Burst_Terminate_Pipeline;
1918        Dq_Dqs_Drivers;
1919        Write_FIFO_DM_Mask_Logic;
1920        Burst_Decode;
1921    end
1922
1923    // Dqs Receiver
1924    always @ (posedge Dqs_in[0]) begin
1925        // Latch data at posedge Dqs
1926        dq_rise[7 : 0] = Dq_in[7 : 0];
1927        dm_rise[0] = Dm_in[0];
1928        expect_pos_dqs[0] = 0;
1929    end
1930
1931    always @ (posedge Dqs_in[1]) begin
1932        // Latch data at posedge Dqs
1933        dq_rise[15 : 8] = Dq_in[15 : 8];
1934        dm_rise[1] = Dm_in[1];
1935        expect_pos_dqs[1] = 0;
1936    end
1937
1938`ifdef x32
1939    always @ (posedge Dqs_in[2]) begin
1940        // Latch data at posedge Dqs
1941        dq_rise[23 : 16] = Dq_in[23 : 16];
1942        dm_rise[2] = Dm_in[2];
1943        expect_pos_dqs[2] = 0;
1944    end
1945
1946    always @ (posedge Dqs_in[3]) begin
1947        // Latch data at posedge Dqs
1948        dq_rise[31 : 24] = Dq_in[31 : 24];
1949        dm_rise[3] = Dm_in[3];
1950        expect_pos_dqs[3] = 0;
1951    end
1952`endif
1953
1954    always @ (negedge Dqs_in[0]) begin
1955        // Latch data at negedge Dqs
1956        dq_fall[7 : 0] = Dq_in[7 : 0];
1957        dm_fall[0] = Dm_in[0];
1958        dm_pair[1:0] = {dm_rise[0], dm_fall[0]};
1959        expect_neg_dqs[0] = 0;
1960    end
1961
1962    always @ (negedge Dqs_in[1]) begin
1963        // Latch data at negedge Dqs
1964        dq_fall[15: 8] = Dq_in[15 : 8];
1965        dm_fall[1] = Dm_in[1];
1966        dm_pair[3:2] = {dm_rise[1], dm_fall[1]};
1967        expect_neg_dqs[1] = 0;
1968    end
1969
1970`ifdef x32
1971    always @ (negedge Dqs_in[2]) begin
1972        // Latch data at negedge Dqs
1973        dq_fall[23: 16] = Dq_in[23 : 16];
1974        dm_fall[2] = Dm_in[2];
1975        dm_pair[5:4] = {dm_rise[2], dm_fall[2]};
1976        expect_neg_dqs[2] = 0;
1977    end
1978
1979    always @ (negedge Dqs_in[3]) begin
1980        // Latch data at negedge Dqs
1981        dq_fall[31: 24] = Dq_in[31 : 24];
1982        dm_fall[3] = Dm_in[3];
1983        dm_pair[7:6] = {dm_rise[3], dm_fall[3]};
1984        expect_neg_dqs[3] = 0;
1985    end
1986`endif
1987
1988    // Dqs edge checking
1989    always @ (posedge Sys_clk) begin
1990// if (Write_pipeline[2] || Write_pipeline[1] || Data_in_enable) begin
1991        if (Write_pipeline[-1]) begin
1992            for (i=0; i<DQS_BITS; i=i+1) begin
1993                if (expect_neg_dqs[i]) begin
1994                    $display ("%m: At time %t ERROR: Negative DQS[%1d] transition required.", $realtime, i);
1995                end
1996                expect_neg_dqs[i] = 1'b1;
1997            end
1998        end else begin
1999           expect_neg_dqs = 0;
2000           expect_pos_dqs = 0;
2001        end
2002    end
2003
2004    always @ (negedge Sys_clk) begin
2005// if (Write_pipeline[2] || Write_pipeline[1] || Data_in_enable) begin
2006        if (Write_pipeline[-1]) begin
2007            for (i=0; i<DQS_BITS; i=i+1) begin
2008                if (expect_pos_dqs[i]) begin
2009                    $display ("%m: At time %t ERROR: Positive DQS[%1d] transition required.", $realtime, i);
2010                end
2011                expect_pos_dqs[i] = 1'b1;
2012            end
2013        end else begin
2014           expect_neg_dqs = 0;
2015           expect_pos_dqs = 0;
2016        end
2017    end
2018
2019    specify
2020                                                   // SYMBOL UNITS DESCRIPTION
2021                                                   // ------ ----- -----------
2022`ifdef sg5 // specparams for -6 (CL = 3)
2023        specparam tCLK_MIN = 5.0 ; // tCLK ns minimum clk cycle time
2024        specparam tDSS = 1.0 ; // tDSS ns DQS falling edge to CLK rising (setup time)
2025        specparam tDSH = 1.0 ; // tDSH ns DQS falling edge from CLK rising (hold time)
2026        specparam tIH = 1.0 ; // tIH ns Input Hold Time (fast)
2027        specparam tIS = 1.0 ; // tIS ns Input Setup Time (fast)
2028        specparam tDQSH = 1.75; // tDQSH ns DQS input High Pulse Width
2029        specparam tDQSL = 1.75; // tDQSL ns DQS input Low Pulse Width
2030`elsif sg54 // specparams for -6 (CL = 3)
2031        specparam tCLK_MIN = 5.4; // tCLK ns minimum clk cycle time
2032        specparam tDSS = 1.08; // tDSS ns DQS falling edge to CLK rising (setup time)
2033        specparam tDSH = 1.08; // tDSH ns DQS falling edge from CLK rising (hold time)
2034        specparam tIH = 1.0; // tIH ns Input Hold Time (fast)
2035        specparam tIS = 1.0; // tIS ns Input Setup Time (fast)
2036        specparam tDQSH = 2.16; // tDQSH ns DQS input High Pulse Width
2037        specparam tDQSL = 2.16; // tDQSL ns DQS input Low Pulse Width
2038`elsif sg6 // specparams for -6 (CL = 3)
2039        specparam tCLK_MIN = 6.0; // tCLK ns minimum clk cycle time
2040        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time)
2041        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time)
2042        specparam tIH = 1.1; // tIH ns Input Hold Time (fast)
2043        specparam tIS = 1.1; // tIS ns Input Setup Time (fast)
2044        specparam tDQSH = 2.1; // tDQSH ns DQS input High Pulse Width
2045        specparam tDQSL = 2.1; // tDQSL ns DQS input Low Pulse Width
2046`elsif sg75 // specparams for -75 (CL = 3)
2047        specparam tCLK_MIN = 7.5; // tCLK ns minimum clk cycle time
2048        specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time)
2049        specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time)
2050        specparam tIH = 1.3; // tIH ns Input Hold Time (fast)
2051        specparam tIS = 1.3; // tIS ns Input Setup Time (fast)
2052        specparam tDQSH = 3.0; // tDQSH ns DQS input High Pulse Width
2053        specparam tDQSL = 3.0; // tDQSL ns DQS input Low Pulse Width
2054`elsif sg5v18 // specparams for -6 (CL = 3)
2055        specparam tCLK_MIN = 5.0 ; // tCLK ns minimum clk cycle time
2056        specparam tDSS = 1.0 ; // tDSS ns DQS falling edge to CLK rising (setup time)
2057        specparam tDSH = 1.0 ; // tDSH ns DQS falling edge from CLK rising (hold time)
2058        specparam tIH = 0.9 ; // tIH ns Input Hold Time (fast)
2059        specparam tIS = 0.9 ; // tIS ns Input Setup Time (fast)
2060        specparam tDQSH = 2.0 ; // tDQSH ns DQS input High Pulse Width
2061        specparam tDQSL = 2.0 ; // tDQSL ns DQS input Low Pulse Width
2062`elsif sg6v18 // specparams for -6 (CL = 3)
2063        specparam tCLK_MIN = 6.0; // tCLK ns minimum clk cycle time
2064        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time)
2065        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time)
2066        specparam tIH = 1.1; // tIH ns Input Hold Time (fast)
2067        specparam tIS = 1.1; // tIS ns Input Setup Time (fast)
2068        specparam tDQSH = 2.4; // tDQSH ns DQS input High Pulse Width
2069        specparam tDQSL = 2.4; // tDQSL ns DQS input Low Pulse Width
2070`elsif sg75v18 // specparams for -75 (CL = 3)
2071        specparam tCLK_MIN = 7.5; // tCLK ns minimum clk cycle time
2072        specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time)
2073        specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time)
2074        specparam tIH = 1.3; // tIH ns Input Hold Time (fast)
2075        specparam tIS = 1.3; // tIS ns Input Setup Time (fast)
2076        specparam tDQSH = 3.0; // tDQSH ns DQS input High Pulse Width
2077        specparam tDQSL = 3.0; // tDQSL ns DQS input Low Pulse Width
2078`elsif sg6v12 // specparams for -6 (CL = 3)
2079        specparam tCLK_MIN = 6.0; // tCLK ns minimum clk cycle time
2080        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time)
2081        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time)
2082        specparam tIH = 1.1; // tIH ns Input Hold Time (fast)
2083        specparam tIS = 1.1; // tIS ns Input Setup Time (fast)
2084        specparam tDQSH = 2.1; // tDQSH ns DQS input High Pulse Width
2085        specparam tDQSL = 2.1; // tDQSL ns DQS input Low Pulse Width
2086`elsif sg75v12 // specparams for -75 (CL = 3)
2087        specparam tCLK_MIN = 7.5; // tCLK ns minimum clk cycle time
2088        specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time)
2089        specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time)
2090        specparam tIH = 1.3; // tIH ns Input Hold Time (fast)
2091        specparam tIS = 1.3; // tIS ns Input Setup Time (fast)
2092        specparam tDQSH = 3.0; // tDQSH ns DQS input High Pulse Width
2093        specparam tDQSL = 3.0; // tDQSL ns DQS input Low Pulse Width
2094`elsif sg10v12 // specparams for -10 (CL = 3)
2095        specparam tCLK_MIN = 9.6; // tCLK ns minimum clk cycle time
2096        specparam tDSS = 1.92; // tDSS ns DQS falling edge to CLK rising (setup time)
2097        specparam tDSH = 1.92; // tDSH ns DQS falling edge from CLK rising (hold time)
2098        specparam tIH = 1.7; // tIH ns Input Hold Time (fast)
2099        specparam tIS = 1.7; // tIS ns Input Setup Time (fast)
2100        specparam tDQSH = 3.84; // tDQSH ns DQS input High Pulse Width
2101        specparam tDQSL = 3.84; // tDQSL ns DQS input Low Pulse Width
2102`else `define sg10 // specparams for -10 (CL = 3)
2103        specparam tCLK_MIN = 9.6; // tCLK ns minimum clk cycle time
2104        specparam tDSS = 1.92; // tDSS ns DQS falling edge to CLK rising (setup time)
2105        specparam tDSH = 1.92; // tDSH ns DQS falling edge from CLK rising (hold time)
2106        specparam tIH = 1.5; // tIH ns Input Hold Time (fast)
2107        specparam tIS = 1.5; // tIS ns Input Setup Time (fast)
2108        specparam tDQSH = 3.84; // tDQSH ns DQS input High Pulse Width
2109        specparam tDQSL = 3.84; // tDQSL ns DQS input Low Pulse Width
2110`endif
2111        $period (posedge Clk, tCLK_MIN);
2112        $width (posedge Dqs_in[0] &&& wdqs_valid, tDQSH);
2113        $width (posedge Dqs_in[1] &&& wdqs_valid, tDQSH);
2114        $width (negedge Dqs_in[0] &&& wdqs_valid, tDQSL);
2115        $width (negedge Dqs_in[1] &&& wdqs_valid, tDQSL);
2116        $setuphold(posedge Clk, Cke, tIS, tIH);
2117        $setuphold(posedge Clk, Cs_n, tIS, tIH);
2118        $setuphold(posedge Clk, Cas_n, tIS, tIH);
2119        $setuphold(posedge Clk, Ras_n, tIS, tIH);
2120        $setuphold(posedge Clk, We_n, tIS, tIH);
2121        $setuphold(posedge Clk, Addr, tIS, tIH);
2122        $setuphold(posedge Clk, Ba, tIS, tIH);
2123        $setuphold(posedge Clk, negedge Dqs &&& wdqs_valid, tDSS , tDSH);
2124    endspecify
2125
2126endmodule
sim/verilog/micron_mobile_ddr/mobile_ddr_mcp.v
1/****************************************************************************************
2*
3* File Name: mobile_ddr_mcp.v
4*
5* Dependencies: mobile_ddr.v, mobile_ddr_parameters.vh
6*
7* Description: Micron MOBILE DDR SDRAM multi-chip package model
8*
9* Disclaimer This software code and all associated documentation, comments or other
10* of Warranty: information (collectively "Software") is provided "AS IS" without
11* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
12* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
13* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
14* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
15* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
16* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
17* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
18* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
19* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
20* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
21* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
22* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
23* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
24* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
25* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
26* DAMAGES. Because some jurisdictions prohibit the exclusion or
27* limitation of liability for consequential or incidental damages, the
28* above limitation may not apply to you.
29*
30* Copyright 2008 Micron Technology, Inc. All rights reserved.
31*
32****************************************************************************************/
33`timescale 1ns / 1ps
34
35module mobile_ddr_mcp (
36    Clk ,
37    Clk_n ,
38    Cke ,
39    Cs_n ,
40    Ras_n ,
41    Cas_n ,
42    We_n ,
43    Addr ,
44    Ba ,
45    Dq ,
46    Dqs ,
47    Dm
48);
49
50    `include "mobile_ddr_parameters.vh"
51
52    // Declare Ports
53    input Clk ;
54    input Clk_n ;
55    input [CS_BITS - 1 : 0] Cke ;
56    input [CS_BITS - 1 : 0] Cs_n ;
57    input Ras_n ;
58    input Cas_n ;
59    input We_n ;
60    input [ADDR_BITS - 1 : 0] Addr ;
61    input [1 : 0] Ba ;
62    inout [DQ_BITS - 1 : 0] Dq ;
63    inout [DQS_BITS - 1 : 0] Dqs ;
64    input [DM_BITS - 1 : 0] Dm ;
65
66    wire [RANKS - 1 : 0] Cke_mcp = Cke ;
67    wire [RANKS - 1 : 0] Cs_n_mcp = Cs_n ;
68
69    mobile_ddr rank [RANKS - 1:0] (
70        .Clk ( Clk ) ,
71        .Clk_n ( Clk_n ) ,
72        .Cke ( Cke_mcp ) ,
73        .Cs_n ( Cs_n_mcp ) ,
74        .Ras_n ( Ras_n ) ,
75        .Cas_n ( Cas_n ) ,
76        .We_n ( We_n ) ,
77        .Addr ( Addr ) ,
78        .Ba ( Ba ) ,
79        .Dq ( Dq ) ,
80        .Dqs ( Dqs ) ,
81        .Dm ( Dm )
82    );
83
84endmodule
sim/verilog/micron_mobile_ddr/readme.txt
1Disclaimer of Warranty:
2-----------------------
3This software code and all associated documentation, comments or other
4information (collectively "Software") is provided "AS IS" without
5warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20DAMAGES. Because some jurisdictions prohibit the exclusion or
21limitation of liability for consequential or incidental damages, the
22above limitation may not apply to you.
23
24Copyright 2008 Micron Technology, Inc. All rights reserved.
25
26Getting Started:
27----------------
28Unzip the included files to a folder.
29Compile mobile_ddr.v and tb.v using a verilog simulator.
30Simulate the top level test bench tb.
31Or, if you are using the ModelSim simulator, type "do tb.do" at the prompt.
32
33File Descriptions:
34------------------
35mobile_ddr.v --mobile ddr model
36mobile_ddr_mcp.v --structural wrapper for mobile_ddr multi-chip package model
37128Mb_mobile_ddr_parameters.vh --File that contains all parameters used by the model
38256Mb_mobile_ddr_parameters.vh --File that contains all parameters used by the model
39512Mb_mobile_ddr_parameters.vh --File that contains all parameters used by the model
401024Mb_mobile_ddr_parameters.vh --File that contains all parameters used by the model
412048Mb_mobile_ddr_parameters.vh --File that contains all parameters used by the model
42readme.txt --This file
43tb.v --Test bench
44tb.do --File that compiles and runs the above files
45
46Defining the Density (part size):
47-------------------------
48The verilog compiler directive "`define" may be used to choose between on of the
49densities supported by the mobile ddr model. Allowable densities are listed in
50the *.vh file. The density is used to select a set of bank, row, column, and timing
51parameters for the mobile ddr model. The following are examples of defining
52the density.
53
54    simulator command line
55    --------- ------------
56    ModelSim vlog +define+den512Mb mobile_ddr.v
57    VCS vcs +define+den512Mb mobile_ddr.v
58    NC-Verilog ncverilog +define+den512Mb mobile_ddr.v
59
60
61Defining the Speed Grade:
62-------------------------
63The verilog compiler directive "`define" may be used to choose between
64multiple speed grades supported by the mobile ddr model. Allowable speed
65grades are listed in the mobile_ddr_parameters.vh file and begin with the
66letters "sg". The speed grade is used to select a set of timing
67parameters for the mobile ddr model. The following are examples of defining
68the speed grade.
69
70    simulator command line
71    --------- ------------
72    ModelSim vlog +define+sg75 mobile_ddr.v
73    VCS vcs +define+sg75 mobile_ddr.v
74    NC-Verilog ncverilog +define+sg75 mobile_ddr.v
75
76
77Defining the Organization:
78--------------------------
79The verilog compiler directive "`define" may be used to choose between
80multiple organizations supported by the mobile ddr model. Valid
81organizations include "x16" and "x32", and are listed in the
82mobile_ddr_parameters.vh file. The organization is used to select the amount
83of memory and the port sizes of the mobile ddr model. The following are
84examples of defining the organization.
85
86    vlog +define+x16 mobile_ddr.v
87    simulator command line
88    --------- ------------
89    ModelSim vlog +define+x16 mobile_ddr.v
90    VCS vcs +define+x16 mobile_ddr.v
91    NC-Verilog ncverilog +define+x16 mobile_ddr.v
92
93All combinations of speed grade and organization are considered valid
94by the mobile ddr model even though a Micron part may not exist for every
95combination.
96
97Allocating Memory:
98------------------
99An associative array has been implemented to reduce the amount of
100static memory allocated by the mobile ddr model. The number of
101entries in the associative array is controlled by the part_mem_bits
102parameter, and is equal to 2^part_mem_bits. For example, if the
103part_mem_bits parameter is equal to 10, the associative array will be
104large enough to store 1024 write data transfers to unique addresses.
105The following are examples of setting the MEM_BITS parameter to 8.
106
107    simulator command line
108    --------- ------------
109    ModelSim vsim -Gpart_mem_bits=8 mobile_ddr
110    VCS vcs -pvalue+part_mem_bits=8 mobile_ddr.v
111    NC-Verilog ncverilog +defparam+mobile_ddr.part_mem_bits=8 mobile_ddr.v
112
113It is possible to allocate memory for every address supported by the
114mobile ddr model by using the verilog compiler directive "`define FULL_MEM".
115This procedure will improve simulation performance at the expense of
116system memory. The following are examples of allocating memory for
117every address.
118
119    Simulator command line
120    --------- ------------
121    ModelSim vlog +define+FULL_MEM mobile_ddr.v
122    VCS vcs +define+FULL_MEM mobile_ddr.v
123    NC-Verilog ncverilog +define+FULL_MEM mobile_ddr.v
124
125
126Reduced Page Mode:
127------------------
128Mobile DDR 256Mb, 512Mb, and 1024Mb part may be built with the reduced page size
129architecture. This part is accessed with the +define+RP designator. RP
130parts have one extra row bit and one less column bit effectively cutting
131the page size in half but doubling the number of rows keeping total part
132size the same.
133
134    Part Size Valid RP Designators
135    --------- --------------------
136    256Mb +define+RP
137    512Mb +define+RP
138    1024Mb +define+RP
139
140    Simulator command line
141    --------- ------------
142    ModelSim vlog +define+RP mobile_ddr.v
143    VCS vcs +define+RP mobile_ddr.v
144    NC-Verilog ncverilog +define+RP mobile_ddr.v
145
146Multi-Chip Package Model:
147-------------------------
148The 1024Mb model can be supported in a Multi Chip Package, that allows
149multiple die models in one structural package. The number of ranks and
150chip selects of the mcp can be configured by using the `DUAL_RANK define
151on the simulator call line. The currently supported configurations are
152listed below:
153
154    Package Configuration Valid MCP Designator
155    --------------------- --------------------
156    2 Chip Selects, 2 Die +define+DUAL_RANK
157    2 Chip Selects, 1 Die (default)
158
159The single rank mcp is the default. In order to simulate the DUAL_RANK
160model, the define needs to be added:
161
162    Simulator command line
163    --------- ------------
164    ModelSim vlog +define+DUAL_RANK mobile_ddr.v mobile_ddr_mcp.v
165    VCS vcs +define+DUAL_RANK mobile_ddr.v mobile_ddr_mcp.v
166    NC-Verilog ncverilog +define+DUAL_RANK mobile_ddr.v mobile_ddr_mcp.v
167
sim/verilog/micron_mobile_ddr/subtest.vh
1initial begin:test
2    //ck <= 1'b0;
3    cke <= 1'b0;
4    cs_n <= 1'bz;
5    ras_n <= 1'bz;
6    cas_n <= 1'bz;
7    we_n <= 1'bz;
8    a <= {ADDR_BITS{1'bz}};
9    ba <= {BA_BITS{1'bz}};
10    dq_en <= 1'b0;
11    dqs_en <= 1'b0;
12    power_up;
13    nop (10); // wait 10 clocks intead of 200 us for simulation purposes
14    precharge('h00000000, 1);
15    nop(trp);
16    refresh;
17    nop(trfc);
18    refresh;
19    nop(trfc);
20    load_mode('h0, 'h00000032);
21    nop(tmrd);
22    load_mode('h2, 'h00004000);
23    nop(tmrd);
24    activate('h00000000, 'h00000000);
25    nop(trcd-1);
26    write('h00000000, 'h00000000, 0, { {DM_BITS{1'b0}}, {DM_BITS{1'b0}}, {DM_BITS{1'b0}}, {DM_BITS{1'b0}}}, { 16'h3000, 16'h2000, 16'h1000, 16'h0});
27    nop(bl/2+twr);
28    read('h00000000, 'h00000000, 1);
29    nop(bl/2-1);
30    nop('h00000014);
31    test_done;
32end
sim/verilog/micron_mobile_ddr/tb.do
1#########################################################################################
2#
3# Disclaimer This software code and all associated documentation, comments or other
4# of Warranty: information (collectively "Software") is provided "AS IS" without
5# warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6# DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7# TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8# OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9# WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10# OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11# FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12# THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13# ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14# OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15# ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16# INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17# WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18# OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19# THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20# DAMAGES. Because some jurisdictions prohibit the exclusion or
21# limitation of liability for consequential or incidental damages, the
22# above limitation may not apply to you.
23#
24# Copyright 2005 Micron Technology, Inc. All rights reserved.
25#
26#########################################################################################
27
28vlib work
29vlog +define+den512Mb +define+sg75 +define+x16 mobile_ddr.v tb.v
30vsim tb
31add wave -p mobile_ddr/*
32run -a
33
34# For Reduced Page Parts run the following and comment out the lines above :
35
36#vlog +define+den512Mb +define+sg75 +define+x32 mobile_ddr.v tb.v
37#vsim tb
38#add wave -p mobile_ddr/*
39#run -a
sim/verilog/micron_mobile_ddr/tb.v
1/****************************************************************************************
2*
3* File Name: tb.v
4* Version: 6.00
5* Model: BUS Functional
6*
7* Dependencies: mobile_ddr.v, mobile_ddr_parameters.vh, subtest.vh
8*
9* Description: Micron SDRAM DDR (Double Data Rate) test bench
10*
11* Note: -Set simulator resolution to "ps" accuracy
12* -Set Debug = 0 to disable $display messages
13*
14* Disclaimer This software code and all associated documentation, comments or other
15* of Warranty: information (collectively "Software") is provided "AS IS" without
16* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
17* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
18* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
19* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
20* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
21* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
22* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
23* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
24* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
25* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
26* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
27* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
28* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
29* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
30* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
31* DAMAGES. Because some jurisdictions prohibit the exclusion or
32* limitation of liability for consequential or incidental damages, the
33* above limitation may not apply to you.
34*
35* Copyright 2003 Micron Technology, Inc. All rights reserved.
36*
37* Rev Author Date Changes
38* --- ------ ---------- ---------------------------------------
39* 4.1 JMK 01/14/2001 -Grouped specify parameters by speed grade
40* -Fixed mem_sizes parameter
41* 2.1 SPH 03/19/2002 -Second Release
42* -Fix tWR and several incompatability
43* between different simulators
44* 3.0 TFK 02/18/2003 -Added tDSS and tDSH timing checks.
45* -Added tDQSH and tDQSL timing checks.
46* 3.1 CAH 05/28/2003 -update all models to release version 3.1
47* (no changes to this model)
48* 3.2 JMK 06/16/2003 -updated all DDR400 models to support CAS Latency 3
49* 3.3 JMK 09/11/2003 -Added initialization sequence checks.
50* 4.0 JMK 12/01/2003 -Grouped parameters into "ddr_parameters.v"
51* -Fixed tWTR check
52* 4.2 JMK 03/19/2004 -Fixed pulse width checking on dqs
53* 4.3 JMK 04/27/2004 -Changed bl wire size in tb module
54* -Changed Dq_buf size to [15:0]
55* 5.0 JMK 06/16/2004 -Added read to write checking.
56* -Added read with precharge truncation to write checking.
57* -Added associative memory array to reduce memory consumption.
58* -Added checking for required DQS edges during write.
59* 6.0 DMR 12/03/2004 -new density
60* 6.01 BAAB 05/18/2006 -assimilating into Minneapolis site organization
61* 3.11 BAS 10/18/2006 -added read_verify
62* 3.35 bas 02/28/07 -mobile_ddr.v file uses tAC correctly to calculate strobe/data launch
63* 3.36 bas 03/05/07 -fixed error messages for different banks interrupting
64                             reads/writes w/autoprecharge
65* 3.37 bas 03/21/07 -added T47M part for 512Mb in parameters file,
66                             modified tXP check to measure in tCLK for T47M
67* 3.60 clk 09/19/07 -fixed dm/dq verification fifo's
68* 3.60 clk 09/19/07 -fixed dqrx module delay statement
69* 3.80 clk 10/29/07 - Support for 1024Mb T48M
70* 4.00 clk 12/30/07 - Fixed Read terminated by precharge testcase
71* 4.70 clk 03/30/08 - Fixed typo in SRR code
72* 4.80 clk 04/03/08 - Disable clk checking during initialization
73* 4.90 clk 04/16/08 - Fixed tInit, added mpc support, updated t35m timing
74* 5.00 clk 05/14/08 - Fixed back to back auto precharge commands
75* 5.20 clk 05/21/08 - Fixed read interrupt by pre (BL8), fixed 1024Mb parameter file
76* 5.30 clk 05/22/08 - Fixed DM signal which cause false tWTR errors
77              05/27/08 - Rewrote write and read pipelins, strobes
78* 5.40 clk 05/28/08 - Fixed Addressing problem in Burst Order logic
79* 5.50 clk 07/25/08 - Added T36N part type
80* 5.60 clk 09/05/08 - Fixed tXP in 256Mb part type
81* 5.70 clk 09/17/08 - Fixed burst term check for write w/ all DM active
82* 5.80 clk 11/18/08 - Fixed internally latched dq & mask widths
83* 5.90 clk 12/10/08 - Updated T36N parameters to latest datasheet
84* 6.00 clk 03/05/09 - Fixed DQS problem w/ CL = 2
85****************************************************************************************/
86
87`timescale 1ns / 1ps
88
89module tb;
90
91`ifdef den128Mb
92    `include "128Mb_mobile_ddr_parameters.vh"
93`elsif den256Mb
94    `include "256Mb_mobile_ddr_parameters.vh"
95`elsif den512Mb
96    `include "512Mb_mobile_ddr_parameters.vh"
97`elsif den1024Mb
98    `include "1024Mb_mobile_ddr_parameters.vh"
99`elsif den2048Mb
100    `include "2048Mb_mobile_ddr_parameters.vh"
101`else
102    // NOTE: Intentionally cause a compile fail here to force the users
103    // to select the correct component density before continuing
104    ERROR: You must specify component density with +define+den____Mb.
105`endif
106
107    reg ck_tb ;
108    reg ck_enable = 1'b1 ;
109    // ports
110    wire ck;
111    wire ck_n = ~ck;
112    reg cke = 1'b0;
113    reg cs_n;
114    reg ras_n;
115    reg cas_n;
116    reg we_n;
117    reg [BA_BITS-1:0] ba;
118    reg [ADDR_BITS-1:0] a;
119    wire [DM_BITS-1:0] dm;
120    wire [DQ_BITS-1:0] dq;
121    wire [DQS_BITS-1:0] dqs;
122
123    // mode registers
124    reg [ADDR_BITS-1:0] mode_reg0; //Mode Register
125    reg [ADDR_BITS-1:0] mode_reg1; //Extended Mode Register
126    wire [2:0] cl = mode_reg0[6:4]; //CAS Latency
127    wire bo = mode_reg0[3]; //Burst Order
128    wire [7:0] bl = (1<<mode_reg0[2:0]); //Burst Length
129    wire wl = 1; //Write Latency
130
131    // dq transmit
132    reg dq_en;
133    reg [DM_BITS-1:0] dm_out;
134    reg [DQ_BITS-1:0] dq_out;
135    reg dqs_en;
136    reg [DQS_BITS-1:0] dqs_out;
137    assign dm = dq_en ? dm_out : {DM_BITS{1'b0}};
138    assign dq = dq_en ? dq_out : {DQ_BITS{1'bz}};
139    assign dqs = dqs_en ? dqs_out : {DQS_BITS{1'bz}};
140
141    // dq receive
142    reg [DM_BITS-1:0] dm_fifo [2*CL_MAX+16:0];
143    reg [DQ_BITS-1:0] dq_fifo [2*CL_MAX+16:0];
144    wire [DQ_BITS-1:0] q0, q1, q2, q3;
145    reg ptr_rst_n;
146    reg [1:0] burst_cntr;
147
148    // timing definition in tCK units
149    real tck;
150    wire [11:0] trc = tRC;
151    wire [11:0] trrd = ceil(tRRD/tck);
152    wire [11:0] trcd = ceil(tRCD/tck);
153    wire [11:0] tras = ceil(tRAS/tck);
154    wire [11:0] twr = ceil(tWR/tck);
155    wire [11:0] trp = ceil(tRP/tck);
156    wire [11:0] tmrd = tMRD;
157    wire [11:0] trfc = ceil(tRFC/tck);
158    wire [11:0] tsrr = ceil(tSRR);
159    wire [11:0] tsrc = ceil(tSRC);
160    wire [11:0] tdqsq = tDQSQ;
161    wire [11:0] twtr = tWTR;
162
163    initial begin
164        $timeformat (-9, 1, " ns", 1);
165`ifdef period
166        tck <= `period;
167`else
168        tck <= tCK;
169`endif
170        ck_tb <= 1'b1;
171        dq_en <= 1'b0;
172        dqs_en <= 1'b0;
173    end
174
175    // component instantiation
176    mobile_ddr mobile_ddr (
177        .Clk ( ck ) ,
178        .Clk_n ( ck_n ) ,
179        .Cke ( cke ) ,
180        .Cs_n ( cs_n ) ,
181        .Ras_n ( ras_n ) ,
182        .Cas_n ( cas_n ) ,
183        .We_n ( we_n ) ,
184        .Addr ( a ) ,
185        .Ba ( ba ) ,
186        .Dq ( dq ) ,
187        .Dqs ( dqs ) ,
188        .Dm ( dm )
189    );
190
191    // clock generator
192    assign ck = ck_enable & ck_tb ;
193    always @(posedge ck_tb) begin
194      ck_tb <= #(tck/2) 1'b0;
195      ck_tb <= #(tck) 1'b1;
196    end
197
198    function integer ceil;
199        input number;
200        real number;
201        if (number > $rtoi(number))
202            ceil = $rtoi(number) + 1;
203        else
204            ceil = number;
205    endfunction
206
207    function integer max;
208        input arg1;
209        input arg2;
210        integer arg1;
211        integer arg2;
212        if (arg1 > arg2)
213            max = arg1;
214        else
215            max = arg2;
216    endfunction
217
218    function [8*DQ_BITS-1:0] burst_order;
219        input [8-1:0] col;
220        input [8*DQ_BITS-1:0] dq;
221        reg [3:0] i;
222        reg [2:0] j;
223        integer k;
224        begin
225            burst_order = dq;
226            for (i=0; i<bl; i=i+1) begin
227                j = ((col%bl) ^ i);
228                if (!bo)
229                    j[1:0] = (col + i);
230                for (k=0; k<DQ_BITS; k=k+1) begin
231                    burst_order[i*DQ_BITS + k] = dq[j*DQ_BITS + k];
232                end
233            end
234        end
235    endfunction
236
237    task power_up;
238        begin
239            cke <= 1'b0;
240            cs_n <= 1'b1;
241            ras_n <= 1'b1;
242            cas_n <= 1'b1;
243            we_n <= 1'b1;
244            ba <= {BA_BITS{1'b0}};
245            a <= {ADDR_BITS{1'b0}};
246            repeat(10) @(negedge ck_tb);
247            @ (negedge ck_tb) cke <= 1'b1;
248            $display ("%m at time %t TB: A 200 us delay is required after cke is brought high.", $time);
249        end
250    endtask
251
252    task stop_clock_enter ;
253    begin
254        @ (negedge ck_tb);
255        ck_enable = 1'b0 ;
256    end
257    endtask
258
259    task stop_clock_exit ;
260    begin
261        @ (negedge ck_tb);
262        ck_enable = 1'b1 ;
263    end
264    endtask
265
266    task load_mode;
267        input [BA_BITS-1:0] bank;
268        input [ROW_BITS-1:0] row;
269        begin
270            case (bank)
271                0: mode_reg0 = row;
272                1: mode_reg1 = row;
273            endcase
274            cke <= 1'b1;
275            cs_n <= 1'b0;
276            ras_n <= 1'b0;
277            cas_n <= 1'b0;
278            we_n <= 1'b0;
279            ba <= bank;
280            a <= row;
281            @(negedge ck_tb);
282        end
283    endtask
284
285    task refresh;
286        begin
287            cke <= 1'b1;
288            cs_n <= 1'b0;
289            ras_n <= 1'b0;
290            cas_n <= 1'b0;
291            we_n <= 1'b1;
292            @(negedge ck_tb);
293        end
294    endtask
295
296    task precharge;
297        input [BA_BITS-1:0] bank;
298        input ap; //precharge all
299        begin
300            cke <= 1'b1;
301            cs_n <= 1'b0;
302            ras_n <= 1'b0;
303            cas_n <= 1'b1;
304            we_n <= 1'b0;
305            ba <= bank;
306            a <= (ap<<10);
307            @(negedge ck_tb);
308        end
309    endtask
310
311    task activate;
312        input [BA_BITS-1:0] bank;
313        input [ROW_BITS-1:0] row;
314        begin
315            cke <= 1'b1;
316            cs_n <= 1'b0;
317            ras_n <= 1'b0;
318            cas_n <= 1'b1;
319            we_n <= 1'b1;
320            ba <= bank;
321            a <= row;
322            @(negedge ck_tb);
323        end
324    endtask
325
326    //write task supports burst lengths <= 8
327    task write;
328        input [BA_BITS-1:0] bank;
329        input [COL_BITS-1:0] col;
330        input ap; //Auto Precharge
331        input [16*DM_BITS-1:0] dm;
332        input [16*DQ_BITS-1:0] dq;
333        reg [ADDR_BITS-1:0] atemp [1:0];
334        integer i;
335        begin
336            cke <= 1'b1;
337            cs_n <= 1'b0;
338            ras_n <= 1'b1;
339            cas_n <= 1'b0;
340            we_n <= 1'b0;
341            ba <= bank;
342            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
343            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
344            a <= atemp[0] | atemp[1] | (ap<<10);
345            for (i=0; i<=bl; i=i+1) begin
346                dqs_en <= #(wl*tck + i*tck/2) 1'b1;
347                if (i%2 == 0) begin
348                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b0}};
349                end else begin
350                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b1}};
351                end
352
353                dq_en <= #(wl*tck + i*tck/2 + tck/4) 1'b1;
354                dm_out <= #(wl*tck + i*tck/2 + tck/4) dm>>i*DM_BITS;
355                dq_out <= #(wl*tck + i*tck/2 + tck/4) dq>>i*DQ_BITS;
356            end
357            dqs_en <= #(wl*tck + bl*tck/2 + tck/2) 1'b0;
358            dq_en <= #(wl*tck + bl*tck/2 + tck/4) 1'b0;
359            @(negedge ck_tb);
360        end
361    endtask
362
363    // read without data verification
364    task read;
365        input [BA_BITS-1:0] bank;
366        input [COL_BITS-1:0] col;
367        input ap; //Auto Precharge
368        reg [ADDR_BITS-1:0] atemp [1:0];
369        begin
370            cke <= 1'b1;
371            cs_n <= 1'b0;
372            ras_n <= 1'b1;
373            cas_n <= 1'b0;
374            we_n <= 1'b1;
375            ba <= bank;
376            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
377            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
378            a <= atemp[0] | atemp[1] | (ap<<10);
379            @(negedge ck_tb);
380        end
381    endtask
382
383    task burst_term;
384        integer i;
385        begin
386            cke <= 1'b1;
387            cs_n <= 1'b0;
388            ras_n <= 1'b1;
389            cas_n <= 1'b1;
390            we_n <= 1'b0;
391            @(negedge ck_tb);
392            for (i=0; i<bl; i=i+1) begin
393                dm_fifo[2*cl + i] <= {DM_BITS{1'bx}};
394                dq_fifo[2*cl + i] <= {DQ_BITS{1'bx}};
395            end
396        end
397    endtask
398
399    task nop;
400        input [31:0] count;
401        begin
402            cke <= 1'b1;
403            cs_n <= 1'b0;
404            ras_n <= 1'b1;
405            cas_n <= 1'b1;
406            we_n <= 1'b1;
407            repeat(count) @(negedge ck_tb);
408        end
409    endtask
410
411    task deselect;
412        input [31:0] count;
413        begin
414            cke <= 1'b1;
415            cs_n <= 1'b1;
416// ras_n <= 1'b1;
417// cas_n <= 1'b1;
418// we_n <= 1'b1;
419            repeat(count) @(negedge ck_tb);
420        end
421    endtask
422
423    task power_down;
424        input [31:0] count;
425        begin
426            cke <= 1'b0;
427            cs_n <= 1'b1;
428            ras_n <= 1'b1;
429            cas_n <= 1'b1;
430            we_n <= 1'b1;
431            repeat(count) @(negedge ck_tb);
432        end
433    endtask
434
435    task deep_power_down;
436        input [31:0] count;
437        begin
438            cke <= 1'b0;
439            cs_n <= 1'b0;
440            ras_n <= 1'b1;
441            cas_n <= 1'b1;
442            we_n <= 1'b0;
443            repeat(count) @(negedge ck_tb);
444        end
445    endtask
446
447    task self_refresh;
448        input [31:0] count;
449        begin
450            cke <= 1'b0;
451            cs_n <= 1'b0;
452            ras_n <= 1'b0;
453            cas_n <= 1'b0;
454            we_n <= 1'b1;
455            repeat(count) @(negedge ck_tb);
456        end
457    endtask
458
459    // read with data verification
460    task read_verify;
461        input [BA_BITS-1:0] bank;
462        input [COL_BITS-1:0] col;
463        input ap; //Auto Precharge
464        input [16*DM_BITS-1:0] dm; //Expected Data Mask
465        input [16*DQ_BITS-1:0] dq; //Expected Data
466        integer i;
467        begin
468            read (bank, col, ap);
469            for (i=0; i<bl; i=i+1) begin
470                dm_fifo[2*cl + i] <= dm>>(i*DM_BITS);
471                dq_fifo[2*cl + i] <= dq>>(i*DQ_BITS);
472            end
473        end
474    endtask
475
476    // receiver(s) for data_verify process
477    dqrx dqrx[DQS_BITS-1:0] (ptr_rst_n, dqs, dq, q0, q1, q2, q3);
478
479    // perform data verification as a result of read_verify task call
480    reg [DQ_BITS-1:0] bit_mask;
481    reg [DM_BITS-1:0] dm_temp;
482    reg [DQ_BITS-1:0] dq_temp;
483    always @(ck) begin:data_verify
484        integer i;
485        integer j;
486
487        for (i=!ck; (i<2/(2.0 - !ck)); i=i+1) begin
488            if (dm_fifo[i] === {DM_BITS{1'bx}}) begin
489                burst_cntr = 0;
490            end else begin
491
492                dm_temp = dm_fifo[i];
493                for (j=0; j<DQ_BITS; j=j+1) begin
494                    bit_mask[j] = !dm_temp[j/(DQ_BITS/DM_BITS)];
495                end
496
497                case (burst_cntr)
498                    0: dq_temp = q0;
499                    1: dq_temp = q1;
500                    2: dq_temp = q2;
501                    3: dq_temp = q3;
502                endcase
503                //if ( ((dq_temp & bit_mask) === (dq_fifo[i] & bit_mask)))
504                // $display ("%m at time %t: INFO: Successful read data compare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
505                if ((dq_temp & bit_mask) !== (dq_fifo[i] & bit_mask))
506                    $display ("%m at time %t: ERROR: Read data miscompare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
507
508                burst_cntr = burst_cntr + 1;
509            end
510        end
511
512        if (ck_tb) begin
513            ptr_rst_n <= (dm_fifo[4] !== {DM_BITS{1'bx}});
514        end else begin
515            //ptr_rst_n <= ptr_rst_n & (dm_fifo[6] !== {DM_BITS{1'bx}});
516            for (i=0; i<=2*CL_MAX+16; i=i+1) begin
517                dm_fifo[i] = dm_fifo[i+2];
518                dq_fifo[i] = dq_fifo[i+2];
519            end
520        end
521    end
522
523    // End-of-test triggered in 'subtest.vh'
524    task test_done;
525        begin
526            $display ("%m at time %t: INFO: Simulation is Complete", $time);
527            $stop(0);
528        end
529    endtask
530
531    // Test included from external file
532    `include "subtest.vh"
533
534endmodule
535
536module dqrx (
537    ptr_rst_n, dqs, dq, q0, q1, q2, q3
538);
539
540`ifdef den128Mb
541    `include "128Mb_mobile_ddr_parameters.vh"
542`elsif den256Mb
543    `include "256Mb_mobile_ddr_parameters.vh"
544`elsif den512Mb
545    `include "512Mb_mobile_ddr_parameters.vh"
546`elsif den1024Mb
547    `include "1024Mb_mobile_ddr_parameters.vh"
548`elsif den2048Mb
549    `include "2048Mb_mobile_ddr_parameters.vh"
550`else
551    // NOTE: Intentionally cause a compile fail here to force the users
552    // to select the correct component density before continuing
553    ERROR: You must specify component density with +define+den____Mb.
554`endif
555
556    input ptr_rst_n;
557    input dqs;
558    input [DQ_BITS/DQS_BITS-1:0] dq;
559    output [DQ_BITS/DQS_BITS-1:0] q0;
560    output [DQ_BITS/DQS_BITS-1:0] q1;
561    output [DQ_BITS/DQS_BITS-1:0] q2;
562    output [DQ_BITS/DQS_BITS-1:0] q3;
563
564    reg [1:0] ptr;
565    reg [DQ_BITS/DQS_BITS-1:0] q [3:0];
566
567    reg ptr_rst_dly_n;
568    always @(posedge ptr_rst_n) ptr_rst_dly_n <= #(tAC2_min + tDQSQ) ptr_rst_n;
569    always @(negedge ptr_rst_n) ptr_rst_dly_n <= #(tAC2_max + tDQSQ + 0.002) ptr_rst_n;
570
571    reg dqs_dly;
572    always @(dqs) dqs_dly <= #(tDQSQ + 0.001) dqs;
573
574    always @(negedge ptr_rst_dly_n or posedge dqs_dly or negedge dqs_dly) begin
575        if (!ptr_rst_dly_n) begin
576            ptr <= 0;
577        end else if (dqs_dly || ptr) begin
578            q[ptr] <= dq;
579            ptr <= ptr + 1;
580        end
581    end
582
583    assign q0 = q[0];
584    assign q1 = q[1];
585    assign q2 = q[2];
586    assign q3 = q[3];
587endmodule

Archive Download the corresponding diff file

Branches:
master



interactive