Separated decoder and controller and cleanup

This commit is contained in:
Andreas Traber 2015-09-15 12:52:15 +02:00
parent d27a2a3f63
commit 9858caff47
4 changed files with 1160 additions and 1025 deletions

File diff suppressed because it is too large Load diff

867
decoder.sv Normal file
View file

@ -0,0 +1,867 @@
////////////////////////////////////////////////////////////////////////////////
// Company: IIS @ ETHZ - Federal Institute of Technology //
// //
// Engineer Andreas Traber - atraber@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// Matthias Baer - baermatt@student.ethz.ch //
// Igor Loi - igor.loi@unibo.it //
// Sven Stucki - svstucki@student.ethz.ch //
// //
// //
// Create Date: 19/09/2013 //
// Design Name: RISC-V processor core //
// Module Name: decoder.sv //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Decoder //
// //
// //
// Revision: //
// Revision v0.1 - File Created, separated controller and decoder //
// //
// //
// //
////////////////////////////////////////////////////////////////////////////////
`include "defines.sv"
module decoder
(
// singals running to/from controller
input logic deassert_we_i, // deassert we, we are stalled or not active
input logic data_misaligned_i, // misaligned data load/store in progress
output logic illegal_insn_o, // illegal instruction encountered
output logic trap_insn_o, // trap instruction encountered
output logic eret_insn_o, // trap instruction encountered
output logic pipe_flush_o, // pipeline flush is requested (e.g. WFI instruction)
output logic rega_used_o, // register A is used by current instruction
output logic regb_used_o, // register B is used by current instruction
output logic regc_used_o, // register C is used by current instruction
// from IF/ID pipeline
input logic [31:0] instr_rdata_i, // Instruction read from instr memory/cache: (sampled in the if stage)
input logic illegal_c_insn_i, // compressed instruction decode failed
// ALU signals
output logic [`ALU_OP_WIDTH-1:0] alu_operator_o, // Operator in the EX stage for the ALU block
output logic [1:0] alu_op_a_mux_sel_o, // Operator a is selected between reg value, PC or immediate
output logic [1:0] alu_op_b_mux_sel_o, // Operator b is selected between reg value or immediate
output logic alu_op_c_mux_sel_o, // Operator c is selected between reg value or PC
output logic [2:0] immediate_mux_sel_o,
output logic [1:0] vector_mode_o, // selects between 32 bit, 16 bit and 8 bit vectorial modes
output logic scalar_replication_o, // activates scalar_replication for vectorial mode
output logic [1:0] alu_cmp_mode_o, // selects comparison mode for ALU (i.e. full, any, all)
// MUL related control signals
output logic mult_en_o, // Perform a multiplication operation
output logic [1:0] mult_sel_subword_o, // Select subwords for 16x16 bit of multiplier
output logic [1:0] mult_signed_mode_o, // Multiplication in signed mode
output logic mult_mac_en_o, // Use the accumulator after multiplication
// register file related signals
output logic regfile_mem_we_o, // Write Enable to regfile
output logic regfile_alu_we_o, // Write Enable to regfile 2nd port
output logic regfile_alu_waddr_sel_o, // Select register write address for ALU/MUL operations
// CSR manipulation
output logic csr_access_o, // perform an access to CSR
output logic [1:0] csr_op_o, // operation to perform on CSR
// LD/ST unit signals
output logic data_req_o, // Request for a transaction to data memory
output logic data_we_o, // Write enable to data memory
output logic prepost_useincr_o, // When not active bypass the alu result for address calculation = op_a
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 bytes inside register for stores
// hwloop signals
output logic [2:0] hwloop_we_o, // write enable for hwloop regs
output logic hwloop_start_mux_sel_o, // selects hwloop start address input
output logic hwloop_end_mux_sel_o, // selects hwloop end address input
output logic hwloop_cnt_mux_sel_o, // selects hwloop counter input
// jump/branches
output logic [1:0] jump_in_dec_o, // jump_in_id without deassert
output logic [1:0] jump_in_id_o, // jump is being calculated in ALU
output logic [1:0] jump_target_mux_sel_o // jump target selection
);
// write enable/request control
logic regfile_mem_we;
logic regfile_alu_we;
logic data_req;
logic data_we;
logic [2:0] hwloop_we;
logic trap_insn;
logic eret_insn;
logic pipe_flush;
logic [1:0] jump_in_id;
logic [`ALU_OP_WIDTH-1:0] alu_operator;
logic mult_en;
logic [1:0] csr_op;
/////////////////////////////////////////////
// ____ _ //
// | _ \ ___ ___ ___ __| | ___ _ __ //
// | | | |/ _ \/ __/ _ \ / _` |/ _ \ '__| //
// | |_| | __/ (_| (_) | (_| | __/ | //
// |____/ \___|\___\___/ \__,_|\___|_| //
// //
/////////////////////////////////////////////
always_comb
begin
jump_in_id = `BRANCH_NONE;
jump_target_mux_sel_o = `JT_JAL;
alu_operator = `ALU_NOP;
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;
immediate_mux_sel_o = `IMM_I;
vector_mode_o = `VEC_MODE32;
scalar_replication_o = 1'b0;
alu_cmp_mode_o = `ALU_CMP_FULL;
mult_en = 1'b0;
mult_signed_mode_o = 2'b00;
mult_sel_subword_o = 2'b00;
mult_mac_en_o = 1'b0;
regfile_mem_we = 1'b0;
regfile_alu_we = 1'b0;
regfile_alu_waddr_sel_o = 1'b1;
prepost_useincr_o = 1'b1;
hwloop_we = 3'b0;
hwloop_start_mux_sel_o = 1'b0;
hwloop_end_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 1'b0;
csr_access_o = 1'b0;
csr_op = `CSR_OP_NONE;
data_we = 1'b0;
data_type_o = 2'b00;
data_sign_extension_o = 1'b0;
data_reg_offset_o = 2'b00;
data_req = 1'b0;
illegal_insn_o = 1'b0;
trap_insn = 1'b0;
eret_insn = 1'b0;
pipe_flush = 1'b0;
rega_used_o = 1'b0;
regb_used_o = 1'b0;
regc_used_o = 1'b0;
unique case (instr_rdata_i[6:0])
//////////////////////////////////////
// _ _ _ __ __ ____ ____ //
// | | | | | \/ | _ \/ ___| //
// _ | | | | | |\/| | |_) \___ \ //
// | |_| | |_| | | | | __/ ___) | //
// \___/ \___/|_| |_|_| |____/ //
// //
//////////////////////////////////////
`OPCODE_JAL: begin // Jump and Link
jump_target_mux_sel_o = `JT_JAL;
jump_in_id = `BRANCH_JAL;
// Calculate and store PC+4
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
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
jump_target_mux_sel_o = `JT_JALR;
jump_in_id = `BRANCH_JALR;
// Calculate and store PC+4
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
alu_operator = `ALU_ADD;
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;
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b0;
end
end
`OPCODE_BRANCH: begin // Branch
jump_target_mux_sel_o = `JT_COND;
jump_in_id = `BRANCH_COND;
alu_op_c_mux_sel_o = `OP_C_JT;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
unique case (instr_rdata_i[14:12])
3'b000: alu_operator = `ALU_EQ;
3'b001: alu_operator = `ALU_NE;
3'b100: alu_operator = `ALU_LTS;
3'b101: alu_operator = `ALU_GES;
3'b110: alu_operator = `ALU_LTU;
3'b111: alu_operator = `ALU_GEU;
default: begin
illegal_insn_o = 1'b1;
end
endcase
end
//////////////////////////////////
// _ ____ ______ _____ //
// | | | _ \ / / ___|_ _| //
// | | | | | |/ /\___ \ | | //
// | |___| |_| / / ___) || | //
// |_____|____/_/ |____/ |_| //
// //
//////////////////////////////////
`OPCODE_STORE,
`OPCODE_STORE_POST: begin
data_req = 1'b1;
data_we = 1'b1;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
alu_operator = `ALU_ADD;
// post-increment setup
if (instr_rdata_i[6:0] == `OPCODE_STORE_POST) begin
prepost_useincr_o = 1'b0;
regfile_alu_waddr_sel_o = 1'b0;
regfile_alu_we = 1'b1;
end
if (instr_rdata_i[14] == 1'b0) begin
// offset from immediate
immediate_mux_sel_o = `IMM_S;
alu_op_b_mux_sel_o = `OP_B_IMM;
end else begin
// offset from register
regc_used_o = 1'b1;
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
end
// store size
unique case (instr_rdata_i[13:12])
2'b00: data_type_o = 2'b10; // SB
2'b01: data_type_o = 2'b01; // SH
2'b10: data_type_o = 2'b00; // SW
default: begin
data_req = 1'b0;
data_we = 1'b0;
illegal_insn_o = 1'b1;
end
endcase
end
`OPCODE_LOAD,
`OPCODE_LOAD_POST: begin
data_req = 1'b1;
regfile_mem_we = 1'b1;
rega_used_o = 1'b1;
data_type_o = 2'b00;
// offset from immediate
alu_operator = `ALU_ADD;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_I;
// post-increment setup
if (instr_rdata_i[6:0] == `OPCODE_LOAD_POST) begin
prepost_useincr_o = 1'b0;
regfile_alu_waddr_sel_o = 1'b0;
regfile_alu_we = 1'b1;
end
// sign/zero extension
data_sign_extension_o = ~instr_rdata_i[14];
// load size
unique case (instr_rdata_i[13:12])
2'b00: data_type_o = 2'b10; // LB
2'b01: data_type_o = 2'b01; // LH
2'b10: data_type_o = 2'b00; // LW
default: data_type_o = 2'b00; // illegal or reg-reg
endcase
// reg-reg load (different encoding)
if (instr_rdata_i[14:12] == 3'b111) begin
// offset from RS2
regb_used_o = 1'b1;
alu_op_b_mux_sel_o = `OP_B_REGB_OR_FWD;
// sign/zero extension
data_sign_extension_o = ~instr_rdata_i[30];
// load size
unique case (instr_rdata_i[31:25])
7'b0000_000,
7'b0100_000: data_type_o = 2'b10; // LB, LBU
7'b0001_000,
7'b0101_000: data_type_o = 2'b01; // LH, LHU
7'b0010_000: data_type_o = 2'b00; // LW
default: begin
data_type_o = 2'b00;
// illegal instruction
data_req = 1'b0;
regfile_mem_we = 1'b0;
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1;
end
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;
illegal_insn_o = 1'b1;
end
end
//////////////////////////
// _ _ _ _ //
// / \ | | | | | | //
// / _ \ | | | | | | //
// / ___ \| |__| |_| | //
// /_/ \_\_____\___/ //
// //
//////////////////////////
`OPCODE_LUI: begin // Load Upper Immediate
alu_op_a_mux_sel_o = `OP_A_ZERO;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_U;
alu_operator = `ALU_ADD;
regfile_alu_we = 1'b1;
end
`OPCODE_AUIPC: begin // Add Upper Immediate to PC
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_U;
alu_operator = `ALU_ADD;
regfile_alu_we = 1'b1;
end
`OPCODE_OPIMM: begin // Reigster-Immediate ALU Operations
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_I;
regfile_alu_we = 1'b1;
rega_used_o = 1'b1;
unique case (instr_rdata_i[14:12])
3'b000: alu_operator = `ALU_ADD; // Add Immediate
3'b010: alu_operator = `ALU_SLTS; // Set to one if Lower Than Immediate
3'b011: alu_operator = `ALU_SLTU; // Set to one if Lower Than Immediate Unsigned
3'b100: alu_operator = `ALU_XOR; // Exclusive Or with Immediate
3'b110: alu_operator = `ALU_OR; // Or with Immediate
3'b111: alu_operator = `ALU_AND; // And with Immediate
3'b001: begin
alu_operator = `ALU_SLL; // Shift Left Logical by Immediate
if (instr_rdata_i[31:25] != 7'b0)
illegal_insn_o = 1'b1;
end
3'b101: begin
if (instr_rdata_i[31:25] == 7'b0)
alu_operator = `ALU_SRL; // Shift Right Logical by Immediate
else if (instr_rdata_i[31:25] == 7'b010_0000)
alu_operator = `ALU_SRA; // Shift Right Arithmetically by Immediate
else
illegal_insn_o = 1'b1;
end
default: illegal_insn_o = 1'b1;
endcase
end
`OPCODE_OP: begin // Register-Register ALU operation
regfile_alu_we = 1'b1;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
unique case ({instr_rdata_i[31:25], instr_rdata_i[14:12]})
{7'b000_0000, 3'b000}: alu_operator = `ALU_ADD; // Add
{7'b010_0000, 3'b000}: alu_operator = `ALU_SUB; // Sub
{7'b000_0000, 3'b010}: alu_operator = `ALU_SLTS; // Set Lower Than
{7'b000_0000, 3'b011}: alu_operator = `ALU_SLTU; // Set Lower Than Unsigned
{7'b000_0000, 3'b100}: alu_operator = `ALU_XOR; // Xor
{7'b000_0000, 3'b110}: alu_operator = `ALU_OR; // Or
{7'b000_0000, 3'b111}: alu_operator = `ALU_AND; // And
{7'b000_0000, 3'b001}: alu_operator = `ALU_SLL; // Shift Left Logical
{7'b000_0000, 3'b101}: alu_operator = `ALU_SRL; // Shift Right Logical
{7'b010_0000, 3'b101}: alu_operator = `ALU_SRA; // Shift Right Arithmetic
{7'b000_0001, 3'b000}: mult_en = 1'b1; // Multiplication
default: begin
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1;
end
endcase
end
/*
`OPCODE_ALU: begin // Arithmetic Operation
rega_used_o = 1'b1;
regb_used_o = 1'b1;
case (instr_rdata_i[9:8])
2'b00: begin // ALU Operation
regfile_alu_we = 1'b1;
casex (instr_rdata_i[3:0])
4'b110X: begin // l.ext{b,h,w}{s,z}
alu_operator = {3'b010, instr_rdata_i[7:6], instr_rdata_i[0]};
regb_used_o = 1'b0; // register b is not used
end
4'b1111: begin // l.ff1
alu_operator = `ALU_FF1;
end
endcase // casex (instr_rdata_i[3:2])
end
2'b01: begin // l.fl1, l.clb, l.cnt
regfile_alu_we = 1'b1;
regb_used_o = 1'b0;
case (instr_rdata_i[3:0])
4'b1101: alu_operator = `ALU_CNT;
4'b1110: alu_operator = `ALU_CLB;
4'b1111: alu_operator = `ALU_FL1;
default: begin
// synopsys translate_off
$display("%t: Illegal ALU instruction received.", $time);
// synopsys translate_on
regfile_alu_we = 1'b0; // disable Write Enable for illegal instruction
illegal_insn_o = 1'b1;
end
endcase //~case(instr_rdata_i[3:0])
end
2'b10: begin // Min, Max, Abs, Avg
regfile_alu_we = 1'b1;
case (instr_rdata_i[3:0])
4'b0000: alu_operator = `ALU_MIN;
4'b0001: alu_operator = `ALU_MINU;
4'b0010: alu_operator = `ALU_MAX;
4'b0011: alu_operator = `ALU_MAXU;
4'b0100: alu_operator = `ALU_AVG;
4'b0101: alu_operator = `ALU_AVGU;
4'b1000: begin
regb_used_o = 1'b0;
alu_operator = `ALU_ABS;
end
default: begin
// synopsys translate_off
$display("%t: Illegal ALU instruction received.", $time);
// synopsys translate_on
regfile_alu_we = 1'b0; // disable Write Enable for illegal instruction
illegal_insn_o = 1'b1;
end
endcase //~case(instr_rdata_i[3:0])
end
endcase; // case (instr_rdata_i[9:8])
end
`OPCODE_MAC: begin // MAC instruction
mult_is_running = 1'b1;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
regfile_alu_waddr_sel_o = 2'b01;
regfile_alu_we = 1'b1;
case (instr_rdata_i[6:5])
2'b00: begin // MAC
case (instr_rdata_i[3:0])
4'b1000: begin // l.mac
mult_mac_en_o = 1'b1;
regc_used_o = 1'b1;
set_carry = 1'b1;
set_overflow = 1'b1;
end
4'b1001: begin // l.mac.c
mult_use_carry_o = 1'b1;
mult_mac_en_o = 1'b1;
regc_used_o = 1'b1;
set_carry = 1'b1;
set_overflow = 1'b1;
end
default: begin
// synopsys translate_off
$display("%t: Illegal MAC instruction received.", $time);
// synopsys translate_on
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1;
end
endcase // case (instr_rdata_i[3:0])
end
2'b01: begin // MAC with subword selection
vector_mode_o = `VEC_MODE216;
mult_mac_en_o = 1'b1;
regc_used_o = 1'b1;
mult_sel_subword_o = instr_rdata_i[2:1];
mult_signed_mode_o = instr_rdata_i[4:3];
mult_use_carry_o = instr_rdata_i[0];
set_carry = 1'b1;
set_overflow = 1'b1;
end
2'b11: begin // mult with subword selection
vector_mode_o = `VEC_MODE216;
mult_sel_subword_o = instr_rdata_i[2:1];
mult_signed_mode_o = instr_rdata_i[4:3];
end
default: begin
// synopsys translate_off
$display("%t: Illegal MAC instruction received.", $time);
// synopsys translate_on
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1;
end
endcase
end
`OPCODE_VEC: begin // vectorial alu operations
rega_used_o = 1'b1;
regfile_alu_we = 1'b1;
if (instr_rdata_i[0] == 1'b0) // choose vector size
vector_mode_o = `VEC_MODE16;
else
vector_mode_o = `VEC_MODE8;
if ((instr_rdata_i[7:6] == 2'b01) || (instr_rdata_i[7:6] == 2'b10)) // replicate scalar 2 or 4 times
scalar_replication_o = 1'b1;
if (instr_rdata_i[7:6] == 2'b10) // use immediate as operand b
begin
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_VEC;
end
else
regb_used_o = 1'b1;
// now decode the sub opcodes
case (instr_rdata_i[5:1])
5'b00000: alu_operator = `ALU_ADD;
5'b00001: alu_operator = `ALU_SUB;
5'b00010: alu_operator = `ALU_AVG;
5'b00011: alu_operator = `ALU_MIN;
5'b00100: alu_operator = `ALU_MAX;
5'b00101: alu_operator = `ALU_SRL;
5'b00110: alu_operator = `ALU_SRA;
5'b00111: alu_operator = `ALU_SLL;
5'b01000: begin // lv32.mul
regfile_alu_waddr_sel_o = 2'b01;
mult_is_running = 1'b1;
end
5'b01001: alu_operator = `ALU_OR;
5'b01010: alu_operator = `ALU_XOR;
5'b01011: alu_operator = `ALU_AND;
5'b01100: begin // lv32.ins
alu_operator = `ALU_INS;
scalar_replication_o = 1'b1;
end
5'b10000: begin // lv32.abs
regb_used_o = 1'b0; // abs does not use operand b
alu_operator = `ALU_ABS;
end
5'b10001: begin // lv32.ext
regb_used_o = 1'b0;
alu_operator = `ALU_EXT;
end
default: begin // unknown instruction encountered
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1;
// synopsys translate_off
$display("%t: Unknown vector opcode 0x%h.", $time, instr_rdata_i[5:1]);
// synopsys translate_on
end
endcase // instr_rdata[5:1]
end
`OPCODE_VCMP: begin // Vectorial comparisons, i.e. lv32.cmp_*, lv32.all_*, lv32.any_*
rega_used_o = 1'b1;
regfile_alu_we = 1'b1;
if (instr_rdata_i[0] == 1'b0) // choose vector size
vector_mode_o = `VEC_MODE16;
else
vector_mode_o = `VEC_MODE8;
if ((instr_rdata_i[7:6] == 2'b01) || (instr_rdata_i[7:6] == 2'b10)) // replicate scalar 2 or 4 times
scalar_replication_o = 1'b1;
if (instr_rdata_i[7:6] == 2'b10) // use immediate as operand b
begin
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_VEC;
end
else
regb_used_o = 1'b1;
// now decode the sub opcodes for the ALU
case (instr_rdata_i[3:1])
3'b000: alu_operator = `ALU_EQ;
3'b001: alu_operator = `ALU_NE;
3'b010: alu_operator = `ALU_GTS;
3'b011: alu_operator = `ALU_GES;
3'b100: alu_operator = `ALU_LTS;
3'b101: alu_operator = `ALU_LES;
default: begin // unknown instruction encountered
illegal_insn_o = 1'b1;
// synopsys translate_off
$display("%t: Unknown vector opcode 0x%h.", $time, instr_rdata_i[5:1]);
// synopsys translate_on
end
endcase //~case(instr_rdata_i[3:1])
alu_cmp_mode_o = instr_rdata_i[5:4]; // which kind of comparison do we have here, i.e. full, any, all
if((instr_rdata_i[5:4] == `ALU_CMP_ANY) || (instr_rdata_i[5:4] == `ALU_CMP_ALL))
set_flag = 1'b1; // set the flag for lv32.all_* and lv32.any_*
end
*/
////////////////////////////////////////////////
// ____ ____ _____ ____ ___ _ _ //
// / ___|| _ \| ____/ ___|_ _| / \ | | //
// \___ \| |_) | _|| | | | / _ \ | | //
// ___) | __/| |__| |___ | | / ___ \| |___ //
// |____/|_| |_____\____|___/_/ \_\_____| //
// //
////////////////////////////////////////////////
`OPCODE_SYSTEM: begin
if (instr_rdata_i[14:12] == 3'b000)
begin
// non CSR related SYSTEM instructions
unique case (instr_rdata_i[31:0])
32'h00_00_00_73: // ECALL
begin
// environment (system) call
// TODO: Handle in controller
end
32'h00_10_00_73: // EBREAK
begin
// debugger trap
trap_insn = 1'b1;
end
32'h10_00_00_73: // ERET
begin
eret_insn = 1'b1;
end
32'h10_20_00_73: // WFI
begin
// flush pipeline
pipe_flush = 1'b1;
end
default:
begin
illegal_insn_o = 1'b1;
end
endcase
end
else
begin
// instruction to read/modify CSR
csr_access_o = 1'b1;
regfile_alu_we = 1'b1;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_I; // CSR address is encoded in I imm
if (instr_rdata_i[14] == 1'b1) begin
// rs1 field is used as immediate
alu_op_a_mux_sel_o = `OP_A_ZIMM;
end else begin
rega_used_o = 1'b1;
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
end
unique case (instr_rdata_i[13:12])
2'b01: csr_op = `CSR_OP_WRITE;
2'b10: csr_op = `CSR_OP_SET;
2'b11: csr_op = `CSR_OP_CLEAR;
default: illegal_insn_o = 1'b1;
endcase
end
end
///////////////////////////////////////////////
// _ ___ ___ ___ ___ ____ //
// | | | \ \ / / | / _ \ / _ \| _ \ //
// | |_| |\ \ /\ / /| | | | | | | | | |_) | //
// | _ | \ V V / | |__| |_| | |_| | __/ //
// |_| |_| \_/\_/ |_____\___/ \___/|_| //
// //
///////////////////////////////////////////////
`OPCODE_HWLOOP: begin
jump_target_mux_sel_o = `JT_HWLP; // get PC + I imm from jump target adder
unique case (instr_rdata_i[14:12])
3'b000: begin
// lp.starti: set start address to PC + I-type immediate
hwloop_we[0] = 1'b1;
hwloop_start_mux_sel_o = 1'b0;
// $display("%t: hwloop start address: %h", $time, instr_rdata_i);
end
3'b001: begin
// lp.endi: set end address to PC + I-type immediate
hwloop_we[1] = 1'b1;
hwloop_end_mux_sel_o = 1'b0; // jump target
// $display("%t: hwloop end address: %h", $time, instr_rdata_i);
end
3'b010: begin
// lp.count initialize counter from rs1
hwloop_we[2] = 1'b1;
hwloop_cnt_mux_sel_o = 1'b1;
rega_used_o = 1'b1;
// $display("%t: hwloop counter: %h", $time, instr_rdata_i);
end
3'b011: begin
// lp.counti initialize counter from I-type immediate
hwloop_we[2] = 1'b1;
hwloop_cnt_mux_sel_o = 1'b0;
// $display("%t: hwloop counter imm: %h", $time, instr_rdata_i);
end
3'b100: begin
// lp.setup: initialize counter from rs1, set start address to
// next instruction and end address to PC + I-type immediate
hwloop_we = 3'b111;
hwloop_start_mux_sel_o = 1'b1;
hwloop_end_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 1'b1;
rega_used_o = 1'b1;
// $display("%t: hwloop setup: %h", $time, instr_rdata_i);
end
3'b101: begin
// lp.setupi: initialize counter from I-type immediate, set start
// address to next instruction and end address to PC + shifted
// z-type immediate
hwloop_we = 3'b111;
hwloop_start_mux_sel_o = 1'b1;
hwloop_end_mux_sel_o = 1'b1;
hwloop_cnt_mux_sel_o = 1'b0;
illegal_insn_o = 1'b1; // TODO: PC + z-imm currently not supported
// $display("%t: hwloop setup imm: %h", $time, instr_rdata_i);
end
default: begin
illegal_insn_o = 1'b1;
end
endcase
end
default: begin
illegal_insn_o = 1'b1;
end
endcase
// make sure invalid compressed instruction causes an exception
if (illegal_c_insn_i) begin
illegal_insn_o = 1'b1;
end
// misaligned access was detected by the LSU
// TODO: this section should eventually be moved out of the decoder
if (data_misaligned_i == 1'b1)
begin
// only part of the pipeline is unstalled, make sure that the
// correct operands are sent to the AGU
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
// if prepost increments are used, we do not write back the
// second address since the first calculated address was
// the correct one
regfile_alu_we = 1'b0;
// if post increments are used, we must make sure that for
// the second memory access we do use the adder
prepost_useincr_o = 1'b1;
end
end
// deassert we signals (in case of stalls)
assign regfile_mem_we_o = (deassert_we_i) ? 1'b0 : regfile_mem_we;
assign regfile_alu_we_o = (deassert_we_i) ? 1'b0 : regfile_alu_we;
assign data_req_o = (deassert_we_i) ? 1'b0 : data_req;
assign data_we_o = (deassert_we_i) ? 1'b0 : data_we; // TODO: is this needed?
assign alu_operator_o = (deassert_we_i) ? `ALU_NOP : alu_operator;
assign mult_en_o = (deassert_we_i) ? 1'b0 : mult_en;
assign hwloop_we_o = (deassert_we_i) ? 3'b0 : hwloop_we;
assign csr_op_o = (deassert_we_i) ? `CSR_OP_NONE : csr_op;
assign jump_in_id_o = (deassert_we_i) ? `BRANCH_NONE : jump_in_id;
assign trap_insn_o = (deassert_we_i) ? 1'b0 : trap_insn;
assign eret_insn_o = (deassert_we_i) ? 1'b0 : eret_insn; // TODO: do not deassert?
assign pipe_flush_o = (deassert_we_i) ? 1'b0 : pipe_flush; // TODO: do not deassert?
assign jump_in_dec_o = jump_in_id;
endmodule // controller

View file

@ -45,7 +45,6 @@ module id_stage
// Interface to instruction memory
input logic [31:0] instr_rdata_i, // comes from pipeline of IF stage
output logic instr_req_o,
input logic instr_gnt_i,
input logic instr_ack_i,
// Jumps and branches
@ -72,20 +71,10 @@ module id_stage
output logic stall_wb_o,
// To the Pipeline ID/EX
output logic [31:0] regfile_rb_data_ex_o,
output logic [31:0] alu_operand_a_ex_o,
output logic [31:0] alu_operand_b_ex_o,
output logic [31:0] alu_operand_c_ex_o,
output logic [`ALU_OP_WIDTH-1:0] alu_operator_ex_o,
output logic [1:0] vector_mode_ex_o,
output logic [1:0] alu_cmp_mode_ex_o,
output logic [1:0] alu_vec_ext_ex_o,
output logic mult_en_ex_o,
output logic [1:0] mult_sel_subword_ex_o,
output logic [1:0] mult_signed_mode_ex_o,
output logic mult_mac_en_ex_o,
output logic [31:0] regfile_rb_data_ex_o,
output logic [31:0] alu_operand_a_ex_o,
output logic [31:0] alu_operand_b_ex_o,
output logic [31:0] alu_operand_c_ex_o,
output logic [4:0] regfile_waddr_ex_o,
output logic regfile_we_ex_o,
@ -93,22 +82,37 @@ module id_stage
output logic [4:0] regfile_alu_waddr_ex_o,
output logic regfile_alu_we_ex_o,
output logic prepost_useincr_ex_o,
input logic data_misaligned_i,
// ALU
output logic [`ALU_OP_WIDTH-1:0] alu_operator_ex_o,
output logic [31:0] hwloop_targ_addr_o,
output logic hwloop_jump_o,
output logic [1:0] vector_mode_ex_o,
output logic [1:0] alu_cmp_mode_ex_o,
output logic [1:0] alu_vec_ext_ex_o,
// MUL
output logic mult_en_ex_o,
output logic [1:0] mult_sel_subword_ex_o,
output logic [1:0] mult_signed_mode_ex_o,
output logic mult_mac_en_ex_o,
// CSR ID/EX
output logic csr_access_ex_o,
output logic [1:0] csr_op_ex_o,
// hwloop signals
output logic [31:0] hwloop_targ_addr_o,
output logic hwloop_jump_o,
// Interface to load store unit
output logic data_req_ex_o,
output logic data_we_ex_o,
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 data_misaligned_ex_o,
output logic data_req_ex_o,
output logic prepost_useincr_ex_o,
input logic data_misaligned_i,
input logic lsu_ready_ex_i,
input logic lsu_ready_wb_i,
@ -149,10 +153,23 @@ module id_stage
output logic perf_ld_stall_o // load-use-hazard
);
// Compressed instruction decoding
logic [31:0] instr;
// Decoder/Controller ID stage internal signals
logic deassert_we;
logic illegal_insn_dec;
logic trap_insn;
logic eret_insn_dec;
logic pipe_flush_dec;
logic rega_used_dec;
logic regb_used_dec;
logic regc_used_dec;
logic [1:0] jump_in_dec;
// Immediate decoding and sign extension
logic [31:0] imm_i_type;
logic [31:0] imm_s_type;
@ -166,14 +183,11 @@ module id_stage
logic [31:0] jump_target; // calculated jump target (-> EX -> IF)
logic exc_pc_sel;
logic [2:0] pc_mux_sel_int; // selects next PC in if stage
logic irq_present;
// Signals running between controller and exception controller
logic illegal_insn;
logic illegal_c_insn;
logic trap_insn;
logic trap_hit;
logic pc_valid;
logic clear_isr_running;
@ -264,9 +278,6 @@ module id_stage
logic [31:0] operand_c;
assign pc_mux_sel_o = pc_mux_sel_int;
assign instr = instr_rdata_i;
// immediate extraction and sign extension
@ -510,6 +521,83 @@ module id_stage
assign dbg_reg_rdata_o = regfile_data_rc_id;
///////////////////////////////////////////////
// ____ _____ ____ ___ ____ _____ ____ //
// | _ \| ____/ ___/ _ \| _ \| ____| _ \ //
// | | | | _|| | | | | | | | | _| | |_) | //
// | |_| | |__| |__| |_| | |_| | |___| _ < //
// |____/|_____\____\___/|____/|_____|_| \_\ //
// //
///////////////////////////////////////////////
decoder decoder_i
(
// controller related signals
.deassert_we_i ( deassert_we ),
.data_misaligned_i ( data_misaligned_i ),
.illegal_insn_o ( illegal_insn_dec ),
.trap_insn_o ( trap_insn ),
.eret_insn_o ( eret_insn_dec ),
.pipe_flush_o ( pipe_flush_dec ),
.rega_used_o ( rega_used_dec ),
.regb_used_o ( regb_used_dec ),
.regc_used_o ( regc_used_dec ),
// from IF/ID pipeline
.instr_rdata_i ( instr ),
.illegal_c_insn_i ( illegal_c_insn_i ),
// ALU signals
.alu_operator_o ( alu_operator ),
.alu_op_a_mux_sel_o ( alu_op_a_mux_sel ),
.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 ),
.vector_mode_o ( vector_mode ),
.scalar_replication_o ( scalar_replication ),
.alu_cmp_mode_o ( alu_cmp_mode ),
// MUL signals
.mult_en_o ( mult_en ),
.mult_sel_subword_o ( mult_sel_subword ),
.mult_signed_mode_o ( mult_signed_mode ),
.mult_mac_en_o ( mult_mac_en ),
// Register file control signals
.regfile_mem_we_o ( regfile_we_id ),
.regfile_alu_we_o ( regfile_alu_we_id ),
.regfile_alu_waddr_sel_o ( regfile_alu_waddr_mux_sel ),
// CSR control signals
.csr_access_o ( csr_access ),
.csr_op_o ( csr_op ),
// Data bus interface
.data_req_o ( data_req_id ),
.data_we_o ( data_we_id ),
.prepost_useincr_o ( prepost_useincr ),
.data_type_o ( data_type_id ),
.data_sign_extension_o ( data_sign_ext_id ),
.data_reg_offset_o ( data_reg_offset_id ),
// hwloop signals
.hwloop_we_o ( hwloop_we ),
.hwloop_start_mux_sel_o ( hwloop_start_mux_sel ),
.hwloop_end_mux_sel_o ( hwloop_end_mux_sel ),
.hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ),
// jump/branches
.jump_in_dec_o ( jump_in_dec ),
.jump_in_id_o ( jump_in_id_o ),
.jump_target_mux_sel_o ( jump_target_mux_sel )
);
////////////////////////////////////////////////////////////////////
// ____ ___ _ _ _____ ____ ___ _ _ _____ ____ //
// / ___/ _ \| \ | |_ _| _ \ / _ \| | | | | ____| _ \ //
@ -520,122 +608,94 @@ module id_stage
////////////////////////////////////////////////////////////////////
controller controller_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.fetch_enable_i ( fetch_enable_i ),
.core_busy_o ( core_busy_o ),
.is_decoding_o ( is_decoding_o ),
.clk ( clk ),
.rst_n ( rst_n ),
// Signal from-to PC pipe (instr rdata) and instr mem system (req and ack)
.instr_rdata_i ( instr ),
.instr_req_o ( instr_req_o ),
.instr_gnt_i ( instr_gnt_i ),
.instr_ack_i ( instr_ack_i ),
.fetch_enable_i ( fetch_enable_i ),
.core_busy_o ( core_busy_o ),
.is_decoding_o ( is_decoding_o ),
.pc_set_o ( pc_set_o ),
.pc_mux_sel_o ( pc_mux_sel_int ),
// decoder related signals
.deassert_we_o ( deassert_we ),
.illegal_insn_i ( illegal_insn_dec ),
.trap_insn_i ( trap_insn ),
.eret_insn_i ( eret_insn_dec ),
.pipe_flush_i ( pipe_flush_dec ),
// Alu signals
.alu_operator_o ( alu_operator ),
.alu_op_a_mux_sel_o ( alu_op_a_mux_sel ),
.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 ),
.rega_used_i ( rega_used_dec ),
.regb_used_i ( regb_used_dec ),
.regc_used_i ( regc_used_dec ),
.scalar_replication_o ( scalar_replication ),
.vector_mode_o ( vector_mode ),
.alu_cmp_mode_o ( alu_cmp_mode ),
// from IF/ID pipeline
.instr_rdata_i ( instr ),
// mult signals
.mult_en_o ( mult_en ),
.mult_sel_subword_o ( mult_sel_subword ),
.mult_signed_mode_o ( mult_signed_mode ),
.mult_mac_en_o ( mult_mac_en ),
// from prefetcher
.instr_req_o ( instr_req_o ),
.instr_ack_i ( instr_ack_i ),
// Register file control signals
.regfile_we_o ( regfile_we_id ),
// to prefetcher
.pc_set_o ( pc_set_o ),
.pc_mux_sel_o ( pc_mux_sel_o ),
.regfile_alu_we_o ( regfile_alu_we_id ),
.regfile_alu_waddr_mux_sel_o ( regfile_alu_waddr_mux_sel ),
// LSU
.data_req_ex_i ( data_req_ex_o ),
.data_misaligned_i ( data_misaligned_i ),
.prepost_useincr_o ( prepost_useincr ),
.data_misaligned_i ( data_misaligned_i ),
// CSR control signals
.csr_access_o ( csr_access ),
.csr_op_o ( csr_op ),
// Data bus interface
.data_we_o ( data_we_id ),
.data_type_o ( data_type_id ),
.data_sign_extension_o ( data_sign_ext_id ),
.data_reg_offset_o ( data_reg_offset_id ),
.data_req_o ( data_req_id ),
.data_req_ex_i ( data_req_ex_o ),
.lsu_ready_ex_i ( lsu_ready_ex_i ),
.lsu_ready_wb_i ( lsu_ready_wb_i ),
.lsu_ready_ex_i ( lsu_ready_ex_i ),
.lsu_ready_wb_i ( lsu_ready_wb_i ),
// hwloop signals
.hwloop_we_o ( hwloop_we ),
.hwloop_start_mux_sel_o ( hwloop_start_mux_sel ),
.hwloop_end_mux_sel_o ( hwloop_end_mux_sel ),
.hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ),
.hwloop_jump_i ( hwloop_jump ),
.hwloop_jump_i ( hwloop_jump ),
// jump/branch control
.jump_in_dec_i ( jump_in_dec ),
.jump_in_id_i ( jump_in_id_o ),
.jump_in_ex_i ( jump_in_ex_o ),
.branch_decision_i ( branch_decision_i ),
// Interrupt signals
.irq_present_i ( irq_present ),
.irq_present_i ( irq_present ),
// Exception Controller Signals
.exc_pc_sel_i ( exc_pc_sel ),
.illegal_c_insn_i ( illegal_c_insn_i ),
.illegal_insn_o ( illegal_insn ),
.trap_insn_o ( trap_insn ),
.pc_valid_i ( pc_valid ),
.clear_isr_running_o ( clear_isr_running ),
.trap_hit_i ( trap_hit ),
.exc_pipe_flush_i ( exc_pipe_flush ),
.exc_pc_sel_i ( exc_pc_sel ),
.pc_valid_i ( pc_valid ),
.exc_pipe_flush_i ( exc_pipe_flush ),
.trap_hit_i ( trap_hit ),
.illegal_insn_o ( illegal_insn ),
.clear_isr_running_o ( clear_isr_running ),
// Debug Unit Signals
.dbg_stall_i ( dbg_stall_i ),
.dbg_set_npc_i ( dbg_set_npc_i ),
.dbg_trap_o ( dbg_trap_o ),
.dbg_stall_i ( dbg_stall_i ),
.dbg_set_npc_i ( dbg_set_npc_i ),
.dbg_trap_o ( dbg_trap_o ),
// regfile port 1
.regfile_waddr_ex_i ( regfile_waddr_ex_o ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_ex_i ( regfile_we_ex_o ),
.regfile_waddr_wb_i ( regfile_waddr_wb_i ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_wb_i ( regfile_we_wb_i ),
// Forwarding signals from regfile
.regfile_waddr_ex_i ( regfile_waddr_ex_o ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_ex_i ( regfile_we_ex_o ),
.regfile_waddr_wb_i ( regfile_waddr_wb_i ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_wb_i ( regfile_we_wb_i ),
// regfile port 2
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw_i ),
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw_i ),
// Forwarding signals
.operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ),
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
// To controller (TODO: Remove when control/decode separated and moved)
.jump_target_mux_sel_o ( jump_target_mux_sel ),
.jump_in_ex_i ( jump_in_ex_o ),
.branch_decision_i ( branch_decision_i ),
// To exception controller and EX: Jump/Branch indication
.jump_in_id_o ( jump_in_id_o ),
.operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ),
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
// Stall signals
.stall_if_o ( stall_if_o ),
.stall_id_o ( stall_id_o ),
.stall_ex_o ( stall_ex_o ),
.stall_wb_o ( stall_wb_o ),
.stall_if_o ( stall_if_o ),
.stall_id_o ( stall_id_o ),
.stall_ex_o ( stall_ex_o ),
.stall_wb_o ( stall_wb_o ),
// Performance Counters
.perf_jump_o ( perf_jump_o ),
.perf_branch_o ( perf_branch_o ),
.perf_jr_stall_o ( perf_jr_stall_o ),
.perf_ld_stall_o ( perf_ld_stall_o )
.perf_jump_o ( perf_jump_o ),
.perf_branch_o ( perf_branch_o ),
.perf_jr_stall_o ( perf_jr_stall_o ),
.perf_ld_stall_o ( perf_ld_stall_o )
);

View file

@ -43,21 +43,21 @@ module riscv_core
input logic [4:0] cluster_id_i,
// Instruction memory interface
output logic [31:0] instr_addr_o,
output logic instr_req_o,
input logic [31:0] instr_rdata_i,
input logic instr_grant_i,
input logic instr_grant_i, // TODO: rename to instr_gnt_i
input logic instr_rvalid_i,
output logic [31:0] instr_addr_o,
input logic [31:0] instr_rdata_i,
// Data memory interface
output logic data_req_o,
input logic data_gnt_i,
input logic data_r_valid_i, // TODO: rename to data_rvalid_i
output logic data_we_o,
output logic [3:0] data_be_o,
output logic [31:0] data_addr_o,
output logic [31:0] data_wdata_o,
output logic data_we_o,
output logic data_req_o,
output logic [3:0] data_be_o,
input logic [31:0] data_rdata_i,
input logic data_gnt_i,
input logic data_r_valid_i,
// Interrupt inputs
input logic irq_i, // level-triggered IR line
@ -291,33 +291,31 @@ module riscv_core
// Processor Enable
.fetch_enable_i ( fetch_enable_i ),
.jump_in_id_o ( jump_in_id ),
.jump_in_ex_o ( jump_in_ex ),
.branch_decision_i ( branch_decision ),
.jump_target_o ( jump_target_id ),
.core_busy_o ( core_busy ),
.is_decoding_o ( is_decoding ),
// Interface to instruction memory
.instr_rdata_i ( instr_rdata_id ),
.instr_req_o ( instr_req_int ),
.instr_gnt_i ( instr_grant_i ),
.instr_ack_i ( instr_ack_int ),
// Jumps and branches
.jump_in_id_o ( jump_in_id ),
.jump_in_ex_o ( jump_in_ex ),
.branch_decision_i ( branch_decision ),
.jump_target_o ( jump_target_id ),
.pc_set_o ( pc_set ),
.pc_mux_sel_o ( pc_mux_sel_id ),
.exc_pc_mux_o ( exc_pc_mux_id ),
.is_compressed_i ( is_compressed_id ),
.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 ),
// STALLS
// Stalls
.stall_if_o ( stall_if ),
.stall_id_o ( stall_id ),
.stall_ex_o ( stall_ex ),
@ -325,20 +323,9 @@ module riscv_core
// From the Pipeline ID/EX
.regfile_rb_data_ex_o ( regfile_rb_data_ex ),
.alu_operand_a_ex_o ( alu_operand_a_ex ),
.alu_operand_b_ex_o ( alu_operand_b_ex ),
.alu_operand_c_ex_o ( alu_operand_c_ex ),
.alu_operator_ex_o ( alu_operator_ex ),
.vector_mode_ex_o ( vector_mode_ex ), // from ID to EX stage
.alu_cmp_mode_ex_o ( alu_cmp_mode_ex ), // from ID to EX stage
.alu_vec_ext_ex_o ( alu_vec_ext_ex ), // from ID to EX stage
.mult_en_ex_o ( mult_en_ex ), // from ID to EX stage
.mult_sel_subword_ex_o ( mult_sel_subword_ex ), // from ID to EX stage
.mult_signed_mode_ex_o ( mult_signed_mode_ex ), // from ID to EX stage
.mult_mac_en_ex_o ( mult_mac_en_ex ), // from ID to EX stage
.regfile_waddr_ex_o ( regfile_waddr_ex ),
.regfile_we_ex_o ( regfile_we_ex ),
@ -346,6 +333,19 @@ module riscv_core
.regfile_alu_we_ex_o ( regfile_alu_we_ex ),
.regfile_alu_waddr_ex_o ( regfile_alu_waddr_ex ),
// ALU
.alu_operator_ex_o ( alu_operator_ex ),
.vector_mode_ex_o ( vector_mode_ex ), // from ID to EX stage
.alu_cmp_mode_ex_o ( alu_cmp_mode_ex ), // from ID to EX stage
.alu_vec_ext_ex_o ( alu_vec_ext_ex ), // from ID to EX stage
// MUL
.mult_en_ex_o ( mult_en_ex ), // from ID to EX stage
.mult_sel_subword_ex_o ( mult_sel_subword_ex ), // from ID to EX stage
.mult_signed_mode_ex_o ( mult_signed_mode_ex ), // from ID to EX stage
.mult_mac_en_ex_o ( mult_mac_en_ex ), // from ID to EX stage
// CSR ID/EX
.csr_access_ex_o ( csr_access_ex ),
.csr_op_ex_o ( csr_op_ex ),
@ -354,16 +354,17 @@ module riscv_core
.hwloop_jump_o ( hwloop_jump ),
.hwloop_targ_addr_o ( hwloop_target ),
.prepost_useincr_ex_o ( useincr_addr_ex ),
.data_misaligned_i ( data_misaligned ),
// 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_req_ex_o ( data_req_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 ),
.lsu_ready_ex_i ( lsu_ready_ex ),
.lsu_ready_wb_i ( lsu_ready_wb ),
@ -388,14 +389,15 @@ module riscv_core
.dbg_set_npc_i ( dbg_set_npc ),
// Forward Signals
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw ),
.regfile_alu_wdata_fw_i ( regfile_alu_wdata_fw ),
.regfile_waddr_wb_i ( regfile_waddr_fw_wb_o), // Write address ex-wb pipeline
.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
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw ),
.regfile_alu_wdata_fw_i ( regfile_alu_wdata_fw ),
// Performance Counters
.perf_jump_o ( perf_jump ),
.perf_branch_o ( perf_branch ),
.perf_jr_stall_o ( perf_jr_stall ),
@ -664,7 +666,7 @@ module riscv_core
rs2_value = id_stage_i.operand_b_fw_id;
// special case for WFI because we don't wait for unstalling there
if ((id_stage_i.stall_ex_o == 1'b0 && is_decoding) || id_stage_i.controller_i.pipe_flush)
if ((id_stage_i.stall_ex_o == 1'b0 && is_decoding) || id_stage_i.controller_i.pipe_flush_i)
begin
mnemonic = "";
imm = 0;