173 lines
5.4 KiB
Systemverilog
173 lines
5.4 KiB
Systemverilog
`timescale 1ns / 1ps
|
|
|
|
module tb_digital_thermometer();
|
|
|
|
// --- Parameter ---
|
|
localparam CLK_PERIOD = 20; // 50MHz Clock
|
|
|
|
// --- Signals ---
|
|
reg clk;
|
|
reg rst_n;
|
|
reg sig_in;
|
|
reg [23:0] win_us;
|
|
reg [1:0] out_mode;
|
|
reg [15:0] temp_85_fre_k;
|
|
reg [15:0] temp_neg_40_fre_k;
|
|
reg report_en;
|
|
reg [23:0] rep_gap_us;
|
|
|
|
wire [23:0] therm_out;
|
|
wire therm_vld;
|
|
|
|
// --- DUT Instantiation ---
|
|
digital_thermometer dut (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.sig_in (sig_in),
|
|
.win_us (win_us),
|
|
.out_mode (out_mode),
|
|
.temp_85_fre_k (temp_85_fre_k),
|
|
.temp_neg_40_fre_k (temp_neg_40_fre_k),
|
|
.report_en (report_en),
|
|
.rep_gap_us (rep_gap_us),
|
|
.therm_out (therm_out),
|
|
.therm_vld (therm_vld)
|
|
);
|
|
|
|
// --- Clock Generation ---
|
|
initial begin
|
|
clk = 0;
|
|
forever #(CLK_PERIOD/2) clk = ~clk;
|
|
end
|
|
|
|
// --- Pulse Generation Task ---
|
|
// freq_khz: Target frequency (kHz)
|
|
// duration_ms: Test duration (ms)
|
|
task automatic gen_pulses(input int freq_khz, input int duration_ms);
|
|
int half_period_ns;
|
|
longint end_time_ns;
|
|
begin
|
|
if (freq_khz <= 0) begin
|
|
sig_in = 0;
|
|
#(duration_ms * 1000000);
|
|
end else begin
|
|
half_period_ns = 500000 / freq_khz;
|
|
end_time_ns = $time + (longint'(duration_ms) * 1000000);
|
|
|
|
$display("[%0t] Start generating signal: %0d kHz", $time, freq_khz);
|
|
while ($time < end_time_ns) begin
|
|
sig_in = 1;
|
|
#(half_period_ns);
|
|
sig_in = 0;
|
|
#(half_period_ns);
|
|
end
|
|
end
|
|
end
|
|
endtask
|
|
|
|
// // --- Basic Test Stimulus ---
|
|
// initial begin
|
|
// // 1. Initialize signals
|
|
// rst_n = 0;
|
|
// sig_in = 0;
|
|
// win_us = 1000; // 1ms measurement window
|
|
// out_mode = 0; // Default: temperature output
|
|
// temp_85_fre_k = 600; // 85°C -> 600kHz
|
|
// temp_neg_40_fre_k = 160; // -40°C -> 160kHz
|
|
// report_en = 0;
|
|
// rep_gap_us = 2000; // Report interval: 2ms
|
|
|
|
// // 2. Release reset
|
|
// #(CLK_PERIOD * 10);
|
|
// rst_n = 1;
|
|
// #(CLK_PERIOD * 10);
|
|
|
|
// // --- Case 1: Test -40°C (160kHz) ---
|
|
// $display("\n--- Test Case 1: -40°C (160kHz) time:%t---",$time);
|
|
// gen_pulses(160, 5);
|
|
|
|
// // --- Case 2: Test 85°C (600kHz) ---
|
|
// $display("\n--- Test Case 2: 85°C (600kHz) ---");
|
|
// gen_pulses(600, 5);
|
|
|
|
// // --- Case 3: Test mid-range temperature (380kHz) ---
|
|
// $display("\n--- Test Case 3: Mid-range (380kHz) ---");
|
|
// gen_pulses(380, 5);
|
|
|
|
// // --- Case 4: Test output modes ---
|
|
// $display("\n--- Test Case 4: Switch output modes ---");
|
|
// out_mode = 1; // Frequency mode
|
|
// gen_pulses(500, 3);
|
|
// out_mode = 2; // Edge count mode
|
|
// gen_pulses(500, 3);
|
|
|
|
// // --- Case 5: Test auto-report function ---
|
|
// $display("\n--- Test Case 5: Auto-report enabled (2ms interval) ---");
|
|
// out_mode = 0;
|
|
// report_en = 1;
|
|
// gen_pulses(300, 10);
|
|
|
|
// // End simulation
|
|
// $display("\nSimulation finished at: %0t", $time);
|
|
// #(CLK_PERIOD * 100);
|
|
// $stop;
|
|
// end
|
|
|
|
// --- Main Test: Verify Configuration & Report Interval ---
|
|
initial begin
|
|
// 1. Init
|
|
rst_n = 0;
|
|
sig_in = 0;
|
|
win_us = 1000; // 1ms window
|
|
out_mode = 0; // Mode 0: Temperature (x100 scale)
|
|
report_en = 0;
|
|
temp_neg_40_fre_k = 200;
|
|
temp_85_fre_k = 700;
|
|
rep_gap_us = 2000; // 2ms report gap
|
|
|
|
// 2. Release reset
|
|
#(CLK_PERIOD * 10);
|
|
rst_n = 1;
|
|
#(CLK_PERIOD * 20);
|
|
|
|
// --- TEST 1: Verify frequency mapping configuration ---
|
|
$display("\n[TEST 1] Verify frequency mapping parameters...");
|
|
|
|
$display(">> Input: 450kHz | Config: -40°C=200k, 85°C=700k | Expected temp: 2250");
|
|
gen_pulses(450, 4);
|
|
|
|
temp_85_fre_k = 450;
|
|
$display(">> Updated config: 85°C=450k | Input: 450kHz | Expected temp: 8500");
|
|
gen_pulses(450, 4);
|
|
|
|
|
|
// --- TEST 2: Verify rep_gap_us control ---
|
|
$display("\n[TEST 2] Verify report interval (rep_gap_us)...");
|
|
report_en = 1;
|
|
|
|
rep_gap_us = 2000;
|
|
$display(">> rep_gap_us = 2ms (Expected vld every 2ms)");
|
|
gen_pulses(300, 10);
|
|
|
|
rep_gap_us = 5000;
|
|
$display(">> rep_gap_us = 5ms (Expected vld every 5ms)");
|
|
gen_pulses(300, 15);
|
|
|
|
|
|
// --- TEST 3: Boundary test (rep_gap_us < win_us) ---
|
|
$display("\n[TEST 3] Boundary test: rep_gap_us < win_us");
|
|
rep_gap_us = 500;
|
|
gen_pulses(300, 5);
|
|
|
|
// End
|
|
$display("\nConfiguration test completed at: %0t", $time);
|
|
#(CLK_PERIOD * 100);
|
|
$stop;
|
|
end
|
|
// --- Monitor ---
|
|
initial begin
|
|
$monitor("[%0t] Valid=%b | Mode=%0d | Result=%0d",
|
|
$time, therm_vld, out_mode, therm_out);
|
|
end
|
|
|
|
endmodule |