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