// SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. module dec_decode_ctl import swerv_types::*; ( input logic [15:0] dec_i0_cinst_d, // 16b compressed instruction input logic [15:0] dec_i1_cinst_d, output logic [31:0] dec_i0_inst_wb1, // 32b instruction at wb+1 for trace encoder output logic [31:0] dec_i1_inst_wb1, output logic [31:1] dec_i0_pc_wb1, // 31b pc at wb+1 for trace encoder output logic [31:1] dec_i1_pc_wb1, input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag input logic lsu_nonblock_load_data_valid, // valid nonblock load data back input logic lsu_nonblock_load_data_error, // nonblock load bus error input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag input logic [3:0] dec_i0_trigger_match_d, // i0 decode trigger matches input logic [3:0] dec_i1_trigger_match_d, // i1 decode trigger matches input logic dec_tlu_wr_pause_wb, // pause instruction at wb input logic dec_tlu_pipelining_disable, // pipeline disable - presync, i0 decode only input logic dec_tlu_dual_issue_disable, // i0 decode only input logic dec_tlu_sec_alu_disable, // no alu ops sent to secondary alus input logic [3:0] lsu_trigger_match_dc3, // lsu trigger matches input logic lsu_pmu_misaligned_dc3, // perf mon: load/store misalign input logic dec_tlu_debug_stall, // debug stall decode input logic dec_tlu_flush_leak_one_wb, // leak1 instruction input logic dec_debug_fence_d, // debug fence instruction input logic [1:0] dbg_cmd_wrdata, // disambiguate fence, fence_i input logic dec_i0_icaf_d, // icache access fault input logic dec_i1_icaf_d, input logic dec_i0_icaf_second_d, // i0 instruction access fault on second 2B of 4B inst input logic dec_i0_perr_d, // icache parity error input logic dec_i1_perr_d, input logic dec_i0_sbecc_d, // icache/iccm single-bit error input logic dec_i1_sbecc_d, input logic dec_i0_dbecc_d, // icache/iccm double-bit error input logic dec_i1_dbecc_d, input br_pkt_t dec_i0_brp, // branch packet input br_pkt_t dec_i1_brp, input logic [15:0] ifu_illegal_inst, // 16b illegal inst from aligner input logic [31:1] dec_i0_pc_d, // pc input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3 input logic lsu_halt_idle_any, // lsu idle: if fence instr & ~lsu_halt_idle_any then stall decode input logic lsu_load_stall_any, // stall any store at load input logic lsu_store_stall_any, // stall any store at decode input logic dma_dccm_stall_any, // stall any load/store at decode input logic exu_div_finish, // div finish this cycle input logic exu_div_stall, // div executing: stall decode input logic [31:0] exu_div_result, // div result input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state input logic dec_tlu_flush_lower_wb, // trap lower flush input logic dec_tlu_flush_pause_wb, // don't clear pause state on initial lower flush input logic dec_tlu_presync_d, // CSR read needs to be presync'd input logic dec_tlu_postsync_d, // CSR ops that need to be postsync'd input logic [31:0] exu_mul_result_e3, // multiply result input logic dec_i0_pc4_d, // inst is 4B inst else 2B input logic dec_i1_pc4_d, input logic [31:0] dec_csr_rddata_d, // csr read data at wb input logic dec_csr_legal_d, // csr indicates legal operation input logic [31:0] exu_csr_rs1_e1, // rs1 for csr instr input logic [31:0] lsu_result_dc3, // load result input logic [31:0] lsu_result_corr_dc4, // corrected load result input logic exu_i0_flush_final, // lower flush or i0 flush at e2 input logic exu_i1_flush_final, // lower flush or i1 flush at e2 input logic [31:1] exu_i0_pc_e1, // pcs at e1 input logic [31:1] exu_i1_pc_e1, input logic [31:0] dec_i0_instr_d, // inst at decode input logic [31:0] dec_i1_instr_d, input logic dec_ib0_valid_d, // inst valid at decode input logic dec_ib1_valid_d, input logic [31:0] exu_i0_result_e1, // from primary alu's input logic [31:0] exu_i1_result_e1, input logic [31:0] exu_i0_result_e4, // from secondary alu's input logic [31:0] exu_i1_result_e4, input logic clk, // for rvdffe's input logic active_clk, // clk except for halt / pause input logic free_clk, // free running clock input logic clk_override, // test stuff input logic rst_l, output logic dec_i0_rs1_en_d, // rs1 enable at decode output logic dec_i0_rs2_en_d, output logic [4:0] dec_i0_rs1_d, // rs1 logical source output logic [4:0] dec_i0_rs2_d, output logic [31:0] dec_i0_immed_d, // 32b immediate data decode output logic dec_i1_rs1_en_d, output logic dec_i1_rs2_en_d, output logic [4:0] dec_i1_rs1_d, output logic [4:0] dec_i1_rs2_d, output logic [31:0] dec_i1_immed_d, output logic [12:1] dec_i0_br_immed_d, // 12b branch immediate output logic [12:1] dec_i1_br_immed_d, output alu_pkt_t i0_ap, // alu packets output alu_pkt_t i1_ap, output logic dec_i0_decode_d, // i0 decode output logic dec_i1_decode_d, output logic dec_ib0_valid_eff_d, // effective valid taking decode into account output logic dec_ib1_valid_eff_d, output logic dec_i0_alu_decode_d, // decode to primary alu's output logic dec_i1_alu_decode_d, output logic [31:0] i0_rs1_bypass_data_d, // i0 rs1 bypass data output logic [31:0] i0_rs2_bypass_data_d, // i0 rs2 bypass data output logic [31:0] i1_rs1_bypass_data_d, output logic [31:0] i1_rs2_bypass_data_d, output logic [4:0] dec_i0_waddr_wb, // i0 logical source to write to gpr's output logic dec_i0_wen_wb, // i0 write enable output logic [31:0] dec_i0_wdata_wb, // i0 write data output logic [4:0] dec_i1_waddr_wb, output logic dec_i1_wen_wb, output logic [31:0] dec_i1_wdata_wb, output logic dec_i0_select_pc_d, // i0 select pc for rs1 - branches output logic dec_i1_select_pc_d, output logic dec_i0_rs1_bypass_en_d, // i0 rs1 bypass enable output logic dec_i0_rs2_bypass_en_d, // i0 rs2 bypass enable output logic dec_i1_rs1_bypass_en_d, output logic dec_i1_rs2_bypass_en_d, output lsu_pkt_t lsu_p, // load/store packet output mul_pkt_t mul_p, // multiply packet output div_pkt_t div_p, // divide packet output logic [11:0] dec_lsu_offset_d, output logic dec_i0_lsu_d, // chose which gpr value to use output logic dec_i1_lsu_d, output logic dec_i0_mul_d, // chose which gpr value to use output logic dec_i1_mul_d, output logic dec_i0_div_d, // chose which gpr value to use output logic dec_i1_div_d, // review output logic flush_final_e3, // flush final at e3: i0 or i1 output logic i0_flush_final_e3, // i0 flush final at e3 output logic dec_csr_ren_d, // valid csr decode output logic dec_csr_wen_unq_d, // valid csr with write - for csr legal output logic dec_csr_any_unq_d, // valid csr - for csr legal output logic dec_csr_wen_wb, // csr write enable at wb output logic [11:0] dec_csr_rdaddr_d, // read address for csr output logic [11:0] dec_csr_wraddr_wb, // write address for csr output logic [31:0] dec_csr_wrdata_wb, // csr write data at wb output logic dec_csr_stall_int_ff, // csr is mie/mstatus output dec_tlu_i0_valid_e4, // i0 valid inst at e4 output dec_tlu_i1_valid_e4, output trap_pkt_t dec_tlu_packet_e4, // trap packet output logic dec_fence_pending, // tell TLU to stall DMA output logic [31:1] dec_tlu_i0_pc_e4, // i0 trap pc output logic [31:1] dec_tlu_i1_pc_e4, output logic [31:0] dec_illegal_inst, // illegal inst output logic dec_i1_valid_e1, // i1 valid e1 output logic dec_div_decode_e4, // i0 div e4 output logic [31:1] pred_correct_npc_e2, // npc e2 if the prediction is correct output logic dec_i0_rs1_bypass_en_e3, // i0 rs1 bypass enables e3 output logic dec_i0_rs2_bypass_en_e3, // i1 rs1 bypass enables e3 output logic dec_i1_rs1_bypass_en_e3, output logic dec_i1_rs2_bypass_en_e3, output logic [31:0] i0_rs1_bypass_data_e3, // i0 rs1 bypass data e3 output logic [31:0] i0_rs2_bypass_data_e3, // i1 rs1 bypass data e3 output logic [31:0] i1_rs1_bypass_data_e3, output logic [31:0] i1_rs2_bypass_data_e3, output logic dec_i0_sec_decode_e3, // i0 secondary alu e3 output logic dec_i1_sec_decode_e3, // i1 secondary alu e3 output logic [31:1] dec_i0_pc_e3, // i0 pc e3 output logic [31:1] dec_i1_pc_e3, // i1 pc e3 output logic dec_i0_rs1_bypass_en_e2, // i0 rs1 bypass enable e2 output logic dec_i0_rs2_bypass_en_e2, // i0 rs2 bypass enable e2 output logic dec_i1_rs1_bypass_en_e2, output logic dec_i1_rs2_bypass_en_e2, output logic [31:0] i0_rs1_bypass_data_e2, // i0 rs1 bypass data e2 output logic [31:0] i0_rs2_bypass_data_e2, // i0 rs2 bypass data e2 output logic [31:0] i1_rs1_bypass_data_e2, output logic [31:0] i1_rs2_bypass_data_e2, output predict_pkt_t i0_predict_p_d, // i0 predict packet decode output predict_pkt_t i1_predict_p_d, output logic dec_i0_lsu_decode_d, // i0 lsu decode output logic [31:0] i0_result_e4_eff, // i0 e4 result taking freeze into account output logic [31:0] i1_result_e4_eff, output logic [31:0] i0_result_e2, // i0 result e2 output logic [4:2] dec_i0_data_en, // clock-gating logic output logic [4:1] dec_i0_ctl_en, output logic [4:2] dec_i1_data_en, output logic [4:1] dec_i1_ctl_en, output logic [1:0] dec_pmu_instr_decoded, // number of instructions decode this cycle encoded output logic dec_pmu_decode_stall, // decode is stalled output logic dec_pmu_presync_stall, // decode has presync stall output logic dec_pmu_postsync_stall, // decode has postsync stall output logic dec_nonblock_load_wen, // write enable for nonblock load output logic [4:0] dec_nonblock_load_waddr, // logical write addr for nonblock load output logic dec_nonblock_load_freeze_dc2, // lsu must freeze nonblock load due to younger dependency in pipe output logic dec_pause_state, // core in pause state output logic dec_pause_state_cg, // pause state for clock-gating output logic dec_i0_load_e4, // pipe down if load is i0 or not in case of lsu_freeze input logic scan_mode ); dec_pkt_t i0_dp_raw, i0_dp; dec_pkt_t i1_dp_raw, i1_dp; logic [31:0] i0, i1; logic i0_valid_d, i1_valid_d; logic [31:0] i0_result_e1, i1_result_e1; logic [31:0] i1_result_e2; logic [31:0] i0_result_e3, i1_result_e3; logic [31:0] i0_result_e4, i1_result_e4; logic [31:0] i0_result_wb, i1_result_wb; logic [31:1] i0_pc_e1, i1_pc_e1; logic [31:1] i0_pc_e2, i1_pc_e2; logic [31:1] i0_pc_e3, i1_pc_e3; logic [31:1] i0_pc_e4, i1_pc_e4; logic [9:0] i0_rs1bypass, i0_rs2bypass; logic [9:0] i1_rs1bypass, i1_rs2bypass; logic i0_jalimm20, i1_jalimm20; logic i0_uiimm20, i1_uiimm20; //logic flush_final_e3; logic lsu_decode_d; logic [31:0] i0_immed_d; logic i0_presync; logic i0_postsync; logic postsync_stall; logic ps_stall; logic prior_inflight, prior_inflight_e1e4, prior_inflight_wb; logic csr_clr_d, csr_set_d, csr_write_d; logic csr_clr_e1,csr_set_e1,csr_write_e1,csr_imm_e1; logic [31:0] csr_mask_e1; logic [31:0] write_csr_data_e1; logic [31:0] write_csr_data_in; logic [31:0] write_csr_data; logic csr_data_wen; logic [4:0] csrimm_e1; logic [31:0] csr_rddata_e1; logic flush_lower_wb; logic i1_load_block_d; logic i1_mul_block_d; logic i1_load2_block_d; logic i1_mul2_block_d; logic mul_decode_d; logic div_decode_d; logic [31:1] div_pc; logic div_stall, div_stall_ff; logic [3:0] div_trigger; logic i0_legal; logic shift_illegal; logic illegal_inst_en; logic [31:0] illegal_inst; logic illegal_lockout_in, illegal_lockout; logic i0_legal_decode_d; logic i1_flush_final_e3; logic [31:0] i0_result_e3_final, i1_result_e3_final; logic [31:0] i0_result_wb_raw, i1_result_wb_raw; logic [12:1] last_br_immed_d; logic i1_depend_i0_d; logic i0_rs1_depend_i0_e1, i0_rs1_depend_i0_e2, i0_rs1_depend_i0_e3, i0_rs1_depend_i0_e4, i0_rs1_depend_i0_wb; logic i0_rs1_depend_i1_e1, i0_rs1_depend_i1_e2, i0_rs1_depend_i1_e3, i0_rs1_depend_i1_e4, i0_rs1_depend_i1_wb; logic i0_rs2_depend_i0_e1, i0_rs2_depend_i0_e2, i0_rs2_depend_i0_e3, i0_rs2_depend_i0_e4, i0_rs2_depend_i0_wb; logic i0_rs2_depend_i1_e1, i0_rs2_depend_i1_e2, i0_rs2_depend_i1_e3, i0_rs2_depend_i1_e4, i0_rs2_depend_i1_wb; logic i1_rs1_depend_i0_e1, i1_rs1_depend_i0_e2, i1_rs1_depend_i0_e3, i1_rs1_depend_i0_e4, i1_rs1_depend_i0_wb; logic i1_rs1_depend_i1_e1, i1_rs1_depend_i1_e2, i1_rs1_depend_i1_e3, i1_rs1_depend_i1_e4, i1_rs1_depend_i1_wb; logic i1_rs2_depend_i0_e1, i1_rs2_depend_i0_e2, i1_rs2_depend_i0_e3, i1_rs2_depend_i0_e4, i1_rs2_depend_i0_wb; logic i1_rs2_depend_i1_e1, i1_rs2_depend_i1_e2, i1_rs2_depend_i1_e3, i1_rs2_depend_i1_e4, i1_rs2_depend_i1_wb; logic i1_rs1_depend_i0_d, i1_rs2_depend_i0_d; logic i0_secondary_d, i1_secondary_d; logic i0_secondary_block_d, i1_secondary_block_d; logic non_block_case_d; logic i0_div_decode_d; logic [31:0] i0_result_e4_final, i1_result_e4_final; logic i0_load_block_d; logic i0_mul_block_d; logic [3:0] i0_rs1_depth_d, i0_rs2_depth_d; logic [3:0] i1_rs1_depth_d, i1_rs2_depth_d; logic i0_rs1_match_e1_e2, i0_rs1_match_e1_e3; logic i0_rs2_match_e1_e2, i0_rs2_match_e1_e3; logic i1_rs1_match_e1_e2, i1_rs1_match_e1_e3; logic i1_rs2_match_e1_e2, i1_rs2_match_e1_e3; logic i0_load_stall_d, i1_load_stall_d; logic i0_store_stall_d, i1_store_stall_d; logic i0_predict_nt, i0_predict_t; logic i1_predict_nt, i1_predict_t; logic i0_notbr_error, i0_br_toffset_error; logic i1_notbr_error, i1_br_toffset_error; logic i0_ret_error, i1_ret_error; logic i0_br_error, i1_br_error; logic i0_br_error_all, i1_br_error_all; logic [11:0] i0_br_offset, i1_br_offset; logic freeze; logic [20:1] i0_pcall_imm, i1_pcall_imm; // predicted jal's logic i0_pcall_12b_offset, i1_pcall_12b_offset; logic i0_pcall_raw, i1_pcall_raw; logic i0_pcall_case, i1_pcall_case; logic i0_pcall, i1_pcall; logic i0_pja_raw, i1_pja_raw; logic i0_pja_case, i1_pja_case; logic i0_pja, i1_pja; logic i0_pret_case, i1_pret_case; logic i0_pret_raw, i0_pret; logic i1_pret_raw, i1_pret; logic i0_jal, i1_jal; // jal's that are not predicted logic i0_predict_br, i1_predict_br; logic freeze_prior1, freeze_prior2; logic [31:0] i0_result_e4_freeze, i1_result_e4_freeze; logic [31:0] i0_result_wb_freeze, i1_result_wb_freeze; logic [31:0] i1_result_wb_eff, i0_result_wb_eff; logic [2:0] i1rs1_intra, i1rs2_intra; logic i1_rs1_intra_bypass, i1_rs2_intra_bypass; logic store_data_bypass_c1, store_data_bypass_c2; logic [1:0] store_data_bypass_e4_c1, store_data_bypass_e4_c2, store_data_bypass_e4_c3; logic store_data_bypass_i0_e2_c2; class_pkt_t i0_rs1_class_d, i0_rs2_class_d; class_pkt_t i1_rs1_class_d, i1_rs2_class_d; class_pkt_t i0_dc, i0_e1c, i0_e2c, i0_e3c, i0_e4c, i0_wbc; class_pkt_t i1_dc, i1_e1c, i1_e2c, i1_e3c, i1_e4c, i1_wbc; logic i0_rs1_match_e1, i0_rs1_match_e2, i0_rs1_match_e3; logic i1_rs1_match_e1, i1_rs1_match_e2, i1_rs1_match_e3; logic i0_rs2_match_e1, i0_rs2_match_e2, i0_rs2_match_e3; logic i1_rs2_match_e1, i1_rs2_match_e2, i1_rs2_match_e3; logic i0_secondary_stall_d; logic i0_ap_pc2, i0_ap_pc4; logic i1_ap_pc2, i1_ap_pc4; logic div_wen_wb; logic i0_rd_en_d; logic i1_rd_en_d; logic [4:0] i1_rd_d; logic [4:0] i0_rd_d; logic load_ldst_bypass_c1; logic load_mul_rs1_bypass_e1; logic load_mul_rs2_bypass_e1; logic leak1_i0_stall_in, leak1_i0_stall; logic leak1_i1_stall_in, leak1_i1_stall; logic leak1_mode; logic i0_csr_write_only_d; logic prior_inflight_e1e3, prior_inflight_eff; logic any_csr_d; logic prior_csr_write; logic [5:0] i0_pipe_en; logic i0_e1_ctl_en, i0_e2_ctl_en, i0_e3_ctl_en, i0_e4_ctl_en, i0_wb_ctl_en; logic i0_e1_data_en, i0_e2_data_en, i0_e3_data_en, i0_e4_data_en, i0_wb_data_en, i0_wb1_data_en; logic [5:0] i1_pipe_en; logic i1_e1_ctl_en, i1_e2_ctl_en, i1_e3_ctl_en, i1_e4_ctl_en, i1_wb_ctl_en; logic i1_e1_data_en, i1_e2_data_en, i1_e3_data_en, i1_e4_data_en, i1_wb_data_en, i1_wb1_data_en; logic debug_fence_i; logic debug_fence; logic i0_csr_write; logic presync_stall; logic i0_instr_error; logic i0_icaf_d; logic i1_icaf_d; logic i0_not_alu_eff, i1_not_alu_eff; logic disable_secondary; logic clear_pause; logic pause_state_in, pause_state; logic pause_stall; logic [31:1] i1_pc_wb; logic i0_brp_valid; logic nonblock_load_cancel; logic lsu_idle; logic csr_read_e1; logic i0_block_d; logic i1_block_d; logic ps_stall_in; logic freeze_after_unfreeze1; logic freeze_after_unfreeze2; logic unfreeze_cycle1; logic unfreeze_cycle2; logic tlu_wr_pause_wb1, tlu_wr_pause_wb2; localparam NBLOAD_SIZE = `RV_LSU_NUM_NBLOAD; localparam NBLOAD_SIZE_MSB = `RV_LSU_NUM_NBLOAD-1; localparam NBLOAD_TAG_MSB = `RV_LSU_NUM_NBLOAD_WIDTH-1; // non block load cam logic logic cam_write, cam_inv_reset, cam_data_reset; logic [NBLOAD_TAG_MSB:0] cam_write_tag, cam_inv_reset_tag, cam_data_reset_tag; logic [NBLOAD_SIZE_MSB:0] cam_wen; logic [NBLOAD_TAG_MSB:0] load_data_tag; logic [NBLOAD_SIZE_MSB:0] nonblock_load_write; load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam; load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_in; logic [4:0] nonblock_load_rd; logic i1_nonblock_load_stall, i0_nonblock_load_stall; logic i1_nonblock_boundary_stall, i0_nonblock_boundary_stall; logic i0_depend_load_e1_d, i0_depend_load_e2_d; logic i1_depend_load_e1_d, i1_depend_load_e2_d; logic depend_load_e1_d, depend_load_e2_d, depend_load_same_cycle_d; logic depend_load_e2_e1, depend_load_same_cycle_e1; logic depend_load_same_cycle_e2; logic nonblock_load_valid_dc4, nonblock_load_valid_wb; logic i0_load_kill_wen, i1_load_kill_wen; logic found; logic cam_reset_same_dest_wb; logic [NBLOAD_SIZE_MSB:0] cam_inv_reset_val, cam_data_reset_val; logic i1_wen_wb, i0_wen_wb; inst_t i0_itype, i1_itype; logic csr_read, csr_write; logic i0_br_unpred, i1_br_unpred; logic debug_fence_raw; logic freeze_before; logic freeze_e3, freeze_e4; logic [3:0] e4t_i0trigger; logic [3:0] e4t_i1trigger; logic e4d_i0load; logic [4:0] div_waddr_wb; logic [12:1] last_br_immed_e1, last_br_immed_e2; logic [31:0] i0_inst_d, i1_inst_d; logic [31:0] i0_inst_e1, i1_inst_e1; logic [31:0] i0_inst_e2, i1_inst_e2; logic [31:0] i0_inst_e3, i1_inst_e3; logic [31:0] i0_inst_e4, i1_inst_e4; logic [31:0] i0_inst_wb, i1_inst_wb; logic [31:0] i0_inst_wb1,i1_inst_wb1; logic [31:0] div_inst; logic [31:1] i0_pc_wb, i0_pc_wb1; logic [31:1] i1_pc_wb1; logic [31:1] last_pc_e2; reg_pkt_t i0r, i1r; trap_pkt_t dt, e1t_in, e1t, e2t_in, e2t, e3t_in, e3t, e4t; class_pkt_t i0_e4c_in, i1_e4c_in; dest_pkt_t dd, e1d, e2d, e3d, e4d, wbd; dest_pkt_t e1d_in, e2d_in, e3d_in, e4d_in; assign freeze = lsu_freeze_dc3; `ifdef RV_NO_SECONDARY_ALU assign disable_secondary = 1; `else assign disable_secondary = dec_tlu_sec_alu_disable; `endif // branch prediction // in leak1_mode, ignore any predictions for i0, treat branch as if we haven't seen it before // in leak1 mode, also ignore branch errors for i0 assign i0_brp_valid = dec_i0_brp.valid & ~leak1_mode; assign i0_predict_p_d.misp = '0; assign i0_predict_p_d.ataken = '0; assign i0_predict_p_d.boffset = '0; assign i0_predict_p_d.pcall = i0_pcall; // dont mark as pcall if branch error assign i0_predict_p_d.pja = i0_pja; assign i0_predict_p_d.pret = i0_pret; assign i0_predict_p_d.prett[31:1] = dec_i0_brp.prett[31:1]; assign i0_predict_p_d.pc4 = dec_i0_pc4_d; assign i0_predict_p_d.hist[1:0] = dec_i0_brp.hist[1:0]; assign i0_predict_p_d.valid = i0_brp_valid & i0_legal_decode_d; assign i0_notbr_error = i0_brp_valid & ~(i0_dp_raw.condbr | i0_pcall_raw | i0_pja_raw | i0_pret_raw); // no toffset error for a pret assign i0_br_toffset_error = i0_brp_valid & dec_i0_brp.hist[1] & (dec_i0_brp.toffset[11:0] != i0_br_offset[11:0]) & !i0_pret_raw; assign i0_ret_error = i0_brp_valid & dec_i0_brp.ret & ~i0_pret_raw; assign i0_br_error = dec_i0_brp.br_error | i0_notbr_error | i0_br_toffset_error | i0_ret_error; assign i0_predict_p_d.br_error = i0_br_error & i0_legal_decode_d & ~leak1_mode; assign i0_predict_p_d.br_start_error = dec_i0_brp.br_start_error & i0_legal_decode_d & ~leak1_mode; assign i0_predict_p_d.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_i0_brp.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; assign i0_predict_p_d.bank[1:0] = dec_i0_brp.bank[1:0]; assign i0_predict_p_d.btag[`RV_BTB_BTAG_SIZE-1:0] = dec_i0_brp.btag[`RV_BTB_BTAG_SIZE-1:0]; assign i0_br_error_all = (i0_br_error | dec_i0_brp.br_start_error) & ~leak1_mode; assign i0_predict_p_d.toffset[11:0] = i0_br_offset[11:0]; assign i0_predict_p_d.fghr[`RV_BHT_GHR_RANGE] = dec_i0_brp.fghr[`RV_BHT_GHR_RANGE]; assign i0_predict_p_d.way = dec_i0_brp.way; assign i1_predict_p_d.misp = '0; assign i1_predict_p_d.ataken = '0; assign i1_predict_p_d.boffset = '0; assign i1_predict_p_d.pcall = i1_pcall; assign i1_predict_p_d.pja = i1_pja; assign i1_predict_p_d.pret = i1_pret; assign i1_predict_p_d.prett[31:1] = dec_i1_brp.prett[31:1]; assign i1_predict_p_d.pc4 = dec_i1_pc4_d; assign i1_predict_p_d.hist[1:0] = dec_i1_brp.hist[1:0]; assign i1_predict_p_d.valid = dec_i1_brp.valid & dec_i1_decode_d; assign i1_notbr_error = dec_i1_brp.valid & ~(i1_dp_raw.condbr | i1_pcall_raw | i1_pja_raw | i1_pret_raw); assign i1_br_toffset_error = dec_i1_brp.valid & dec_i1_brp.hist[1] & (dec_i1_brp.toffset[11:0] != i1_br_offset[11:0]) & !i1_pret_raw; assign i1_ret_error = dec_i1_brp.valid & dec_i1_brp.ret & ~i1_pret_raw; assign i1_br_error = dec_i1_brp.br_error | i1_notbr_error | i1_br_toffset_error | i1_ret_error; assign i1_predict_p_d.br_error = i1_br_error & dec_i1_decode_d; assign i1_predict_p_d.br_start_error = dec_i1_brp.br_start_error & dec_i1_decode_d; assign i1_predict_p_d.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_i1_brp.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; assign i1_predict_p_d.bank[1:0] = dec_i1_brp.bank[1:0]; assign i1_predict_p_d.btag[`RV_BTB_BTAG_SIZE-1:0] = dec_i1_brp.btag[`RV_BTB_BTAG_SIZE-1:0]; assign i1_br_error_all = (i1_br_error | dec_i1_brp.br_start_error); assign i1_predict_p_d.toffset[11:0] = i1_br_offset[11:0]; assign i1_predict_p_d.fghr[`RV_BHT_GHR_RANGE] = dec_i1_brp.fghr[`RV_BHT_GHR_RANGE]; assign i1_predict_p_d.way = dec_i1_brp.way; // end // on br error turn anything into a nop // on i0 instruction fetch access fault turn anything into a nop // nop => alu rs1 imm12 rd lor assign i0_icaf_d = dec_i0_icaf_d | dec_i0_dbecc_d; assign i1_icaf_d = dec_i1_icaf_d | dec_i1_dbecc_d; assign i0_instr_error = i0_icaf_d | dec_i0_perr_d | dec_i0_sbecc_d; always_comb begin i0_dp = i0_dp_raw; if (i0_br_error_all | i0_instr_error) begin i0_dp = '0; i0_dp.alu = 1'b1; i0_dp.rs1 = 1'b1; i0_dp.rs2 = 1'b1; i0_dp.lor = 1'b1; i0_dp.legal = 1'b1; i0_dp.postsync = 1'b1; end i1_dp = i1_dp_raw; if (i1_br_error_all) begin i1_dp = '0; i1_dp.alu = 1'b1; i1_dp.rs1 = 1'b1; i1_dp.rs2 = 1'b1; i1_dp.lor = 1'b1; i1_dp.legal = 1'b1; i1_dp.postsync = 1'b1; end end assign flush_lower_wb = dec_tlu_flush_lower_wb; assign i0[31:0] = dec_i0_instr_d[31:0]; assign i1[31:0] = dec_i1_instr_d[31:0]; assign dec_i0_select_pc_d = i0_dp.pc; assign dec_i1_select_pc_d = i1_dp.pc; // branches that can be predicted assign i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret; assign i1_predict_br = i1_dp.condbr | i1_pcall | i1_pja | i1_pret; assign i0_predict_nt = ~(dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; assign i0_predict_t = (dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; assign i0_ap.valid = (i0_dc.sec | i0_dc.alu | i0_dp.alu ); assign i0_ap.add = i0_dp.add; assign i0_ap.sub = i0_dp.sub; assign i0_ap.land = i0_dp.land; assign i0_ap.lor = i0_dp.lor; assign i0_ap.lxor = i0_dp.lxor; assign i0_ap.sll = i0_dp.sll; assign i0_ap.srl = i0_dp.srl; assign i0_ap.sra = i0_dp.sra; assign i0_ap.slt = i0_dp.slt; assign i0_ap.unsign = i0_dp.unsign; assign i0_ap.beq = i0_dp.beq; assign i0_ap.bne = i0_dp.bne; assign i0_ap.blt = i0_dp.blt; assign i0_ap.bge = i0_dp.bge; assign i0_ap.csr_write = i0_csr_write_only_d; assign i0_ap.csr_imm = i0_dp.csr_imm; assign i0_ap.jal = i0_jal; assign i0_ap_pc2 = ~dec_i0_pc4_d; assign i0_ap_pc4 = dec_i0_pc4_d; assign i0_ap.predict_nt = i0_predict_nt; assign i0_ap.predict_t = i0_predict_t; assign i1_predict_nt = ~(dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; assign i1_predict_t = (dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; assign i1_ap.valid = (i1_dc.sec | i1_dc.alu | i1_dp.alu); assign i1_ap.add = i1_dp.add; assign i1_ap.sub = i1_dp.sub; assign i1_ap.land = i1_dp.land; assign i1_ap.lor = i1_dp.lor; assign i1_ap.lxor = i1_dp.lxor; assign i1_ap.sll = i1_dp.sll; assign i1_ap.srl = i1_dp.srl; assign i1_ap.sra = i1_dp.sra; assign i1_ap.slt = i1_dp.slt; assign i1_ap.unsign = i1_dp.unsign; assign i1_ap.beq = i1_dp.beq; assign i1_ap.bne = i1_dp.bne; assign i1_ap.blt = i1_dp.blt; assign i1_ap.bge = i1_dp.bge; assign i1_ap.csr_write = 1'b0; assign i1_ap.csr_imm = 1'b0; assign i1_ap.jal = i1_jal; assign i1_ap_pc2 = ~dec_i1_pc4_d; assign i1_ap_pc4 = dec_i1_pc4_d; assign i1_ap.predict_nt = i1_predict_nt; assign i1_ap.predict_t = i1_predict_t; always_comb begin found = 0; cam_wen[NBLOAD_SIZE_MSB:0] = '0; for (int i=0; i used for clockgating for wb stage ctl logic rvdff #(1) divwbff (.*, .clk(active_clk), .din(exu_div_finish), .dout(div_wen_wb)); assign i0_result_e1[31:0] = exu_i0_result_e1[31:0]; assign i1_result_e1[31:0] = exu_i1_result_e1[31:0]; // pipe the results down the pipe rvdffe #(32) i0e2resultff (.*, .en(i0_e2_data_en), .din(i0_result_e1[31:0]), .dout(i0_result_e2[31:0])); rvdffe #(32) i1e2resultff (.*, .en(i1_e2_data_en), .din(i1_result_e1[31:0]), .dout(i1_result_e2[31:0])); rvdffe #(32) i0e3resultff (.*, .en(i0_e3_data_en), .din(i0_result_e2[31:0]), .dout(i0_result_e3[31:0])); rvdffe #(32) i1e3resultff (.*, .en(i1_e3_data_en), .din(i1_result_e2[31:0]), .dout(i1_result_e3[31:0])); assign i0_result_e3_final[31:0] = (e3d.i0v & e3d.i0load) ? lsu_result_dc3[31:0] : (e3d.i0v & e3d.i0mul) ? exu_mul_result_e3[31:0] : i0_result_e3[31:0]; assign i1_result_e3_final[31:0] = (e3d.i1v & e3d.i1load) ? lsu_result_dc3[31:0] : (e3d.i1v & e3d.i1mul) ? exu_mul_result_e3[31:0] : i1_result_e3[31:0]; rvdffe #(32) i0e4resultff (.*, .en(i0_e4_data_en), .din(i0_result_e3_final[31:0]), .dout(i0_result_e4[31:0])); rvdffe #(32) i1e4resultff (.*, .en(i1_e4_data_en), .din(i1_result_e3_final[31:0]), .dout(i1_result_e4[31:0])); assign i0_result_e4_final[31:0] = ( e4d.i0secondary) ? exu_i0_result_e4[31:0] : (e4d.i0v & e4d.i0load) ? lsu_result_corr_dc4[31:0] : i0_result_e4[31:0]; assign i1_result_e4_final[31:0] = (e4d.i1v & e4d.i1secondary) ? exu_i1_result_e4[31:0] : (e4d.i1v & e4d.i1load) ? lsu_result_corr_dc4[31:0] :i1_result_e4[31:0]; rvdffe #(32) i0wbresultff (.*, .en(i0_wb_data_en), .din(i0_result_e4_final[31:0]), .dout(i0_result_wb_raw[31:0])); rvdffe #(32) i1wbresultff (.*, .en(i1_wb_data_en), .din(i1_result_e4_final[31:0]), .dout(i1_result_wb_raw[31:0])); assign i0_result_wb[31:0] = (div_wen_wb) ? exu_div_result[31:0] : i0_result_wb_raw[31:0]; assign i1_result_wb[31:0] = i1_result_wb_raw[31:0]; rvdffe #(12) e1brpcff (.*, .en(i0_e1_data_en), .din(last_br_immed_d[12:1] ), .dout(last_br_immed_e1[12:1])); rvdffe #(12) e2brpcff (.*, .en(i0_e2_data_en), .din(last_br_immed_e1[12:1]), .dout(last_br_immed_e2[12:1])); // trace stuff rvdffe #(32) divinstff (.*, .en(i0_div_decode_d), .din(i0_inst_d[31:0]), .dout(div_inst[31:0])); assign i0_inst_d[31:0] = (dec_i0_pc4_d) ? i0[31:0] : {16'b0, dec_i0_cinst_d[15:0] }; rvdffe #(32) i0e1instff (.*, .en(i0_e1_data_en), .din(i0_inst_d[31:0]), .dout(i0_inst_e1[31:0])); rvdffe #(32) i0e2instff (.*, .en(i0_e2_data_en), .din(i0_inst_e1[31:0]), .dout(i0_inst_e2[31:0])); rvdffe #(32) i0e3instff (.*, .en(i0_e3_data_en), .din(i0_inst_e2[31:0]), .dout(i0_inst_e3[31:0])); rvdffe #(32) i0e4instff (.*, .en(i0_e4_data_en), .din(i0_inst_e3[31:0]), .dout(i0_inst_e4[31:0])); rvdffe #(32) i0wbinstff (.*, .en(i0_wb_data_en | exu_div_finish), .din( (exu_div_finish) ? div_inst[31:0] : i0_inst_e4[31:0]), .dout(i0_inst_wb[31:0])); rvdffe #(32) i0wb1instff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_inst_wb[31:0]), .dout(i0_inst_wb1[31:0])); assign i1_inst_d[31:0] = (dec_i1_pc4_d) ? i1[31:0] : {16'b0, dec_i1_cinst_d[15:0] }; rvdffe #(32) i1e1instff (.*, .en(i1_e1_data_en), .din(i1_inst_d[31:0]), .dout(i1_inst_e1[31:0])); rvdffe #(32) i1e2instff (.*, .en(i1_e2_data_en), .din(i1_inst_e1[31:0]), .dout(i1_inst_e2[31:0])); rvdffe #(32) i1e3instff (.*, .en(i1_e3_data_en), .din(i1_inst_e2[31:0]), .dout(i1_inst_e3[31:0])); rvdffe #(32) i1e4instff (.*, .en(i1_e4_data_en), .din(i1_inst_e3[31:0]), .dout(i1_inst_e4[31:0])); rvdffe #(32) i1wbinstff (.*, .en(i1_wb_data_en), .din(i1_inst_e4[31:0]), .dout(i1_inst_wb[31:0])); rvdffe #(32) i1wb1instff (.*, .en(i1_wb1_data_en),.din(i1_inst_wb[31:0]), .dout(i1_inst_wb1[31:0])); assign dec_i0_inst_wb1[31:0] = i0_inst_wb1[31:0]; assign dec_i1_inst_wb1[31:0] = i1_inst_wb1[31:0]; rvdffe #(31) i0wbpcff (.*, .en(i0_wb_data_en | exu_div_finish), .din(dec_tlu_i0_pc_e4[31:1]), .dout(i0_pc_wb[31:1])); rvdffe #(31) i0wb1pcff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_pc_wb[31:1]), .dout(i0_pc_wb1[31:1])); rvdffe #(31) i1wb1pcff (.*, .en(i1_wb1_data_en),.din(i1_pc_wb[31:1]), .dout(i1_pc_wb1[31:1])); assign dec_i0_pc_wb1[31:1] = i0_pc_wb1[31:1]; assign dec_i1_pc_wb1[31:1] = i1_pc_wb1[31:1]; // pipe the pc's down the pipe assign i0_pc_e1[31:1] = exu_i0_pc_e1[31:1]; assign i1_pc_e1[31:1] = exu_i1_pc_e1[31:1]; rvdffe #(31) i0e2pcff (.*, .en(i0_e2_data_en), .din(i0_pc_e1[31:1]), .dout(i0_pc_e2[31:1])); rvdffe #(31) i0e3pcff (.*, .en(i0_e3_data_en), .din(i0_pc_e2[31:1]), .dout(i0_pc_e3[31:1])); rvdffe #(31) i0e4pcff (.*, .en(i0_e4_data_en), .din(i0_pc_e3[31:1]), .dout(i0_pc_e4[31:1])); rvdffe #(31) i1e2pcff (.*, .en(i1_e2_data_en), .din(i1_pc_e1[31:1]), .dout(i1_pc_e2[31:1])); rvdffe #(31) i1e3pcff (.*, .en(i1_e3_data_en), .din(i1_pc_e2[31:1]), .dout(i1_pc_e3[31:1])); rvdffe #(31) i1e4pcff (.*, .en(i1_e4_data_en), .din(i1_pc_e3[31:1]), .dout(i1_pc_e4[31:1])); assign dec_i0_pc_e3[31:1] = i0_pc_e3[31:1]; assign dec_i1_pc_e3[31:1] = i1_pc_e3[31:1]; assign dec_tlu_i0_pc_e4[31:1] = (exu_div_finish) ? div_pc[31:1] : i0_pc_e4[31:1]; assign dec_tlu_i1_pc_e4[31:1] = i1_pc_e4[31:1]; // generate the correct npc for correct br predictions assign last_pc_e2[31:1] = (e2d.i1valid) ? i1_pc_e2[31:1] : i0_pc_e2[31:1]; rvbradder ibradder_correct ( .pc(last_pc_e2[31:1]), .offset(last_br_immed_e2[12:1]), .dout(pred_correct_npc_e2[31:1]) ); // needed for debug triggers rvdffe #(31) i1wbpcff (.*, .en(i1_wb_data_en), .din(dec_tlu_i1_pc_e4[31:1]), .dout(i1_pc_wb[31:1])); // bit 9 is priority match, bit 0 lowest priority, i1_e1, i0_e1, i1_e2, ... i1_wb, i0_wb assign i0_rs1bypass[9:0] = { i0_rs1_depth_d[3:0] == 4'd1 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd2 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd3 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd4 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd5 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul), i0_rs1_depth_d[3:0] == 4'd6 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul), i0_rs1_depth_d[3:0] == 4'd7 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd8 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd9 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd10 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec) }; assign i0_rs2bypass[9:0] = { i0_rs2_depth_d[3:0] == 4'd1 & i0_rs2_class_d.alu, i0_rs2_depth_d[3:0] == 4'd2 & i0_rs2_class_d.alu, i0_rs2_depth_d[3:0] == 4'd3 & i0_rs2_class_d.alu, i0_rs2_depth_d[3:0] == 4'd4 & i0_rs2_class_d.alu, i0_rs2_depth_d[3:0] == 4'd5 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul), i0_rs2_depth_d[3:0] == 4'd6 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul), i0_rs2_depth_d[3:0] == 4'd7 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd8 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd9 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd10 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec) }; assign i1_rs1bypass[9:0] = { i1_rs1_depth_d[3:0] == 4'd1 & i1_rs1_class_d.alu, i1_rs1_depth_d[3:0] == 4'd2 & i1_rs1_class_d.alu, i1_rs1_depth_d[3:0] == 4'd3 & i1_rs1_class_d.alu, i1_rs1_depth_d[3:0] == 4'd4 & i1_rs1_class_d.alu, i1_rs1_depth_d[3:0] == 4'd5 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul), i1_rs1_depth_d[3:0] == 4'd6 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul), i1_rs1_depth_d[3:0] == 4'd7 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd8 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd9 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd10 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec) }; assign i1_rs2bypass[9:0] = { i1_rs2_depth_d[3:0] == 4'd1 & i1_rs2_class_d.alu, i1_rs2_depth_d[3:0] == 4'd2 & i1_rs2_class_d.alu, i1_rs2_depth_d[3:0] == 4'd3 & i1_rs2_class_d.alu, i1_rs2_depth_d[3:0] == 4'd4 & i1_rs2_class_d.alu, i1_rs2_depth_d[3:0] == 4'd5 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul), i1_rs2_depth_d[3:0] == 4'd6 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul), i1_rs2_depth_d[3:0] == 4'd7 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd8 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd9 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd10 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec) }; assign dec_i0_rs1_bypass_en_d = |i0_rs1bypass[9:0]; assign dec_i0_rs2_bypass_en_d = |i0_rs2bypass[9:0]; assign dec_i1_rs1_bypass_en_d = |i1_rs1bypass[9:0]; assign dec_i1_rs2_bypass_en_d = |i1_rs2bypass[9:0]; assign i0_rs1_bypass_data_d[31:0] = ({32{i0_rs1bypass[9]}} & i1_result_e1[31:0]) | ({32{i0_rs1bypass[8]}} & i0_result_e1[31:0]) | ({32{i0_rs1bypass[7]}} & i1_result_e2[31:0]) | ({32{i0_rs1bypass[6]}} & i0_result_e2[31:0]) | ({32{i0_rs1bypass[5]}} & i1_result_e3_final[31:0]) | ({32{i0_rs1bypass[4]}} & i0_result_e3_final[31:0]) | ({32{i0_rs1bypass[3]}} & i1_result_e4_final[31:0]) | ({32{i0_rs1bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i0_rs1bypass[1]}} & i1_result_wb[31:0]) | ({32{i0_rs1bypass[0]}} & i0_result_wb[31:0]); assign i0_rs2_bypass_data_d[31:0] = ({32{i0_rs2bypass[9]}} & i1_result_e1[31:0]) | ({32{i0_rs2bypass[8]}} & i0_result_e1[31:0]) | ({32{i0_rs2bypass[7]}} & i1_result_e2[31:0]) | ({32{i0_rs2bypass[6]}} & i0_result_e2[31:0]) | ({32{i0_rs2bypass[5]}} & i1_result_e3_final[31:0]) | ({32{i0_rs2bypass[4]}} & i0_result_e3_final[31:0]) | ({32{i0_rs2bypass[3]}} & i1_result_e4_final[31:0]) | ({32{i0_rs2bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i0_rs2bypass[1]}} & i1_result_wb[31:0]) | ({32{i0_rs2bypass[0]}} & i0_result_wb[31:0]); assign i1_rs1_bypass_data_d[31:0] = ({32{i1_rs1bypass[9]}} & i1_result_e1[31:0]) | ({32{i1_rs1bypass[8]}} & i0_result_e1[31:0]) | ({32{i1_rs1bypass[7]}} & i1_result_e2[31:0]) | ({32{i1_rs1bypass[6]}} & i0_result_e2[31:0]) | ({32{i1_rs1bypass[5]}} & i1_result_e3_final[31:0]) | ({32{i1_rs1bypass[4]}} & i0_result_e3_final[31:0]) | ({32{i1_rs1bypass[3]}} & i1_result_e4_final[31:0]) | ({32{i1_rs1bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i1_rs1bypass[1]}} & i1_result_wb[31:0]) | ({32{i1_rs1bypass[0]}} & i0_result_wb[31:0]); assign i1_rs2_bypass_data_d[31:0] = ({32{i1_rs2bypass[9]}} & i1_result_e1[31:0]) | ({32{i1_rs2bypass[8]}} & i0_result_e1[31:0]) | ({32{i1_rs2bypass[7]}} & i1_result_e2[31:0]) | ({32{i1_rs2bypass[6]}} & i0_result_e2[31:0]) | ({32{i1_rs2bypass[5]}} & i1_result_e3_final[31:0]) | ({32{i1_rs2bypass[4]}} & i0_result_e3_final[31:0]) | ({32{i1_rs2bypass[3]}} & i1_result_e4_final[31:0]) | ({32{i1_rs2bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i1_rs2bypass[1]}} & i1_result_wb[31:0]) | ({32{i1_rs2bypass[0]}} & i0_result_wb[31:0]); endmodule // file "decode" is human readable file that has all of the instruction decodes defined and is part of git repo // modify this file as needed // to generate all the equations below from "decode" except legal equation: // 1) coredecode -in decode > coredecode.e // 2) espresso -Dso -oeqntott coredecode.e | addassign -pre out. > equations // to generate the legal (32b instruction is legal) equation below: // 1) coredecode -in decode -legal > legal.e // 2) espresso -Dso -oeqntott legal.e | addassign -pre out. > legal_equation module dec_dec_ctl import swerv_types::*; ( input logic [31:0] inst, output dec_pkt_t out ); logic [31:0] i; assign i[31:0] = inst[31:0]; assign out.alu = (i[2]) | (i[6]) | (!i[25]&i[4]) | (!i[5]&i[4]); assign out.rs1 = (!i[14]&!i[13]&!i[2]) | (!i[13]&i[11]&!i[2]) | (i[19]&i[13]&!i[2]) | ( !i[13]&i[10]&!i[2]) | (i[18]&i[13]&!i[2]) | (!i[13]&i[9]&!i[2]) | ( i[17]&i[13]&!i[2]) | (!i[13]&i[8]&!i[2]) | (i[16]&i[13]&!i[2]) | ( !i[13]&i[7]&!i[2]) | (i[15]&i[13]&!i[2]) | (!i[4]&!i[3]) | (!i[6] &!i[2]); assign out.rs2 = (i[5]&!i[4]&!i[2]) | (!i[6]&i[5]&!i[2]); assign out.imm12 = (!i[4]&!i[3]&i[2]) | (i[13]&!i[5]&i[4]&!i[2]) | (!i[13]&!i[12] &i[6]&i[4]) | (!i[12]&!i[5]&i[4]&!i[2]); assign out.rd = (!i[5]&!i[2]) | (i[5]&i[2]) | (i[4]); assign out.shimm5 = (!i[13]&i[12]&!i[5]&i[4]&!i[2]); assign out.imm20 = (i[5]&i[3]) | (i[4]&i[2]); assign out.pc = (!i[5]&!i[3]&i[2]) | (i[5]&i[3]); assign out.load = (!i[5]&!i[4]&!i[2]); assign out.store = (!i[6]&i[5]&!i[4]); assign out.lsu = (!i[6]&!i[4]&!i[2]); assign out.add = (!i[14]&!i[13]&!i[12]&!i[5]&i[4]) | (!i[5]&!i[3]&i[2]) | (!i[30] &!i[25]&!i[14]&!i[13]&!i[12]&!i[6]&i[4]&!i[2]); assign out.sub = (i[30]&!i[12]&!i[6]&i[5]&i[4]&!i[2]) | (!i[25]&!i[14]&i[13]&!i[6] &i[4]&!i[2]) | (!i[14]&i[13]&!i[5]&i[4]&!i[2]) | (i[6]&!i[4]&!i[2]); assign out.land = (i[14]&i[13]&i[12]&!i[5]&!i[2]) | (!i[25]&i[14]&i[13]&i[12]&!i[6] &!i[2]); assign out.lor = (!i[6]&i[3]) | (!i[25]&i[14]&i[13]&!i[12]&i[4]&!i[2]) | (i[5]&i[4] &i[2]) | (!i[12]&i[6]&i[4]) | (i[13]&i[6]&i[4]) | (i[14]&i[13]&!i[12] &!i[5]&!i[2]) | (i[7]&i[6]&i[4]) | (i[8]&i[6]&i[4]) | (i[9]&i[6]&i[4]) | ( i[10]&i[6]&i[4]) | (i[11]&i[6]&i[4]); assign out.lxor = (!i[25]&i[14]&!i[13]&!i[12]&i[4]&!i[2]) | (i[14]&!i[13]&!i[12] &!i[5]&i[4]&!i[2]); assign out.sll = (!i[25]&!i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); assign out.sra = (i[30]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); assign out.srl = (!i[30]&!i[25]&i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); assign out.slt = (!i[25]&!i[14]&i[13]&!i[6]&i[4]&!i[2]) | (!i[14]&i[13]&!i[5]&i[4] &!i[2]); assign out.unsign = (!i[14]&i[13]&i[12]&!i[5]&!i[2]) | (i[13]&i[6]&!i[4]&!i[2]) | ( i[14]&!i[5]&!i[4]) | (!i[25]&!i[14]&i[13]&i[12]&!i[6]&!i[2]) | ( i[25]&i[14]&i[12]&!i[6]&i[5]&!i[2]); assign out.condbr = (i[6]&!i[4]&!i[2]); assign out.beq = (!i[14]&!i[12]&i[6]&!i[4]&!i[2]); assign out.bne = (!i[14]&i[12]&i[6]&!i[4]&!i[2]); assign out.bge = (i[14]&i[12]&i[5]&!i[4]&!i[2]); assign out.blt = (i[14]&!i[12]&i[5]&!i[4]&!i[2]); assign out.jal = (i[6]&i[2]); assign out.by = (!i[13]&!i[12]&!i[6]&!i[4]&!i[2]); assign out.half = (i[12]&!i[6]&!i[4]&!i[2]); assign out.word = (i[13]&!i[6]&!i[4]); assign out.csr_read = (i[13]&i[6]&i[4]) | (i[7]&i[6]&i[4]) | (i[8]&i[6]&i[4]) | ( i[9]&i[6]&i[4]) | (i[10]&i[6]&i[4]) | (i[11]&i[6]&i[4]); assign out.csr_clr = (i[15]&i[13]&i[12]&i[6]&i[4]) | (i[16]&i[13]&i[12]&i[6]&i[4]) | ( i[17]&i[13]&i[12]&i[6]&i[4]) | (i[18]&i[13]&i[12]&i[6]&i[4]) | ( i[19]&i[13]&i[12]&i[6]&i[4]); assign out.csr_set = (i[15]&!i[12]&i[6]&i[4]) | (i[16]&!i[12]&i[6]&i[4]) | (i[17] &!i[12]&i[6]&i[4]) | (i[18]&!i[12]&i[6]&i[4]) | (i[19]&!i[12]&i[6] &i[4]); assign out.csr_write = (!i[13]&i[12]&i[6]&i[4]); assign out.csr_imm = (i[14]&!i[13]&i[6]&i[4]) | (i[15]&i[14]&i[6]&i[4]) | (i[16] &i[14]&i[6]&i[4]) | (i[17]&i[14]&i[6]&i[4]) | (i[18]&i[14]&i[6]&i[4]) | ( i[19]&i[14]&i[6]&i[4]); assign out.presync = (!i[5]&i[3]) | (i[25]&i[14]&!i[6]&i[5]&!i[2]) | (!i[13]&i[7] &i[6]&i[4]) | (!i[13]&i[8]&i[6]&i[4]) | (!i[13]&i[9]&i[6]&i[4]) | ( !i[13]&i[10]&i[6]&i[4]) | (!i[13]&i[11]&i[6]&i[4]) | (i[15]&i[13] &i[6]&i[4]) | (i[16]&i[13]&i[6]&i[4]) | (i[17]&i[13]&i[6]&i[4]) | ( i[18]&i[13]&i[6]&i[4]) | (i[19]&i[13]&i[6]&i[4]); assign out.postsync = (i[12]&!i[5]&i[3]) | (!i[22]&!i[13]&!i[12]&i[6]&i[4]) | ( i[25]&i[14]&!i[6]&i[5]&!i[2]) | (!i[13]&i[7]&i[6]&i[4]) | (!i[13] &i[8]&i[6]&i[4]) | (!i[13]&i[9]&i[6]&i[4]) | (!i[13]&i[10]&i[6]&i[4]) | ( !i[13]&i[11]&i[6]&i[4]) | (i[15]&i[13]&i[6]&i[4]) | (i[16]&i[13]&i[6] &i[4]) | (i[17]&i[13]&i[6]&i[4]) | (i[18]&i[13]&i[6]&i[4]) | (i[19] &i[13]&i[6]&i[4]); assign out.ebreak = (!i[22]&i[20]&!i[13]&!i[12]&i[6]&i[4]); assign out.ecall = (!i[21]&!i[20]&!i[13]&!i[12]&i[6]&i[4]); assign out.mret = (i[29]&!i[13]&!i[12]&i[6]&i[4]); assign out.mul = (i[25]&!i[14]&!i[6]&i[5]&i[4]&!i[2]); assign out.rs1_sign = (i[25]&!i[14]&i[13]&!i[12]&!i[6]&i[5]&i[4]&!i[2]) | (i[25] &!i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); assign out.rs2_sign = (i[25]&!i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); assign out.low = (i[25]&!i[14]&!i[13]&!i[12]&i[5]&i[4]&!i[2]); assign out.div = (i[25]&i[14]&!i[6]&i[5]&!i[2]); assign out.rem = (i[25]&i[14]&i[13]&!i[6]&i[5]&!i[2]); assign out.fence = (!i[5]&i[3]); assign out.fence_i = (i[12]&!i[5]&i[3]); assign out.pm_alu = (i[28]&i[22]&!i[13]&!i[12]&i[4]) | (i[4]&i[2]) | (!i[25]&!i[6] &i[4]) | (!i[5]&i[4]); assign out.legal = (!i[31]&!i[30]&i[29]&i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23] &!i[22]&i[21]&!i[20]&!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[11] &!i[10]&!i[9]&!i[8]&!i[7]&i[6]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | ( !i[31]&!i[30]&!i[29]&i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23]&i[22] &!i[21]&i[20]&!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[11]&!i[10] &!i[9]&!i[8]&!i[7]&i[6]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[31] &!i[30]&!i[29]&!i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23]&!i[22]&!i[21] &!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[11]&!i[10]&!i[9]&!i[8] &!i[7]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29]&!i[28] &!i[27]&!i[26]&!i[25]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[29] &!i[28]&!i[27]&!i[26]&!i[25]&!i[14]&!i[13]&!i[12]&!i[6]&!i[3]&!i[2] &i[1]&i[0]) | (!i[31]&!i[29]&!i[28]&!i[27]&!i[26]&!i[25]&i[14]&!i[13] &i[12]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29]&!i[28] &!i[27]&!i[26]&!i[6]&i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[14]&!i[13] &!i[12]&i[6]&i[5]&!i[4]&!i[3]&i[1]&i[0]) | (i[14]&i[6]&i[5]&!i[4] &!i[3]&!i[2]&i[1]&i[0]) | (!i[12]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | ( !i[14]&!i[13]&i[5]&!i[4]&!i[3]&!i[2]&i[1]&i[0]) | (i[12]&i[6]&i[5] &i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29]&!i[28]&!i[27] &!i[26]&!i[25]&!i[24]&!i[23]&!i[22]&!i[21]&!i[20]&!i[19]&!i[18]&!i[17] &!i[16]&!i[15]&!i[14]&!i[13]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[6] &!i[5]&!i[4]&i[3]&i[2]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29]&!i[28] &!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[13]&!i[12]&!i[11]&!i[10] &!i[9]&!i[8]&!i[7]&!i[6]&!i[5]&!i[4]&i[3]&i[2]&i[1]&i[0]) | (i[13] &i[6]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[13]&!i[6]&!i[5]&!i[4] &!i[3]&!i[2]&i[1]&i[0]) | (i[6]&i[5]&!i[4]&i[3]&i[2]&i[1]&i[0]) | ( i[13]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[14]&!i[12]&!i[6]&!i[4] &!i[3]&!i[2]&i[1]&i[0]) | (!i[6]&i[4]&!i[3]&i[2]&i[1]&i[0]); endmodule