mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 04:57:25 -04:00
Move compressed decoder/expander to IF stage
I.e. the decoder is now before the IF/ID pipeline It turns out there is enough timing budget to put it there and thus it simplifies timing in the ID stage
This commit is contained in:
parent
f5e1020f57
commit
b347299f31
3 changed files with 47 additions and 24 deletions
19
id_stage.sv
19
id_stage.sv
|
@ -55,11 +55,12 @@ module id_stage
|
|||
output logic [31:0] jump_target_o,
|
||||
|
||||
// IF and ID stage signals
|
||||
output logic compressed_instr_o,
|
||||
output logic [2:0] pc_mux_sel_o,
|
||||
output logic [1:0] exc_pc_mux_o,
|
||||
output logic force_nop_o,
|
||||
|
||||
input logic illegal_c_insn_i,
|
||||
|
||||
input logic [31:0] current_pc_if_i,
|
||||
input logic [31:0] current_pc_id_i,
|
||||
|
||||
|
@ -140,6 +141,7 @@ module id_stage
|
|||
input logic [31:0] regfile_alu_wdata_fw_i,
|
||||
|
||||
// Performance Counters
|
||||
output logic perf_compressed_o, // current instrution is compressed
|
||||
output logic perf_jump_o, // we are executing a jump instruction
|
||||
output logic perf_branch_o, // we are executing a branch instruction
|
||||
output logic perf_jr_stall_o, // jump-register-hazard
|
||||
|
@ -149,6 +151,7 @@ module id_stage
|
|||
|
||||
// Compressed instruction decoding
|
||||
logic [31:0] instr;
|
||||
logic is_compressed;
|
||||
|
||||
// Immediate decoding and sign extension
|
||||
logic [31:0] imm_i_type;
|
||||
|
@ -267,14 +270,10 @@ module id_stage
|
|||
assign pc_mux_sel_o = (exc_pc_sel == 1'b1) ? `PC_EXCEPTION : pc_mux_sel_int;
|
||||
|
||||
|
||||
// compressed instruction decoding
|
||||
compressed_decoder compressed_decoder_i (
|
||||
.instr_i ( instr_rdata_i ),
|
||||
.instr_o ( instr ),
|
||||
.is_compressed_o ( compressed_instr_o ),
|
||||
.illegal_instr_o ( illegal_c_insn )
|
||||
);
|
||||
assign instr = instr_rdata_i;
|
||||
assign is_compressed = (instr[1:0] != 2'b11);
|
||||
|
||||
assign perf_compressed_o = is_compressed;
|
||||
|
||||
// immediate extraction and sign extension
|
||||
assign imm_i_type = { {20 {instr[31]}}, instr[31:20] };
|
||||
|
@ -414,7 +413,7 @@ module id_stage
|
|||
`IMM_I: immediate_b = imm_i_type;
|
||||
`IMM_S: immediate_b = imm_s_type;
|
||||
`IMM_U: immediate_b = imm_u_type;
|
||||
`IMM_PCINCR: immediate_b = compressed_instr_o ? 32'h2 : 32'h4;
|
||||
`IMM_PCINCR: immediate_b = is_compressed ? 32'h2 : 32'h4;
|
||||
default: immediate_b = imm_i_type;
|
||||
endcase; // case (immediate_mux_sel)
|
||||
end
|
||||
|
@ -591,7 +590,7 @@ module id_stage
|
|||
.irq_present_i ( irq_present ),
|
||||
|
||||
// Exception Controller Signals
|
||||
.illegal_c_insn_i ( illegal_c_insn ),
|
||||
.illegal_c_insn_i ( illegal_c_insn_i ),
|
||||
.illegal_insn_o ( illegal_insn ),
|
||||
.trap_insn_o ( trap_insn ),
|
||||
.pc_valid_i ( pc_valid ),
|
||||
|
|
29
if_stage.sv
29
if_stage.sv
|
@ -55,6 +55,7 @@ module if_stage
|
|||
|
||||
// Output of IF Pipeline stage
|
||||
output logic [31:0] instr_rdata_id_o, // read instruction is sampled and sent to ID stage for decoding
|
||||
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,
|
||||
|
||||
|
@ -441,20 +442,40 @@ module if_stage
|
|||
offset_fsm_cs == UNALIGNED_16) || instr_req_o;
|
||||
|
||||
|
||||
|
||||
// compressed instruction decoding, or more precisely compressed instruction
|
||||
// expander
|
||||
//
|
||||
// since it does not matter where we decompress instructions, we do it here
|
||||
// to ease timing closure
|
||||
logic [31:0] instr_decompressed;
|
||||
logic illegal_c_insn;
|
||||
|
||||
compressed_decoder compressed_decoder_i
|
||||
(
|
||||
.instr_i ( instr_rdata_int ),
|
||||
.instr_o ( instr_decompressed ),
|
||||
.is_compressed_o ( ),
|
||||
.illegal_instr_o ( illegal_c_insn )
|
||||
);
|
||||
|
||||
|
||||
// IF-ID pipeline registers, frozen when the ID stage is stalled
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin : IF_ID_PIPE_REGISTERS
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
instr_rdata_id_o <= '0;
|
||||
current_pc_id_o <= '0;
|
||||
instr_rdata_id_o <= '0;
|
||||
illegal_c_insn_id_o <= 1'b0;
|
||||
current_pc_id_o <= '0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (~stall_id_i)
|
||||
begin : ENABLED_PIPE
|
||||
instr_rdata_id_o <= instr_rdata_int;
|
||||
current_pc_id_o <= current_pc_if_o;
|
||||
instr_rdata_id_o <= instr_decompressed;
|
||||
illegal_c_insn_id_o <= illegal_c_insn;
|
||||
current_pc_id_o <= current_pc_if_o;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -83,6 +83,7 @@ module riscv_core
|
|||
|
||||
// IF/ID signals
|
||||
logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
|
||||
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 force_nop_id;
|
||||
|
@ -90,7 +91,7 @@ module riscv_core
|
|||
logic [1:0] exc_pc_mux_id; // Mux selector for exception PC
|
||||
|
||||
// ID performance counter signals
|
||||
logic compressed_instr;
|
||||
logic perf_compressed;
|
||||
logic is_decoding;
|
||||
|
||||
|
||||
|
@ -240,9 +241,10 @@ module riscv_core
|
|||
.instr_rdata_i ( instr_rdata_i ),
|
||||
|
||||
// outputs to ID stage
|
||||
.instr_rdata_id_o ( instr_rdata_id ), // Output of IF Pipeline stage
|
||||
.current_pc_if_o ( current_pc_if ), // current pc
|
||||
.current_pc_id_o ( current_pc_id ), // current pc
|
||||
.instr_rdata_id_o ( instr_rdata_id ), // Output of IF Pipeline stage
|
||||
.illegal_c_insn_id_o ( illegal_c_insn_id ),
|
||||
.current_pc_if_o ( current_pc_if ), // current pc in IF stage
|
||||
.current_pc_id_o ( current_pc_id ), // current pc in ID stage
|
||||
|
||||
// Forwrding ports - control signals
|
||||
.force_nop_i ( force_nop_id ), // select incoming instr or NOP
|
||||
|
@ -308,11 +310,11 @@ module riscv_core
|
|||
.exc_pc_mux_o ( exc_pc_mux_id ),
|
||||
.force_nop_o ( force_nop_id ),
|
||||
|
||||
.illegal_c_insn_i ( illegal_c_insn_id ),
|
||||
|
||||
.current_pc_if_i ( current_pc_if ),
|
||||
.current_pc_id_i ( current_pc_id ),
|
||||
|
||||
.compressed_instr_o ( compressed_instr ),
|
||||
|
||||
// STALLS
|
||||
.stall_if_o ( stall_if ),
|
||||
.stall_id_o ( stall_id ),
|
||||
|
@ -391,6 +393,7 @@ module riscv_core
|
|||
.regfile_we_wb_i ( regfile_we_wb ), // write enable for the register file
|
||||
.regfile_wdata_wb_i ( regfile_wdata ), // write data to commit in the register file
|
||||
|
||||
.perf_compressed_o ( perf_compressed ),
|
||||
.perf_jump_o ( perf_jump ),
|
||||
.perf_branch_o ( perf_branch ),
|
||||
.perf_jr_stall_o ( perf_jr_stall ),
|
||||
|
@ -540,9 +543,9 @@ module riscv_core
|
|||
.epcr_o ( epcr ),
|
||||
|
||||
// performance counter related signals
|
||||
.stall_id_i ( stall_id ),
|
||||
.is_compressed_i ( compressed_instr ),
|
||||
.is_decoding_i ( is_decoding ),
|
||||
.stall_id_i ( stall_id ),
|
||||
.is_compressed_i ( perf_compressed ),
|
||||
.is_decoding_i ( is_decoding ),
|
||||
|
||||
.instr_fetch_i ( ~instr_ack_int ),
|
||||
|
||||
|
@ -646,7 +649,7 @@ module riscv_core
|
|||
begin
|
||||
// get current PC and instruction
|
||||
instr = id_stage_i.instr[31:0];
|
||||
compressed = id_stage_i.compressed_instr_o;
|
||||
compressed = id_stage_i.is_compressed;
|
||||
pc = id_stage_i.current_pc_id_i;
|
||||
|
||||
// get register values
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue