`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