📄 ddr_sdram_tb.v
字号:
begin
if (CL == 2)
ddr_cl <= 2; //cas latency = 2.0
if (CL == 3)
ddr_cl <= 2; //cas latency = 2.5
if (CL == 4)
ddr_cl <= 3; //cas latency = 3.0;
addr <= address; // Setup the requested address
cmd <= 3'b001; // Issue a burst read command
@(cmdack == 1); // wait for the ack from the controller
@(posedge clk);
cmd <= 3'b000; // Issue a NOP
for (i=1 ; i<=(ddr_cl+RCD+4); i=i+1) // wait for RCD to pass
@(posedge clk);
for(i = 1; i <= BL; i = i + 1)
begin
@(posedge clk);
read_data <= dataout; // capture the read data
#2;
if (read_data !== start_value + i - 1)
begin
$display("Read error at %h read %h expected %h", (addr+i-1), read_data, (start_value + i -1));
$stop;
end
end
end
endtask
// config(bl, cl, rc, pm, ref)
//
// This task cofigures the SDRAM devices and the controller
//
// bl : Burst length 2,4, or 8
// cl : Cas latency, 2 or 3
// rc : Ras to Cas delay.
// pm : page mode setting
// ref : refresh period setting
task config;
input [3 : 0] bl;
input [2 : 0] cl;
input [1 : 0] rc;
input pm;
input [15: 0] ref;
reg [`ASIZE-1 : 0] config_data;
begin
config_data <= 0;
@(posedge clk);
@(posedge clk);
if (bl == 2)
config_data[2:0] <= 3'b001; // set the burst length bits
else if (bl == 4)
config_data[2:0] <= 3'b010;
else if (bl == 8)
config_data[2:0] <= 3'b011;
if (cl == 2)
config_data[6:4] <= 3'b010; // set the cas latency bits
else if (cl == 3)
config_data[6:4] <= 3'b110;
else if (cl == 4)
config_data[6:4] <= 3'b011;
// issue precharge before issuing load_mode
@(posedge clk);
cmd <= 3'b100; // Issupe precharge command
@(cmdack == 1) // wait for acknowledge from controller
#2;
cmd <= 3'b000; // NOP
@(posedge clk);
#2;
// load mode register
cmd <= 3'b101; // issued the load mode command
addr[15:0] <= config_data; // put the config data onto the address bus
@(cmdack == 1) // wait for an ack from the controller
cmd <= 3'b000; // NOP
@(posedge clk);
@(posedge clk);
config_data <= 0;
config_data[15:0] <= ref; // set the refresh value
@(posedge clk);
// load refresh counter
@(posedge clk);
addr[15:0] <= config_data; // put the refresh period value onto ADDR
cmd <= 3'b111; // issue a load reg2 command
@(cmdack == 1 ); // wait for an ack from the controller
#2;
cmd <= 3'b000; // NOP
addr <= 0;
config_data <= 0;
config_data[1:0] <= cl; // load controller reg1
config_data[3:2] <= rc;
config_data[8] <= pm;
config_data[12:9] <= bl/2;
@(posedge clk);
#2;
addr[15:0] <= config_data;
cmd <= 3'b110; // issue load reg2 command
@(cmdack == 1) // wait for command ack from the controller
#2;
cmd <= 3'b000; // NOP
addr <= 0;
config_data <= 0;
end
endtask
initial begin
cmd = 0;
addr = 0;
ref_ack = 0;
dm <= 0;
#3000;
bl = 1;
$display("Testing data mask inputs");
config(8,3,3,0,1526);
#1000;
$display("writing pattern 0,1,2,3,4,5,6,7 to sdram at address 0x0");
burst_write(0, 0, 16'b0, 3, 4);
$display("Reading and verifing the pattern 0,1,2,3,4,5,6,7 at sdram address 0x0");
burst_read(0, 0, 3, 3, 4);
$display("Writing pattern 0xfffffff0, 0xfffffff1, 0xfffffff2, 0xfffffff3, 0xfffffff4, 0xfffffff5, 0xfffffff6, 0xfffffff7");
$display("with DM set to 0xf");
burst_write(0, 32'hfffffff0, 16'hffff, 3, 4);
$display("Reading and verifing that the pattern at sdram address 0x0 is");
$display("still 0,1,2,3,4,5,6,7");
burst_read(0, 0, 3, 3, 4);
$display("End of data mask test");
for (x = 1; x <=3; x = x + 1) // step through all burst lengths
begin
for (y = 2; y <= 4; y = y + 1) // step through all cas latencies
begin
for (z = 2; z <=3; z = z + 1) // step through all RC
begin
if (y == 1)
$display("configuring for bl = %d cl = 1.5 rc = %d",bl,z);
else if (y==2)
$display("configuring for bl = %d cl = 2.0 rc = %d",bl,z);
else if (y == 3)
$display("configuring for bl = %d cl = 2.5 rc = %d",bl,z);
else
$display("configuring for bl = %d cl = 3.0 rc = %d",bl,z);
config(bl*2, y, z, 0, 1526);
// perform 1024 burst writes, writing a ramp pattern
$display("Peforming burst write to first sdram bank");
test_data <= 0;
test_addr <= 0;
@(posedge clk);
@(posedge clk);
for (j = 0; j < `LOOP_LENGTH; j = j + 1)
begin
burst_write(test_addr, test_data, 4'h0, z, bl);
test_data <= test_data + bl;
test_addr <= test_addr + bl*2;
#50;
end
// perform 1024 burst reads, verifing the ramp pattern
$display("Performing burst read, verify ramp values in first sdram bank");
test_data <= 0;
test_addr <= 0;
@(posedge clk);
@(posedge clk);
for (j = 0; j < `LOOP_LENGTH; j = j + 1)
begin
burst_read(test_addr, test_data, y, z, bl);
test_data <= test_data + bl;
test_addr <= test_addr + bl*2;
@(posedge clk);
end
#500;
// perform 1024 burst writes, writing a ramp pattern
$display("Peforming burst write to second sdram bank");
test_data <= 0;
test_addr <= 22'h200000;
@(posedge clk);
@(posedge clk);
for (j = 0; j < `LOOP_LENGTH; j = j + 1)
begin
burst_write(test_addr, test_data, 4'h0, z, bl);
test_data <= test_data + bl;
test_addr <= test_addr + bl*2;
@(posedge clk);
end
// perform 1024 burst reads, verifing the ramp pattern
$display("Performing burst read, verify ramp values in second sdram bank");
test_data <= 0;
test_addr <= 22'h200000;
@(posedge clk);
@(posedge clk);
for (j = 0; j < `LOOP_LENGTH; j = j + 1)
begin
burst_read(test_addr, test_data, y, z, bl);
test_data <= test_data + bl;
test_addr <= test_addr + bl*2;
@(posedge clk);
end
#500;
$display("Test complete");
end
end
bl = bl * 2;
end
$stop;
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -