| module ibex_id_stage ( |
| clk_i, |
| rst_ni, |
| ctrl_busy_o, |
| illegal_insn_o, |
| instr_valid_i, |
| instr_rdata_i, |
| instr_rdata_alu_i, |
| instr_rdata_c_i, |
| instr_is_compressed_i, |
| instr_bp_taken_i, |
| instr_req_o, |
| instr_first_cycle_id_o, |
| instr_valid_clear_o, |
| id_in_ready_o, |
| icache_inval_o, |
| branch_decision_i, |
| pc_set_o, |
| pc_set_spec_o, |
| pc_mux_o, |
| nt_branch_mispredict_o, |
| nt_branch_addr_o, |
| exc_pc_mux_o, |
| exc_cause_o, |
| illegal_c_insn_i, |
| instr_fetch_err_i, |
| instr_fetch_err_plus2_i, |
| pc_id_i, |
| ex_valid_i, |
| lsu_resp_valid_i, |
| alu_operator_ex_o, |
| alu_operand_a_ex_o, |
| alu_operand_b_ex_o, |
| imd_val_we_ex_i, |
| imd_val_d_ex_i, |
| imd_val_q_ex_o, |
| bt_a_operand_o, |
| bt_b_operand_o, |
| mult_en_ex_o, |
| div_en_ex_o, |
| mult_sel_ex_o, |
| div_sel_ex_o, |
| multdiv_operator_ex_o, |
| multdiv_signed_mode_ex_o, |
| multdiv_operand_a_ex_o, |
| multdiv_operand_b_ex_o, |
| multdiv_ready_id_o, |
| eFPGA_en_o, |
| eFPGA_operator_o, |
| eFPGA_operand_a_o, |
| eFPGA_operand_b_o, |
| eFPGA_delay_o, |
| csr_access_o, |
| csr_op_o, |
| csr_op_en_o, |
| csr_save_if_o, |
| csr_save_id_o, |
| csr_save_wb_o, |
| csr_restore_mret_id_o, |
| csr_restore_dret_id_o, |
| csr_save_cause_o, |
| csr_mtval_o, |
| priv_mode_i, |
| csr_mstatus_tw_i, |
| illegal_csr_insn_i, |
| data_ind_timing_i, |
| lsu_req_o, |
| lsu_we_o, |
| lsu_type_o, |
| lsu_sign_ext_o, |
| lsu_wdata_o, |
| lsu_req_done_i, |
| lsu_addr_incr_req_i, |
| lsu_addr_last_i, |
| csr_mstatus_mie_i, |
| irq_pending_i, |
| irqs_i, |
| irq_nm_i, |
| nmi_mode_o, |
| lsu_load_err_i, |
| lsu_store_err_i, |
| debug_mode_o, |
| debug_cause_o, |
| debug_csr_save_o, |
| debug_req_i, |
| debug_single_step_i, |
| debug_ebreakm_i, |
| debug_ebreaku_i, |
| trigger_match_i, |
| result_ex_i, |
| csr_rdata_i, |
| rf_raddr_a_o, |
| rf_rdata_a_i, |
| rf_raddr_b_o, |
| rf_rdata_b_i, |
| rf_ren_a_o, |
| rf_ren_b_o, |
| rf_waddr_id_o, |
| rf_wdata_id_o, |
| rf_we_id_o, |
| rf_rd_a_wb_match_o, |
| rf_rd_b_wb_match_o, |
| rf_waddr_wb_i, |
| rf_wdata_fwd_wb_i, |
| rf_write_wb_i, |
| en_wb_o, |
| instr_type_wb_o, |
| instr_perf_count_id_o, |
| ready_wb_i, |
| outstanding_load_wb_i, |
| outstanding_store_wb_i, |
| perf_jump_o, |
| perf_branch_o, |
| perf_tbranch_o, |
| perf_dside_wait_o, |
| perf_mul_wait_o, |
| perf_div_wait_o, |
| instr_id_done_o |
| ); |
| parameter [0:0] RV32E = 0; |
| parameter integer RV32M = 32'sd2; |
| parameter integer RV32B = 32'sd0; |
| parameter integer RV32Zk = 32'sd0; |
| parameter [0:0] DataIndTiming = 1'b0; |
| parameter [0:0] BranchTargetALU = 0; |
| parameter [0:0] SpecBranch = 0; |
| parameter [0:0] WritebackStage = 0; |
| parameter [0:0] BranchPredictor = 0; |
| input wire clk_i; |
| input wire rst_ni; |
| output wire ctrl_busy_o; |
| output wire illegal_insn_o; |
| input wire instr_valid_i; |
| input wire [31:0] instr_rdata_i; |
| input wire [31:0] instr_rdata_alu_i; |
| input wire [15:0] instr_rdata_c_i; |
| input wire instr_is_compressed_i; |
| input wire instr_bp_taken_i; |
| output wire instr_req_o; |
| output wire instr_first_cycle_id_o; |
| output wire instr_valid_clear_o; |
| output wire id_in_ready_o; |
| output wire icache_inval_o; |
| input wire branch_decision_i; |
| output wire pc_set_o; |
| output wire pc_set_spec_o; |
| output wire [2:0] pc_mux_o; |
| output wire nt_branch_mispredict_o; |
| output wire [31:0] nt_branch_addr_o; |
| output wire [1:0] exc_pc_mux_o; |
| output wire [5:0] exc_cause_o; |
| input wire illegal_c_insn_i; |
| input wire instr_fetch_err_i; |
| input wire instr_fetch_err_plus2_i; |
| input wire [31:0] pc_id_i; |
| input wire ex_valid_i; |
| input wire lsu_resp_valid_i; |
| output wire [6:0] alu_operator_ex_o; |
| output wire [31:0] alu_operand_a_ex_o; |
| output wire [31:0] alu_operand_b_ex_o; |
| input wire [1:0] imd_val_we_ex_i; |
| input wire [67:0] imd_val_d_ex_i; |
| output wire [67:0] imd_val_q_ex_o; |
| output reg [31:0] bt_a_operand_o; |
| output reg [31:0] bt_b_operand_o; |
| output wire mult_en_ex_o; |
| output wire div_en_ex_o; |
| output wire mult_sel_ex_o; |
| output wire div_sel_ex_o; |
| output wire [1:0] multdiv_operator_ex_o; |
| output wire [1:0] multdiv_signed_mode_ex_o; |
| output wire [31:0] multdiv_operand_a_ex_o; |
| output wire [31:0] multdiv_operand_b_ex_o; |
| output wire multdiv_ready_id_o; |
| output wire eFPGA_en_o; |
| output wire [1:0] eFPGA_operator_o; |
| output wire [31:0] eFPGA_operand_a_o; |
| output wire [31:0] eFPGA_operand_b_o; |
| output wire [3:0] eFPGA_delay_o; |
| output wire csr_access_o; |
| output wire [1:0] csr_op_o; |
| output wire csr_op_en_o; |
| output wire csr_save_if_o; |
| output wire csr_save_id_o; |
| output wire csr_save_wb_o; |
| output wire csr_restore_mret_id_o; |
| output wire csr_restore_dret_id_o; |
| output wire csr_save_cause_o; |
| output wire [31:0] csr_mtval_o; |
| input wire [1:0] priv_mode_i; |
| input wire csr_mstatus_tw_i; |
| input wire illegal_csr_insn_i; |
| input wire data_ind_timing_i; |
| output wire lsu_req_o; |
| output wire lsu_we_o; |
| output wire [1:0] lsu_type_o; |
| output wire lsu_sign_ext_o; |
| output wire [31:0] lsu_wdata_o; |
| input wire lsu_req_done_i; |
| input wire lsu_addr_incr_req_i; |
| input wire [31:0] lsu_addr_last_i; |
| input wire csr_mstatus_mie_i; |
| input wire irq_pending_i; |
| input wire [17:0] irqs_i; |
| input wire irq_nm_i; |
| output wire nmi_mode_o; |
| input wire lsu_load_err_i; |
| input wire lsu_store_err_i; |
| output wire debug_mode_o; |
| output wire [2:0] debug_cause_o; |
| output wire debug_csr_save_o; |
| input wire debug_req_i; |
| input wire debug_single_step_i; |
| input wire debug_ebreakm_i; |
| input wire debug_ebreaku_i; |
| input wire trigger_match_i; |
| input wire [31:0] result_ex_i; |
| input wire [31:0] csr_rdata_i; |
| output wire [4:0] rf_raddr_a_o; |
| input wire [31:0] rf_rdata_a_i; |
| output wire [4:0] rf_raddr_b_o; |
| input wire [31:0] rf_rdata_b_i; |
| output wire rf_ren_a_o; |
| output wire rf_ren_b_o; |
| output wire [4:0] rf_waddr_id_o; |
| output reg [31:0] rf_wdata_id_o; |
| output wire rf_we_id_o; |
| output wire rf_rd_a_wb_match_o; |
| output wire rf_rd_b_wb_match_o; |
| input wire [4:0] rf_waddr_wb_i; |
| input wire [31:0] rf_wdata_fwd_wb_i; |
| input wire rf_write_wb_i; |
| output wire en_wb_o; |
| output wire [1:0] instr_type_wb_o; |
| output wire instr_perf_count_id_o; |
| input wire ready_wb_i; |
| input wire outstanding_load_wb_i; |
| input wire outstanding_store_wb_i; |
| output wire perf_jump_o; |
| output reg perf_branch_o; |
| output wire perf_tbranch_o; |
| output wire perf_dside_wait_o; |
| output wire perf_mul_wait_o; |
| output wire perf_div_wait_o; |
| output wire instr_id_done_o; |
| wire illegal_insn_dec; |
| wire ebrk_insn; |
| wire mret_insn_dec; |
| wire dret_insn_dec; |
| wire ecall_insn_dec; |
| wire wfi_insn_dec; |
| wire wb_exception; |
| wire id_exception; |
| wire branch_in_dec; |
| reg branch_spec; |
| wire branch_set_spec; |
| wire branch_set_raw_spec; |
| wire branch_set; |
| wire branch_set_raw; |
| reg branch_set_raw_d; |
| reg branch_jump_set_done_q; |
| wire branch_jump_set_done_d; |
| reg branch_not_set; |
| wire branch_taken; |
| wire jump_in_dec; |
| wire jump_set_dec; |
| wire jump_set; |
| reg jump_set_raw; |
| wire instr_first_cycle; |
| wire instr_executing_spec; |
| wire instr_executing; |
| wire instr_done; |
| wire controller_run; |
| wire stall_ld_hz; |
| wire stall_mem; |
| reg stall_multdiv; |
| reg stall_branch; |
| reg stall_jump; |
| wire stall_id; |
| wire stall_wb; |
| wire flush_id; |
| wire multicycle_done; |
| reg eFPGA_stall; |
| wire [31:0] imm_i_type; |
| wire [31:0] imm_s_type; |
| wire [31:0] imm_b_type; |
| wire [31:0] imm_u_type; |
| wire [31:0] imm_j_type; |
| wire [31:0] zimm_rs1_type; |
| wire [31:0] imm_a; |
| reg [31:0] imm_b; |
| wire rf_wdata_sel; |
| wire rf_we_dec; |
| reg rf_we_raw; |
| wire rf_ren_a; |
| wire rf_ren_b; |
| wire rf_ren_a_dec; |
| wire rf_ren_b_dec; |
| assign rf_ren_a = ((instr_valid_i & ~instr_fetch_err_i) & ~illegal_insn_o) & rf_ren_a_dec; |
| assign rf_ren_b = ((instr_valid_i & ~instr_fetch_err_i) & ~illegal_insn_o) & rf_ren_b_dec; |
| assign rf_ren_a_o = rf_ren_a; |
| assign rf_ren_b_o = rf_ren_b; |
| wire [31:0] rf_rdata_a_fwd; |
| wire [31:0] rf_rdata_b_fwd; |
| wire [6:0] alu_operator; |
| wire [1:0] alu_op_a_mux_sel; |
| wire [1:0] alu_op_a_mux_sel_dec; |
| wire alu_op_b_mux_sel; |
| wire alu_op_b_mux_sel_dec; |
| wire alu_multicycle_dec; |
| reg stall_alu; |
| reg [67:0] imd_val_q; |
| wire [1:0] bt_a_mux_sel; |
| wire [2:0] bt_b_mux_sel; |
| wire imm_a_mux_sel; |
| wire [2:0] imm_b_mux_sel; |
| wire [2:0] imm_b_mux_sel_dec; |
| wire mult_en_id; |
| wire mult_en_dec; |
| wire div_en_id; |
| wire div_en_dec; |
| wire multdiv_en_dec; |
| wire [1:0] multdiv_operator; |
| wire [1:0] multdiv_signed_mode; |
| wire lsu_we; |
| wire [1:0] lsu_type; |
| wire lsu_sign_ext; |
| wire lsu_req; |
| wire lsu_req_dec; |
| wire data_req_allowed; |
| reg csr_pipe_flush; |
| reg [31:0] alu_operand_a; |
| wire [31:0] alu_operand_b; |
| assign alu_op_a_mux_sel = (lsu_addr_incr_req_i ? 2'd1 : alu_op_a_mux_sel_dec); |
| assign alu_op_b_mux_sel = (lsu_addr_incr_req_i ? 1'd1 : alu_op_b_mux_sel_dec); |
| assign imm_b_mux_sel = (lsu_addr_incr_req_i ? 3'd6 : imm_b_mux_sel_dec); |
| assign imm_a = (imm_a_mux_sel == 1'd0 ? zimm_rs1_type : {32 {1'sb0}}); |
| always @(*) begin : alu_operand_a_mux |
| case (alu_op_a_mux_sel) |
| 2'd0: alu_operand_a = rf_rdata_a_fwd; |
| 2'd1: alu_operand_a = lsu_addr_last_i; |
| 2'd2: alu_operand_a = pc_id_i; |
| 2'd3: alu_operand_a = imm_a; |
| default: alu_operand_a = pc_id_i; |
| endcase |
| end |
| generate |
| if (BranchTargetALU) begin : g_btalu_muxes |
| always @(*) begin : bt_operand_a_mux |
| case (bt_a_mux_sel) |
| 2'd0: bt_a_operand_o = rf_rdata_a_fwd; |
| 2'd2: bt_a_operand_o = pc_id_i; |
| default: bt_a_operand_o = pc_id_i; |
| endcase |
| end |
| always @(*) begin : bt_immediate_b_mux |
| case (bt_b_mux_sel) |
| 3'd0: bt_b_operand_o = imm_i_type; |
| 3'd2: bt_b_operand_o = imm_b_type; |
| 3'd4: bt_b_operand_o = imm_j_type; |
| 3'd5: bt_b_operand_o = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004); |
| default: bt_b_operand_o = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004); |
| endcase |
| end |
| always @(*) begin : immediate_b_mux |
| case (imm_b_mux_sel) |
| 3'd0: imm_b = imm_i_type; |
| 3'd1: imm_b = imm_s_type; |
| 3'd3: imm_b = imm_u_type; |
| 3'd5: imm_b = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004); |
| 3'd6: imm_b = 32'h00000004; |
| default: imm_b = 32'h00000004; |
| endcase |
| end |
| end |
| else begin : g_nobtalu |
| wire [1:0] unused_a_mux_sel; |
| wire [2:0] unused_b_mux_sel; |
| assign unused_a_mux_sel = bt_a_mux_sel; |
| assign unused_b_mux_sel = bt_b_mux_sel; |
| wire [32:1] sv2v_tmp_FACAA; |
| assign sv2v_tmp_FACAA = 1'sb0; |
| always @(*) bt_a_operand_o = sv2v_tmp_FACAA; |
| wire [32:1] sv2v_tmp_A4AF9; |
| assign sv2v_tmp_A4AF9 = 1'sb0; |
| always @(*) bt_b_operand_o = sv2v_tmp_A4AF9; |
| always @(*) begin : immediate_b_mux |
| case (imm_b_mux_sel) |
| 3'd0: imm_b = imm_i_type; |
| 3'd1: imm_b = imm_s_type; |
| 3'd2: imm_b = imm_b_type; |
| 3'd3: imm_b = imm_u_type; |
| 3'd4: imm_b = imm_j_type; |
| 3'd5: imm_b = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004); |
| 3'd6: imm_b = 32'h00000004; |
| default: imm_b = 32'h00000004; |
| endcase |
| end |
| end |
| endgenerate |
| assign alu_operand_b = (alu_op_b_mux_sel == 1'd1 ? imm_b : rf_rdata_b_fwd); |
| genvar i; |
| generate |
| for (i = 0; i < 2; i = i + 1) begin : gen_intermediate_val_reg |
| always @(posedge clk_i or negedge rst_ni) begin : intermediate_val_reg |
| if (!rst_ni) |
| imd_val_q[(1 - i) * 34+:34] <= 1'sb0; |
| else if (imd_val_we_ex_i[i]) |
| imd_val_q[(1 - i) * 34+:34] <= imd_val_d_ex_i[(1 - i) * 34+:34]; |
| end |
| end |
| endgenerate |
| assign imd_val_q_ex_o = imd_val_q; |
| assign rf_we_id_o = (rf_we_raw & instr_executing) & ~illegal_csr_insn_i; |
| always @(*) begin : rf_wdata_id_mux |
| case (rf_wdata_sel) |
| 1'd0: rf_wdata_id_o = result_ex_i; |
| 1'd1: rf_wdata_id_o = csr_rdata_i; |
| default: rf_wdata_id_o = result_ex_i; |
| endcase |
| end |
| wire eFPGA_int_en; |
| wire [1:0] eFPGA_operator; |
| wire [3:0] eFPGA_delay; |
| assign eFPGA_en_o = eFPGA_int_en; |
| assign eFPGA_operator_o = eFPGA_operator; |
| assign eFPGA_delay_o = eFPGA_delay; |
| ibex_decoder #( |
| .RV32E(RV32E), |
| .RV32M(RV32M), |
| .RV32B(RV32B), |
| .RV32Zk(RV32Zk), |
| .BranchTargetALU(BranchTargetALU) |
| ) decoder_i( |
| .clk_i(clk_i), |
| .rst_ni(rst_ni), |
| .illegal_insn_o(illegal_insn_dec), |
| .ebrk_insn_o(ebrk_insn), |
| .mret_insn_o(mret_insn_dec), |
| .dret_insn_o(dret_insn_dec), |
| .ecall_insn_o(ecall_insn_dec), |
| .wfi_insn_o(wfi_insn_dec), |
| .jump_set_o(jump_set_dec), |
| .branch_taken_i(branch_taken), |
| .icache_inval_o(icache_inval_o), |
| .instr_first_cycle_i(instr_first_cycle), |
| .instr_rdata_i(instr_rdata_i), |
| .instr_rdata_alu_i(instr_rdata_alu_i), |
| .illegal_c_insn_i(illegal_c_insn_i), |
| .imm_a_mux_sel_o(imm_a_mux_sel), |
| .imm_b_mux_sel_o(imm_b_mux_sel_dec), |
| .bt_a_mux_sel_o(bt_a_mux_sel), |
| .bt_b_mux_sel_o(bt_b_mux_sel), |
| .imm_i_type_o(imm_i_type), |
| .imm_s_type_o(imm_s_type), |
| .imm_b_type_o(imm_b_type), |
| .imm_u_type_o(imm_u_type), |
| .imm_j_type_o(imm_j_type), |
| .zimm_rs1_type_o(zimm_rs1_type), |
| .rf_wdata_sel_o(rf_wdata_sel), |
| .rf_we_o(rf_we_dec), |
| .rf_raddr_a_o(rf_raddr_a_o), |
| .rf_raddr_b_o(rf_raddr_b_o), |
| .rf_waddr_o(rf_waddr_id_o), |
| .rf_ren_a_o(rf_ren_a_dec), |
| .rf_ren_b_o(rf_ren_b_dec), |
| .alu_operator_o(alu_operator), |
| .alu_op_a_mux_sel_o(alu_op_a_mux_sel_dec), |
| .alu_op_b_mux_sel_o(alu_op_b_mux_sel_dec), |
| .alu_multicycle_o(alu_multicycle_dec), |
| .eFPGA_operator_o(eFPGA_operator), |
| .eFPGA_int_en_o(eFPGA_int_en), |
| .eFPGA_delay_o(eFPGA_delay), |
| .mult_en_o(mult_en_dec), |
| .div_en_o(div_en_dec), |
| .mult_sel_o(mult_sel_ex_o), |
| .div_sel_o(div_sel_ex_o), |
| .multdiv_operator_o(multdiv_operator), |
| .multdiv_signed_mode_o(multdiv_signed_mode), |
| .csr_access_o(csr_access_o), |
| .csr_op_o(csr_op_o), |
| .data_req_o(lsu_req_dec), |
| .data_we_o(lsu_we), |
| .data_type_o(lsu_type), |
| .data_sign_extension_o(lsu_sign_ext), |
| .jump_in_dec_o(jump_in_dec), |
| .branch_in_dec_o(branch_in_dec) |
| ); |
| always @(*) begin : csr_pipeline_flushes |
| csr_pipe_flush = 1'b0; |
| if ((csr_op_en_o == 1'b1) && ((csr_op_o == 2'd1) || (csr_op_o == 2'd2))) begin |
| if ((instr_rdata_i[31:20] == 12'h300) || (instr_rdata_i[31:20] == 12'h304)) |
| csr_pipe_flush = 1'b1; |
| end |
| else if ((csr_op_en_o == 1'b1) && (csr_op_o != 2'd0)) |
| if ((((instr_rdata_i[31:20] == 12'h7b0) || (instr_rdata_i[31:20] == 12'h7b1)) || (instr_rdata_i[31:20] == 12'h7b2)) || (instr_rdata_i[31:20] == 12'h7b3)) |
| csr_pipe_flush = 1'b1; |
| end |
| assign illegal_insn_o = instr_valid_i & (illegal_insn_dec | illegal_csr_insn_i); |
| ibex_controller #( |
| .WritebackStage(WritebackStage), |
| .BranchPredictor(BranchPredictor) |
| ) controller_i( |
| .clk_i(clk_i), |
| .rst_ni(rst_ni), |
| .ctrl_busy_o(ctrl_busy_o), |
| .illegal_insn_i(illegal_insn_o), |
| .ecall_insn_i(ecall_insn_dec), |
| .mret_insn_i(mret_insn_dec), |
| .dret_insn_i(dret_insn_dec), |
| .wfi_insn_i(wfi_insn_dec), |
| .ebrk_insn_i(ebrk_insn), |
| .csr_pipe_flush_i(csr_pipe_flush), |
| .instr_valid_i(instr_valid_i), |
| .instr_i(instr_rdata_i), |
| .instr_compressed_i(instr_rdata_c_i), |
| .instr_is_compressed_i(instr_is_compressed_i), |
| .instr_bp_taken_i(instr_bp_taken_i), |
| .instr_fetch_err_i(instr_fetch_err_i), |
| .instr_fetch_err_plus2_i(instr_fetch_err_plus2_i), |
| .pc_id_i(pc_id_i), |
| .instr_valid_clear_o(instr_valid_clear_o), |
| .id_in_ready_o(id_in_ready_o), |
| .controller_run_o(controller_run), |
| .instr_req_o(instr_req_o), |
| .pc_set_o(pc_set_o), |
| .pc_set_spec_o(pc_set_spec_o), |
| .pc_mux_o(pc_mux_o), |
| .nt_branch_mispredict_o(nt_branch_mispredict_o), |
| .exc_pc_mux_o(exc_pc_mux_o), |
| .exc_cause_o(exc_cause_o), |
| .lsu_addr_last_i(lsu_addr_last_i), |
| .load_err_i(lsu_load_err_i), |
| .store_err_i(lsu_store_err_i), |
| .wb_exception_o(wb_exception), |
| .id_exception_o(id_exception), |
| .branch_set_i(branch_set), |
| .branch_set_spec_i(branch_set_spec), |
| .branch_not_set_i(branch_not_set), |
| .jump_set_i(jump_set), |
| .csr_mstatus_mie_i(csr_mstatus_mie_i), |
| .irq_pending_i(irq_pending_i), |
| .irqs_i(irqs_i), |
| .irq_nm_i(irq_nm_i), |
| .nmi_mode_o(nmi_mode_o), |
| .csr_save_if_o(csr_save_if_o), |
| .csr_save_id_o(csr_save_id_o), |
| .csr_save_wb_o(csr_save_wb_o), |
| .csr_restore_mret_id_o(csr_restore_mret_id_o), |
| .csr_restore_dret_id_o(csr_restore_dret_id_o), |
| .csr_save_cause_o(csr_save_cause_o), |
| .csr_mtval_o(csr_mtval_o), |
| .priv_mode_i(priv_mode_i), |
| .csr_mstatus_tw_i(csr_mstatus_tw_i), |
| .debug_mode_o(debug_mode_o), |
| .debug_cause_o(debug_cause_o), |
| .debug_csr_save_o(debug_csr_save_o), |
| .debug_req_i(debug_req_i), |
| .debug_single_step_i(debug_single_step_i), |
| .debug_ebreakm_i(debug_ebreakm_i), |
| .debug_ebreaku_i(debug_ebreaku_i), |
| .trigger_match_i(trigger_match_i), |
| .stall_id_i(stall_id), |
| .stall_wb_i(stall_wb), |
| .flush_id_o(flush_id), |
| .ready_wb_i(ready_wb_i), |
| .perf_jump_o(perf_jump_o), |
| .perf_tbranch_o(perf_tbranch_o) |
| ); |
| assign multdiv_en_dec = mult_en_dec | div_en_dec; |
| assign lsu_req = (instr_executing ? data_req_allowed & lsu_req_dec : 1'b0); |
| assign mult_en_id = (instr_executing ? mult_en_dec : 1'b0); |
| assign div_en_id = (instr_executing ? div_en_dec : 1'b0); |
| assign lsu_req_o = lsu_req; |
| assign lsu_we_o = lsu_we; |
| assign lsu_type_o = lsu_type; |
| assign lsu_sign_ext_o = lsu_sign_ext; |
| assign lsu_wdata_o = rf_rdata_b_fwd; |
| assign csr_op_en_o = (csr_access_o & instr_executing) & instr_id_done_o; |
| assign alu_operator_ex_o = alu_operator; |
| assign alu_operand_a_ex_o = alu_operand_a; |
| assign alu_operand_b_ex_o = alu_operand_b; |
| assign mult_en_ex_o = mult_en_id; |
| assign div_en_ex_o = div_en_id; |
| assign multdiv_operator_ex_o = multdiv_operator; |
| assign multdiv_signed_mode_ex_o = multdiv_signed_mode; |
| assign multdiv_operand_a_ex_o = rf_rdata_a_fwd; |
| assign multdiv_operand_b_ex_o = rf_rdata_b_fwd; |
| generate |
| if (BranchTargetALU && !DataIndTiming) begin : g_branch_set_direct |
| assign branch_set_raw = branch_set_raw_d; |
| assign branch_set_raw_spec = branch_spec; |
| end |
| else begin : g_branch_set_flop |
| reg branch_set_raw_q; |
| always @(posedge clk_i or negedge rst_ni) |
| if (!rst_ni) |
| branch_set_raw_q <= 1'b0; |
| else |
| branch_set_raw_q <= branch_set_raw_d; |
| assign branch_set_raw = (BranchTargetALU && !data_ind_timing_i ? branch_set_raw_d : branch_set_raw_q); |
| assign branch_set_raw_spec = (BranchTargetALU && !data_ind_timing_i ? branch_spec : branch_set_raw_q); |
| end |
| endgenerate |
| assign branch_jump_set_done_d = ((branch_set_raw | jump_set_raw) | branch_jump_set_done_q) & ~instr_valid_clear_o; |
| always @(posedge clk_i or negedge rst_ni) |
| if (!rst_ni) |
| branch_jump_set_done_q <= 1'b0; |
| else |
| branch_jump_set_done_q <= branch_jump_set_done_d; |
| assign jump_set = jump_set_raw & ~branch_jump_set_done_q; |
| assign branch_set = branch_set_raw & ~branch_jump_set_done_q; |
| assign branch_set_spec = branch_set_raw_spec & ~branch_jump_set_done_q; |
| generate |
| if (DataIndTiming) begin : g_sec_branch_taken |
| reg branch_taken_q; |
| always @(posedge clk_i or negedge rst_ni) |
| if (!rst_ni) |
| branch_taken_q <= 1'b0; |
| else |
| branch_taken_q <= branch_decision_i; |
| assign branch_taken = ~data_ind_timing_i | branch_taken_q; |
| end |
| else begin : g_nosec_branch_taken |
| assign branch_taken = 1'b1; |
| end |
| if (BranchPredictor) begin : g_calc_nt_addr |
| assign nt_branch_addr_o = pc_id_i + (instr_is_compressed_i ? 32'd2 : 32'd4); |
| end |
| else begin : g_n_calc_nt_addr |
| assign nt_branch_addr_o = 32'd0; |
| end |
| endgenerate |
| assign eFPGA_operand_a_o = rf_rdata_a_fwd; |
| assign eFPGA_operand_b_o = rf_rdata_b_fwd; |
| reg id_fsm_q; |
| reg id_fsm_d; |
| always @(posedge clk_i or negedge rst_ni) begin : id_pipeline_reg |
| if (!rst_ni) |
| id_fsm_q <= 1'd0; |
| else if (instr_executing) |
| id_fsm_q <= id_fsm_d; |
| end |
| always @(*) begin |
| id_fsm_d = id_fsm_q; |
| rf_we_raw = rf_we_dec; |
| stall_multdiv = 1'b0; |
| eFPGA_stall = 1'b0; |
| stall_jump = 1'b0; |
| stall_branch = 1'b0; |
| stall_alu = 1'b0; |
| branch_set_raw_d = 1'b0; |
| branch_spec = 1'b0; |
| branch_not_set = 1'b0; |
| jump_set_raw = 1'b0; |
| perf_branch_o = 1'b0; |
| if (instr_executing_spec) |
| case (id_fsm_q) |
| 1'd0: |
| case (1'b1) |
| lsu_req_dec: |
| if (!WritebackStage) |
| id_fsm_d = 1'd1; |
| else if (~lsu_req_done_i) |
| id_fsm_d = 1'd1; |
| multdiv_en_dec: |
| if (~ex_valid_i) begin |
| id_fsm_d = 1'd1; |
| rf_we_raw = 1'b0; |
| stall_multdiv = 1'b1; |
| end |
| eFPGA_int_en: |
| if (~ex_valid_i) begin |
| id_fsm_d = 1'd1; |
| rf_we_raw = 1'b0; |
| eFPGA_stall = 1'b1; |
| end |
| branch_in_dec: begin |
| id_fsm_d = (data_ind_timing_i || (!BranchTargetALU && branch_decision_i) ? 1'd1 : 1'd0); |
| stall_branch = (~BranchTargetALU & branch_decision_i) | data_ind_timing_i; |
| branch_set_raw_d = branch_decision_i | data_ind_timing_i; |
| if (BranchPredictor) |
| branch_not_set = ~branch_decision_i; |
| branch_spec = (SpecBranch ? 1'b1 : branch_decision_i); |
| perf_branch_o = 1'b1; |
| end |
| jump_in_dec: begin |
| id_fsm_d = (BranchTargetALU ? 1'd0 : 1'd1); |
| stall_jump = ~BranchTargetALU; |
| jump_set_raw = jump_set_dec; |
| end |
| alu_multicycle_dec: begin |
| stall_alu = 1'b1; |
| id_fsm_d = 1'd1; |
| rf_we_raw = 1'b0; |
| end |
| default: id_fsm_d = 1'd0; |
| endcase |
| 1'd1: begin |
| if (multdiv_en_dec) |
| rf_we_raw = rf_we_dec & ex_valid_i; |
| if (multicycle_done & ready_wb_i) |
| id_fsm_d = 1'd0; |
| else begin |
| stall_multdiv = multdiv_en_dec; |
| stall_branch = branch_in_dec; |
| stall_jump = jump_in_dec; |
| eFPGA_stall = eFPGA_int_en; |
| end |
| end |
| default: id_fsm_d = 1'd0; |
| endcase |
| end |
| assign multdiv_ready_id_o = ready_wb_i; |
| assign stall_id = (((((stall_ld_hz | stall_mem) | stall_multdiv) | stall_jump) | stall_branch) | stall_alu) | eFPGA_stall; |
| assign instr_done = (~stall_id & ~flush_id) & instr_executing; |
| assign instr_first_cycle = instr_valid_i & (id_fsm_q == 1'd0); |
| assign instr_first_cycle_id_o = instr_first_cycle; |
| generate |
| if (WritebackStage) begin : gen_stall_mem |
| wire rf_rd_a_wb_match; |
| wire rf_rd_b_wb_match; |
| wire rf_rd_a_hz; |
| wire rf_rd_b_hz; |
| wire outstanding_memory_access; |
| wire instr_kill; |
| assign multicycle_done = (lsu_req_dec ? ~stall_mem : ex_valid_i); |
| assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) & ~lsu_resp_valid_i; |
| assign data_req_allowed = ~outstanding_memory_access; |
| assign instr_kill = ((instr_fetch_err_i | wb_exception) | id_exception) | ~controller_run; |
| assign instr_executing_spec = ((instr_valid_i & ~instr_fetch_err_i) & controller_run) & ~stall_ld_hz; |
| assign instr_executing = ((instr_valid_i & ~instr_kill) & ~stall_ld_hz) & ~outstanding_memory_access; |
| assign stall_mem = instr_valid_i & (outstanding_memory_access | (lsu_req_dec & ~lsu_req_done_i)); |
| assign rf_rd_a_wb_match = (rf_waddr_wb_i == rf_raddr_a_o) & |rf_raddr_a_o; |
| assign rf_rd_b_wb_match = (rf_waddr_wb_i == rf_raddr_b_o) & |rf_raddr_b_o; |
| assign rf_rd_a_wb_match_o = rf_rd_a_wb_match; |
| assign rf_rd_b_wb_match_o = rf_rd_b_wb_match; |
| assign rf_rd_a_hz = rf_rd_a_wb_match & rf_ren_a; |
| assign rf_rd_b_hz = rf_rd_b_wb_match & rf_ren_b; |
| assign rf_rdata_a_fwd = (rf_rd_a_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_a_i); |
| assign rf_rdata_b_fwd = (rf_rd_b_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_b_i); |
| assign stall_ld_hz = outstanding_load_wb_i & (rf_rd_a_hz | rf_rd_b_hz); |
| assign instr_type_wb_o = (~lsu_req_dec ? 2'd2 : (lsu_we ? 2'd1 : 2'd0)); |
| assign instr_id_done_o = en_wb_o & ready_wb_i; |
| assign stall_wb = en_wb_o & ~ready_wb_i; |
| assign perf_dside_wait_o = (instr_valid_i & ~instr_kill) & (outstanding_memory_access | stall_ld_hz); |
| end |
| else begin : gen_no_stall_mem |
| assign multicycle_done = (lsu_req_dec ? lsu_resp_valid_i : ex_valid_i); |
| assign data_req_allowed = instr_first_cycle; |
| assign stall_mem = instr_valid_i & (lsu_req_dec & (~lsu_resp_valid_i | instr_first_cycle)); |
| assign stall_ld_hz = 1'b0; |
| assign instr_executing_spec = (instr_valid_i & ~instr_fetch_err_i) & controller_run; |
| assign instr_executing = instr_executing_spec; |
| assign rf_rdata_a_fwd = rf_rdata_a_i; |
| assign rf_rdata_b_fwd = rf_rdata_b_i; |
| assign rf_rd_a_wb_match_o = 1'b0; |
| assign rf_rd_b_wb_match_o = 1'b0; |
| wire unused_data_req_done_ex; |
| wire [4:0] unused_rf_waddr_wb; |
| wire unused_rf_write_wb; |
| wire unused_outstanding_load_wb; |
| wire unused_outstanding_store_wb; |
| wire unused_wb_exception; |
| wire [31:0] unused_rf_wdata_fwd_wb; |
| wire unused_id_exception; |
| assign unused_data_req_done_ex = lsu_req_done_i; |
| assign unused_rf_waddr_wb = rf_waddr_wb_i; |
| assign unused_rf_write_wb = rf_write_wb_i; |
| assign unused_outstanding_load_wb = outstanding_load_wb_i; |
| assign unused_outstanding_store_wb = outstanding_store_wb_i; |
| assign unused_wb_exception = wb_exception; |
| assign unused_rf_wdata_fwd_wb = rf_wdata_fwd_wb_i; |
| assign unused_id_exception = id_exception; |
| assign instr_type_wb_o = 2'd2; |
| assign stall_wb = 1'b0; |
| assign perf_dside_wait_o = (instr_executing & lsu_req_dec) & ~lsu_resp_valid_i; |
| assign instr_id_done_o = instr_done; |
| end |
| endgenerate |
| assign instr_perf_count_id_o = (((~ebrk_insn & ~ecall_insn_dec) & ~illegal_insn_dec) & ~illegal_csr_insn_i) & ~instr_fetch_err_i; |
| assign en_wb_o = instr_done; |
| assign perf_mul_wait_o = stall_multdiv & mult_en_dec; |
| assign perf_div_wait_o = stall_multdiv & div_en_dec; |
| endmodule |