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:
Andreas Traber 2016-01-21 13:08:16 +01:00
parent 11ffa5630c
commit a15f007d46
4 changed files with 100 additions and 52 deletions

View file

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

View file

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

View file

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

View file

@ -135,6 +135,11 @@
`define REG_D 11:07
`define REGC_ZERO 2'b00
`define REGC_RD 2'b01
`define REGC_S3 2'b10
//////////////////////////////////////////////////////////////////////////////
// _ _ _ _ ___ _ _ //
// / \ | | | | | | / _ \ _ __ ___ _ __ __ _| |_(_) ___ _ __ ___ //