📄 tb.v
字号:
/****************************************************************************************
*
* File Name: tb.v
*
*****************************************************************************************/
`timescale 1ns / 1ps
module tb;
`include "ddr_parameters.vh"
reg clk ;
reg clk_n ;
reg cke ;
reg cs_n ;
reg ras_n ;
reg cas_n ;
reg we_n ;
reg [BA_BITS - 1 : 0] ba ;
reg [ADDR_BITS - 1 : 0] a ;
reg dq_en ; reg [DM_BITS - 1 : 0] dm_out ; reg [DQ_BITS - 1 : 0] dq_out ;
reg [DM_BITS-1 : 0] dm_fifo [0 : 13]; reg [DQ_BITS-1 : 0] dq_fifo [0 : 13]; reg [DQ_BITS-1 : 0] dq_in_pos ; reg [DQ_BITS-1 : 0] dq_in_neg ; reg dqs_en ; reg [DQS_BITS - 1 : 0] dqs_out ;
reg [12 : 0] mode_reg ; //Mode Register
reg [12 : 0] ext_mode_reg; //Extended Mode Register
wire BO = mode_reg[3]; //Burst Order wire [7 : 0] BL = (1<<mode_reg[2:0]); //Burst Length
wire [2 : 0] CL = (mode_reg[6:4] == 3'b110) ? 2.5 : mode_reg[6:4]; //CAS Latency wire dqs_n_en = ~ext_mode_reg[10]; //dqs# Enable wire [2 : 0] AL = ext_mode_reg[5:3]; //Additive Latency wire [3 : 0] RL = CL ; //Read Latency wire [3 : 0] WL = 1 ; //Write Latency
wire [DM_BITS - 1 : 0] dm = dq_en ? dm_out : {DM_BITS{1'bz}}; wire [DQ_BITS - 1 : 0] dq = dq_en ? dq_out : {DQ_BITS{1'bz}}; wire [DQS_BITS - 1 : 0] dqs = dqs_en ? dqs_out : {DQS_BITS{1'bz}}; wire [DQS_BITS - 1 : 0] dqs_n = (dqs_en & dqs_n_en) ? ~dqs_out : {DQS_BITS{1'bz}}; wire [DQS_BITS - 1 : 0] rdqs_n = {DM_BITS{1'bz}};
wire [15 : 0] dqs_in = dqs; wire [63 : 0] dq_in = dq; ddr sdramddr (
clk , clk_n , cke , cs_n , ras_n , cas_n , we_n , ba , a , dm , dq , dqs );
// timing definition in tCK units real tck ;
integer tmrd ; integer trap ; integer tras ; integer trc ; integer trfc ; integer trcd ; integer trp ; integer trrd ; integer twr ;
initial begin`ifdef period tck = `period ; `else tck = tCK;`endif tmrd = ciel(tMRD/tck); trap = ciel(tRAP/tck);
tras = ciel(tRAS/tck); trc = ciel(tRC/tck); trfc = ciel(tRFC/tck); trcd = ciel(tRCD/tck); trp = ciel(tRP/tck); trrd = ciel(tRRD/tck); twr = ciel(tWR/tck); end
initial clk <= 1'b1; initial clk_n <= 1'b0; always @(posedge clk) begin clk <= #(tck/2) 1'b0; clk_n <= #(tck/2) 1'b1; clk <= #(tck) 1'b1; clk_n <= #(tck) 1'b0; end function integer ciel; input number; real number; if (number > $rtoi(number)) ciel = $rtoi(number) + 1; else ciel = number; endfunction
task power_up;
begin
cke <= 1'b0; repeat(10) @(negedge clk);
$display ("%m at time %t TB: A 200 us delay is required before CKE can be brought high.", $time); @ (negedge clk) cke = 1'b1; nop (400/tck+1);
end
endtask
task load_mode;
input [BA_BITS - 1 : 0] bank;
input [ADDR_BITS - 1 : 0] addr;
begin
case (bank)
0: mode_reg = addr;
1: ext_mode_reg = addr;
endcase
cke = 1'b1;
cs_n = 1'b0;
ras_n = 1'b0;
cas_n = 1'b0;
we_n = 1'b0;
ba = bank;
a = addr;
@(negedge clk);
end
endtask
task refresh;
begin
cke = 1'b1;
cs_n = 1'b0;
ras_n = 1'b0;
cas_n = 1'b0;
we_n = 1'b1;
@(negedge clk);
end
endtask
task burst_term; integer i;
begin cke = 1'b1; cs_n = 1'b0; ras_n = 1'b1; cas_n = 1'b1; we_n = 1'b0; @(negedge clk); for (i=0; i<BL; i=i+1) begin
dm_fifo[2*RL + i] = {DM_BITS{1'bz}} ;
dq_fifo[2*RL + i] = {DQ_BITS{1'bz}} ;
end
end endtask task self_refresh;
input count;
integer count;
begin
cke = 1'b0;
cs_n = 1'b0;
ras_n = 1'b0;
cas_n = 1'b0;
we_n = 1'b1;
repeat(count) @(negedge clk);
end
endtask
task precharge;
input [BA_BITS - 1 : 0] bank;
input ap; //precharge all
begin
cke = 1'b1;
cs_n = 1'b0;
ras_n = 1'b0;
cas_n = 1'b1;
we_n = 1'b0;
ba = bank;
a = (ap<<10);
@(negedge clk);
end
endtask
task activate;
input [BA_BITS - 1 : 0] bank;
input [ADDR_BITS - 1 : 0] row;
begin
cke = 1'b1;
cs_n = 1'b0;
ras_n = 1'b0;
cas_n = 1'b1;
we_n = 1'b1;
ba = bank;
a = row;
@(negedge clk);
end
endtask
//write task supports burst lengths <= 16
task write;
input [BA_BITS - 1 : 0] bank;
input [COL_BITS - 1 : 0] col;
input ap; //Auto Precharge input [16*DM_BITS - 1 : 0] dm; input [16*DQ_BITS - 1 : 0] dq; reg [ADDR_BITS - 1 : 0] atemp [1:0]; reg [DQ_BITS/DM_BITS - 1 : 0] dm_temp; integer i,j;
begin
cke = 1'b1;
cs_n = 1'b0;
ras_n = 1'b1;
cas_n = 1'b0;
we_n = 1'b0;
ba = bank;
atemp[0] = col & 10'h3ff; //ADDR[ 9: 0] = COL[ 9: 0] atemp[1] = (col>>10)<<11; //ADDR[ N:11] = COL[ N:10] a = atemp[0] | atemp[1] | (ap<<10);
for (i=0; i<=BL; i=i+1) begin dqs_en <= #(WL*tck + i*tck/2) 1'b1; if (i%2 === 0) begin
dqs_out <= #(WL*tck + i*tck/2) {DQS_BITS{1'b0}};
end else begin
dqs_out <= #(WL*tck + i*tck/2) {DQS_BITS{1'b1}}; end dq_en <= #(WL*tck + i*tck/2 + tck/4) 1'b1; for (j=0; j<DM_BITS; j=j+1) begin dm_temp = dm>>((i*DM_BITS + j)*DQ_BITS/DM_BITS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -