ic_com/tb/fifo/sync/fifo_sync_tb.sv

127 lines
3.0 KiB
Systemverilog
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// =============================================================
// 测试模块fifo_sync_tb
// 功能描述同步FIFO仿真测试
// 仿真时钟频率1GHz周期0.5ns
// =============================================================
`timescale 1ns/1ps
module fifo_sync_tb;
parameter DATA_WIDTH = 8;
parameter DEPTH = 16;
parameter USE_RAM = 0;
parameter OUT_REG = 1;
reg clk;
reg rst_n;
reg wr_en;
reg [DATA_WIDTH-1:0] din;
reg rd_en;
wire [DATA_WIDTH-1:0] dout;
wire empty;
wire full;
wire [$clog2(DEPTH):0] fill_level;
wire err;
// 实例化DUT
fifo_sync #(
.DATA_WIDTH(DATA_WIDTH),
.DEPTH(DEPTH),
.USE_RAM(USE_RAM),
.OUT_REG(OUT_REG)
) dut (
.clk(clk),
.rst_n(rst_n),
.wr_en(wr_en),
.din(din),
.rd_en(rd_en),
.dout(dout),
.empty(empty),
.full(full),
.fill_level(fill_level),
.err(err)
);
// 仿真时钟频率1GHz周期0.5ns
// 时钟生成
initial clk = 0;
always #0.25 clk = ~clk; // 0.5ns周期1GHz
// 复位
initial begin
rst_n = 0;
wr_en = 0;
rd_en = 0;
din = 0;
#20;
rst_n = 1;
end
// 主测试流程
initial begin
wait(rst_n == 1);
@(negedge clk);
// 写入DEPTH个数据
for (int i = 0; i < DEPTH; i++) begin
@(negedge clk);
wr_en = 1;
din = i;
rd_en = 0;
end
@(negedge clk);
wr_en = 0;
// 检查full信号
if (!full) $display("[TB][ERROR] FIFO未满!");
else $display("[TB][INFO] FIFO已满!");
// 读出DEPTH个数据
for (int i = 0; i < DEPTH; i++) begin
@(negedge clk);
wr_en = 0;
rd_en = 1;
end
@(negedge clk);
rd_en = 0;
// 检查empty信号
if (!empty) $display("[TB][ERROR] FIFO未空!");
else $display("[TB][INFO] FIFO已空!");
// 尝试在empty时读触发err
@(negedge clk);
rd_en = 1;
@(negedge clk);
rd_en = 0;
if (err) $display("[TB][INFO] 读空FIFO触发err信号");
else $display("[TB][ERROR] 读空FIFO未触发err!");
// 交错写读
for (int i = 0; i < 8; i++) begin
@(negedge clk);
wr_en = 1;
din = i + 100;
rd_en = 1;
end
@(negedge clk);
wr_en = 0;
rd_en = 0;
#20;
$display("[TB][INFO] 测试结束");
$finish;
end
// 监控输出
always @(posedge clk) begin
if (wr_en && !full)
$display("[TB][WRITE] @%0t: din=%0d, wr_ptr=%0d, fill_level=%0d", $time, din, dut.wr_ptr, fill_level);
if (rd_en && !empty)
$display("[TB][READ ] @%0t: dout=%0d, rd_ptr=%0d, fill_level=%0d", $time, dout, dut.rd_ptr, fill_level);
if (err)
$display("[TB][ERR ] @%0t: 读空FIFO!", $time);
end
endmodule