157 lines
3.4 KiB
Coq
157 lines
3.4 KiB
Coq
![]() |
`timescale 1ns/1ps
|
|||
|
|
|||
|
module tb_sync_fifo();
|
|||
|
|
|||
|
// 参数定义,与被测试模块保持一致
|
|||
|
parameter DATA_WIDTH = 256;
|
|||
|
parameter FIFO_DEPTH = 8;
|
|||
|
|
|||
|
// 信号定义
|
|||
|
reg clk;
|
|||
|
reg rst_n;
|
|||
|
reg wr_en;
|
|||
|
reg [DATA_WIDTH-1:0] wr_data;
|
|||
|
wire full;
|
|||
|
reg rd_en;
|
|||
|
wire [DATA_WIDTH-1:0] rd_data;
|
|||
|
wire empty;
|
|||
|
|
|||
|
// 生成时钟,周期为10ns(100MHz)
|
|||
|
initial begin
|
|||
|
clk = 1'b0;
|
|||
|
forever #5 clk = ~clk;
|
|||
|
end
|
|||
|
|
|||
|
// 实例化被测试的FIFO模块
|
|||
|
sync_fifo #(
|
|||
|
.DATA_WIDTH(DATA_WIDTH),
|
|||
|
.FIFO_DEPTH(FIFO_DEPTH)
|
|||
|
) u_sync_fifo (
|
|||
|
.clk(clk),
|
|||
|
.rst_n(rst_n),
|
|||
|
.wr_en(wr_en),
|
|||
|
.wr_data(wr_data),
|
|||
|
.full(full),
|
|||
|
.rd_en(rd_en),
|
|||
|
.rd_data(rd_data),
|
|||
|
.empty(empty)
|
|||
|
);
|
|||
|
|
|||
|
// 生成FSDB波形文件
|
|||
|
initial begin
|
|||
|
$fsdbDumpfile("tb.fsdb"); // 指定波形文件名称
|
|||
|
$fsdbDumpvars(0, tb_sync_fifo); // 记录所有层次的信号
|
|||
|
end
|
|||
|
|
|||
|
// 测试过程
|
|||
|
initial begin
|
|||
|
// 初始化所有输入信号
|
|||
|
rst_n = 1'b0;
|
|||
|
wr_en = 1'b0;
|
|||
|
wr_data = {DATA_WIDTH{1'b0}};
|
|||
|
rd_en = 1'b0;
|
|||
|
|
|||
|
// 复位操作
|
|||
|
#20;
|
|||
|
rst_n = 1'b1;
|
|||
|
#20;
|
|||
|
|
|||
|
// 测试1: 连续写入数据直到FIFO满
|
|||
|
$display("Test 1: Writing until FIFO is full");
|
|||
|
|
|||
|
rd_en = 1'b0;
|
|||
|
repeat (FIFO_DEPTH + 2) begin // 多写2个验证满状态保护
|
|||
|
|
|||
|
wr_data = $urandom_range(1, 255); // 生成1-255的随机数
|
|||
|
wr_en = 1'b1;
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
wr_en = 1'b0;
|
|||
|
#20;
|
|||
|
|
|||
|
// 测试2: 连续读出数据直到FIFO空
|
|||
|
$display("Test 2: Reading until FIFO is empty");
|
|||
|
wr_en = 1'b0;
|
|||
|
@(negedge clk);
|
|||
|
rd_en = 1'b1;
|
|||
|
repeat (FIFO_DEPTH + 2) begin // 多读2个验证空状态保护
|
|||
|
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
rd_en = 1'b0;
|
|||
|
#20;
|
|||
|
|
|||
|
// 测试3: 同时读写操作
|
|||
|
$display("Test 3: Simultaneous read and write");
|
|||
|
|
|||
|
repeat (30) begin // 同时进行30次读写
|
|||
|
wr_en = 1'b1;
|
|||
|
rd_en = 1'b1;
|
|||
|
wr_data = $urandom_range(1, 255);
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
wr_en = 1'b0;
|
|||
|
rd_en = 1'b0;
|
|||
|
#20;
|
|||
|
|
|||
|
// 测试4: 交替读写(写入一个,读出一个)
|
|||
|
$display("Test 4: Alternate read and write");
|
|||
|
repeat (10) begin
|
|||
|
// 写入一个数据
|
|||
|
wr_en = 1'b1;
|
|||
|
rd_en = 1'b0;
|
|||
|
wr_data = $urandom_range(1, 255);
|
|||
|
@(posedge clk);
|
|||
|
|
|||
|
// 读出一个数据
|
|||
|
wr_en = 1'b0;
|
|||
|
rd_en = 1'b1;
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
wr_en = 1'b0;
|
|||
|
rd_en = 1'b0;
|
|||
|
#20;
|
|||
|
|
|||
|
// 测试5: 部分填充后连续读写
|
|||
|
$display("Test 5: Partial fill then continuous read/write");
|
|||
|
// 先填充一半
|
|||
|
wr_en = 1'b1;
|
|||
|
rd_en = 1'b0;
|
|||
|
repeat (FIFO_DEPTH/2) begin
|
|||
|
wr_data = $urandom_range(1, 255);
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
|
|||
|
// 然后同时读写
|
|||
|
wr_en = 1'b1;
|
|||
|
rd_en = 1'b1;
|
|||
|
repeat (20) begin
|
|||
|
wr_data = $urandom_range(1, 255);
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
|
|||
|
// 最后清空FIFO
|
|||
|
wr_en = 1'b0;
|
|||
|
rd_en = 1'b1;
|
|||
|
repeat (FIFO_DEPTH/2) begin
|
|||
|
@(posedge clk);
|
|||
|
end
|
|||
|
rd_en = 1'b0;
|
|||
|
#50;
|
|||
|
|
|||
|
$display("All tests completed!");
|
|||
|
$finish;
|
|||
|
end
|
|||
|
|
|||
|
// 监控异常操作并打印信息
|
|||
|
always @(posedge clk) begin
|
|||
|
if (wr_en && full) begin
|
|||
|
$display("%t: Error: Trying to write to a full FIFO!", $time);
|
|||
|
end
|
|||
|
if (rd_en && empty) begin
|
|||
|
$display("%t: Error: Trying to read from an empty FIFO!", $time);
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
endmodule
|