//+FHDR--------------------------------------------------------------------------------------------------------
// Add a new register:

// SECTION A: Add localparam ADDR_NEW = 16'hXX;.

// SECTION B: Declare wire sel_new, we_new, [31:0] reg_new;.

// SECTION C: Add decoding logic: assign sel_new = (reg_idx == ADDR_NEW >> 2);.

// SECTION D: Instantiate the underlying library, e.g., sirv_gnrl_dfflr #(32) new_dff (we_new, wrdata, reg_new, clk, rst_n);.

// SECTION F: Add else if (sel_new) rddata_reg = reg_new; in the always block.

// SECTION G: Map reg_new to the module's output ports.
//-FHDR--------------------------------------------------------------------------------------------------------

module system_regfile (
    // [BLOCK 0] System and Bus Interface
    input           clk,             
    input           rst_n,          
    input  [31:0]   wrdata,          
    input           wren,            
    input  [24:0]   rwaddr,          
    input           rden,            
    output [31:0]   rddata,

    output [23:0]win_us,
    output [1:0]out_mode,  //0: output temperature, 1: output frequency, 2: output pulse count per window
    output [15:0]temp_85_fre_k,   //Frequency at 85¡ãC, default 600khz
    output [15:0]temp_neg_40_fre_k , //Frequency at -40¡ãC, default 160khz, unit khz 
    output report_en, 
    output [23:0]rep_gap_us,  //Minimum interval (us), no reporting if smaller than win_us
    input  [23:0]therm_out, 
    input  therm_vld          

);

// =============================================================================
// [SECTION A] Address Offset Definition (Localparams)
// =============================================================================
 localparam TESTR      = 16'h00,   DATER     = 16'h04;
 localparam WIN_MODE_R = 16'h08; // Configure window time and output mode
 localparam CALIB_R    = 16'h0C; // Calibration parameter register
 localparam REPORT_R   = 16'h10; // Report enable and interval
 localparam RESULT_R   = 16'h14; // Status and result register (Read-only)



// =============================================================================
// [SECTION B] Internal Wire Declaration (Wires)
// =============================================================================

// Register selection signals (Enable Wires)
 wire sel_testr,   sel_dater;
 wire sel_win_mode, sel_calib, sel_report, sel_result;

// Write enable signals (Write Enable Wires)
 wire we_testr, we_dater;
 wire we_win_mode, we_calib, we_report;


// Register storage wires (Storage Wires)
 wire [31:0] testr, dater;
 wire [31:0]  win_mode_r, calib_r, report_r, result_r;
// =============================================================================
// [SECTION C] Decoding Logic (Decoding)
// =============================================================================
 assign sel_testr    = (rwaddr[15:0] == TESTR );
 assign sel_dater    = (rwaddr[15:0] == DATER );
 assign sel_win_mode = (rwaddr[15:0] == WIN_MODE_R );
 assign sel_calib    = (rwaddr[15:0] == CALIB_R );
 assign sel_report   = (rwaddr[15:0] == REPORT_R );
 assign sel_result   = (rwaddr[15:0] == RESULT_R );

// Write enable allocation
assign we_testr    = sel_testr    & wren;
assign we_dater    = sel_dater    & wren;
assign we_win_mode = sel_win_mode & wren;
assign we_calib    = sel_calib    & wren;
assign we_report   = sel_report   & wren;


// =============================================================================
// [SECTION D] Register Instantiation (Storage Implementation)
// =============================================================================

// --- General and Test Registers ---
sirv_gnrl_dfflrd #(32) testr_dff (32'h01234567, we_testr, wrdata[31:0], testr, clk, rst_n);
sirv_gnrl_dfflrd #(32) sfrtr_dff (32'h20260406, we_dater, wrdata[31:0], dater, clk, rst_n);

// --- Thermometer Functional Registers ---
// win_mode_r: [25:24] out_mode, [23:0] win_us (Default window 1000us)
sirv_gnrl_dfflrd #(32) win_mode_dff (32'h0000_03E8, we_win_mode, wrdata, win_mode_r, clk, rst_n);
// calib_r: [31:16] Frequency at 85¡ãC (default 600k), [15:0] Frequency at -40¡ãC (default 160k)
sirv_gnrl_dfflrd #(32) calib_dff (32'h0258_00A0, we_calib, wrdata, calib_r, clk, rst_n);
// report_r: [31] report_en, [23:0] rep_gap_us (Default interval 50ms)
sirv_gnrl_dfflrd #(32) report_dff (32'h0000_C350, we_report, wrdata, report_r, clk, rst_n);

sirv_gnrl_dffr #(32) result_dff ({8'b0,therm_out},result_r, clk, rst_n);

// =============================================================================
// [SECTION E] Special Business Logic (Business Logic)
// =============================================================================

// LVDS Real-time status register
// sirv_gnrl_dffr #(8) lvdssr_inst ({link_down, train_ready, crc_error_r, phase_adj_req_r, phase_tap[2:0], prefilling}, lvdssr, clk, rst_n);

// =============================================================================
// [SECTION F] Readback Logic (Readback Mux)
// =============================================================================
reg [31:0] rddata_reg;
always @(*) begin 
    rddata_reg = 32'b0;
    if      (sel_testr)       rddata_reg = testr;
    else if (sel_dater)       rddata_reg = dater;
    else if (sel_win_mode)    rddata_reg = win_mode_r;
    else if (sel_calib)       rddata_reg = calib_r;
    else if (sel_report)      rddata_reg = report_r;
    else if (sel_result)      rddata_reg = result_r;
end

 sirv_gnrl_dfflr #(32) rddata_out_dff (rden, rddata_reg, rddata, clk, rst_n);

// =============================================================================
// [SECTION G] Output Mapping (Output Assignments)
// =============================================================================
assign win_us            = win_mode_r[23:0];
assign out_mode          = win_mode_r[25:24];
assign temp_85_fre_k     = calib_r[31:16];
assign temp_neg_40_fre_k = calib_r[15:0];
assign report_en         = report_r[31];
assign rep_gap_us        = report_r[23:0];

endmodule