127 lines
3.0 KiB
Systemverilog
127 lines
3.0 KiB
Systemverilog
|
||
// =============================================================
|
||
// 测试模块: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
|