Date:2010-12-19 02:38:43 (3 years 10 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