Root/sim/verilog/micron_mobile_ddr/tb.v

1/****************************************************************************************
2*
3* File Name: tb.v
4* Version: 6.00
5* Model: BUS Functional
6*
7* Dependencies: mobile_ddr.v, mobile_ddr_parameters.vh, subtest.vh
8*
9* Description: Micron SDRAM DDR (Double Data Rate) test bench
10*
11* Note: -Set simulator resolution to "ps" accuracy
12* -Set Debug = 0 to disable $display messages
13*
14* Disclaimer This software code and all associated documentation, comments or other
15* of Warranty: information (collectively "Software") is provided "AS IS" without
16* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
17* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
18* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
19* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
20* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
21* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
22* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
23* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
24* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
25* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
26* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
27* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
28* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
29* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
30* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
31* DAMAGES. Because some jurisdictions prohibit the exclusion or
32* limitation of liability for consequential or incidental damages, the
33* above limitation may not apply to you.
34*
35* Copyright 2003 Micron Technology, Inc. All rights reserved.
36*
37* Rev Author Date Changes
38* --- ------ ---------- ---------------------------------------
39* 4.1 JMK 01/14/2001 -Grouped specify parameters by speed grade
40* -Fixed mem_sizes parameter
41* 2.1 SPH 03/19/2002 -Second Release
42* -Fix tWR and several incompatability
43* between different simulators
44* 3.0 TFK 02/18/2003 -Added tDSS and tDSH timing checks.
45* -Added tDQSH and tDQSL timing checks.
46* 3.1 CAH 05/28/2003 -update all models to release version 3.1
47* (no changes to this model)
48* 3.2 JMK 06/16/2003 -updated all DDR400 models to support CAS Latency 3
49* 3.3 JMK 09/11/2003 -Added initialization sequence checks.
50* 4.0 JMK 12/01/2003 -Grouped parameters into "ddr_parameters.v"
51* -Fixed tWTR check
52* 4.2 JMK 03/19/2004 -Fixed pulse width checking on dqs
53* 4.3 JMK 04/27/2004 -Changed bl wire size in tb module
54* -Changed Dq_buf size to [15:0]
55* 5.0 JMK 06/16/2004 -Added read to write checking.
56* -Added read with precharge truncation to write checking.
57* -Added associative memory array to reduce memory consumption.
58* -Added checking for required DQS edges during write.
59* 6.0 DMR 12/03/2004 -new density
60* 6.01 BAAB 05/18/2006 -assimilating into Minneapolis site organization
61* 3.11 BAS 10/18/2006 -added read_verify
62* 3.35 bas 02/28/07 -mobile_ddr.v file uses tAC correctly to calculate strobe/data launch
63* 3.36 bas 03/05/07 -fixed error messages for different banks interrupting
64                             reads/writes w/autoprecharge
65* 3.37 bas 03/21/07 -added T47M part for 512Mb in parameters file,
66                             modified tXP check to measure in tCLK for T47M
67* 3.60 clk 09/19/07 -fixed dm/dq verification fifo's
68* 3.60 clk 09/19/07 -fixed dqrx module delay statement
69* 3.80 clk 10/29/07 - Support for 1024Mb T48M
70* 4.00 clk 12/30/07 - Fixed Read terminated by precharge testcase
71* 4.70 clk 03/30/08 - Fixed typo in SRR code
72* 4.80 clk 04/03/08 - Disable clk checking during initialization
73* 4.90 clk 04/16/08 - Fixed tInit, added mpc support, updated t35m timing
74* 5.00 clk 05/14/08 - Fixed back to back auto precharge commands
75* 5.20 clk 05/21/08 - Fixed read interrupt by pre (BL8), fixed 1024Mb parameter file
76* 5.30 clk 05/22/08 - Fixed DM signal which cause false tWTR errors
77              05/27/08 - Rewrote write and read pipelins, strobes
78* 5.40 clk 05/28/08 - Fixed Addressing problem in Burst Order logic
79* 5.50 clk 07/25/08 - Added T36N part type
80* 5.60 clk 09/05/08 - Fixed tXP in 256Mb part type
81* 5.70 clk 09/17/08 - Fixed burst term check for write w/ all DM active
82* 5.80 clk 11/18/08 - Fixed internally latched dq & mask widths
83* 5.90 clk 12/10/08 - Updated T36N parameters to latest datasheet
84* 6.00 clk 03/05/09 - Fixed DQS problem w/ CL = 2
85****************************************************************************************/
86
87`timescale 1ns / 1ps
88
89module tb;
90
91`ifdef den128Mb
92    `include "128Mb_mobile_ddr_parameters.vh"
93`elsif den256Mb
94    `include "256Mb_mobile_ddr_parameters.vh"
95`elsif den512Mb
96    `include "512Mb_mobile_ddr_parameters.vh"
97`elsif den1024Mb
98    `include "1024Mb_mobile_ddr_parameters.vh"
99`elsif den2048Mb
100    `include "2048Mb_mobile_ddr_parameters.vh"
101`else
102    // NOTE: Intentionally cause a compile fail here to force the users
103    // to select the correct component density before continuing
104    ERROR: You must specify component density with +define+den____Mb.
105`endif
106
107    reg ck_tb ;
108    reg ck_enable = 1'b1 ;
109    // ports
110    wire ck;
111    wire ck_n = ~ck;
112    reg cke = 1'b0;
113    reg cs_n;
114    reg ras_n;
115    reg cas_n;
116    reg we_n;
117    reg [BA_BITS-1:0] ba;
118    reg [ADDR_BITS-1:0] a;
119    wire [DM_BITS-1:0] dm;
120    wire [DQ_BITS-1:0] dq;
121    wire [DQS_BITS-1:0] dqs;
122
123    // mode registers
124    reg [ADDR_BITS-1:0] mode_reg0; //Mode Register
125    reg [ADDR_BITS-1:0] mode_reg1; //Extended Mode Register
126    wire [2:0] cl = mode_reg0[6:4]; //CAS Latency
127    wire bo = mode_reg0[3]; //Burst Order
128    wire [7:0] bl = (1<<mode_reg0[2:0]); //Burst Length
129    wire wl = 1; //Write Latency
130
131    // dq transmit
132    reg dq_en;
133    reg [DM_BITS-1:0] dm_out;
134    reg [DQ_BITS-1:0] dq_out;
135    reg dqs_en;
136    reg [DQS_BITS-1:0] dqs_out;
137    assign dm = dq_en ? dm_out : {DM_BITS{1'b0}};
138    assign dq = dq_en ? dq_out : {DQ_BITS{1'bz}};
139    assign dqs = dqs_en ? dqs_out : {DQS_BITS{1'bz}};
140
141    // dq receive
142    reg [DM_BITS-1:0] dm_fifo [2*CL_MAX+16:0];
143    reg [DQ_BITS-1:0] dq_fifo [2*CL_MAX+16:0];
144    wire [DQ_BITS-1:0] q0, q1, q2, q3;
145    reg ptr_rst_n;
146    reg [1:0] burst_cntr;
147
148    // timing definition in tCK units
149    real tck;
150    wire [11:0] trc = tRC;
151    wire [11:0] trrd = ceil(tRRD/tck);
152    wire [11:0] trcd = ceil(tRCD/tck);
153    wire [11:0] tras = ceil(tRAS/tck);
154    wire [11:0] twr = ceil(tWR/tck);
155    wire [11:0] trp = ceil(tRP/tck);
156    wire [11:0] tmrd = tMRD;
157    wire [11:0] trfc = ceil(tRFC/tck);
158    wire [11:0] tsrr = ceil(tSRR);
159    wire [11:0] tsrc = ceil(tSRC);
160    wire [11:0] tdqsq = tDQSQ;
161    wire [11:0] twtr = tWTR;
162
163    initial begin
164        $timeformat (-9, 1, " ns", 1);
165`ifdef period
166        tck <= `period;
167`else
168        tck <= tCK;
169`endif
170        ck_tb <= 1'b1;
171        dq_en <= 1'b0;
172        dqs_en <= 1'b0;
173    end
174
175    // component instantiation
176    mobile_ddr mobile_ddr (
177        .Clk ( ck ) ,
178        .Clk_n ( ck_n ) ,
179        .Cke ( cke ) ,
180        .Cs_n ( cs_n ) ,
181        .Ras_n ( ras_n ) ,
182        .Cas_n ( cas_n ) ,
183        .We_n ( we_n ) ,
184        .Addr ( a ) ,
185        .Ba ( ba ) ,
186        .Dq ( dq ) ,
187        .Dqs ( dqs ) ,
188        .Dm ( dm )
189    );
190
191    // clock generator
192    assign ck = ck_enable & ck_tb ;
193    always @(posedge ck_tb) begin
194      ck_tb <= #(tck/2) 1'b0;
195      ck_tb <= #(tck) 1'b1;
196    end
197
198    function integer ceil;
199        input number;
200        real number;
201        if (number > $rtoi(number))
202            ceil = $rtoi(number) + 1;
203        else
204            ceil = number;
205    endfunction
206
207    function integer max;
208        input arg1;
209        input arg2;
210        integer arg1;
211        integer arg2;
212        if (arg1 > arg2)
213            max = arg1;
214        else
215            max = arg2;
216    endfunction
217
218    function [8*DQ_BITS-1:0] burst_order;
219        input [8-1:0] col;
220        input [8*DQ_BITS-1:0] dq;
221        reg [3:0] i;
222        reg [2:0] j;
223        integer k;
224        begin
225            burst_order = dq;
226            for (i=0; i<bl; i=i+1) begin
227                j = ((col%bl) ^ i);
228                if (!bo)
229                    j[1:0] = (col + i);
230                for (k=0; k<DQ_BITS; k=k+1) begin
231                    burst_order[i*DQ_BITS + k] = dq[j*DQ_BITS + k];
232                end
233            end
234        end
235    endfunction
236
237    task power_up;
238        begin
239            cke <= 1'b0;
240            cs_n <= 1'b1;
241            ras_n <= 1'b1;
242            cas_n <= 1'b1;
243            we_n <= 1'b1;
244            ba <= {BA_BITS{1'b0}};
245            a <= {ADDR_BITS{1'b0}};
246            repeat(10) @(negedge ck_tb);
247            @ (negedge ck_tb) cke <= 1'b1;
248            $display ("%m at time %t TB: A 200 us delay is required after cke is brought high.", $time);
249        end
250    endtask
251
252    task stop_clock_enter ;
253    begin
254        @ (negedge ck_tb);
255        ck_enable = 1'b0 ;
256    end
257    endtask
258
259    task stop_clock_exit ;
260    begin
261        @ (negedge ck_tb);
262        ck_enable = 1'b1 ;
263    end
264    endtask
265
266    task load_mode;
267        input [BA_BITS-1:0] bank;
268        input [ROW_BITS-1:0] row;
269        begin
270            case (bank)
271                0: mode_reg0 = row;
272                1: mode_reg1 = row;
273            endcase
274            cke <= 1'b1;
275            cs_n <= 1'b0;
276            ras_n <= 1'b0;
277            cas_n <= 1'b0;
278            we_n <= 1'b0;
279            ba <= bank;
280            a <= row;
281            @(negedge ck_tb);
282        end
283    endtask
284
285    task refresh;
286        begin
287            cke <= 1'b1;
288            cs_n <= 1'b0;
289            ras_n <= 1'b0;
290            cas_n <= 1'b0;
291            we_n <= 1'b1;
292            @(negedge ck_tb);
293        end
294    endtask
295     
296    task precharge;
297        input [BA_BITS-1:0] bank;
298        input ap; //precharge all
299        begin
300            cke <= 1'b1;
301            cs_n <= 1'b0;
302            ras_n <= 1'b0;
303            cas_n <= 1'b1;
304            we_n <= 1'b0;
305            ba <= bank;
306            a <= (ap<<10);
307            @(negedge ck_tb);
308        end
309    endtask
310     
311    task activate;
312        input [BA_BITS-1:0] bank;
313        input [ROW_BITS-1:0] row;
314        begin
315            cke <= 1'b1;
316            cs_n <= 1'b0;
317            ras_n <= 1'b0;
318            cas_n <= 1'b1;
319            we_n <= 1'b1;
320            ba <= bank;
321            a <= row;
322            @(negedge ck_tb);
323        end
324    endtask
325
326    //write task supports burst lengths <= 8
327    task write;
328        input [BA_BITS-1:0] bank;
329        input [COL_BITS-1:0] col;
330        input ap; //Auto Precharge
331        input [16*DM_BITS-1:0] dm;
332        input [16*DQ_BITS-1:0] dq;
333        reg [ADDR_BITS-1:0] atemp [1:0];
334        integer i;
335        begin
336            cke <= 1'b1;
337            cs_n <= 1'b0;
338            ras_n <= 1'b1;
339            cas_n <= 1'b0;
340            we_n <= 1'b0;
341            ba <= bank;
342            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
343            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
344            a <= atemp[0] | atemp[1] | (ap<<10);
345            for (i=0; i<=bl; i=i+1) begin
346                dqs_en <= #(wl*tck + i*tck/2) 1'b1;
347                if (i%2 == 0) begin
348                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b0}};
349                end else begin
350                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b1}};
351                end
352
353                dq_en <= #(wl*tck + i*tck/2 + tck/4) 1'b1;
354                dm_out <= #(wl*tck + i*tck/2 + tck/4) dm>>i*DM_BITS;
355                dq_out <= #(wl*tck + i*tck/2 + tck/4) dq>>i*DQ_BITS;
356            end
357            dqs_en <= #(wl*tck + bl*tck/2 + tck/2) 1'b0;
358            dq_en <= #(wl*tck + bl*tck/2 + tck/4) 1'b0;
359            @(negedge ck_tb);
360        end
361    endtask
362
363    // read without data verification
364    task read;
365        input [BA_BITS-1:0] bank;
366        input [COL_BITS-1:0] col;
367        input ap; //Auto Precharge
368        reg [ADDR_BITS-1:0] atemp [1:0];
369        begin
370            cke <= 1'b1;
371            cs_n <= 1'b0;
372            ras_n <= 1'b1;
373            cas_n <= 1'b0;
374            we_n <= 1'b1;
375            ba <= bank;
376            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
377            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
378            a <= atemp[0] | atemp[1] | (ap<<10);
379            @(negedge ck_tb);
380        end
381    endtask
382
383    task burst_term;
384        integer i;
385        begin
386            cke <= 1'b1;
387            cs_n <= 1'b0;
388            ras_n <= 1'b1;
389            cas_n <= 1'b1;
390            we_n <= 1'b0;
391            @(negedge ck_tb);
392            for (i=0; i<bl; i=i+1) begin
393                dm_fifo[2*cl + i] <= {DM_BITS{1'bx}};
394                dq_fifo[2*cl + i] <= {DQ_BITS{1'bx}};
395            end
396        end
397    endtask
398
399    task nop;
400        input [31:0] count;
401        begin
402            cke <= 1'b1;
403            cs_n <= 1'b0;
404            ras_n <= 1'b1;
405            cas_n <= 1'b1;
406            we_n <= 1'b1;
407            repeat(count) @(negedge ck_tb);
408        end
409    endtask
410
411    task deselect;
412        input [31:0] count;
413        begin
414            cke <= 1'b1;
415            cs_n <= 1'b1;
416// ras_n <= 1'b1;
417// cas_n <= 1'b1;
418// we_n <= 1'b1;
419            repeat(count) @(negedge ck_tb);
420        end
421    endtask
422
423    task power_down;
424        input [31:0] count;
425        begin
426            cke <= 1'b0;
427            cs_n <= 1'b1;
428            ras_n <= 1'b1;
429            cas_n <= 1'b1;
430            we_n <= 1'b1;
431            repeat(count) @(negedge ck_tb);
432        end
433    endtask
434
435    task deep_power_down;
436        input [31:0] count;
437        begin
438            cke <= 1'b0;
439            cs_n <= 1'b0;
440            ras_n <= 1'b1;
441            cas_n <= 1'b1;
442            we_n <= 1'b0;
443            repeat(count) @(negedge ck_tb);
444        end
445    endtask
446
447    task self_refresh;
448        input [31:0] count;
449        begin
450            cke <= 1'b0;
451            cs_n <= 1'b0;
452            ras_n <= 1'b0;
453            cas_n <= 1'b0;
454            we_n <= 1'b1;
455            repeat(count) @(negedge ck_tb);
456        end
457    endtask
458
459    // read with data verification
460    task read_verify;
461        input [BA_BITS-1:0] bank;
462        input [COL_BITS-1:0] col;
463        input ap; //Auto Precharge
464        input [16*DM_BITS-1:0] dm; //Expected Data Mask
465        input [16*DQ_BITS-1:0] dq; //Expected Data
466        integer i;
467        begin
468            read (bank, col, ap);
469            for (i=0; i<bl; i=i+1) begin
470                dm_fifo[2*cl + i] <= dm>>(i*DM_BITS);
471                dq_fifo[2*cl + i] <= dq>>(i*DQ_BITS);
472            end
473        end
474    endtask
475
476    // receiver(s) for data_verify process
477    dqrx dqrx[DQS_BITS-1:0] (ptr_rst_n, dqs, dq, q0, q1, q2, q3);
478
479    // perform data verification as a result of read_verify task call
480    reg [DQ_BITS-1:0] bit_mask;
481    reg [DM_BITS-1:0] dm_temp;
482    reg [DQ_BITS-1:0] dq_temp;
483    always @(ck) begin:data_verify
484        integer i;
485        integer j;
486        
487        for (i=!ck; (i<2/(2.0 - !ck)); i=i+1) begin
488            if (dm_fifo[i] === {DM_BITS{1'bx}}) begin
489                burst_cntr = 0;
490            end else begin
491
492                dm_temp = dm_fifo[i];
493                for (j=0; j<DQ_BITS; j=j+1) begin
494                    bit_mask[j] = !dm_temp[j/(DQ_BITS/DM_BITS)];
495                end
496
497                case (burst_cntr)
498                    0: dq_temp = q0;
499                    1: dq_temp = q1;
500                    2: dq_temp = q2;
501                    3: dq_temp = q3;
502                endcase
503                //if ( ((dq_temp & bit_mask) === (dq_fifo[i] & bit_mask)))
504                // $display ("%m at time %t: INFO: Successful read data compare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
505                if ((dq_temp & bit_mask) !== (dq_fifo[i] & bit_mask))
506                    $display ("%m at time %t: ERROR: Read data miscompare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
507
508                burst_cntr = burst_cntr + 1;
509            end
510        end
511
512        if (ck_tb) begin
513            ptr_rst_n <= (dm_fifo[4] !== {DM_BITS{1'bx}});
514        end else begin
515            //ptr_rst_n <= ptr_rst_n & (dm_fifo[6] !== {DM_BITS{1'bx}});
516            for (i=0; i<=2*CL_MAX+16; i=i+1) begin
517                dm_fifo[i] = dm_fifo[i+2];
518                dq_fifo[i] = dq_fifo[i+2];
519            end
520        end
521    end
522
523    // End-of-test triggered in 'subtest.vh'
524    task test_done;
525        begin
526            $display ("%m at time %t: INFO: Simulation is Complete", $time);
527            $stop(0);
528        end
529    endtask
530
531    // Test included from external file
532    `include "subtest.vh"
533
534endmodule
535
536module dqrx (
537    ptr_rst_n, dqs, dq, q0, q1, q2, q3
538);
539
540`ifdef den128Mb
541    `include "128Mb_mobile_ddr_parameters.vh"
542`elsif den256Mb
543    `include "256Mb_mobile_ddr_parameters.vh"
544`elsif den512Mb
545    `include "512Mb_mobile_ddr_parameters.vh"
546`elsif den1024Mb
547    `include "1024Mb_mobile_ddr_parameters.vh"
548`elsif den2048Mb
549    `include "2048Mb_mobile_ddr_parameters.vh"
550`else
551    // NOTE: Intentionally cause a compile fail here to force the users
552    // to select the correct component density before continuing
553    ERROR: You must specify component density with +define+den____Mb.
554`endif
555
556    input ptr_rst_n;
557    input dqs;
558    input [DQ_BITS/DQS_BITS-1:0] dq;
559    output [DQ_BITS/DQS_BITS-1:0] q0;
560    output [DQ_BITS/DQS_BITS-1:0] q1;
561    output [DQ_BITS/DQS_BITS-1:0] q2;
562    output [DQ_BITS/DQS_BITS-1:0] q3;
563
564    reg [1:0] ptr;
565    reg [DQ_BITS/DQS_BITS-1:0] q [3:0];
566
567    reg ptr_rst_dly_n;
568    always @(posedge ptr_rst_n) ptr_rst_dly_n <= #(tAC2_min + tDQSQ) ptr_rst_n;
569    always @(negedge ptr_rst_n) ptr_rst_dly_n <= #(tAC2_max + tDQSQ + 0.002) ptr_rst_n;
570
571    reg dqs_dly;
572    always @(dqs) dqs_dly <= #(tDQSQ + 0.001) dqs;
573
574    always @(negedge ptr_rst_dly_n or posedge dqs_dly or negedge dqs_dly) begin
575        if (!ptr_rst_dly_n) begin
576            ptr <= 0;
577        end else if (dqs_dly || ptr) begin
578            q[ptr] <= dq;
579            ptr <= ptr + 1;
580        end
581    end
582
583    assign q0 = q[0];
584    assign q1 = q[1];
585    assign q2 = q[2];
586    assign q3 = q[3];
587endmodule
588

Archive Download this file

Branches:
master



interactive