`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Yangshenbo
// version:V1.0
// Create Date: 2026/04/05
//////////////////////////////////////////////////////////////////////////////////


module digital_thermometer(
    input clk,
    input rst_n,
    input sig_in, 
    input [23:0]win_us,
    input [1:0]out_mode,  //0: output temperature, 1: output frequency, 2: output pulse count per window
    input [15:0]temp_85_fre_k,   //Frequency at 85¡ãC, default 600khz
    input [15:0]temp_neg_40_fre_k , //Frequency at -40¡ãC, default 160khz, unit khz 
    input report_en, //Auto report enable
    input [23:0]rep_gap_us,  //Minimum report gap (us)
    output reg [23:0]therm_out, 
    output reg therm_vld
    );


    wire [23:0] wd_cnt_out;
    wire wd_cnt_vld;
    reg [23:0]  gap_cnt;         // Report interval counter
     reg [23:0] cur_freq_khz;
     reg signed [23:0] temp_scaled;

always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cur_freq_khz <= 0;
            temp_scaled <= 0;
        end
        else begin
            cur_freq_khz <= (wd_cnt_out * 1000) / win_us;

            if (cur_freq_khz <= temp_neg_40_fre_k) begin
                temp_scaled <= -32'sd4000; 
            end 
            else begin
                temp_scaled <= ((cur_freq_khz - temp_neg_40_fre_k) * 12500) / (temp_85_fre_k - temp_neg_40_fre_k) - 4000;
            end
        end
    end


    // Report logic and output selection
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            gap_cnt   <= 0;
            therm_vld <= 0;
            therm_out <= 0;
        end else if (wd_cnt_vld) begin
            if (report_en) begin
                if (gap_cnt >= (rep_gap_us / win_us) - 1) begin
                    gap_cnt   <= 0;
                    therm_vld <= 1'b1;
                end else begin
                    gap_cnt   <= gap_cnt + 1'b1;
                    therm_vld <= 1'b0;
                end
            end 
            else begin
                gap_cnt   <= 0;
                therm_vld <= 1'b0; 
            end

            //Output mode switching
            case (out_mode)
                2'd0: therm_out <= temp_scaled; //Output temperature scaled by 100
                2'd1: therm_out <= cur_freq_khz;     //Output frequency (kHz)
                2'd2: therm_out <= wd_cnt_out;       //Output raw pulse count
                default: therm_out <= temp_scaled;
            endcase
        end 
        else begin
            therm_vld <= 1'b0;
        end
    end


    //Instantiate sub-module
    pulse_cnt #(
        .CLK_FREQ(50_000_000)
    ) pulse_cnt_inst (
        .clk    (clk),
        .rst_n  (rst_n),
        .sig_in (sig_in),
        .win_us (win_us),
        .cnt_out(wd_cnt_out),
        .vld_out(wd_cnt_vld)
    );

endmodule