175 lines
5.7 KiB
Verilog
175 lines
5.7 KiB
Verilog
`timescale 1ns/1ps
|
||
|
||
module tb_array_rd();
|
||
|
||
// 时钟和复位信号
|
||
reg clk;
|
||
reg rst_n;
|
||
|
||
// 输入信号(DUT 的输入)
|
||
reg array_rd_frame_valid;
|
||
reg [151:0] array_rd_frame_data;
|
||
reg array_rdata_vld;
|
||
reg [127:0] array_rdata;
|
||
reg [7:0] array_inner_tras;
|
||
reg [7:0] array_inner_trp;
|
||
reg [7:0] array_inner_trcd_rd;
|
||
reg [7:0] array_inner_trtp;
|
||
|
||
// 输出信号(DUT 的输出)
|
||
wire array_rd_frame_ready;
|
||
wire array_rd_done;
|
||
wire array_rd_csn;
|
||
wire [15:0] array_rd_raddr;
|
||
wire array_caddr_vld_rd;
|
||
wire [5:0] array_caddr_rd;
|
||
wire array2axi_rdata_valid;
|
||
wire [127:0] array2axi_rdata;
|
||
|
||
// 实例化被测试模块(DUT)
|
||
array_rd u_array_rd(
|
||
.clk (clk),
|
||
.rst_n (rst_n),
|
||
.array_rd_frame_valid(array_rd_frame_valid),
|
||
.array_rd_frame_data(array_rd_frame_data),
|
||
.array_rd_frame_ready(array_rd_frame_ready),
|
||
.array_rd_done (array_rd_done),
|
||
.array_rd_csn (array_rd_csn),
|
||
.array_rd_raddr (array_rd_raddr),
|
||
.array_caddr_vld_rd (array_caddr_vld_rd),
|
||
.array_caddr_rd (array_caddr_rd),
|
||
.array_rdata_vld (array_rdata_vld),
|
||
.array_rdata (array_rdata),
|
||
.array_inner_tras (array_inner_tras),
|
||
.array_inner_trp (array_inner_trp),
|
||
.array_inner_trcd_rd(array_inner_trcd_rd),
|
||
.array_inner_trtp (array_inner_trtp),
|
||
.array2axi_rdata_valid(array2axi_rdata_valid),
|
||
.array2axi_rdata (array2axi_rdata)
|
||
);
|
||
|
||
// 生成时钟(50MHz,周期 20ns)
|
||
initial begin
|
||
clk = 1'b0;
|
||
forever #10 clk = ~clk;
|
||
end
|
||
|
||
// 主测试流程
|
||
initial begin
|
||
// 初始化信号
|
||
rst_n = 1'b0;
|
||
array_rd_frame_valid = 1'b0;
|
||
array_rd_frame_data = 152'd0;
|
||
array_rdata_vld = 1'b0;
|
||
array_rdata = 128'd0;
|
||
array_inner_tras = 8'd3; // 示例值:TRAS = 3 个时钟周期
|
||
array_inner_trp = 8'd2; // 示例值:TRP = 2 个时钟周期
|
||
array_inner_trcd_rd = 8'd2; // 示例值:TRCD_RD = 2 个时钟周期
|
||
array_inner_trtp = 8'd1; // 示例值:TRTP = 1 个时钟周期
|
||
|
||
// 复位释放(10 个时钟周期后)
|
||
#200;
|
||
rst_n = 1'b1;
|
||
#20;
|
||
|
||
// 测试场景 1:单帧数据读取(含 SOF 和 EOF)
|
||
$display("=== 测试场景 1:单帧数据读取 ===");
|
||
send_frame(
|
||
1'b1, // 起始标志
|
||
1'b1, // 结束标志(单帧)
|
||
16'h1234,// 读取地址
|
||
6'h05, // 列地址
|
||
128'h0 // 读取操作的帧数据中数据段无效,填0
|
||
);
|
||
#20;
|
||
drive_rdata(128'hA5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5); // 返回读取数据
|
||
wait(array_rd_done); // 等待读取完成
|
||
#100;
|
||
|
||
// 测试场景 2:多帧数据读取(首帧 SOF,末帧 EOF)
|
||
$display("=== 测试场景 2:多帧数据读取 ===");
|
||
// 第一帧(SOF=1,EOF=0)
|
||
send_frame(
|
||
1'b1,
|
||
1'b0,
|
||
16'h5678,
|
||
6'h0A,
|
||
128'h0 // 数据段无效
|
||
);
|
||
// 模拟返回第一帧数据
|
||
drive_rdata(128'h55AA55AA55AA55AA55AA55AA55AA55AA);
|
||
#10;
|
||
// 第二帧(SOF=0,EOF=1)
|
||
send_frame(
|
||
1'b0,
|
||
1'b1,
|
||
16'h5678, // 地址与前一帧相同(连续读取)
|
||
6'h0B,
|
||
128'h0 // 数据段无效
|
||
);
|
||
drive_rdata(128'hAA55AA55AA55AA55AA55AA55AA55AA55);
|
||
wait(array_rd_done); // 等待读取完成
|
||
#100;
|
||
|
||
// 测试场景 3:无输入时的空闲状态
|
||
$display("=== 测试场景 3:空闲状态验证 ===");
|
||
array_rd_frame_valid = 1'b0;
|
||
#200;
|
||
|
||
// 测试结束
|
||
$display("=== 所有测试场景完成 ===");
|
||
$finish;
|
||
end
|
||
|
||
// 任务:发送一帧读取请求
|
||
task send_frame;
|
||
input rsof; // 帧起始标志
|
||
input reof; // 帧结束标志
|
||
input [15:0] rraddr; // 读取地址
|
||
input [5:0] rcaddr; // 列地址
|
||
input [127:0] wdata; // 占位(读取操作中无效)
|
||
begin
|
||
// 等待模块就绪(ready 信号为高)
|
||
wait(array_rd_frame_ready);
|
||
#10; // 延迟一小段时间
|
||
|
||
// 驱动输入信号
|
||
array_rd_frame_valid = 1'b1;
|
||
array_rd_frame_data = {rsof, reof, rraddr, rcaddr, wdata}; // 拼接帧数据
|
||
#20; // 保持一个时钟周期
|
||
|
||
// 撤销有效信号
|
||
array_rd_frame_valid = 1'b0;
|
||
array_rd_frame_data = 152'd0;
|
||
end
|
||
endtask
|
||
|
||
// 任务:驱动读取数据返回
|
||
task drive_rdata;
|
||
input [127:0] data; // 要返回的读取数据
|
||
begin
|
||
array_rdata_vld = 1'b1;
|
||
array_rdata = data;
|
||
#20; // 保持一个时钟周期
|
||
array_rdata_vld = 1'b0;
|
||
array_rdata = 128'd0;
|
||
end
|
||
endtask
|
||
|
||
initial begin
|
||
$fsdbDumpfile("tb.fsdb");
|
||
$fsdbDumpvars(0,tb_array_rd,"+all");
|
||
$vcdpluson;
|
||
$vcdplusmemon;
|
||
end
|
||
|
||
// 监控关键信号变化(用于调试)
|
||
initial begin
|
||
$monitor(
|
||
"Time: %0t, State: %h, CSN: %b, Ready: %b, Done: %b, CaddrVld: %b, FIFOValid: %b",
|
||
$time, u_array_rd.cur_state, array_rd_csn, array_rd_frame_ready,
|
||
array_rd_done, array_caddr_vld_rd, array2axi_rdata_valid
|
||
);
|
||
end
|
||
|
||
endmodule |