`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