Map hardware loop registers to CSR, so they can be saved/restored for

irqs
This commit is contained in:
Andreas Traber 2015-12-07 16:36:23 +01:00
parent 5678ed7a75
commit 2c5e9b9407
3 changed files with 78 additions and 19 deletions

View file

@ -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

View file

@ -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 ),

View file

@ -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 ),