mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 13:27:10 -04:00
Add special event load instruction (p.elw)
This commit is contained in:
parent
3b127ca326
commit
217adf9dc0
7 changed files with 99 additions and 71 deletions
|
@ -141,7 +141,7 @@ module riscv_controller
|
|||
// print warning in case of decoding errors
|
||||
if (is_decoding_o && illegal_insn_i) begin
|
||||
$display("%t: Illegal instruction (core %0d) at PC 0x%h:", $time, riscv_core.core_id_i,
|
||||
riscv_id_stage.current_pc_id_i);
|
||||
riscv_id_stage.pc_id_i);
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
|
|
@ -58,6 +58,8 @@ module riscv_cs_registers
|
|||
output logic [31:0] mepc_o,
|
||||
|
||||
input logic [31:0] curr_pc_id_i,
|
||||
input logic [31:0] data_pc_ex_i,
|
||||
input logic data_load_event_ex_i,
|
||||
input logic exc_save_i,
|
||||
input logic exc_restore_i,
|
||||
|
||||
|
@ -204,7 +206,7 @@ module riscv_cs_registers
|
|||
|
||||
// exception controller gets priority over other writes
|
||||
if (exc_save_i) begin
|
||||
mepc_n = curr_pc_id_i;
|
||||
mepc_n = data_load_event_ex_i ? data_pc_ex_i : curr_pc_id_i; // save EX PC if special event load
|
||||
mestatus_n = mstatus_q;
|
||||
mstatus_n = 1'b0;
|
||||
end
|
||||
|
|
14
decoder.sv
14
decoder.sv
|
@ -81,6 +81,7 @@ module riscv_decoder
|
|||
output logic [1:0] data_type_o, // data type on data memory: byte, half word or word
|
||||
output logic data_sign_extension_o, // sign extension on read data from data memory
|
||||
output logic [1:0] data_reg_offset_o, // offset in byte inside register for stores
|
||||
output logic data_load_event_o, // data request is in the special event range
|
||||
|
||||
// hwloop signals
|
||||
output logic [2:0] hwloop_we_o, // write enable for hwloop regs
|
||||
|
@ -159,6 +160,7 @@ module riscv_decoder
|
|||
data_sign_extension_o = 1'b0;
|
||||
data_reg_offset_o = 2'b00;
|
||||
data_req = 1'b0;
|
||||
data_load_event_o = 1'b0;
|
||||
|
||||
illegal_insn_o = 1'b0;
|
||||
trap_insn = 1'b0;
|
||||
|
@ -345,12 +347,12 @@ module riscv_decoder
|
|||
endcase
|
||||
end
|
||||
|
||||
if (instr_rdata_i[14:12] == 3'b011 || instr_rdata_i[14:12] == 3'b110)
|
||||
begin
|
||||
// LD, LWU -> RV64 only
|
||||
data_req = 1'b0;
|
||||
regfile_mem_we = 1'b0;
|
||||
regfile_alu_we = 1'b0;
|
||||
// special p.elw (event load)
|
||||
if (instr_rdata_i[14:12] == 3'b110)
|
||||
data_load_event_o = 1'b1;
|
||||
|
||||
if (instr_rdata_i[14:12] == 3'b011) begin
|
||||
// LD -> RV64 only
|
||||
illegal_insn_o = 1'b1;
|
||||
end
|
||||
end
|
||||
|
|
35
id_stage.sv
35
id_stage.sv
|
@ -66,8 +66,8 @@ module riscv_id_stage
|
|||
input logic illegal_c_insn_i,
|
||||
input logic is_compressed_i,
|
||||
|
||||
input logic [31:0] current_pc_if_i,
|
||||
input logic [31:0] current_pc_id_i,
|
||||
input logic [31:0] pc_if_i,
|
||||
input logic [31:0] pc_id_i,
|
||||
|
||||
// Stalls
|
||||
output logic halt_if_o, // controller requests a halt of the IF stage
|
||||
|
@ -132,6 +132,9 @@ module riscv_id_stage
|
|||
output logic [1:0] data_type_ex_o,
|
||||
output logic data_sign_ext_ex_o,
|
||||
output logic [1:0] data_reg_offset_ex_o,
|
||||
output logic [31:0] data_pc_ex_o,
|
||||
output logic data_load_event_ex_o,
|
||||
|
||||
output logic data_misaligned_ex_o,
|
||||
|
||||
output logic prepost_useincr_ex_o,
|
||||
|
@ -269,6 +272,7 @@ module riscv_id_stage
|
|||
logic data_sign_ext_id;
|
||||
logic [1:0] data_reg_offset_id;
|
||||
logic data_req_id;
|
||||
logic data_load_event_id;
|
||||
|
||||
// hwloop signals
|
||||
logic [N_HWLP_BITS-1:0] hwloop_regid, hwloop_regid_int;
|
||||
|
@ -405,8 +409,8 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin
|
||||
unique case (hwloop_target_mux_sel)
|
||||
1'b0: hwloop_target = current_pc_id_i + {imm_iz_type[30:0], 1'b0};
|
||||
1'b1: hwloop_target = current_pc_id_i + {imm_z_type[30:0], 1'b0};
|
||||
1'b0: hwloop_target = pc_id_i + {imm_iz_type[30:0], 1'b0};
|
||||
1'b1: hwloop_target = pc_id_i + {imm_z_type[30:0], 1'b0};
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -415,7 +419,7 @@ module riscv_id_stage
|
|||
begin
|
||||
unique case (hwloop_start_mux_sel)
|
||||
1'b0: hwloop_start_int = hwloop_target; // for PC + I imm
|
||||
1'b1: hwloop_start_int = current_pc_if_i; // for next PC
|
||||
1'b1: hwloop_start_int = pc_if_i; // for next PC
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -449,8 +453,8 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : jump_target_mux
|
||||
unique case (jump_target_mux_sel)
|
||||
`JT_JAL: jump_target = current_pc_id_i + imm_uj_type;
|
||||
`JT_COND: jump_target = current_pc_id_i + imm_sb_type;
|
||||
`JT_JAL: jump_target = pc_id_i + imm_uj_type;
|
||||
`JT_COND: jump_target = pc_id_i + imm_sb_type;
|
||||
|
||||
// JALR: Cannot forward RS1, since the path is too long
|
||||
`JT_JALR: jump_target = regfile_data_ra_id + imm_i_type;
|
||||
|
@ -475,7 +479,7 @@ module riscv_id_stage
|
|||
begin : alu_operand_a_mux
|
||||
case (alu_op_a_mux_sel)
|
||||
`OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
|
||||
`OP_A_CURRPC: alu_operand_a = current_pc_id_i;
|
||||
`OP_A_CURRPC: alu_operand_a = pc_id_i;
|
||||
`OP_A_ZIMM: alu_operand_a = imm_z_type;
|
||||
`OP_A_ZERO: alu_operand_a = 32'b0;
|
||||
default: alu_operand_a = operand_a_fw_id;
|
||||
|
@ -703,6 +707,7 @@ module riscv_id_stage
|
|||
.data_type_o ( data_type_id ),
|
||||
.data_sign_extension_o ( data_sign_ext_id ),
|
||||
.data_reg_offset_o ( data_reg_offset_id ),
|
||||
.data_load_event_o ( data_load_event_id ),
|
||||
|
||||
// hwloop signals
|
||||
.hwloop_we_o ( hwloop_we_int ),
|
||||
|
@ -925,7 +930,7 @@ module riscv_id_stage
|
|||
end
|
||||
else begin
|
||||
if (jump_in_id == `BRANCH_COND && id_valid_o)
|
||||
branch_pc_ex_o <= current_pc_id_i;
|
||||
branch_pc_ex_o <= pc_id_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -966,6 +971,8 @@ module riscv_id_stage
|
|||
data_sign_ext_ex_o <= 1'b0;
|
||||
data_reg_offset_ex_o <= 2'b0;
|
||||
data_req_ex_o <= 1'b0;
|
||||
data_pc_ex_o <= '0;
|
||||
data_load_event_ex_o <= 1'b0;
|
||||
|
||||
data_misaligned_ex_o <= 1'b0;
|
||||
|
||||
|
@ -1043,6 +1050,15 @@ module riscv_id_stage
|
|||
data_type_ex_o <= data_type_id;
|
||||
data_sign_ext_ex_o <= data_sign_ext_id;
|
||||
data_reg_offset_ex_o <= data_reg_offset_id;
|
||||
|
||||
if (data_load_event_id) begin
|
||||
data_pc_ex_o <= pc_id_i;
|
||||
data_load_event_ex_o <= 1'b1;
|
||||
end else begin
|
||||
data_load_event_ex_o <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
data_load_event_ex_o <= 1'b0;
|
||||
end
|
||||
|
||||
data_misaligned_ex_o <= 1'b0;
|
||||
|
@ -1059,6 +1075,7 @@ module riscv_id_stage
|
|||
csr_op_ex_o <= `CSR_OP_NONE;
|
||||
|
||||
data_req_ex_o <= 1'b0;
|
||||
data_load_event_ex_o <= 1'b0;
|
||||
|
||||
data_misaligned_ex_o <= 1'b0;
|
||||
|
||||
|
|
10
if_stage.sv
10
if_stage.sv
|
@ -57,8 +57,8 @@ module riscv_if_stage
|
|||
output logic [31:0] instr_rdata_id_o, // read instruction is sampled and sent to ID stage for decoding
|
||||
output logic is_compressed_id_o, // compressed decoder thinks this is a compressed instruction
|
||||
output logic illegal_c_insn_id_o, // compressed decoder thinks this is an invalid instruction
|
||||
output logic [31:0] current_pc_if_o,
|
||||
output logic [31:0] current_pc_id_o,
|
||||
output logic [31:0] pc_if_o,
|
||||
output logic [31:0] pc_id_o,
|
||||
|
||||
// Forwarding ports - control signals
|
||||
input logic clear_instr_valid_i, // clear instruction valid bit in IF/ID pipe
|
||||
|
@ -304,7 +304,7 @@ module riscv_if_stage
|
|||
);
|
||||
|
||||
|
||||
assign current_pc_if_o = fetch_addr;
|
||||
assign pc_if_o = fetch_addr;
|
||||
|
||||
assign if_busy_o = prefetch_busy;
|
||||
|
||||
|
@ -351,7 +351,7 @@ module riscv_if_stage
|
|||
instr_rdata_id_o <= '0;
|
||||
illegal_c_insn_id_o <= 1'b0;
|
||||
is_compressed_id_o <= 1'b0;
|
||||
current_pc_id_o <= '0;
|
||||
pc_id_o <= '0;
|
||||
is_hwlp_id_q <= 1'b0;
|
||||
hwlp_dec_cnt_id_o <= '0;
|
||||
end
|
||||
|
@ -364,7 +364,7 @@ module riscv_if_stage
|
|||
instr_rdata_id_o <= instr_decompressed;
|
||||
illegal_c_insn_id_o <= illegal_c_insn;
|
||||
is_compressed_id_o <= instr_compressed_int;
|
||||
current_pc_id_o <= current_pc_if_o;
|
||||
pc_id_o <= pc_if_o;
|
||||
is_hwlp_id_q <= fetch_is_hwlp;
|
||||
|
||||
if (fetch_is_hwlp)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
// no traces for synthesis, they are not synthesizable
|
||||
`ifndef SYNTHESIS
|
||||
`define TRACE_EXECUTION
|
||||
//`define SIMCHECKER
|
||||
`define SIMCHECKER
|
||||
`endif
|
||||
|
||||
|
||||
|
|
103
riscv_core.sv
103
riscv_core.sv
|
@ -93,8 +93,8 @@ module riscv_core
|
|||
logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
|
||||
logic is_compressed_id;
|
||||
logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
|
||||
logic [31:0] current_pc_if; // Current Program counter
|
||||
logic [31:0] current_pc_id; // Current Program counter
|
||||
logic [31:0] pc_if; // Program counter in IF stage
|
||||
logic [31:0] pc_id; // Program counter in ID stage
|
||||
|
||||
logic clear_instr_valid;
|
||||
logic pc_set;
|
||||
|
@ -173,6 +173,8 @@ module riscv_core
|
|||
logic data_sign_ext_ex;
|
||||
logic [1:0] data_reg_offset_ex;
|
||||
logic data_req_ex;
|
||||
logic [31:0] data_pc_ex;
|
||||
logic data_load_event_ex;
|
||||
logic data_misaligned_ex;
|
||||
|
||||
// stall control
|
||||
|
@ -279,8 +281,8 @@ module riscv_core
|
|||
.instr_rdata_id_o ( instr_rdata_id ),
|
||||
.is_compressed_id_o ( is_compressed_id ),
|
||||
.illegal_c_insn_id_o ( illegal_c_insn_id ),
|
||||
.current_pc_if_o ( current_pc_if ),
|
||||
.current_pc_id_o ( current_pc_id ),
|
||||
.pc_if_o ( pc_if ),
|
||||
.pc_id_o ( pc_id ),
|
||||
|
||||
// control signals
|
||||
.clear_instr_valid_i ( clear_instr_valid ),
|
||||
|
@ -360,8 +362,8 @@ module riscv_core
|
|||
.illegal_c_insn_i ( illegal_c_insn_id ),
|
||||
.is_compressed_i ( is_compressed_id ),
|
||||
|
||||
.current_pc_if_i ( current_pc_if ),
|
||||
.current_pc_id_i ( current_pc_id ),
|
||||
.pc_if_i ( pc_if ),
|
||||
.pc_id_i ( pc_id ),
|
||||
|
||||
// Stalls
|
||||
.halt_if_o ( halt_if ),
|
||||
|
@ -418,12 +420,15 @@ module riscv_core
|
|||
.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
|
||||
.data_type_ex_o ( data_type_ex ), // to load store unit
|
||||
.data_sign_ext_ex_o ( data_sign_ext_ex ), // to load store unit
|
||||
.data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit
|
||||
.data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit
|
||||
.data_req_ex_o ( data_req_ex ), // to load store unit
|
||||
.data_we_ex_o ( data_we_ex ), // to load store unit
|
||||
.data_type_ex_o ( data_type_ex ), // to load store unit
|
||||
.data_sign_ext_ex_o ( data_sign_ext_ex ), // to load store unit
|
||||
.data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit
|
||||
.data_pc_ex_o ( data_pc_ex ), // to load store unit
|
||||
.data_load_event_ex_o ( data_load_event_ex ), // to load store unit
|
||||
|
||||
.data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit
|
||||
|
||||
.prepost_useincr_ex_o ( useincr_addr_ex ),
|
||||
.data_misaligned_i ( data_misaligned ),
|
||||
|
@ -607,52 +612,54 @@ module riscv_core
|
|||
)
|
||||
cs_registers_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
// Core and Cluster ID from outside
|
||||
.core_id_i ( core_id_i ),
|
||||
.cluster_id_i ( cluster_id_i ),
|
||||
.core_id_i ( core_id_i ),
|
||||
.cluster_id_i ( cluster_id_i ),
|
||||
|
||||
// Interface to CSRs (SRAM like)
|
||||
.csr_access_i ( csr_access_ex ),
|
||||
.csr_addr_i ( csr_addr ),
|
||||
.csr_wdata_i ( csr_wdata ),
|
||||
.csr_op_i ( csr_op ),
|
||||
.csr_rdata_o ( csr_rdata ),
|
||||
.csr_access_i ( csr_access_ex ),
|
||||
.csr_addr_i ( csr_addr ),
|
||||
.csr_wdata_i ( csr_wdata ),
|
||||
.csr_op_i ( csr_op ),
|
||||
.csr_rdata_o ( csr_rdata ),
|
||||
|
||||
// Interrupt related control signals
|
||||
.irq_enable_o ( irq_enable ),
|
||||
.mepc_o ( mepc ),
|
||||
.irq_enable_o ( irq_enable ),
|
||||
.mepc_o ( mepc ),
|
||||
|
||||
.curr_pc_id_i ( current_pc_id ), // from IF stage
|
||||
.exc_save_i ( exc_save_id ),
|
||||
.exc_restore_i ( exc_restore_id ),
|
||||
.curr_pc_id_i ( pc_id ), // from IF stage
|
||||
.data_pc_ex_i ( data_pc_ex ), // from ID/EX pipeline
|
||||
.data_load_event_ex_i ( data_load_event_ex ), // from ID/EX pipeline
|
||||
.exc_save_i ( exc_save_id ),
|
||||
.exc_restore_i ( exc_restore_id ),
|
||||
|
||||
.exc_cause_i ( exc_cause ),
|
||||
.save_exc_cause_i ( save_exc_cause ),
|
||||
.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_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 ),
|
||||
.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 ),
|
||||
.is_decoding_i ( is_decoding ),
|
||||
.id_valid_i ( id_valid ),
|
||||
.is_compressed_i ( is_compressed_id ),
|
||||
.is_decoding_i ( is_decoding ),
|
||||
|
||||
.imiss_i ( perf_imiss ),
|
||||
.pc_set_i ( pc_set ),
|
||||
.jump_i ( perf_jump ),
|
||||
.branch_i ( branch_in_ex ),
|
||||
.branch_taken_i ( branch_decision ),
|
||||
.ld_stall_i ( perf_ld_stall ),
|
||||
.jr_stall_i ( perf_jr_stall ),
|
||||
.imiss_i ( perf_imiss ),
|
||||
.pc_set_i ( pc_set ),
|
||||
.jump_i ( perf_jump ),
|
||||
.branch_i ( branch_in_ex ),
|
||||
.branch_taken_i ( branch_decision ),
|
||||
.ld_stall_i ( perf_ld_stall ),
|
||||
.jr_stall_i ( perf_jr_stall ),
|
||||
|
||||
.mem_load_i ( data_req_o & data_gnt_i & (~data_we_o) ),
|
||||
.mem_store_i ( data_req_o & data_gnt_i & data_we_o ),
|
||||
|
@ -713,8 +720,8 @@ module riscv_core
|
|||
.regfile_rdata_i ( dbg_rdata ),
|
||||
|
||||
// signals for PPC and NPC
|
||||
.curr_pc_if_i ( current_pc_if ), // from IF stage
|
||||
.curr_pc_id_i ( current_pc_id ), // from IF stage
|
||||
.curr_pc_if_i ( pc_if ), // from IF stage
|
||||
.curr_pc_id_i ( pc_id ), // from IF stage
|
||||
.branch_pc_i ( branch_pc_ex ), // PC of last executed branch (in EX stage)
|
||||
|
||||
.branch_in_ex_i ( branch_in_ex ),
|
||||
|
@ -735,7 +742,7 @@ module riscv_core
|
|||
.core_id ( core_id_i ),
|
||||
.cluster_id ( cluster_id_i ),
|
||||
|
||||
.pc ( id_stage_i.current_pc_id_i ),
|
||||
.pc ( id_stage_i.pc_id_i ),
|
||||
.instr ( id_stage_i.instr ),
|
||||
.compressed ( id_stage_i.is_compressed_i ),
|
||||
.id_valid ( id_stage_i.id_valid_o ),
|
||||
|
@ -794,7 +801,7 @@ module riscv_core
|
|||
.pc_set ( pc_set ),
|
||||
.if_valid ( if_valid ),
|
||||
|
||||
.pc ( id_stage_i.current_pc_id_i ),
|
||||
.pc ( id_stage_i.pc_id_i ),
|
||||
.instr ( id_stage_i.instr ),
|
||||
.is_compressed ( is_compressed_id ),
|
||||
.id_valid ( id_stage_i.id_valid_o ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue