blob: ae09c5d2bd9ebbc4c793cb166f1c61c9b619fd95 [file] [log] [blame]
module ibex_decoder (
clk_i,
rst_ni,
illegal_insn_o,
ebrk_insn_o,
mret_insn_o,
dret_insn_o,
ecall_insn_o,
wfi_insn_o,
jump_set_o,
branch_taken_i,
icache_inval_o,
instr_first_cycle_i,
instr_rdata_i,
instr_rdata_alu_i,
illegal_c_insn_i,
imm_a_mux_sel_o,
imm_b_mux_sel_o,
bt_a_mux_sel_o,
bt_b_mux_sel_o,
imm_i_type_o,
imm_s_type_o,
imm_b_type_o,
imm_u_type_o,
imm_j_type_o,
zimm_rs1_type_o,
rf_wdata_sel_o,
rf_we_o,
rf_raddr_a_o,
rf_raddr_b_o,
rf_waddr_o,
rf_ren_a_o,
rf_ren_b_o,
alu_operator_o,
alu_op_a_mux_sel_o,
alu_op_b_mux_sel_o,
alu_multicycle_o,
eFPGA_operator_o,
eFPGA_int_en_o,
eFPGA_delay_o,
mult_en_o,
div_en_o,
mult_sel_o,
div_sel_o,
multdiv_operator_o,
multdiv_signed_mode_o,
csr_access_o,
csr_op_o,
data_req_o,
data_we_o,
data_type_o,
data_sign_extension_o,
jump_in_dec_o,
branch_in_dec_o
);
parameter [0:0] RV32E = 0;
parameter integer RV32M = 32'sd2;
parameter integer RV32B = 32'sd0;
parameter integer RV32Zk = 32'sd0;
parameter [0:0] BranchTargetALU = 0;
input wire clk_i;
input wire rst_ni;
output wire illegal_insn_o;
output reg ebrk_insn_o;
output reg mret_insn_o;
output reg dret_insn_o;
output reg ecall_insn_o;
output reg wfi_insn_o;
output reg jump_set_o;
input wire branch_taken_i;
output reg icache_inval_o;
input wire instr_first_cycle_i;
input wire [31:0] instr_rdata_i;
input wire [31:0] instr_rdata_alu_i;
input wire illegal_c_insn_i;
output reg imm_a_mux_sel_o;
output reg [2:0] imm_b_mux_sel_o;
output reg [1:0] bt_a_mux_sel_o;
output reg [2:0] bt_b_mux_sel_o;
output wire [31:0] imm_i_type_o;
output wire [31:0] imm_s_type_o;
output wire [31:0] imm_b_type_o;
output wire [31:0] imm_u_type_o;
output wire [31:0] imm_j_type_o;
output wire [31:0] zimm_rs1_type_o;
output reg rf_wdata_sel_o;
output wire rf_we_o;
output wire [4:0] rf_raddr_a_o;
output wire [4:0] rf_raddr_b_o;
output wire [4:0] rf_waddr_o;
output reg rf_ren_a_o;
output reg rf_ren_b_o;
output reg [6:0] alu_operator_o;
output reg [1:0] alu_op_a_mux_sel_o;
output reg alu_op_b_mux_sel_o;
output reg alu_multicycle_o;
output reg [1:0] eFPGA_operator_o;
output wire eFPGA_int_en_o;
output reg [3:0] eFPGA_delay_o;
output wire mult_en_o;
output wire div_en_o;
output reg mult_sel_o;
output reg div_sel_o;
output reg [1:0] multdiv_operator_o;
output reg [1:0] multdiv_signed_mode_o;
output reg csr_access_o;
output reg [1:0] csr_op_o;
output reg data_req_o;
output reg data_we_o;
output reg [1:0] data_type_o;
output reg data_sign_extension_o;
output reg jump_in_dec_o;
output reg branch_in_dec_o;
reg illegal_insn;
wire illegal_reg_rv32e;
reg csr_illegal;
reg rf_we;
wire [31:0] instr;
wire [31:0] instr_alu;
wire [9:0] unused_instr_alu;
wire [4:0] instr_rs1;
wire [4:0] instr_rs2;
wire [4:0] instr_rs3;
wire [4:0] instr_rd;
reg use_rs3_d;
reg use_rs3_q;
reg [1:0] csr_op;
reg [6:0] opcode;
reg [6:0] opcode_alu;
assign instr = instr_rdata_i;
assign instr_alu = instr_rdata_alu_i;
assign imm_i_type_o = {{20 {instr[31]}}, instr[31:20]};
assign imm_s_type_o = {{20 {instr[31]}}, instr[31:25], instr[11:7]};
assign imm_b_type_o = {{19 {instr[31]}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0};
assign imm_u_type_o = {instr[31:12], 12'b000000000000};
assign imm_j_type_o = {{12 {instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0};
assign zimm_rs1_type_o = {27'b000000000000000000000000000, instr_rs1};
generate
if (RV32B != 32'sd0) begin : gen_rs3_flop
always @(posedge clk_i or negedge rst_ni)
if (!rst_ni)
use_rs3_q <= 1'b0;
else
use_rs3_q <= use_rs3_d;
end
else begin : gen_no_rs3_flop
wire unused_clk;
wire unused_rst_n;
assign unused_clk = clk_i;
assign unused_rst_n = rst_ni;
wire [1:1] sv2v_tmp_44B6F;
assign sv2v_tmp_44B6F = use_rs3_d;
always @(*) use_rs3_q = sv2v_tmp_44B6F;
end
endgenerate
assign instr_rs1 = instr[19:15];
assign instr_rs2 = instr[24:20];
assign instr_rs3 = instr[31:27];
assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i ? instr_rs3 : instr_rs1);
assign rf_raddr_b_o = instr_rs2;
assign instr_rd = instr[11:7];
assign rf_waddr_o = instr_rd;
generate
if (RV32E) begin : gen_rv32e_reg_check_active
assign illegal_reg_rv32e = ((rf_raddr_a_o[4] & (alu_op_a_mux_sel_o == 2'd0)) | (rf_raddr_b_o[4] & (alu_op_b_mux_sel_o == 1'd0))) | (rf_waddr_o[4] & rf_we);
end
else begin : gen_rv32e_reg_check_inactive
assign illegal_reg_rv32e = 1'b0;
end
endgenerate
always @(*) begin : csr_operand_check
csr_op_o = csr_op;
if (((csr_op == 2'd2) || (csr_op == 2'd3)) && (instr_rs1 == {5 {1'sb0}}))
csr_op_o = 2'd0;
end
reg eFPGA_int_en;
always @(*) begin
jump_in_dec_o = 1'b0;
jump_set_o = 1'b0;
branch_in_dec_o = 1'b0;
icache_inval_o = 1'b0;
eFPGA_int_en = 1'b0;
eFPGA_operator_o = 2'b00;
eFPGA_delay_o = 4'b0000;
multdiv_operator_o = 2'd0;
multdiv_signed_mode_o = 2'b00;
rf_wdata_sel_o = 1'd0;
rf_we = 1'b0;
rf_ren_a_o = 1'b0;
rf_ren_b_o = 1'b0;
csr_access_o = 1'b0;
csr_illegal = 1'b0;
csr_op = 2'd0;
data_we_o = 1'b0;
data_type_o = 2'b00;
data_sign_extension_o = 1'b0;
data_req_o = 1'b0;
illegal_insn = 1'b0;
ebrk_insn_o = 1'b0;
mret_insn_o = 1'b0;
dret_insn_o = 1'b0;
ecall_insn_o = 1'b0;
wfi_insn_o = 1'b0;
opcode = instr[6:0];
case (opcode)
7'h6f: begin
jump_in_dec_o = 1'b1;
if (instr_first_cycle_i) begin
rf_we = BranchTargetALU;
jump_set_o = 1'b1;
end
else
rf_we = 1'b1;
end
7'h67: begin
jump_in_dec_o = 1'b1;
if (instr_first_cycle_i) begin
rf_we = BranchTargetALU;
jump_set_o = 1'b1;
end
else
rf_we = 1'b1;
if (instr[14:12] != 3'b000)
illegal_insn = 1'b1;
rf_ren_a_o = 1'b1;
end
7'h63: begin
branch_in_dec_o = 1'b1;
case (instr[14:12])
3'b000, 3'b001, 3'b100, 3'b101, 3'b110, 3'b111: illegal_insn = 1'b0;
default: illegal_insn = 1'b1;
endcase
rf_ren_a_o = 1'b1;
rf_ren_b_o = 1'b1;
end
7'h23: begin
rf_ren_a_o = 1'b1;
rf_ren_b_o = 1'b1;
data_req_o = 1'b1;
data_we_o = 1'b1;
if (instr[14])
illegal_insn = 1'b1;
case (instr[13:12])
2'b00: data_type_o = 2'b10;
2'b01: data_type_o = 2'b01;
2'b10: data_type_o = 2'b00;
default: illegal_insn = 1'b1;
endcase
end
7'h03: begin
rf_ren_a_o = 1'b1;
data_req_o = 1'b1;
data_type_o = 2'b00;
data_sign_extension_o = ~instr[14];
case (instr[13:12])
2'b00: data_type_o = 2'b10;
2'b01: data_type_o = 2'b01;
2'b10: begin
data_type_o = 2'b00;
if (instr[14])
illegal_insn = 1'b1;
end
default: illegal_insn = 1'b1;
endcase
end
7'h37: rf_we = 1'b1;
7'h17: rf_we = 1'b1;
7'h13: begin
rf_ren_a_o = 1'b1;
rf_we = 1'b1;
case (instr[14:12])
3'b000, 3'b010, 3'b011, 3'b100, 3'b110, 3'b111: illegal_insn = 1'b0;
3'b001:
case (instr[31:27])
5'b00000: illegal_insn = (instr[26:25] == 2'b00 ? 1'b0 : 1'b1);
5'b00100, 5'b01001, 5'b00101, 5'b01101: illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
5'b00001:
if (instr[26] == 1'b0) begin
if (RV32B == 32'sd2)
illegal_insn = 1'b0;
else if (RV32Zk != 32'sd0)
illegal_insn = (instr[25:20] == 6'b001111 ? 1'b0 : 1'b1);
else
illegal_insn = 1'b1;
end
else
illegal_insn = 1'b1;
5'b01100:
case (instr[26:20])
7'b0000000, 7'b0000001, 7'b0000010, 7'b0000100, 7'b0000101: illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
7'b0010000, 7'b0010001, 7'b0010010, 7'b0011000, 7'b0011001, 7'b0011010: illegal_insn = (RV32B == 32'sd2 ? 1'b0 : 1'b1);
default: illegal_insn = 1'b1;
endcase
5'b00010:
case (instr[26:20])
7'b0000000, 7'b0000001, 7'b0000010, 7'b0000011: illegal_insn = (RV32Zk == 32'sd2 ? 1'b0 : 1'b1);
7'b0001000, 7'b0001001: illegal_insn = (RV32Zk == 32'sd3 ? 1'b0 : 1'b1);
default: illegal_insn = 1'b1;
endcase
default: illegal_insn = 1'b1;
endcase
3'b101:
if (instr[26])
illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
else
case (instr[31:27])
5'b00000, 5'b01000: illegal_insn = (instr[26:25] == 2'b00 ? 1'b0 : 1'b1);
5'b00100, 5'b01001: illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
5'b01100: illegal_insn = ((RV32B != 32'sd0) || (RV32Zk != 32'sd0) ? 1'b0 : 1'b1);
5'b01101:
if (RV32B == 32'sd2)
illegal_insn = 1'b0;
else
case (instr[24:20])
5'b11111: illegal_insn = (RV32B == 32'sd1 ? 1'b0 : 1'b1);
5'b11000: illegal_insn = ((RV32B == 32'sd1) || (RV32Zk != 32'sd0) ? 1'b0 : 1'b1);
5'b00111: illegal_insn = (RV32Zk != 32'sd0 ? 1'b0 : 1'b1);
default: illegal_insn = 1'b1;
endcase
5'b00101:
if (RV32B == 32'sd2)
illegal_insn = 1'b0;
else if (instr[24:20] == 5'b00111)
illegal_insn = (RV32B == 32'sd1 ? 1'b0 : 1'b1);
else
illegal_insn = 1'b1;
5'b00001:
if (instr[26] == 1'b0) begin
if (RV32B == 32'sd2)
illegal_insn = 1'b0;
else if (RV32Zk != 32'sd0)
illegal_insn = (instr[25:20] == 6'b001111 ? 1'b0 : 1'b1);
else
illegal_insn = 1'b1;
end
else
illegal_insn = 1'b1;
default: illegal_insn = 1'b1;
endcase
default: illegal_insn = 1'b1;
endcase
end
7'h33: begin
rf_ren_a_o = 1'b1;
rf_ren_b_o = 1'b1;
rf_we = 1'b1;
if ({instr[26], instr[13:12]} == 3'b101)
illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
else if ({instr[29:28], instr[25], instr[14:12]} == 6'b101000)
illegal_insn = (RV32Zk == 32'sd2 ? 1'b0 : 1'b1);
else if ({instr[29:27], instr[25], instr[14:12]} == 7'b1100000)
illegal_insn = (RV32Zk == 32'sd3 ? 1'b0 : 1'b1);
else
case ({instr[31:25], instr[14:12]})
10'b0000000000, 10'b0100000000, 10'b0000000010, 10'b0000000011, 10'b0000000100, 10'b0000000110, 10'b0000000111, 10'b0000000001, 10'b0000000101, 10'b0100000101: illegal_insn = 1'b0;
10'b0010000010, 10'b0010000100, 10'b0010000110: illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
10'b0100000111, 10'b0100000110, 10'b0100000100, 10'b0110000001, 10'b0110000101, 10'b0000100100, 10'b0000100111: illegal_insn = ((RV32B != 32'sd0) || (RV32Zk != 32'sd0) ? 1'b0 : 1'b1);
10'b0100100100, 10'b0010000001, 10'b0010000101, 10'b0000101100, 10'b0000101101, 10'b0000101110, 10'b0000101111, 10'b0100100001, 10'b0010100001, 10'b0110100001, 10'b0100100101, 10'b0100100111: illegal_insn = (RV32B != 32'sd0 ? 1'b0 : 1'b1);
10'b0100100110, 10'b0000100110, 10'b0110100101, 10'b0010100101, 10'b0000100001, 10'b0000100101: illegal_insn = (RV32B == 32'sd2 ? 1'b0 : 1'b1);
10'b0000101001, 10'b0000101011: illegal_insn = ((RV32B == 32'sd2) || (RV32Zk != 32'sd0) ? 1'b0 : 1'b1);
10'b0000101010: illegal_insn = (RV32B == 32'sd2 ? 1'b0 : 1'b1);
10'b0010100100, 10'b0010100010: illegal_insn = (RV32Zk != 32'sd0 ? 1'b0 : 1'b1);
10'b0101000000, 10'b0101001000, 10'b0101010000, 10'b0101011000, 10'b0101110000, 10'b0101111000: illegal_insn = (RV32Zk == 32'sd2 ? 1'b0 : 1'b1);
10'b0000001000: begin
multdiv_operator_o = 2'd0;
multdiv_signed_mode_o = 2'b00;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001001: begin
multdiv_operator_o = 2'd1;
multdiv_signed_mode_o = 2'b11;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001010: begin
multdiv_operator_o = 2'd1;
multdiv_signed_mode_o = 2'b01;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001011: begin
multdiv_operator_o = 2'd1;
multdiv_signed_mode_o = 2'b00;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001100: begin
multdiv_operator_o = 2'd2;
multdiv_signed_mode_o = 2'b11;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001101: begin
multdiv_operator_o = 2'd2;
multdiv_signed_mode_o = 2'b00;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001110: begin
multdiv_operator_o = 2'd3;
multdiv_signed_mode_o = 2'b11;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
10'b0000001111: begin
multdiv_operator_o = 2'd3;
multdiv_signed_mode_o = 2'b00;
illegal_insn = (RV32M == 32'sd0 ? 1'b1 : 1'b0);
end
default: illegal_insn = 1'b1;
endcase
end
7'h0b: begin
rf_ren_a_o = 1'b1;
rf_ren_b_o = 1'b1;
rf_we = 1'b1;
eFPGA_operator_o = instr_rdata_i[13:12];
eFPGA_delay_o = instr_rdata_i[28:25];
eFPGA_int_en = 1'b1;
illegal_insn = 1'b0;
end
7'h0f:
case (instr[14:12])
3'b000: rf_we = 1'b0;
3'b001: begin
jump_in_dec_o = 1'b1;
rf_we = 1'b0;
if (instr_first_cycle_i) begin
jump_set_o = 1'b1;
icache_inval_o = 1'b1;
end
end
default: illegal_insn = 1'b1;
endcase
7'h73:
if (instr[14:12] == 3'b000) begin
case (instr[31:20])
12'h000: ecall_insn_o = 1'b1;
12'h001: ebrk_insn_o = 1'b1;
12'h302: mret_insn_o = 1'b1;
12'h7b2: dret_insn_o = 1'b1;
12'h105: wfi_insn_o = 1'b1;
default: illegal_insn = 1'b1;
endcase
if ((instr_rs1 != 5'b00000) || (instr_rd != 5'b00000))
illegal_insn = 1'b1;
end
else begin
csr_access_o = 1'b1;
rf_wdata_sel_o = 1'd1;
rf_we = 1'b1;
if (~instr[14])
rf_ren_a_o = 1'b1;
case (instr[13:12])
2'b01: csr_op = 2'd1;
2'b10: csr_op = 2'd2;
2'b11: csr_op = 2'd3;
default: csr_illegal = 1'b1;
endcase
illegal_insn = csr_illegal;
end
default: illegal_insn = 1'b1;
endcase
if (illegal_c_insn_i)
illegal_insn = 1'b1;
if (illegal_insn) begin
rf_we = 1'b0;
data_req_o = 1'b0;
data_we_o = 1'b0;
jump_in_dec_o = 1'b0;
jump_set_o = 1'b0;
branch_in_dec_o = 1'b0;
csr_access_o = 1'b0;
end
end
always @(*) begin
alu_operator_o = 7'd41;
alu_op_a_mux_sel_o = 2'd3;
alu_op_b_mux_sel_o = 1'd1;
imm_a_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd0;
bt_a_mux_sel_o = 2'd2;
bt_b_mux_sel_o = 3'd0;
opcode_alu = instr_alu[6:0];
use_rs3_d = 1'b0;
alu_multicycle_o = 1'b0;
mult_sel_o = 1'b0;
div_sel_o = 1'b0;
case (opcode_alu)
7'h6f: begin
if (BranchTargetALU) begin
bt_a_mux_sel_o = 2'd2;
bt_b_mux_sel_o = 3'd4;
end
if (instr_first_cycle_i && !BranchTargetALU) begin
alu_op_a_mux_sel_o = 2'd2;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd4;
alu_operator_o = 7'd0;
end
else begin
alu_op_a_mux_sel_o = 2'd2;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd5;
alu_operator_o = 7'd0;
end
end
7'h67: begin
if (BranchTargetALU) begin
bt_a_mux_sel_o = 2'd0;
bt_b_mux_sel_o = 3'd0;
end
if (instr_first_cycle_i && !BranchTargetALU) begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd0;
alu_operator_o = 7'd0;
end
else begin
alu_op_a_mux_sel_o = 2'd2;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd5;
alu_operator_o = 7'd0;
end
end
7'h63: begin
case (instr_alu[14:12])
3'b000: alu_operator_o = 7'd26;
3'b001: alu_operator_o = 7'd27;
3'b100: alu_operator_o = 7'd22;
3'b101: alu_operator_o = 7'd24;
3'b110: alu_operator_o = 7'd23;
3'b111: alu_operator_o = 7'd25;
default:
;
endcase
if (BranchTargetALU) begin
bt_a_mux_sel_o = 2'd2;
bt_b_mux_sel_o = (branch_taken_i ? 3'd2 : 3'd5);
end
if (instr_first_cycle_i) begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd0;
end
else if (!BranchTargetALU) begin
alu_op_a_mux_sel_o = 2'd2;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = (branch_taken_i ? 3'd2 : 3'd5);
alu_operator_o = 7'd0;
end
end
7'h23: begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd0;
alu_operator_o = 7'd0;
if (!instr_alu[14]) begin
imm_b_mux_sel_o = 3'd1;
alu_op_b_mux_sel_o = 1'd1;
end
end
7'h03: begin
alu_op_a_mux_sel_o = 2'd0;
alu_operator_o = 7'd0;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd0;
end
7'h37: begin
alu_op_a_mux_sel_o = 2'd3;
alu_op_b_mux_sel_o = 1'd1;
imm_a_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd3;
alu_operator_o = 7'd0;
end
7'h17: begin
alu_op_a_mux_sel_o = 2'd2;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd3;
alu_operator_o = 7'd0;
end
7'h13: begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd0;
case (instr_alu[14:12])
3'b000: alu_operator_o = 7'd0;
3'b010: alu_operator_o = 7'd40;
3'b011: alu_operator_o = 7'd41;
3'b100: alu_operator_o = 7'd2;
3'b110: alu_operator_o = 7'd3;
3'b111: alu_operator_o = 7'd4;
3'b001:
case (instr_alu[31:27])
5'b00000: alu_operator_o = 7'd10;
5'b00100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd12;
5'b01001:
if (RV32B != 32'sd0)
alu_operator_o = 7'd47;
5'b00101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd46;
5'b01101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd48;
5'b00001:
if (instr_alu[26] == 0)
if (RV32B == 32'sd2)
alu_operator_o = 7'd17;
else if (RV32Zk != 32'sd0)
alu_operator_o = (instr[25:20] == 6'b001111 ? 7'd65 : 7'd10);
else
alu_operator_o = 7'd10;
5'b01100:
case (instr_alu[26:20])
7'b0000000:
if (RV32B != 32'sd0)
alu_operator_o = 7'd37;
7'b0000001:
if (RV32B != 32'sd0)
alu_operator_o = 7'd38;
7'b0000010:
if (RV32B != 32'sd0)
alu_operator_o = 7'd39;
7'b0000100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd35;
7'b0000101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd36;
7'b0010000:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd56;
alu_multicycle_o = 1'b1;
end
7'b0010001:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd58;
alu_multicycle_o = 1'b1;
end
7'b0010010:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd60;
alu_multicycle_o = 1'b1;
end
7'b0011000:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd57;
alu_multicycle_o = 1'b1;
end
7'b0011001:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd59;
alu_multicycle_o = 1'b1;
end
7'b0011010:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd61;
alu_multicycle_o = 1'b1;
end
default:
;
endcase
5'b00010:
case (instr_alu[26:20])
7'b0000000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd78;
7'b0000001:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd79;
7'b0000010:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd80;
7'b0000011:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd81;
7'b0001000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd112;
7'b0001001:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd113;
default: alu_operator_o = 7'd10;
endcase
default: alu_operator_o = 7'd10;
endcase
3'b101:
if (RV32B != 32'sd0) begin
if (instr_alu[26] == 1'b1) begin
alu_operator_o = 7'd45;
alu_multicycle_o = 1'b1;
if (instr_first_cycle_i)
use_rs3_d = 1'b1;
else
use_rs3_d = 1'b0;
end
else
case (instr_alu[31:27])
5'b00000: alu_operator_o = 7'd9;
5'b01000: alu_operator_o = 7'd8;
5'b00100: alu_operator_o = 7'd11;
5'b01001: alu_operator_o = 7'd49;
5'b01100: begin
alu_operator_o = 7'd13;
alu_multicycle_o = 1'b1;
end
5'b01101: alu_operator_o = 7'd15;
5'b00101: alu_operator_o = 7'd16;
5'b00001:
if (RV32B == 32'sd2)
if (instr_alu[26] == 1'b0)
alu_operator_o = 7'd18;
default:
;
endcase
end
else
case (instr_alu[31:27])
5'b00000: alu_operator_o = 7'd9;
5'b01000: alu_operator_o = 7'd8;
5'b01100:
if (RV32Zk != 32'sd0)
if (instr_alu[26] == 1'b0)
alu_operator_o = 7'd62;
5'b01101:
if (RV32Zk != 32'sd0) begin
if (instr_alu[26:20] == 7'b0000111)
alu_operator_o = 7'd63;
if (instr_alu[26:20] == 7'b0011000)
alu_operator_o = 7'd64;
end
5'b00001:
if (RV32Zk != 32'sd0)
if (instr_alu[26:20] == 7'b0001111)
alu_operator_o = 7'd66;
default:
;
endcase
default:
;
endcase
end
7'h33: begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd0;
if ({instr[26], instr[13:12]} == 3'b101) begin
if (RV32B != 32'sd0)
case ({instr_alu[26:25], instr_alu[14:12]})
5'b11001: begin
alu_operator_o = 7'd43;
alu_multicycle_o = 1'b1;
if (instr_first_cycle_i)
use_rs3_d = 1'b1;
else
use_rs3_d = 1'b0;
end
5'b11101: begin
alu_operator_o = 7'd42;
alu_multicycle_o = 1'b1;
if (instr_first_cycle_i)
use_rs3_d = 1'b1;
else
use_rs3_d = 1'b0;
end
5'b10001: begin
alu_operator_o = 7'd44;
alu_multicycle_o = 1'b1;
if (instr_first_cycle_i)
use_rs3_d = 1'b1;
else
use_rs3_d = 1'b0;
end
5'b10101: begin
alu_operator_o = 7'd45;
alu_multicycle_o = 1'b1;
if (instr_first_cycle_i)
use_rs3_d = 1'b1;
else
use_rs3_d = 1'b0;
end
default:
;
endcase
end
else
case ({instr_alu[31:25], instr_alu[14:12]})
10'b0000000000: alu_operator_o = 7'd0;
10'b0100000000: alu_operator_o = 7'd1;
10'b0000000010: alu_operator_o = 7'd40;
10'b0000000011: alu_operator_o = 7'd41;
10'b0000000100: alu_operator_o = 7'd2;
10'b0000000110: alu_operator_o = 7'd3;
10'b0000000111: alu_operator_o = 7'd4;
10'b0000000001: alu_operator_o = 7'd10;
10'b0000000101: alu_operator_o = 7'd9;
10'b0100000101: alu_operator_o = 7'd8;
10'b0010000001:
if (RV32B != 32'sd0)
alu_operator_o = 7'd12;
10'b0010000101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd11;
10'b0110000001:
if (RV32B != 32'sd0) begin
alu_operator_o = 7'd14;
alu_multicycle_o = 1'b1;
end
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd68;
10'b0110000101:
if (RV32B != 32'sd0) begin
alu_operator_o = 7'd13;
alu_multicycle_o = 1'b1;
end
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd67;
10'b0000101100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd28;
10'b0000101101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd30;
10'b0000101110:
if (RV32B != 32'sd0)
alu_operator_o = 7'd29;
10'b0000101111:
if (RV32B != 32'sd0)
alu_operator_o = 7'd31;
10'b0000100100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd32;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd72;
10'b0100100100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd33;
10'b0000100111:
if (RV32B != 32'sd0)
alu_operator_o = 7'd34;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd73;
10'b0100000100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd5;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd71;
10'b0100000110:
if (RV32B != 32'sd0)
alu_operator_o = 7'd6;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd70;
10'b0100000111:
if (RV32B != 32'sd0)
alu_operator_o = 7'd7;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd69;
10'b0010000010:
if (RV32B != 32'sd0)
alu_operator_o = 7'd19;
10'b0010000100:
if (RV32B != 32'sd0)
alu_operator_o = 7'd20;
10'b0010000110:
if (RV32B != 32'sd0)
alu_operator_o = 7'd21;
10'b0100100001:
if (RV32B != 32'sd0)
alu_operator_o = 7'd47;
10'b0010100001:
if (RV32B != 32'sd0)
alu_operator_o = 7'd46;
10'b0110100001:
if (RV32B != 32'sd0)
alu_operator_o = 7'd48;
10'b0100100101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd49;
10'b0100100111:
if (RV32B != 32'sd0)
alu_operator_o = 7'd52;
10'b0110100101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd15;
10'b0010100101:
if (RV32B != 32'sd0)
alu_operator_o = 7'd16;
10'b0000100001:
if (RV32B == 32'sd2)
alu_operator_o = 7'd17;
10'b0000100101:
if (RV32B == 32'sd2)
alu_operator_o = 7'd18;
10'b0000101001:
if (RV32B == 32'sd2)
alu_operator_o = 7'd53;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd74;
10'b0000101010:
if (RV32B == 32'sd2)
alu_operator_o = 7'd54;
10'b0000101011:
if (RV32B == 32'sd2)
alu_operator_o = 7'd55;
else if (RV32Zk != 32'sd0)
alu_operator_o = 7'd75;
10'b0100100110:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd51;
alu_multicycle_o = 1'b1;
end
10'b0000100110:
if (RV32B == 32'sd2) begin
alu_operator_o = 7'd50;
alu_multicycle_o = 1'b1;
end
10'b0010100100:
if (RV32Zk != 32'sd0)
alu_operator_o = 7'd76;
10'b0010100010:
if (RV32Zk != 32'sd0)
alu_operator_o = 7'd77;
10'b0101000000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd82;
10'b0101001000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd83;
10'b0101010000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd84;
10'b0101011000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd85;
10'b0101110000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd86;
10'b0101111000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd87;
10'b0010001000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd96;
10'b0110001000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd97;
10'b1010001000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd98;
10'b1110001000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd99;
10'b0010011000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd100;
10'b0110011000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd101;
10'b1010011000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd102;
10'b1110011000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd103;
10'b0010101000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd88;
10'b0110101000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd89;
10'b1010101000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd90;
10'b1110101000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd91;
10'b0010111000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd92;
10'b0110111000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd93;
10'b1010111000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd94;
10'b1110111000:
if (RV32Zk == 32'sd2)
alu_operator_o = 7'd95;
10'b0011000000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd104;
10'b0111000000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd105;
10'b1011000000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd106;
10'b1111000000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd107;
10'b0011010000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd108;
10'b0111010000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd109;
10'b1011010000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd110;
10'b1111010000:
if (RV32Zk == 32'sd3)
alu_operator_o = 7'd111;
10'b0000001000: begin
alu_operator_o = 7'd0;
mult_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001001: begin
alu_operator_o = 7'd0;
mult_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001010: begin
alu_operator_o = 7'd0;
mult_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001011: begin
alu_operator_o = 7'd0;
mult_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001100: begin
alu_operator_o = 7'd0;
div_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001101: begin
alu_operator_o = 7'd0;
div_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001110: begin
alu_operator_o = 7'd0;
div_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
10'b0000001111: begin
alu_operator_o = 7'd0;
div_sel_o = (RV32M == 32'sd0 ? 1'b0 : 1'b1);
end
default:
;
endcase
end
7'h0b: begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd0;
end
7'h0f:
case (instr_alu[14:12])
3'b000: begin
alu_operator_o = 7'd0;
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd1;
end
3'b001:
if (BranchTargetALU) begin
bt_a_mux_sel_o = 2'd2;
bt_b_mux_sel_o = 3'd5;
end
else begin
alu_op_a_mux_sel_o = 2'd2;
alu_op_b_mux_sel_o = 1'd1;
imm_b_mux_sel_o = 3'd5;
alu_operator_o = 7'd0;
end
default:
;
endcase
7'h73:
if (instr_alu[14:12] == 3'b000) begin
alu_op_a_mux_sel_o = 2'd0;
alu_op_b_mux_sel_o = 1'd1;
end
else begin
alu_op_b_mux_sel_o = 1'd1;
imm_a_mux_sel_o = 1'd0;
imm_b_mux_sel_o = 3'd0;
if (instr_alu[14])
alu_op_a_mux_sel_o = 2'd3;
else
alu_op_a_mux_sel_o = 2'd0;
end
default:
;
endcase
end
assign eFPGA_int_en_o = (illegal_insn ? 1'b0 : eFPGA_int_en);
assign mult_en_o = (illegal_insn ? 1'b0 : mult_sel_o);
assign div_en_o = (illegal_insn ? 1'b0 : div_sel_o);
assign illegal_insn_o = illegal_insn | illegal_reg_rv32e;
assign rf_we_o = rf_we & ~illegal_reg_rv32e;
assign unused_instr_alu = {instr_alu[19:15], instr_alu[11:7]};
endmodule