mirror of
https://github.com/lowRISC/ibex.git
synced 2025-06-27 17:00:41 -04:00
This change has been informed by advice from the lowRISC legal committee. The Solderpad 0.51 license states "the Licensor permits any Work licensed under this License, at the option of the Licensee, to be treated as licensed under the Apache License Version 2.0". We use this freedom to convert license markings to Apache 2.0. This commit ensures that we retain all authorship and copyright attribution information.
578 lines
20 KiB
Systemverilog
578 lines
20 KiB
Systemverilog
// Copyright lowRISC contributors.
|
|
// Copyright 2018 ETH Zurich and University of Bologna.
|
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// 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 //
|
|
// Davide Schiavone - pschiavo@iis.ee.ethz.ch //
|
|
// Markus Wegmann - markus.wegmann@technokrat.ch //
|
|
// //
|
|
// Design Name: Decoder //
|
|
// Project Name: ibex //
|
|
// Language: SystemVerilog //
|
|
// //
|
|
// Description: Decoder //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`include "ibex_config.sv"
|
|
|
|
import ibex_defines::*;
|
|
|
|
module ibex_decoder
|
|
#(
|
|
parameter RV32M = 1
|
|
)
|
|
(
|
|
// 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
|
|
input logic branch_mux_i,
|
|
input logic jump_mux_i,
|
|
output logic illegal_insn_o, // illegal instruction encountered
|
|
output logic ebrk_insn_o, // trap instruction encountered
|
|
output logic mret_insn_o, // return from exception instruction encountered
|
|
output logic ecall_insn_o, // environment call (syscall) instruction encountered
|
|
output logic pipe_flush_o, // pipeline flush is requested
|
|
|
|
// from IF/ID pipeline
|
|
input logic [31:0] instr_rdata_i, // instruction read from instr memory/cache
|
|
input logic illegal_c_insn_i, // compressed instruction decode failed
|
|
|
|
// ALU signals
|
|
output logic [ALU_OP_WIDTH-1:0] alu_operator_o, // ALU operation selection
|
|
output logic [2:0] alu_op_a_mux_sel_o, // operand a selection: reg value, PC, immediate or zero
|
|
output logic [2:0] alu_op_b_mux_sel_o, // oNOperand b selection: reg value or immediate
|
|
|
|
output logic [0:0] imm_a_mux_sel_o, // immediate selection for operand a
|
|
output logic [3:0] imm_b_mux_sel_o, // immediate selection for operand b
|
|
|
|
// MUL, DIV related control signals
|
|
output logic mult_int_en_o, // perform integer multiplication
|
|
output logic div_int_en_o, // perform integer division or reminder
|
|
output logic [1:0] multdiv_operator_o,
|
|
output logic [1:0] multdiv_signed_mode_o,
|
|
// register file related signals
|
|
output logic regfile_we_o, // write enable for regfile
|
|
|
|
// CSR manipulation
|
|
output logic csr_access_o, // access to CSR
|
|
output logic [1:0] csr_op_o, // operation to perform on CSR
|
|
output logic csr_status_o, // access to xstatus CSR
|
|
|
|
// LD/ST unit signals
|
|
output logic data_req_o, // start transaction to data memory
|
|
output logic data_we_o, // data memory write enable
|
|
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 byte inside register for stores
|
|
|
|
// jump/branches
|
|
output logic jump_in_id_o, // jump is being calculated in ALU
|
|
output logic branch_in_id_o
|
|
);
|
|
|
|
// write enable/request control
|
|
logic regfile_we;
|
|
logic data_req;
|
|
|
|
logic mult_int_en;
|
|
logic div_int_en;
|
|
logic branch_in_id;
|
|
logic jump_in_id;
|
|
|
|
logic [1:0] csr_op;
|
|
logic csr_illegal;
|
|
|
|
/////////////////////////////////////////////
|
|
// ____ _ //
|
|
// | _ \ ___ ___ ___ __| | ___ _ __ //
|
|
// | | | |/ _ \/ __/ _ \ / _` |/ _ \ '__| //
|
|
// | |_| | __/ (_| (_) | (_| | __/ | //
|
|
// |____/ \___|\___\___/ \__,_|\___|_| //
|
|
// //
|
|
/////////////////////////////////////////////
|
|
|
|
always_comb
|
|
begin
|
|
jump_in_id = 1'b0;
|
|
branch_in_id = 1'b0;
|
|
alu_operator_o = ALU_SLTU;
|
|
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
|
|
alu_op_b_mux_sel_o = OP_B_REGB_OR_FWD;
|
|
|
|
imm_a_mux_sel_o = IMMA_ZERO;
|
|
imm_b_mux_sel_o = IMMB_I;
|
|
|
|
mult_int_en = 1'b0;
|
|
div_int_en = 1'b0;
|
|
multdiv_operator_o = MD_OP_MULL;
|
|
multdiv_signed_mode_o = 2'b00;
|
|
|
|
regfile_we = 1'b0;
|
|
|
|
csr_access_o = 1'b0;
|
|
csr_status_o = 1'b0;
|
|
csr_illegal = 1'b0;
|
|
csr_op = CSR_OP_NONE;
|
|
|
|
data_we_o = 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;
|
|
ebrk_insn_o = 1'b0;
|
|
mret_insn_o = 1'b0;
|
|
ecall_insn_o = 1'b0;
|
|
pipe_flush_o = 1'b0;
|
|
|
|
unique case (instr_rdata_i[6:0])
|
|
|
|
//////////////////////////////////////
|
|
// _ _ _ __ __ ____ ____ //
|
|
// | | | | | \/ | _ \/ ___| //
|
|
// _ | | | | | |\/| | |_) \___ \ //
|
|
// | |_| | |_| | | | | __/ ___) | //
|
|
// \___/ \___/|_| |_|_| |____/ //
|
|
// //
|
|
//////////////////////////////////////
|
|
|
|
OPCODE_JAL: begin // Jump and Link
|
|
jump_in_id = 1'b1;
|
|
if(jump_mux_i) begin
|
|
// Calculate jump target
|
|
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_UJ;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_we = 1'b0;
|
|
end else begin
|
|
// Calculate and store PC+4
|
|
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_PCINCR;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_we = 1'b1;
|
|
end
|
|
end
|
|
|
|
OPCODE_JALR: begin // Jump and Link Register
|
|
jump_in_id = 1'b1;
|
|
if(jump_mux_i) begin
|
|
// Calculate jump target
|
|
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_I;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_we = 1'b0;
|
|
end else begin
|
|
// Calculate and store PC+4
|
|
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_PCINCR;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_we = 1'b1;
|
|
end
|
|
if (instr_rdata_i[14:12] != 3'b0) begin
|
|
jump_in_id = 1'b0;
|
|
regfile_we = 1'b0;
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
|
|
end
|
|
|
|
OPCODE_BRANCH: begin // Branch
|
|
|
|
branch_in_id = 1'b1;
|
|
|
|
if (branch_mux_i)
|
|
begin
|
|
unique case (instr_rdata_i[14:12])
|
|
3'b000: alu_operator_o = ALU_EQ;
|
|
3'b001: alu_operator_o = ALU_NE;
|
|
3'b100: alu_operator_o = ALU_LTS;
|
|
3'b101: alu_operator_o = ALU_GES;
|
|
3'b110: alu_operator_o = ALU_LTU;
|
|
3'b111: alu_operator_o = ALU_GEU;
|
|
default: begin
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
endcase
|
|
end
|
|
else begin
|
|
// Calculate jump target in EX
|
|
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_SB;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_we = 1'b0;
|
|
end
|
|
|
|
end
|
|
|
|
|
|
//////////////////////////////////
|
|
// _ ____ ______ _____ //
|
|
// | | | _ \ / / ___|_ _| //
|
|
// | | | | | |/ /\___ \ | | //
|
|
// | |___| |_| / / ___) || | //
|
|
// |_____|____/_/ |____/ |_| //
|
|
// //
|
|
//////////////////////////////////
|
|
|
|
OPCODE_STORE: begin
|
|
data_req = 1'b1;
|
|
data_we_o = 1'b1;
|
|
alu_operator_o = ALU_ADD;
|
|
|
|
if (instr_rdata_i[14] == 1'b0) begin
|
|
// offset from immediate
|
|
imm_b_mux_sel_o = IMMB_S;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
end
|
|
// Register offset is illegal since no register c available
|
|
else begin
|
|
data_req = 1'b0;
|
|
data_we_o = 1'b0;
|
|
illegal_insn_o = 1'b1;
|
|
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_o = 1'b0;
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
OPCODE_LOAD: begin
|
|
data_req = 1'b1;
|
|
regfile_we = 1'b1;
|
|
data_type_o = 2'b00;
|
|
|
|
// offset from immediate
|
|
alu_operator_o = ALU_ADD;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_I;
|
|
|
|
|
|
// 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
|
|
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
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
if (instr_rdata_i[14:12] == 3'b011) begin
|
|
// LD -> RV64 only
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
end
|
|
|
|
|
|
//////////////////////////
|
|
// _ _ _ _ //
|
|
// / \ | | | | | | //
|
|
// / _ \ | | | | | | //
|
|
// / ___ \| |__| |_| | //
|
|
// /_/ \_\_____\___/ //
|
|
// //
|
|
//////////////////////////
|
|
|
|
OPCODE_LUI: begin // Load Upper Immediate
|
|
alu_op_a_mux_sel_o = OP_A_IMM;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_a_mux_sel_o = IMMA_ZERO;
|
|
imm_b_mux_sel_o = IMMB_U;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_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;
|
|
imm_b_mux_sel_o = IMMB_U;
|
|
alu_operator_o = ALU_ADD;
|
|
regfile_we = 1'b1;
|
|
end
|
|
|
|
OPCODE_OPIMM: begin // Register-Immediate ALU Operations
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_b_mux_sel_o = IMMB_I;
|
|
regfile_we = 1'b1;
|
|
|
|
unique case (instr_rdata_i[14:12])
|
|
3'b000: alu_operator_o = ALU_ADD; // Add Immediate
|
|
3'b010: alu_operator_o = ALU_SLTS; // Set to one if Lower Than Immediate
|
|
3'b011: alu_operator_o = ALU_SLTU; // Set to one if Lower Than Immediate Unsigned
|
|
3'b100: alu_operator_o = ALU_XOR; // Exclusive Or with Immediate
|
|
3'b110: alu_operator_o = ALU_OR; // Or with Immediate
|
|
3'b111: alu_operator_o = ALU_AND; // And with Immediate
|
|
|
|
3'b001: begin
|
|
alu_operator_o = 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_o = ALU_SRL; // Shift Right Logical by Immediate
|
|
else if (instr_rdata_i[31:25] == 7'b010_0000)
|
|
alu_operator_o = 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_we = 1'b1;
|
|
|
|
if (instr_rdata_i[31]) begin
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
else
|
|
begin // non bit-manipulation instructions
|
|
|
|
if (~instr_rdata_i[28])
|
|
|
|
unique case ({instr_rdata_i[30:25], instr_rdata_i[14:12]})
|
|
// RV32I ALU operations
|
|
{6'b00_0000, 3'b000}: alu_operator_o = ALU_ADD; // Add
|
|
{6'b10_0000, 3'b000}: alu_operator_o = ALU_SUB; // Sub
|
|
{6'b00_0000, 3'b010}: alu_operator_o = ALU_SLTS; // Set Lower Than
|
|
{6'b00_0000, 3'b011}: alu_operator_o = ALU_SLTU; // Set Lower Than Unsigned
|
|
{6'b00_0000, 3'b100}: alu_operator_o = ALU_XOR; // Xor
|
|
{6'b00_0000, 3'b110}: alu_operator_o = ALU_OR; // Or
|
|
{6'b00_0000, 3'b111}: alu_operator_o = ALU_AND; // And
|
|
{6'b00_0000, 3'b001}: alu_operator_o = ALU_SLL; // Shift Left Logical
|
|
{6'b00_0000, 3'b101}: alu_operator_o = ALU_SRL; // Shift Right Logical
|
|
{6'b10_0000, 3'b101}: alu_operator_o = ALU_SRA; // Shift Right Arithmetic
|
|
|
|
// supported RV32M instructions
|
|
{6'b00_0001, 3'b000}: begin // mul
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_MULL;
|
|
mult_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b00;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b001}: begin // mulh
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_MULH;
|
|
mult_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b11;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b010}: begin // mulhsu
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_MULH;
|
|
mult_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b01;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b011}: begin // mulhu
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_MULH;
|
|
mult_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b00;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b100}: begin // div
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_DIV;
|
|
div_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b11;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b101}: begin // divu
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_DIV;
|
|
div_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b00;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b110}: begin // rem
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_REM;
|
|
div_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b11;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
{6'b00_0001, 3'b111}: begin // remu
|
|
alu_operator_o = ALU_ADD;
|
|
multdiv_operator_o = MD_OP_REM;
|
|
div_int_en = 1'b1;
|
|
multdiv_signed_mode_o = 2'b00;
|
|
illegal_insn_o = RV32M ? 1'b0 : 1'b1;
|
|
end
|
|
default: begin
|
|
illegal_insn_o = 1'b1;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
// ____ ____ _____ ____ ___ _ _ //
|
|
// / ___|| _ \| ____/ ___|_ _| / \ | | //
|
|
// \___ \| |_) | _|| | | | / _ \ | | //
|
|
// ___) | __/| |__| |___ | | / ___ \| |___ //
|
|
// |____/|_| |_____\____|___/_/ \_\_____| //
|
|
// //
|
|
////////////////////////////////////////////////
|
|
|
|
OPCODE_SYSTEM: begin
|
|
if (instr_rdata_i[14:12] == 3'b000)
|
|
begin
|
|
// non CSR related SYSTEM instructions
|
|
unique case (instr_rdata_i[31:20])
|
|
12'h000: // ECALL
|
|
begin
|
|
// environment (system) call
|
|
ecall_insn_o = 1'b1;
|
|
end
|
|
|
|
12'h001: // ebreak
|
|
begin
|
|
// debugger trap
|
|
ebrk_insn_o = 1'b1;
|
|
end
|
|
|
|
12'h302: // mret
|
|
begin
|
|
mret_insn_o = 1'b1;
|
|
end
|
|
|
|
12'h105: // wfi
|
|
begin
|
|
// flush pipeline
|
|
pipe_flush_o = 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_we = 1'b1;
|
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
|
imm_a_mux_sel_o = IMMA_Z;
|
|
imm_b_mux_sel_o = IMMB_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_IMM;
|
|
end else begin
|
|
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: csr_illegal = 1'b1;
|
|
endcase
|
|
|
|
if(~csr_illegal)
|
|
if (instr_rdata_i[31:20] == 12'h300)
|
|
//access to mstatus
|
|
csr_status_o = 1'b1;
|
|
|
|
illegal_insn_o = csr_illegal;
|
|
|
|
end
|
|
|
|
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;
|
|
imm_b_mux_sel_o = IMMB_PCINCR;
|
|
|
|
// if prepost increments are used, we do not write back the
|
|
// second address since the first calculated address was
|
|
// the correct one
|
|
regfile_we = 1'b0;
|
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// deassert we signals (in case of stalls)
|
|
assign regfile_we_o = (deassert_we_i) ? 1'b0 : regfile_we;
|
|
assign mult_int_en_o = RV32M ? ((deassert_we_i) ? 1'b0 : mult_int_en) : 1'b0;
|
|
assign div_int_en_o = RV32M ? ((deassert_we_i) ? 1'b0 : div_int_en ) : 1'b0;
|
|
assign data_req_o = (deassert_we_i) ? 1'b0 : data_req;
|
|
assign csr_op_o = (deassert_we_i) ? CSR_OP_NONE : csr_op;
|
|
assign jump_in_id_o = (deassert_we_i) ? 1'b0 : jump_in_id;
|
|
assign branch_in_id_o = (deassert_we_i) ? 1'b0 : branch_in_id;
|
|
|
|
endmodule // controller
|