```
`timescale 1ns/1ps
module tb_icap_ctrl;
// Testbench parameters
parameter CLK_PERIOD = 10; // 10ns clock period (100MHz)
// 主设备信号生成器
reg m_axis_tvalid; // 主设备数据有效
reg [7:0] m_axis_tdata; // 主设备数据总线
wire s_axis_tready; // 从设备就绪信号(来自DUT)
// Signals
reg clk;
reg resetn;
reg s_axis_tvalid;
wire s_axis_tready;
reg [31:0] s_axis_tdata;
reg [3:0] s_axis_tkeep;
reg s_axis_tlast;
// DUT signals
wire start;
wire done;
wire err;
// Instantiate the DUT
icap_ctrl uut (
.clk(clk),
.resetn(resetn),
.start(start),
.done(done),
.err(err),
.s_axis_tvalid(m_axis_tvalid),
.s_axis_tready(s_axis_tready),
.s_axis_tdata(m_axis_tdata),
.s_axis_tkeep(s_axis_tkeep),
.s_axis_tlast(s_axis_tlast)
);
// Clock generation
initial begin
clk = 0;
forever #(CLK_PERIOD/2) clk = ~clk;
end
// 模拟主设备响应从设备就绪状态
always @(posedge clk) begin
if(m_axis_tvalid && !s_axis_tready) begin
// 保持数据直到从设备就绪
m_axis_tdata <= m_axis_tdata;
m_axis_tvalid <= m_axis_tvalid;
end
end
// Test sequence
initial begin
// Initialize signals
resetn = 0;
s_axis_tvalid = 0;
s_axis_tdata = 0;
s_axis_tkeep = 0;
s_axis_tlast = 0;
// Reset the DUT
#20;
resetn = 1;
// Test case 1: Send normal data
#20;
s_axis_tvalid = 1;
@(posedge clk);
s_axis_tdata = 32'h12345678;
s_axis_tkeep = 4'hF;
s_axis_tlast = 0;
@(posedge clk);
s_axis_tdata = 32'h87654321;
s_axis_tlast = 0;
@(posedge clk);
s_axis_tdata = 32'hABCF0010; // Special ID
s_axis_tlast = 0;
@(posedge clk);
s_axis_tdata = 32'hDEADBEEF;
s_axis_tlast = 0;
@(posedge clk);
s_axis_tdata = 32'h34434789;
s_axis_tlast = 1;
@(posedge clk);
s_axis_tvalid = 0;
// Wait for some time and check the outputs
#100;
$display("Test case 2: done=%b, err=%b", done, err);
// Test case 3: Send data when buffer is almost full
#20;
// Simulate buffer almost full
// (Assuming buffer_almost_full is connected in the DUT)
// You can add additional logic to simulate this condition
// For example:
// uut.buffer_almost_full = 1;
// Then send data and check s_axis_tready
// Replace the following lines with your implementation
// $display("Test case 3: s_axis_tready=%b", s_axis_tready);
// Finish the simulation
#50;
$finish;
end
// Monitor the signals
initial begin
$monitor("Time:%0t | s_axis_tvalid=%b, s_axis_tready=%b, s_axis_tdata=%h, s_axis_tlast=%b | start=%b, done=%b, err=%b", $time,
s_axis_tvalid, s_axis_tready, s_axis_tdata, s_axis_tlast, start, done, err);
end
// Debug waveform dump (optional)
initial begin
$dumpfile("wave.vcd");
$dumpvars(0, tb_icap_ctrl);
end
endmodule```在这个代码基础上添加一个stream端口的模拟主设备,以在s_axis_tready=0时s_axi_data不变,以测试icap_ctrl功能的正确性