thermometer_digital/uart_thermometer_digital/tb/tb_pulse_cnt.sv

160 lines
4.9 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.

`timescale 1ns / 1ps
module tb_pulse_cnt();
// 参数定义
localparam CLK_FREQ = 50_000_000; // 50 MHz 时钟
localparam CLK_PERIOD = 20ns; // 1/50MHz = 20ns
// 信号声明
reg clk;
reg rst_n;
reg [23:0] win_us;
reg sig_in;
wire [23:0] cnt_out;
wire vld_out;
// 实例化被测模块
pulse_cnt #(
.CLK_FREQ(CLK_FREQ)
) dut (
.clk (clk),
.rst_n (rst_n),
.sig_in (sig_in),
.win_us (win_us),
.cnt_out(cnt_out),
.vld_out(vld_out)
);
// 时钟生成
initial begin
clk = 0;
forever #(CLK_PERIOD/2) clk = ~clk;
end
// 测试激励
initial begin
// 初始化
rst_n = 0;
win_us = 24'd1000; // 默认窗口 1000 us = 1 ms
sig_in = 0;
// 释放复位
repeat(5) @(posedge clk);
rst_n = 1;
repeat(2) @(posedge clk);
// --------------------------------------------------
// 测试1窗口内无脉冲
// --------------------------------------------------
$display("Test 1: No pulse, expect cnt_out = 0 after window");
win_us = 24'd1000; // 1 ms 窗口
wait (vld_out);
$display(" cnt_out = %0d (expected 0)", cnt_out);
#(CLK_PERIOD*2);
// --------------------------------------------------
// 测试2固定频率脉冲 50 kHz (周期 20 us)
// --------------------------------------------------
$display("Test 2: 50 kHz pulse, window = 1 ms -> expected 50 pulses");
fork
begin : pulse_gen
forever begin
#10us sig_in = 1;
#10us sig_in = 0;
end
end
join_none
wait (vld_out);
$display(" cnt_out = %0d (expected 50)", cnt_out);
#(CLK_PERIOD*2);
disable pulse_gen;
// --------------------------------------------------
// 测试3脉冲频率 250 kHz (周期 2 us),窗口 1 ms -> 250 个脉冲
// --------------------------------------------------
$display("Test 3: 250 kHz pulse, window = 1 ms -> expected 250 pulses");
fork
begin : pulse_gen2
forever begin
#2us sig_in = 1;
#2us sig_in = 0;
end
end
join_none
wait (vld_out);
$display(" cnt_out = %0d (expected 250)", cnt_out);
#(CLK_PERIOD*2);
disable pulse_gen2;
// --------------------------------------------------
// 测试4动态改变窗口宽度 (2 ms),脉冲频率 250 kHz
// --------------------------------------------------
$display("Test 4: 250 kHz pulse, window = 2 ms -> expected 500 pulses");
win_us = 24'd2000; // 2 ms
// 重新启动一个脉冲生成进程
fork
begin : pulse_gen3
forever begin
#2us sig_in = 1; // 250 kHz -> 周期 4 us
#2us sig_in = 0;
end
end
join_none
wait (vld_out);
$display(" cnt_out = %0d (expected 500)", cnt_out);
#(CLK_PERIOD*2);
disable pulse_gen3;
// --------------------------------------------------
// 测试5边界情况 - 窗口极小 (1 us)
// --------------------------------------------------
$display("Test 5: 500 kHz pulse, window = 1 us -> expected 0.5? rounded to 0 or 1?");
win_us = 24'd2;
// 重新启动一个脉冲生成进程
fork
begin : pulse_gen4
forever begin
#1us sig_in = 1;
#1us sig_in = 0;
end
end
join_none
wait (vld_out);
$display(" cnt_out = %0d (expected 500)", cnt_out);
#(CLK_PERIOD*2);
disable pulse_gen4;
// --------------------------------------------------
// 测试6复位过程中行为
// --------------------------------------------------
$display("Test 6: Assert reset mid-window, check output goes to 0");
win_us = 24'd1000;
#(500us); // 窗口中间复位
rst_n = 0;
repeat(5) @(posedge clk);
rst_n = 1;
wait (vld_out);
$display(" cnt_out = %0d (should be fresh measurement)", cnt_out);
#(10us);
$display("Simulation finished.");
$finish;
end
// 监控输出有效标志并打印结果
always @(posedge vld_out) begin
$display("[%t] vld_out asserted, cnt_out = %0d", $time, cnt_out);
end
// 可选:波形转储
initial begin
$dumpfile("tb_pulse_cnt.vcd");
$dumpvars(0, tb_pulse_cnt);
end
endmodule