thermometer_digital/rtl/systemregfile/my_systemregfile.v

134 lines
6.0 KiB
Verilog

//+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