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:
Andreas Traber 2015-09-08 19:33:10 +02:00
parent f5e1020f57
commit b347299f31
3 changed files with 47 additions and 24 deletions

View file

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

View file

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

View file

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