`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