Add special event load instruction (p.elw)

This commit is contained in:
Andreas Traber 2016-03-02 14:26:29 +01:00
parent 3b127ca326
commit 217adf9dc0
7 changed files with 99 additions and 71 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,7 +29,7 @@
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`define TRACE_EXECUTION
//`define SIMCHECKER
`define SIMCHECKER
`endif

View file

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