📄 tb.v
字号:
////////////////////////////////////////////////
//[Disclaimer]
//This software code and all associated documentation, comments
//or other information (collectively "Software") is provided
//"AS IS" without warranty of any kind. MICRON TECHNOLOGY, INC.
//("MTI") EXPRESSLY DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED,
//INCLUDING BUT NOT LIMITED TO, NONINFRINGEMENT OF THIRD PARTY
//RIGHTS, AND ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
//FOR ANY PARTICULAR PURPOSE. MTI DOES NOT WARRANT THAT THE
//SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
//THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. FURTHERMORE,
//MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR THE
//RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
//ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT
//OF USE OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO
//EVENT SHALL MTI, ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE
//LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR
//SPECIAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
//OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION)
//ARISING OUT OF YOUR USE OF OR INABILITY TO USE THE SOFTWARE,
//EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
//Because some jurisdictions prohibit the exclusion or limitation
//of liability for consequential or incidental damages, the above
//limitation may not apply to you.
//
//Copyright 2006-2008 Micron Technology, Inc. All rights reserved.
////////////////////////////////////////////////
`timescale 1ns / 1ps
module tb;
`include "nand_parameters.vh"
initial begin
`ifdef VCD
$dumpfile("jcnmvcd.vcd");
$dumpvars(0,uut);
`endif
end
// Ports Declaration
reg [DQ_BITS - 1 : 0] Io;
reg Cle;
reg Ale;
reg Ce_n;
reg Re_n;
reg We_n;
reg Wp_n;
reg Ce2_n;
reg Ce3_n; //reserved for future use
reg Ce4_n; //reserved for future use
reg Pre;
reg Lock;
reg Dqs;
tri1 Rb2_n; // pullup
tri1 Rb_n; // pullup
tri1 Rb3_n; //reserved for future use
tri1 Rb4_n; //reserved for future use
wire [DQ_BITS - 1 : 0] IO = Io;
// high-speed sync signals
wire Clk = We_n;
wire Wr_n = Re_n;
wire DQS = Dqs;
// some testbench signals here
wire cache_mode;
wire sync_mode;
wire any_device_active = ~Ce_n || ~Ce2_n || ~Ce3_n || ~Ce4_n;
reg rd_verify;
reg enable_rd_verify;
reg rd_verify_sync;
reg device;
reg [DQ_BITS -1 : 0] rd_dq;
reg [7:0] lastCmd;
reg [2:0] lastState;
reg Clk_int = 0;
reg check_idle = 0;
//read cycle timing parameters
real tRP; //read cycle pulse width low
real tREH;//read cycle high
real tRC; //read cycle time
//write cycle timing parameters
real tWP; //write cycle pulse width low
real tWH; //write cycle high
real tWC; //write cycle time
realtime tm_ren_pos=0;
realtime tm_ren_neg=0;
realtime tm_cen_pos=0;
realtime tm_cen_neg=0;
realtime tm_wen_pos=0;
realtime tm_wen_neg=0;
realtime tm_ale_pos=0;
realtime tm_ale_neg=0;
realtime tm_ale_clk=0;
realtime tm_cle_pos=0;
realtime tm_cle_neg=0;
realtime tm_cle_clk=0;
realtime tm_ce2n_pos=0;
realtime tm_ce2n_neg=0;
realtime tm_rbn_pos=0;
realtime tm_io =0;
realtime tm_cad_r=0;
realtime tm_clk_pos=0;
realtime tm_clk_neg=0;
realtime tm_dqs_pos=0;
realtime tm_dqs_neg=0;
real tCK_sync;
initial begin
// ----------------------------
//these toggle times are set to larger values to allow the IO bus to transition back to z before the next read
// to demonstrate the data->x->z transition. For min cycles, set these appropriately.
// Redefine these as needed with the set_read_cycle and set_write_cycle tasks.
tRP = tCEA_cache_max ; // Re_n low pulse width, adjust as needed
tREH = tRHZ_max; // Re_n high width, adjust as needed
tRC = tRP + tREH;
tWP = tWP_cache_min;
tWC = tWC_cache_min;
if ((tWC - tWP) > tWH_cache_min) begin
tWH = tWC - tWP;
end else begin
tWH = tWH_cache_min;
end
// ----------------------------
//initialize some regs that will be used
rd_verify = 0;
enable_rd_verify = 0;
rd_verify_sync = 0;
device = 0;
lastCmd = 8'h00;
lastState = 3'b000;
Dqs = 1'bz;
end
//to determine whether or not the testbench needs to use cache mode timing when driving the NAND inputs,
// we'll keep track of whether any of the NAND dies are in cache mode.
// `ifdef (CLASSB || CLASSC || CLASSD || CLASSE || CLASSQ || CLASSR)
`ifdef CLASSB
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode);
`else `ifdef CLASSC
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode);
`else `ifdef CLASSD
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode);
`else `ifdef CLASSE
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode);
`else `ifdef CLASSQ
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode);
`else `ifdef CLASSR
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode);
// `else `ifdef (CLASSF || CLASSG || CLASST || CLASSU)
`else `ifdef CLASSF
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op || tb.uut.uut_2.cache_op || tb.uut.uut_3.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode || tb.uut.uut_2.sync_mode || tb.uut.uut_3.sync_mode);
`else `ifdef CLASSG
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op || tb.uut.uut_2.cache_op || tb.uut.uut_3.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode || tb.uut.uut_2.sync_mode || tb.uut.uut_3.sync_mode);
`else `ifdef CLASST
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op || tb.uut.uut_2.cache_op || tb.uut.uut_3.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode || tb.uut.uut_2.sync_mode || tb.uut.uut_3.sync_mode);
`else `ifdef CLASSU
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op || tb.uut.uut_2.cache_op || tb.uut.uut_3.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode || tb.uut.uut_2.sync_mode || tb.uut.uut_3.sync_mode);
// `else `ifdef (CLASSK || CLASSW)
`else `ifdef CLASSK
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op || tb.uut.uut_2.cache_op || tb.uut.uut_3.cache_op || tb.uut.uut_4.cache_op || tb.uut.uut_5.cache_op || tb.uut.uut_6.cache_op || tb.uut.uut_7.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode || tb.uut.uut_2.sync_mode || tb.uut.uut_3.sync_mode || tb.uut.uut_4.sync_mode || tb.uut.uut_5.sync_mode || tb.uut.uut_6.sync_mode || tb.uut.uut_7.sync_mode);
`else `ifdef CLASSW
assign cache_mode = (tb.uut.uut_0.cache_op || tb.uut.uut_1.cache_op || tb.uut.uut_2.cache_op || tb.uut.uut_3.cache_op || tb.uut.uut_4.cache_op || tb.uut.uut_5.cache_op || tb.uut.uut_6.cache_op || tb.uut.uut_7.cache_op);
assign sync_mode = (tb.uut.uut_0.sync_mode || tb.uut.uut_1.sync_mode || tb.uut.uut_2.sync_mode || tb.uut.uut_3.sync_mode || tb.uut.uut_4.sync_mode || tb.uut.uut_5.sync_mode || tb.uut.uut_6.sync_mode || tb.uut.uut_7.sync_mode);
`else
assign cache_mode = tb.uut.uut_0.cache_op;
assign sync_mode = tb.uut.uut_0.sync_mode;
`endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif
`endif
nand_model uut (
`ifdef CLASSC Ce2_n,
`else `ifdef CLASSD Ce2_n, Rb2_n,
`else `ifdef CLASSE Ce2_n, Rb2_n, IO2, Cle2, Ale2, Clk_We2_n, Wr_Re2_n, Wp2_n,
`else `ifdef CLASSF Ce2_n, Rb2_n,
`else `ifdef CLASSG Ce2_n, Rb2_n, IO2, Cle2, Ale2, Clk_We2_n, Wr_Re2_n, Wp2_n,
`else `ifdef CLASSK Ce2_n, Ce3_n, Ce4_n, Rb2_n, Rb3_n, Rb4_n, IO2, Cle2, Ale2, Clk_We2_n, Wr_Re2_n, Wp2_n,
`else `ifdef CLASSQ Ce2_n, Rb2_n,
`else `ifdef CLASSR Ce2_n, Rb2_n, IO2, Cle2, Ale2, Clk_We2_n, Wr_Re2_n, Wp2_n,
`else `ifdef CLASST Ce2_n, Rb2_n,
`else `ifdef CLASSU Ce2_n, Rb2_n, IO2, Cle2, Ale2, Clk_We2_n, Wr_Re2_n, Wp2_n,
`else `ifdef CLASSW Ce2_n, Ce3_n, Ce4_n, Rb2_n, Rb3_n, Rb4_n, IO2, Cle2, Ale2, Clk_We2_n, Wr_Re2_n, Wp2_n,
`else // CLASS A,B,M
`endif `endif `endif `endif `endif `endif `endif `endif `endif `endif
`endif
IO,
Cle,
Ale,
We_n,
Re_n,
Ce_n,
Wp_n,
Rb_n
);
always @(posedge Re_n) begin
tm_ren_pos = $realtime;
end
always @(negedge Re_n) begin
tm_ren_neg = $realtime;
end
always @(posedge We_n) begin
tm_wen_pos <= $realtime;
end
always @(posedge Clk) begin
tm_clk_pos = $realtime;
if (sync_mode && any_device_active && Ale && ~Cle) begin
tm_ale_clk <= $realtime;
end
if (sync_mode && any_device_active && ~Ale && Cle) begin
tm_cle_clk <= $realtime;
end
end
always @(negedge Clk) tm_clk_neg = $realtime;
always @(negedge We_n) begin
tm_wen_neg = $realtime;
end
always @(posedge Ce_n) begin
tm_cen_pos = $realtime;
end
always @(negedge Ce_n) begin
tm_cen_neg = $realtime;
end
always @(posedge Ce2_n) begin
tm_ce2n_pos = $realtime;
end
always @(negedge Ce2_n) begin
tm_ce2n_neg = $realtime;
end
always @(posedge Cle) begin
tm_cle_pos = $realtime;
end
always @(negedge Cle) begin
tm_cle_neg = $realtime;
end
always @(posedge Ale) begin
tm_ale_pos = $realtime;
end
always @(negedge Ale) begin
tm_ale_neg = $realtime;
end
always @(posedge Rb_n) begin
tm_rbn_pos = $realtime;
end
always @(IO) begin
tm_io = $realtime;
end
function [23 : 0] fn_row_addr ;
input [BLCK_BITS -1 : 0] blck_addr ;
input [PAGE_BITS -1 : 0] page_addr ;
input page_en ;
begin
`ifdef PAGEBITSGT8
fn_row_addr [07:00] = {8{page_en}} & page_addr [(PAGE_BITS -1 -(PAGE_BITS-8)) : 0];
fn_row_addr [15:08] = {blck_addr [(15 - PAGE_BITS) : 0], ({(PAGE_BITS-8){page_en}} & page_addr[PAGE_BITS-8: 8])};
fn_row_addr [23:16] = {{(24 - (BLCK_BITS + PAGE_BITS)){1'b0}}, blck_addr [(BLCK_BITS -1) : (16 - PAGE_BITS)]};
`else `ifdef PAGEBITS8
fn_row_addr [07:00] = {8{page_en}} & page_addr[7 : 0];
fn_row_addr [15:08] = blck_addr [(15 - PAGE_BITS) : 0];
fn_row_addr [23:16] = {{(24 - (BLCK_BITS + PAGE_BITS)){1'b0}}, blck_addr [(BLCK_BITS -1) : (16 - PAGE_BITS)]};
`else
fn_row_addr [07:00] = {blck_addr [(7 - PAGE_BITS):0],({PAGE_BITS {page_en}} & page_addr[PAGE_BITS-1:0])};
fn_row_addr [15:08] = blck_addr [(15 - PAGE_BITS) : (8 - PAGE_BITS)];
fn_row_addr [23:16] = {{(24 - (BLCK_BITS + PAGE_BITS)){1'b0}}, blck_addr [(BLCK_BITS -1) : (16 - PAGE_BITS)]};
`endif `endif
end
endfunction
//lets user define read cycle time parameters
task set_read_cycle;
input tRP_new; //low time
input tREH_new; //high time
real tRP_new; //low time
real tREH_new; //high time
begin
tRP = tRP_new;
tREH = tREH_new;
tRC = tRP + tREH;
end
endtask
//lets user define read cycle time parameters
task set_write_cycle;
input tWP_new;
input tWH_new;
real tWP_new;
real tWH_new;
begin
tWP = tWP_new;
tWH = tWH_new;
tWC = tRP + tREH;
end
endtask
task wait_posedge_clk;
begin
if (Clk === 1) wait (Clk === 0);
wait (Clk === 1);
end
endtask
task wait_negedge_clk;
begin
if (Clk === 0) wait (Clk === 1);
wait (Clk === 0);
end
endtask
// 0 = dies controlled by Ce_n, 1 = dies controlled by Ce2_n
task activate_device;
input dev;
begin
device = dev; //device variable is global
if (sync_mode) begin //can't transition Ce pin while data is on Io/Dq
end
if (dev==1) begin
if (Ce_n == 0) begin
Ce_n <= 1;
end
Ce2_n <= 0;
end else begin
if (Ce2_n == 0) begin
Ce2_n <= 1;
end
Ce_n <= 0;
end
end
endtask
task disable_device;
input [1:0] dev;
begin
if (sync_mode) begin //can't transition Ce pin while data is on Io/Dq
end
case (dev)
2'b00 : Ce_n <= 1;
2'b01 : Ce2_n <= 1;
2'b10 : Ce3_n <= 1;
2'b11 : Ce4_n <= 1;
endcase
end
endtask
// Wait Ready : wait for [ready]->busy->ready
task wait_ready;
begin
if (device == 1) begin
if (Rb2_n === 1) begin
if (($realtime - tm_wen_pos) < tWB_max) #tWB_max;
wait (Rb2_n === 1);
end else if (Rb2_n === 0) begin
wait (Rb2_n === 1);
end
#tRR_min;
end else begin
if (Rb_n === 1) begin
if (sync_mode) begin
end else begin
if (($realtime - tm_wen_pos) < tWB_max) #tWB_max;
wait (Rb_n === 1);
end
end else if (Rb_n === 0) begin
wait (Rb_n === 1);
end
#tRR_min;
end
end
endtask
//pulse Re_n to latch read data
task latch_read;
// parameter trl=tRP;
// parameter trh=(tRC - tRP);
real tCCS;
real tCCS_cache;
begin
Cle = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -