diff --git a/cs_registers.sv b/cs_registers.sv index 856fc528..0d24c56e 100644 --- a/cs_registers.sv +++ b/cs_registers.sv @@ -27,6 +27,8 @@ module riscv_cs_registers #( + parameter N_HWLP = 2, + parameter N_HWLP_BITS = $clog2(N_HWLP), parameter N_EXT_PERF_COUNTERS = 0 ) ( @@ -55,6 +57,15 @@ module riscv_cs_registers input logic [5:0] exc_cause_i, input logic save_exc_cause_i, + // Hardware loops + input logic [N_HWLP-1:0] [31:0] hwlp_start_i, + input logic [N_HWLP-1:0] [31:0] hwlp_end_i, + input logic [N_HWLP-1:0] [31:0] hwlp_cnt_i, + + output logic [31:0] hwlp_data_o, + output logic [N_HWLP_BITS-1:0] hwlp_regid_o, + output logic [2:0] hwlp_we_o, + // Performance Counters input logic id_valid_i, // ID stage is done input logic is_compressed_i, // compressed instruction in ID @@ -143,6 +154,14 @@ module riscv_cs_registers 12'hF01: csr_rdata_int = 32'h00_00_80_00; // mhartid: unique hardware thread id 12'hF10: csr_rdata_int = {22'b0, cluster_id_i, core_id_i}; + + // hardware loops + 12'h7B0: csr_rdata_int = hwlp_start_i[0]; + 12'h7B1: csr_rdata_int = hwlp_end_i[0]; + 12'h7B2: csr_rdata_int = hwlp_cnt_i[0]; + 12'h7B4: csr_rdata_int = hwlp_start_i[1]; + 12'h7B5: csr_rdata_int = hwlp_end_i[1]; + 12'h7B6: csr_rdata_int = hwlp_cnt_i[1]; endcase end @@ -164,9 +183,19 @@ module riscv_cs_registers 12'h341: if (csr_we_int) csr_n[`CSR_IDX_MEPC] = csr_wdata_int; // mcause 12'h342: if (csr_we_int) exc_cause_n = {csr_wdata_int[5], csr_wdata_int[4:0]}; + + // hardware loops + 12'h7B0: if (csr_we_int) begin hwlp_we_o = 2'b00; hwlp_regid_o = 1'b0; end + 12'h7B1: if (csr_we_int) begin hwlp_we_o = 2'b01; hwlp_regid_o = 1'b0; end + 12'h7B2: if (csr_we_int) begin hwlp_we_o = 2'b10; hwlp_regid_o = 1'b0; end + 12'h7B4: if (csr_we_int) begin hwlp_we_o = 2'b00; hwlp_regid_o = 1'b1; end + 12'h7B5: if (csr_we_int) begin hwlp_we_o = 2'b01; hwlp_regid_o = 1'b1; end + 12'h7B6: if (csr_we_int) begin hwlp_we_o = 2'b10; hwlp_regid_o = 1'b1; end endcase end + assign hwlp_data_o = csr_wdata_int; + // CSR operation logic always_comb diff --git a/id_stage.sv b/id_stage.sv index ba52455b..b16d5dce 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -119,6 +119,11 @@ module riscv_id_stage output logic [N_HWLP-1:0] [31:0] hwlp_end_o, output logic [N_HWLP-1:0] [31:0] hwlp_cnt_o, + // hwloop signals from CS register + input logic [N_HWLP_BITS-1:0] csr_hwlp_regid_i, + input logic [2:0] csr_hwlp_we_i, + input logic [31:0] csr_hwlp_data_i, + // Interface to load store unit output logic data_req_ex_o, output logic data_we_ex_o, @@ -259,16 +264,16 @@ module riscv_id_stage logic data_req_id; // hwloop signals - logic [N_HWLP_BITS-1:0] hwloop_regid; - logic [2:0] hwloop_we; - logic hwloop_target_mux_sel; - logic hwloop_start_mux_sel; - logic hwloop_cnt_mux_sel; + logic [N_HWLP_BITS-1:0] hwloop_regid, hwloop_regid_int; + logic [2:0] hwloop_we, hwloop_we_int; + logic hwloop_target_mux_sel; + logic hwloop_start_mux_sel; + logic hwloop_cnt_mux_sel; - logic [31:0] hwloop_target; - logic [31:0] hwloop_start; - logic [31:0] hwloop_end; - logic [31:0] hwloop_cnt; + logic [31:0] hwloop_target; + logic [31:0] hwloop_start, hwloop_start_int; + logic [31:0] hwloop_end; + logic [31:0] hwloop_cnt, hwloop_cnt_int; // CSR control logic csr_access; @@ -333,7 +338,7 @@ module riscv_id_stage /////////////////////////////////////////////// // hwloop register id - assign hwloop_regid = instr[8:7]; // rd contains hwloop register id + assign hwloop_regid_int = instr[8:7]; // rd contains hwloop register id // hwloop target mux always_comb @@ -348,23 +353,28 @@ module riscv_id_stage always_comb begin unique case (hwloop_start_mux_sel) - 1'b0: hwloop_start = hwloop_target; // for PC + I imm - 1'b1: hwloop_start = current_pc_if_i; // for next PC + 1'b0: hwloop_start_int = hwloop_target; // for PC + I imm + 1'b1: hwloop_start_int = current_pc_if_i; // for next PC endcase end - // hwloop end mux - assign hwloop_end = hwloop_target; // hwloop cnt mux always_comb begin : hwloop_cnt_mux unique case (hwloop_cnt_mux_sel) - 1'b0: hwloop_cnt = imm_iz_type; - 1'b1: hwloop_cnt = operand_a_fw_id; + 1'b0: hwloop_cnt_int = imm_iz_type; + 1'b1: hwloop_cnt_int = operand_a_fw_id; endcase; end + // multiplex between access from instructions and access via CSR registers + assign hwloop_start = hwloop_we_int[0] ? hwloop_start_int : csr_hwlp_data_i; + assign hwloop_end = hwloop_we_int[1] ? hwloop_target : csr_hwlp_data_i; + assign hwloop_cnt = hwloop_we_int[2] ? hwloop_cnt_int : csr_hwlp_data_i; + assign hwloop_regid = (|hwloop_we_int) ? hwloop_regid_int : csr_hwlp_regid_i; + assign hwloop_we = (|hwloop_we_int) ? hwloop_we_int : csr_hwlp_we_i; + ////////////////////////////////////////////////////////////////// // _ _____ _ // @@ -601,7 +611,7 @@ module riscv_id_stage .data_reg_offset_o ( data_reg_offset_id ), // hwloop signals - .hwloop_we_o ( hwloop_we ), + .hwloop_we_o ( hwloop_we_int ), .hwloop_target_mux_sel_o ( hwloop_target_mux_sel ), .hwloop_start_mux_sel_o ( hwloop_start_mux_sel ), .hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ), diff --git a/riscv_core.sv b/riscv_core.sv index cc459497..2f7f3969 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -83,7 +83,8 @@ module riscv_core input logic [N_EXT_PERF_COUNTERS-1:0] ext_perf_counters_i ); - localparam N_HWLP = 2; + localparam N_HWLP = 2; + localparam N_HWLP_BITS = $clog2(N_HWLP); // IF/ID signals @@ -198,6 +199,11 @@ module riscv_core logic [N_HWLP-1:0] [31:0] hwlp_end; logic [N_HWLP-1:0] [31:0] hwlp_cnt; + // used to write from CS registers to hardware loop registers + logic [N_HWLP_BITS-1:0] csr_hwlp_regid; + logic [2:0] csr_hwlp_we; + logic [31:0] csr_hwlp_data; + // Debug Unit logic dbg_stall; @@ -277,7 +283,7 @@ module riscv_core .exc_pc_mux_i ( exc_pc_mux_id ), .exc_vec_pc_mux_i ( exc_vec_pc_mux_id ), - // from hwloop controller + // from hwloop registers .hwlp_start_i ( hwlp_start ), .hwlp_end_i ( hwlp_end ), .hwlp_cnt_i ( hwlp_cnt ), @@ -393,6 +399,11 @@ module riscv_core .hwlp_end_o ( hwlp_end ), .hwlp_cnt_o ( hwlp_cnt ), + // hardware loop signals from CSR + .csr_hwlp_regid_i ( csr_hwlp_regid ), + .csr_hwlp_we_i ( csr_hwlp_we ), + .csr_hwlp_data_i ( csr_hwlp_data ), + // LSU .data_req_ex_o ( data_req_ex ), // to load store unit .data_we_ex_o ( data_we_ex ), // to load store unit @@ -601,6 +612,15 @@ module riscv_core .exc_cause_i ( exc_cause ), .save_exc_cause_i ( save_exc_cause ), + // from hwloop registers + .hwlp_start_i ( hwlp_start ), + .hwlp_end_i ( hwlp_end ), + .hwlp_cnt_i ( hwlp_cnt ), + + .hwlp_regid_o ( csr_hwlp_regid ), + .hwlp_we_o ( csr_hwlp_we ), + .hwlp_data_o ( csr_hwlp_data ), + // performance counter related signals .id_valid_i ( id_valid ), .is_compressed_i ( is_compressed_id ),