mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
Change to new encoding from Eric
This changes the way mac and mul are handled and moves the rs3 register for mac operations. When rs3 is not used, the register file port is now silenced
This commit is contained in:
parent
11ffa5630c
commit
a15f007d46
4 changed files with 100 additions and 52 deletions
|
@ -91,6 +91,18 @@ module riscv_controller
|
|||
output logic [1:0] operand_b_fw_mux_sel_o, // regfile rb data selector form ID stage
|
||||
output logic [1:0] operand_c_fw_mux_sel_o, // regfile rc data selector form ID stage
|
||||
|
||||
// forwarding detection signals
|
||||
input logic reg_d_ex_is_reg_a_i,
|
||||
input logic reg_d_ex_is_reg_b_i,
|
||||
input logic reg_d_ex_is_reg_c_i,
|
||||
input logic reg_d_wb_is_reg_a_i,
|
||||
input logic reg_d_wb_is_reg_b_i,
|
||||
input logic reg_d_wb_is_reg_c_i,
|
||||
input logic reg_d_alu_is_reg_a_i,
|
||||
input logic reg_d_alu_is_reg_b_i,
|
||||
input logic reg_d_alu_is_reg_c_i,
|
||||
|
||||
|
||||
// stall signals
|
||||
output logic halt_if_o,
|
||||
output logic halt_id_o,
|
||||
|
@ -118,16 +130,6 @@ module riscv_controller
|
|||
|
||||
logic jump_done, jump_done_q;
|
||||
|
||||
logic reg_d_ex_is_reg_a_id;
|
||||
logic reg_d_ex_is_reg_b_id;
|
||||
logic reg_d_ex_is_reg_c_id;
|
||||
logic reg_d_wb_is_reg_a_id;
|
||||
logic reg_d_wb_is_reg_b_id;
|
||||
logic reg_d_wb_is_reg_c_id;
|
||||
logic reg_d_alu_is_reg_a_id;
|
||||
logic reg_d_alu_is_reg_b_id;
|
||||
logic reg_d_alu_is_reg_c_id;
|
||||
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
// synopsys translate_off
|
||||
|
@ -426,7 +428,7 @@ module riscv_controller
|
|||
|
||||
// Stall because of load operation
|
||||
if ((data_req_ex_i == 1'b1) && (regfile_we_ex_i == 1'b1) &&
|
||||
((reg_d_ex_is_reg_a_id == 1'b1) || (reg_d_ex_is_reg_b_id == 1'b1) || (reg_d_ex_is_reg_c_id == 1'b1)) )
|
||||
((reg_d_ex_is_reg_a_i == 1'b1) || (reg_d_ex_is_reg_b_i == 1'b1) || (reg_d_ex_is_reg_c_i == 1'b1)) )
|
||||
begin
|
||||
deassert_we_o = 1'b1;
|
||||
load_stall_o = 1'b1;
|
||||
|
@ -437,9 +439,9 @@ module riscv_controller
|
|||
// we don't care about in which state the ctrl_fsm is as we deassert_we
|
||||
// anyway when we are not in DECODE
|
||||
if ((jump_in_dec_i == `BRANCH_JALR) &&
|
||||
(((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_id == 1'b1)) ||
|
||||
((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_a_id == 1'b1)) ||
|
||||
((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_id == 1'b1))) )
|
||||
(((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1)) ||
|
||||
((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_a_i == 1'b1)) ||
|
||||
((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1))) )
|
||||
begin
|
||||
jr_stall_o = 1'b1;
|
||||
deassert_we_o = 1'b1;
|
||||
|
@ -450,17 +452,6 @@ module riscv_controller
|
|||
assign misaligned_stall_o = data_misaligned_i;
|
||||
|
||||
|
||||
// Forwarding control signals
|
||||
assign reg_d_ex_is_reg_a_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_S1]) && (rega_used_i == 1'b1);
|
||||
assign reg_d_ex_is_reg_b_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_S2]) && (regb_used_i == 1'b1);
|
||||
assign reg_d_ex_is_reg_c_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_S3]) && (regc_used_i == 1'b1);
|
||||
assign reg_d_wb_is_reg_a_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_S1]) && (rega_used_i == 1'b1);
|
||||
assign reg_d_wb_is_reg_b_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_S2]) && (regb_used_i == 1'b1);
|
||||
assign reg_d_wb_is_reg_c_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_S3]) && (regc_used_i == 1'b1);
|
||||
assign reg_d_alu_is_reg_a_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_S1]) && (rega_used_i == 1'b1);
|
||||
assign reg_d_alu_is_reg_b_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_S2]) && (regb_used_i == 1'b1);
|
||||
assign reg_d_alu_is_reg_c_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_S3]) && (regc_used_i == 1'b1);
|
||||
|
||||
// Forwarding control unit
|
||||
always_comb
|
||||
begin
|
||||
|
@ -472,31 +463,25 @@ module riscv_controller
|
|||
// Forwarding WB -> ID
|
||||
if (regfile_we_wb_i == 1'b1)
|
||||
begin
|
||||
if (reg_d_wb_is_reg_a_id == 1'b1)
|
||||
if (reg_d_wb_is_reg_a_i == 1'b1)
|
||||
operand_a_fw_mux_sel_o = `SEL_FW_WB;
|
||||
if (reg_d_wb_is_reg_b_id == 1'b1)
|
||||
if (reg_d_wb_is_reg_b_i == 1'b1)
|
||||
operand_b_fw_mux_sel_o = `SEL_FW_WB;
|
||||
if (reg_d_wb_is_reg_c_id == 1'b1)
|
||||
if (reg_d_wb_is_reg_c_i == 1'b1)
|
||||
operand_c_fw_mux_sel_o = `SEL_FW_WB;
|
||||
end
|
||||
|
||||
// Forwarding EX -> ID
|
||||
if (regfile_alu_we_fw_i == 1'b1)
|
||||
begin
|
||||
if (reg_d_alu_is_reg_a_id == 1'b1)
|
||||
if (reg_d_alu_is_reg_a_i == 1'b1)
|
||||
operand_a_fw_mux_sel_o = `SEL_FW_EX;
|
||||
if (reg_d_alu_is_reg_b_id == 1'b1)
|
||||
if (reg_d_alu_is_reg_b_i == 1'b1)
|
||||
operand_b_fw_mux_sel_o = `SEL_FW_EX;
|
||||
if (reg_d_alu_is_reg_c_id == 1'b1)
|
||||
if (reg_d_alu_is_reg_c_i == 1'b1)
|
||||
operand_c_fw_mux_sel_o = `SEL_FW_EX;
|
||||
end
|
||||
|
||||
// Make sure x0 is never forwarded
|
||||
if (instr_rdata_i[`REG_S1] == 5'b0)
|
||||
operand_a_fw_mux_sel_o = `SEL_REGFILE;
|
||||
if (instr_rdata_i[`REG_S2] == 5'b0)
|
||||
operand_b_fw_mux_sel_o = `SEL_REGFILE;
|
||||
|
||||
// for misaligned memory accesses
|
||||
if (data_misaligned_i == 1'b1)
|
||||
begin
|
||||
|
|
34
decoder.sv
34
decoder.sv
|
@ -52,6 +52,7 @@ module riscv_decoder
|
|||
output logic [1:0] alu_op_b_mux_sel_o, // operand b selection: reg value or immediate
|
||||
output logic [1:0] alu_op_c_mux_sel_o, // operand c selection: reg value or jump target
|
||||
output logic [2:0] immediate_mux_sel_o, // immediate selection for operand b
|
||||
output logic [1:0] regc_mux_o, // register c selection: S3, RD or 0
|
||||
|
||||
output logic vector_mode_o, // selects between 32 bit, 16 bit and 8 bit vectorial modes
|
||||
|
||||
|
@ -126,6 +127,7 @@ module riscv_decoder
|
|||
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGB_OR_FWD;
|
||||
alu_op_c_mux_sel_o = `OP_C_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
|
||||
immediate_mux_sel_o = `IMM_I;
|
||||
|
||||
|
@ -188,7 +190,6 @@ module riscv_decoder
|
|||
alu_operator = `ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
// Calculate jump target (= PC + UJ imm)
|
||||
alu_op_c_mux_sel_o = `OP_C_JT;
|
||||
end
|
||||
|
||||
`OPCODE_JALR: begin // Jump and Link Register
|
||||
|
@ -202,7 +203,6 @@ module riscv_decoder
|
|||
regfile_alu_we = 1'b1;
|
||||
// Calculate jump target (= RS1 + I imm)
|
||||
rega_used_o = 1'b1;
|
||||
alu_op_c_mux_sel_o = `OP_C_JT;
|
||||
|
||||
if (instr_rdata_i[14:12] != 3'b0) begin
|
||||
jump_in_id = `BRANCH_NONE;
|
||||
|
@ -268,6 +268,7 @@ module riscv_decoder
|
|||
// offset from register
|
||||
regc_used_o = 1'b1;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S3;
|
||||
end
|
||||
|
||||
// store size
|
||||
|
@ -432,6 +433,12 @@ module riscv_decoder
|
|||
|
||||
// supported RV32M instructions
|
||||
{7'b000_0001, 3'b000}: mult_en = 1'b1; // Multiplication
|
||||
{7'b000_0001, 3'b001}: begin // MAC
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
mult_en = 1'b1;
|
||||
mult_mac_en = 1'b1;
|
||||
end
|
||||
|
||||
// PULP specific instructions
|
||||
{7'b000_0010, 3'b000}: alu_operator = `ALU_AVG; // Average
|
||||
|
@ -468,21 +475,22 @@ module riscv_decoder
|
|||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
regc_used_o = 1'b1;
|
||||
|
||||
case (instr_rdata_i[14:12])
|
||||
3'b000: begin // MAC
|
||||
mult_en = 1'b1;
|
||||
mult_mac_en = 1'b1;
|
||||
case (instr_rdata_i[13:12])
|
||||
2'b00: begin // multiply with subword selection
|
||||
vector_mode_o = 1'b1;
|
||||
mult_sel_subword_o = {2{instr_rdata_i[30]}};
|
||||
mult_signed_mode_o = {2{instr_rdata_i[31]}};
|
||||
|
||||
mult_en = 1'b1;
|
||||
end
|
||||
|
||||
3'b100,
|
||||
3'b101,
|
||||
3'b110,
|
||||
3'b111: begin // MAC with subword selection
|
||||
2'b01: begin // MAC with subword selection
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
vector_mode_o = 1'b1;
|
||||
mult_sel_subword_o = instr_rdata_i[13:12];
|
||||
mult_signed_mode_o = instr_rdata_i[31:30];
|
||||
mult_sel_subword_o = {2{instr_rdata_i[30]}};
|
||||
mult_signed_mode_o = {2{instr_rdata_i[31]}};
|
||||
|
||||
mult_en = 1'b1;
|
||||
mult_mac_en = 1'b1;
|
||||
|
|
54
id_stage.sv
54
id_stage.sv
|
@ -237,6 +237,7 @@ module riscv_id_stage
|
|||
logic [1:0] alu_op_a_mux_sel;
|
||||
logic [1:0] alu_op_b_mux_sel;
|
||||
logic [1:0] alu_op_c_mux_sel;
|
||||
logic [1:0] regc_mux;
|
||||
|
||||
logic vector_mode;
|
||||
|
||||
|
@ -292,6 +293,17 @@ module riscv_id_stage
|
|||
logic [31:0] alu_operand_b;
|
||||
logic [31:0] alu_operand_c;
|
||||
|
||||
// Forwarding detection signals
|
||||
logic reg_d_ex_is_reg_a_i;
|
||||
logic reg_d_ex_is_reg_b_i;
|
||||
logic reg_d_ex_is_reg_c_i;
|
||||
logic reg_d_wb_is_reg_a_i;
|
||||
logic reg_d_wb_is_reg_b_i;
|
||||
logic reg_d_wb_is_reg_c_i;
|
||||
logic reg_d_alu_is_reg_a_i;
|
||||
logic reg_d_alu_is_reg_b_i;
|
||||
logic reg_d_alu_is_reg_c_i;
|
||||
|
||||
|
||||
assign instr = instr_rdata_i;
|
||||
|
||||
|
@ -306,12 +318,26 @@ module riscv_id_stage
|
|||
// immediate for CSR manipulatin (zero extended)
|
||||
assign imm_z_type = { 27'b0, instr[`REG_S1] };
|
||||
|
||||
// source registers
|
||||
//---------------------------------------------------------------------------
|
||||
// source register selection
|
||||
//---------------------------------------------------------------------------
|
||||
assign regfile_addr_ra_id = instr[`REG_S1];
|
||||
assign regfile_addr_rb_id = instr[`REG_S2];
|
||||
assign regfile_addr_rc_id = instr[`REG_S3];
|
||||
|
||||
// register C mux
|
||||
always_comb
|
||||
begin
|
||||
unique case (regc_mux)
|
||||
`REGC_ZERO: regfile_addr_rc_id = '0;
|
||||
`REGC_RD: regfile_addr_rc_id = instr[`REG_D];
|
||||
`REGC_S3: regfile_addr_rc_id = instr[`REG_S3];
|
||||
default: regfile_addr_rc_id = '0;
|
||||
endcase
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// destination registers
|
||||
//---------------------------------------------------------------------------
|
||||
assign regfile_waddr_id = instr[`REG_D];
|
||||
|
||||
// Second Register Write Adress Selection
|
||||
|
@ -319,6 +345,18 @@ module riscv_id_stage
|
|||
assign regfile_alu_waddr_id = regfile_alu_waddr_mux_sel ?
|
||||
regfile_waddr_id : regfile_addr_ra_id;
|
||||
|
||||
// Forwarding control signals
|
||||
assign reg_d_ex_is_reg_a_id = (regfile_waddr_ex_o == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
|
||||
assign reg_d_ex_is_reg_b_id = (regfile_waddr_ex_o == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
|
||||
assign reg_d_ex_is_reg_c_id = (regfile_waddr_ex_o == regfile_addr_rc_id) && (regc_used_dec == 1'b1) && (regfile_addr_rc_id != '0);
|
||||
assign reg_d_wb_is_reg_a_id = (regfile_waddr_wb_i == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
|
||||
assign reg_d_wb_is_reg_b_id = (regfile_waddr_wb_i == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
|
||||
assign reg_d_wb_is_reg_c_id = (regfile_waddr_wb_i == regfile_addr_rc_id) && (regc_used_dec == 1'b1) && (regfile_addr_rc_id != '0);
|
||||
assign reg_d_alu_is_reg_a_id = (regfile_alu_waddr_fw_i == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0);
|
||||
assign reg_d_alu_is_reg_b_id = (regfile_alu_waddr_fw_i == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0);
|
||||
assign reg_d_alu_is_reg_c_id = (regfile_alu_waddr_fw_i == regfile_addr_rc_id) && (regc_used_dec == 1'b1) && (regfile_addr_rc_id != '0);
|
||||
|
||||
|
||||
|
||||
// kill instruction in the IF/ID stage by setting the instr_valid_id control
|
||||
// signal to 0 for instructions that are done
|
||||
|
@ -583,6 +621,7 @@ module riscv_id_stage
|
|||
.alu_op_b_mux_sel_o ( alu_op_b_mux_sel ),
|
||||
.alu_op_c_mux_sel_o ( alu_op_c_mux_sel ),
|
||||
.immediate_mux_sel_o ( immediate_mux_sel ),
|
||||
.regc_mux_o ( regc_mux ),
|
||||
|
||||
.vector_mode_o ( vector_mode ),
|
||||
|
||||
|
@ -692,6 +731,17 @@ module riscv_id_stage
|
|||
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ),
|
||||
.regfile_alu_we_fw_i ( regfile_alu_we_fw_i ),
|
||||
|
||||
// Forwarding detection signals
|
||||
.reg_d_ex_is_reg_a_i ( reg_d_ex_is_reg_a_id ),
|
||||
.reg_d_ex_is_reg_b_i ( reg_d_ex_is_reg_b_id ),
|
||||
.reg_d_ex_is_reg_c_i ( reg_d_ex_is_reg_c_id ),
|
||||
.reg_d_wb_is_reg_a_i ( reg_d_wb_is_reg_a_id ),
|
||||
.reg_d_wb_is_reg_b_i ( reg_d_wb_is_reg_b_id ),
|
||||
.reg_d_wb_is_reg_c_i ( reg_d_wb_is_reg_c_id ),
|
||||
.reg_d_alu_is_reg_a_i ( reg_d_alu_is_reg_a_id ),
|
||||
.reg_d_alu_is_reg_b_i ( reg_d_alu_is_reg_b_id ),
|
||||
.reg_d_alu_is_reg_c_i ( reg_d_alu_is_reg_c_id ),
|
||||
|
||||
// Forwarding signals
|
||||
.operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ),
|
||||
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
|
||||
|
|
|
@ -135,6 +135,11 @@
|
|||
`define REG_D 11:07
|
||||
|
||||
|
||||
`define REGC_ZERO 2'b00
|
||||
`define REGC_RD 2'b01
|
||||
`define REGC_S3 2'b10
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// _ _ _ _ ___ _ _ //
|
||||
// / \ | | | | | | / _ \ _ __ ___ _ __ __ _| |_(_) ___ _ __ ___ //
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue