package ifu import chisel3._ import chisel3.internal.naming.chiselName import chisel3.util._ import lib._ import include._ import scala.math.pow @chiselName class mem_ctl_bundle extends Bundle with el2_lib{ val free_clk = Input(Clock()) val active_clk = Input(Clock()) val exu_flush_final = Input(Bool()) val dec_tlu_flush_lower_wb = Input(Bool()) val dec_tlu_flush_err_wb = Input(Bool()) val dec_tlu_i0_commit_cmt = Input(Bool()) val dec_tlu_force_halt = Input(Bool()) val ifc_fetch_addr_bf = Input(UInt(31.W)) val ifc_fetch_uncacheable_bf = Input(Bool()) val ifc_fetch_req_bf = Input(Bool()) val ifc_fetch_req_bf_raw = Input(Bool()) val ifc_iccm_access_bf = Input(Bool()) val ifc_region_acc_fault_bf = Input(Bool()) val ifc_dma_access_ok = Input(Bool()) val dec_tlu_fence_i_wb = Input(Bool()) val ifu_bp_hit_taken_f = Input(Bool()) val ifu_bp_inst_mask_f = Input(Bool()) val ifu_axi_arready = Input(Bool()) val ifu_axi_rvalid = Input(Bool()) val ifu_axi_rid = Input(UInt(IFU_BUS_TAG.W)) val ifu_axi_rdata = Input(UInt(64.W)) val ifu_axi_rresp = Input(UInt(2.W)) val ifu_bus_clk_en = Input(Bool()) val dma_iccm_req = Input(Bool()) val dma_mem_addr = Input(UInt(32.W)) val dma_mem_sz = Input(UInt(3.W)) val dma_mem_write = Input(Bool()) val dma_mem_wdata = Input(UInt(64.W)) val dma_mem_tag = Input(UInt(3.W)) val ic_rd_data = Input(UInt(64.W)) val ic_debug_rd_data = Input(UInt(71.W)) val ictag_debug_rd_data = Input(UInt(26.W)) val ic_eccerr = Input(UInt(ICACHE_BANKS_WAY.W)) val ic_parerr = Input(UInt(ICACHE_BANKS_WAY.W)) val ic_rd_hit = Input(UInt(ICACHE_NUM_WAYS.W)) val ic_tag_perr = Input(Bool()) val iccm_rd_data = Input(UInt(64.W)) val iccm_rd_data_ecc = Input(UInt(78.W)) val ifu_fetch_val = Input(UInt(2.W)) val dec_tlu_ic_diag_pkt = Input(new el2_cache_debug_pkt_t) val ifu_miss_state_idle = Output(Bool()) val ifu_ic_mb_empty = Output(Bool()) val ic_dma_active = Output(Bool()) val ic_write_stall = Output(Bool()) val ifu_pmu_ic_miss = Output(Bool()) val ifu_pmu_ic_hit = Output(Bool()) val ifu_pmu_bus_error = Output(Bool()) val ifu_pmu_bus_busy = Output(Bool()) val ifu_pmu_bus_trxn = Output(Bool()) val ifu_axi_awvalid = Output(Bool()) val ifu_axi_awid = Output(UInt(IFU_BUS_TAG.W)) val ifu_axi_awaddr = Output(UInt(32.W)) val ifu_axi_awregion = Output(UInt(4.W)) val ifu_axi_awlen = Output(UInt(8.W)) val ifu_axi_awsize = Output(UInt(3.W)) val ifu_axi_awburst = Output(UInt(2.W)) val ifu_axi_awlock = Output(Bool()) val ifu_axi_awcache = Output(UInt(4.W)) val ifu_axi_awprot = Output(UInt(3.W)) val ifu_axi_awqos = Output(UInt(4.W)) val ifu_axi_wvalid = Output(Bool()) val ifu_axi_wdata = Output(UInt(64.W)) val ifu_axi_wstrb = Output(UInt(8.W)) val ifu_axi_wlast = Output(Bool()) val ifu_axi_bready = Output(Bool()) val ifu_axi_arvalid = Output(Bool()) val ifu_axi_arid = Output(UInt(IFU_BUS_TAG.W)) val ifu_axi_araddr = Output(UInt(32.W)) val ifu_axi_arregion = Output(UInt(4.W)) val ifu_axi_arlen = Output(UInt(8.W)) val ifu_axi_arsize = Output(UInt(3.W)) val ifu_axi_arburst = Output(UInt(2.W)) val ifu_axi_arlock = Output(Bool()) val ifu_axi_arcache = Output(UInt(4.W)) val ifu_axi_arprot = Output(UInt(3.W)) val ifu_axi_arqos = Output(UInt(4.W)) val ifu_axi_rready = Output(Bool()) val iccm_dma_ecc_error = Output(Bool()) val iccm_dma_rvalid = Output(Bool()) val iccm_dma_rdata = Output(UInt(64.W)) val iccm_dma_rtag = Output(UInt(3.W)) val iccm_ready = Output(Bool()) val ic_rw_addr = Output(UInt(31.W)) val ic_wr_en = Output(UInt(ICACHE_NUM_WAYS.W)) val ic_rd_en = Output(Bool()) val ic_wr_data = Output(Vec(ICACHE_BANKS_WAY, UInt(71.W))) val ic_debug_wr_data = Output(UInt(71.W)) val ifu_ic_debug_rd_data = Output(UInt(71.W)) val ic_debug_addr = Output(UInt((ICACHE_INDEX_HI-2).W)) val ic_debug_rd_en = Output(Bool()) val ic_debug_wr_en = Output(Bool()) val ic_debug_tag_array = Output(Bool()) val ic_debug_way = Output(UInt(ICACHE_NUM_WAYS.W)) val ic_tag_valid = Output(UInt(ICACHE_NUM_WAYS.W)) val iccm_rw_addr = Output(UInt((ICCM_BITS-1).W)) val iccm_wren = Output(Bool()) val iccm_rden = Output(Bool()) val iccm_wr_data = Output(UInt(78.W)) val iccm_wr_size = Output(UInt(3.W)) val ic_hit_f = Output(Bool()) val ic_access_fault_f = Output(Bool()) val ic_access_fault_type_f = Output(UInt(2.W)) val iccm_rd_ecc_single_err = Output(Bool()) val iccm_rd_ecc_double_err = Output(Bool()) val ic_error_start = Output(Bool()) val ifu_async_error_start = Output(Bool()) val iccm_dma_sb_error = Output(Bool()) val ic_fetch_val_f = Output(UInt(2.W)) val ic_data_f = Output(UInt(32.W)) val ic_premux_data = Output(UInt(64.W)) val ic_sel_premux_data = Output(Bool()) val dec_tlu_core_ecc_disable = Input(Bool()) val ifu_ic_debug_rd_data_valid = Output(Bool()) val iccm_buf_correct_ecc = Output(Bool()) val iccm_correction_state = Output(Bool()) val scan_mode = Input(Bool()) } class el2_ifu_mem_ctl extends Module with el2_lib { val io = IO(new mem_ctl_bundle) io.ifu_axi_wvalid := 0.U io.ifu_axi_wdata := 0.U io.ifu_axi_awqos := 0.U io.ifu_axi_awaddr := 0.U io.ifu_axi_awprot := 0.U io.ifu_axi_awlen := 0.U io.ifu_axi_arlock := 0.U io.ifu_axi_awregion := 0.U io.ifu_axi_awid := 0.U io.ifu_axi_awvalid := 0.U io.ifu_axi_wstrb := 0.U io.ifu_axi_awcache := 0.U io.ifu_axi_arqos := 0.U io.ifu_axi_awlock := 0.U io.ifu_axi_bready := 0.U io.ifu_axi_arlen := 0.U io.ifu_axi_awsize := 0.U io.ifu_axi_arprot := 0.U io.ifu_axi_awburst := 0.U io.ifu_axi_wlast := 0.U val idle_C :: crit_byp_ok_C :: hit_u_miss_C :: miss_wait_C :: crit_wrd_rdy_C :: scnd_miss_C :: stream_C :: stall_scnd_miss_C :: Nil = Enum(8) val err_stop_idle_C :: err_fetch1_C :: err_fetch2_C :: err_stop_fetch_C :: Nil = Enum(4) val err_idle_C :: ic_wff_C :: ecc_wff_C :: ecc_cor_C :: dma_sb_err_C :: Nil = Enum(5) val iccm_single_ecc_error = WireInit(UInt(2.W), 0.U) val ifc_fetch_req_f = WireInit(Bool(), false.B) val miss_pending = WireInit(Bool(), false.B) val scnd_miss_req = WireInit(Bool(), false.B) val dma_iccm_req_f = WireInit(Bool(), false.B) val iccm_correct_ecc = WireInit(Bool(), false.B) val perr_state = WireInit(UInt(3.W), 0.U) val err_stop_state = WireInit(UInt(2.W), 0.U) val err_stop_fetch = WireInit(Bool(), false.B) val miss_state = WireInit(UInt(3.W), 0.U) val miss_nxtstate = WireInit(UInt(3.W), 0.U) val miss_state_en = WireInit(Bool(), false.B) val ifu_bus_rsp_valid = WireInit(Bool(), false.B) val bus_ifu_bus_clk_en = WireInit(Bool(), false.B) val ifu_bus_rsp_ready = WireInit(Bool(), false.B) val uncacheable_miss_ff = WireInit(Bool(), false.B) val ic_act_miss_f = WireInit(Bool(), false.B) val ic_byp_hit_f = WireInit(Bool(), false.B) val bus_new_data_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) val bus_ifu_wr_en_ff = WireInit(Bool(), false.B) val last_beat = WireInit(Bool(), false.B) val last_data_recieved_ff = WireInit(Bool(), false.B) //val flush_final_f = WireInit(Bool(), 0.U) val stream_eol_f = WireInit(Bool(), false.B) val ic_miss_under_miss_f = WireInit(Bool(), false.B) val ic_ignore_2nd_miss_f = WireInit(Bool(), false.B) val ic_debug_rd_en_ff = WireInit(Bool(), false.B) val debug_data_clk = rvclkhdr(clock, ic_debug_rd_en_ff, io.scan_mode) val flush_final_f = RegNext(io.exu_flush_final, 0.U) val fetch_bf_f_c1_clken = io.ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | io.exu_flush_final | scnd_miss_req val debug_c1_clken = io.ic_debug_rd_en | io.ic_debug_wr_en val debug_c1_clk = rvclkhdr(clock, debug_c1_clken, io.scan_mode) val fetch_bf_f_c1_clk = rvclkhdr(clock, fetch_bf_f_c1_clken, io.scan_mode) io.iccm_dma_sb_error := iccm_single_ecc_error.orR() & dma_iccm_req_f.asBool() io.ifu_async_error_start := io.iccm_rd_ecc_single_err | io.ic_error_start io.ic_dma_active := iccm_correct_ecc | (perr_state === dma_sb_err_C) | (err_stop_state === err_stop_fetch_C) | err_stop_fetch | io.dec_tlu_flush_err_wb val scnd_miss_req_in = ifu_bus_rsp_valid & bus_ifu_bus_clk_en & ifu_bus_rsp_ready & (bus_new_data_beat_count.andR) & !uncacheable_miss_ff & ((miss_state === scnd_miss_C)|(miss_nxtstate === scnd_miss_C)) & !io.exu_flush_final val ifu_bp_hit_taken_q_f = io.ifu_bp_hit_taken_f & io.ic_hit_f ///////////////////////////////// MISS FSM ///////////////////////////////// switch(miss_state){ is (idle_C){ miss_nxtstate := Mux((ic_act_miss_f & !io.exu_flush_final).asBool, crit_byp_ok_C, hit_u_miss_C) miss_state_en := ic_act_miss_f & !io.dec_tlu_force_halt} is (crit_byp_ok_C){ miss_nxtstate := Mux((io.dec_tlu_force_halt | (ic_byp_hit_f & (last_data_recieved_ff | (bus_ifu_wr_en_ff & last_beat)) & uncacheable_miss_ff)).asBool, idle_C, Mux((ic_byp_hit_f & !last_data_recieved_ff & uncacheable_miss_ff).asBool, miss_wait_C, Mux((!ic_byp_hit_f & !io.exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & uncacheable_miss_ff).asBool, crit_wrd_rdy_C, Mux(((bus_ifu_wr_en_ff & last_beat) & !uncacheable_miss_ff).asBool, idle_C, Mux((ic_byp_hit_f & !io.exu_flush_final & !(bus_ifu_wr_en_ff & last_beat) & !ifu_bp_hit_taken_q_f & !uncacheable_miss_ff).asBool, stream_C, Mux((bus_ifu_wr_en_ff & !io.exu_flush_final & !(bus_ifu_wr_en_ff & last_beat) & !ifu_bp_hit_taken_q_f & !uncacheable_miss_ff).asBool, stream_C, Mux((!ic_byp_hit_f & !io.exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & !uncacheable_miss_ff).asBool, idle_C, Mux(((io.exu_flush_final | ifu_bp_hit_taken_q_f) & !(bus_ifu_wr_en_ff & last_beat)).asBool, hit_u_miss_C, idle_C)))))))) miss_state_en := io.dec_tlu_force_halt | io.exu_flush_final | ic_byp_hit_f | ifu_bp_hit_taken_q_f | (bus_ifu_wr_en_ff & last_beat) | (bus_ifu_wr_en_ff & !uncacheable_miss_ff) } is (crit_wrd_rdy_C){ miss_nxtstate := idle_C miss_state_en := io.exu_flush_final | flush_final_f | ic_byp_hit_f | io.dec_tlu_force_halt } is (stream_C){ miss_nxtstate := Mux(((io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f)&(!(bus_ifu_wr_en_ff & last_beat)) & !io.dec_tlu_force_halt).asBool, hit_u_miss_C, idle_C) miss_state_en := io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f | (bus_ifu_wr_en_ff & last_beat) | io.dec_tlu_force_halt } is (miss_wait_C){ miss_nxtstate := Mux((io.exu_flush_final & !(bus_ifu_wr_en_ff & last_beat) & !io.dec_tlu_force_halt).asBool, hit_u_miss_C, idle_C) miss_state_en := io.exu_flush_final | (bus_ifu_wr_en_ff & last_beat) | io.dec_tlu_force_halt } is (hit_u_miss_C){ miss_nxtstate := Mux((ic_miss_under_miss_f & !(bus_ifu_wr_en_ff & last_beat) & !io.dec_tlu_force_halt).asBool, scnd_miss_C, Mux((ic_ignore_2nd_miss_f & !(bus_ifu_wr_en_ff & last_beat) & !io.dec_tlu_force_halt).asBool, stall_scnd_miss_C, idle_C)) miss_state_en := (bus_ifu_wr_en_ff & last_beat) | ic_miss_under_miss_f | ic_ignore_2nd_miss_f | io.dec_tlu_force_halt } is (scnd_miss_C){ miss_nxtstate := Mux(io.dec_tlu_force_halt, idle_C, Mux(io.exu_flush_final, Mux((bus_ifu_wr_en_ff & last_beat).asBool, idle_C, hit_u_miss_C), crit_byp_ok_C)) miss_state_en := (bus_ifu_wr_en_ff & last_beat) | io.exu_flush_final | io.dec_tlu_force_halt } is (stall_scnd_miss_C){ miss_nxtstate := Mux(io.dec_tlu_force_halt, idle_C, Mux(io.exu_flush_final, Mux((bus_ifu_wr_en_ff & last_beat).asBool, idle_C, hit_u_miss_C), idle_C)) miss_state_en := (bus_ifu_wr_en_ff & last_beat) | io.exu_flush_final | io.dec_tlu_force_halt } } miss_state := RegEnable(miss_nxtstate, 0.U, miss_state_en.asBool) val crit_byp_hit_f = WireInit(Bool(), 0.U) val way_status_mb_scnd_ff = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val tagv_mb_scnd_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val uncacheable_miss_scnd_ff = WireInit(Bool(), 0.U) val imb_scnd_ff = WireInit(UInt(31.W), 0.U) val reset_all_tags = WireInit(Bool(), 0.U) val bus_rd_addr_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) val ifu_bus_rid_ff = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) miss_pending := miss_state =/= idle_C val crit_wd_byp_ok_ff = (miss_state === crit_byp_ok_C) | ((miss_state === crit_wrd_rdy_C) & !flush_final_f) val sel_hold_imb = (miss_pending & !(bus_ifu_wr_en_ff & last_beat) & !((miss_state === crit_wrd_rdy_C) & io.exu_flush_final) & !((miss_state === crit_wrd_rdy_C) & crit_byp_hit_f) ) | ic_act_miss_f | (miss_pending & (miss_nxtstate === crit_wrd_rdy_C)) val sel_hold_imb_scnd = ((miss_state === scnd_miss_C) | ic_miss_under_miss_f) & !flush_final_f val way_status_mb_scnd_in = Mux(miss_state === scnd_miss_C, way_status_mb_scnd_ff, way_status) val tagv_mb_scnd_in = Mux(miss_state === scnd_miss_C, tagv_mb_scnd_ff, Fill(ICACHE_NUM_WAYS, !reset_all_tags) & io.ic_tag_valid) val uncacheable_miss_scnd_in = Mux(sel_hold_imb_scnd.asBool, uncacheable_miss_scnd_ff, io.ifc_fetch_uncacheable_bf) uncacheable_miss_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(uncacheable_miss_scnd_in, 0.U)} val imb_scnd_in = Mux(sel_hold_imb_scnd.asBool, imb_scnd_ff, io.ifc_fetch_addr_bf) imb_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(imb_scnd_in, 0.U)} way_status_mb_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(way_status_mb_scnd_in, 0.U)} tagv_mb_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(tagv_mb_scnd_in, 0.U)} val ic_req_addr_bits_hi_3 = bus_rd_addr_count val ic_wr_addr_bits_hi_3 = ifu_bus_rid_ff & Fill(ICACHE_BEAT_BITS, bus_ifu_wr_en_ff) val ifc_iccm_access_f = WireInit(Bool(), 0.U) val ifc_region_acc_fault_final_f = WireInit(Bool(), 0.U) val fetch_req_icache_f = ifc_fetch_req_f & !ifc_iccm_access_f & !ifc_region_acc_fault_final_f val fetch_req_iccm_f = ifc_fetch_req_f & ifc_iccm_access_f val ic_iccm_hit_f = fetch_req_iccm_f & (!miss_pending | (miss_state === hit_u_miss_C) | (miss_state === stream_C)) val stream_hit_f = WireInit(Bool(), 0.U) ic_byp_hit_f := (crit_byp_hit_f | stream_hit_f) & fetch_req_icache_f & miss_pending val sel_mb_addr_ff = WireInit(Bool(), 0.U) val imb_ff = WireInit(UInt(31.W), 0.U) val ifu_fetch_addr_int_f = WireInit(UInt(31.W), 0.U) val ic_act_hit_f = io.ic_rd_hit.orR & fetch_req_icache_f & !reset_all_tags & (!miss_pending | (miss_state===hit_u_miss_C)) & !sel_mb_addr_ff ic_act_miss_f := (((!io.ic_rd_hit.orR | reset_all_tags) & fetch_req_icache_f & !miss_pending) | scnd_miss_req) & !ifc_region_acc_fault_final_f ic_miss_under_miss_f := (!io.ic_rd_hit | reset_all_tags) & fetch_req_icache_f & (miss_state===hit_u_miss_C) & (imb_ff(30,ICACHE_TAG_INDEX_LO-1) =/= ifu_fetch_addr_int_f(30,ICACHE_TAG_INDEX_LO-1)) & !uncacheable_miss_ff & !sel_mb_addr_ff & !ifc_region_acc_fault_final_f ic_ignore_2nd_miss_f := (!io.ic_rd_hit.orR | reset_all_tags) & fetch_req_icache_f & (miss_state === hit_u_miss_C) & ((imb_ff(30,ICACHE_TAG_INDEX_LO-1)===ifu_fetch_addr_int_f(30,ICACHE_TAG_INDEX_LO-1)) | uncacheable_miss_ff) // Output io.ic_hit_f := ic_act_hit_f | ic_byp_hit_f | ic_iccm_hit_f | (ifc_region_acc_fault_final_f & ifc_fetch_req_f) val uncacheable_miss_in = Mux(scnd_miss_req.asBool, uncacheable_miss_scnd_ff, Mux(sel_hold_imb.asBool, uncacheable_miss_ff, io.ifc_fetch_uncacheable_bf)) val imb_in = Mux(scnd_miss_req.asBool, imb_scnd_ff, Mux(sel_hold_imb.asBool, imb_ff, io.ifc_fetch_addr_bf)) val ifu_wr_cumulative_err_data = WireInit(Bool(), 0.U) val scnd_miss_index_match = (imb_ff(ICACHE_INDEX_HI-1,ICACHE_TAG_INDEX_LO-1)===imb_scnd_ff(ICACHE_INDEX_HI-1,ICACHE_TAG_INDEX_LO-1))& scnd_miss_req & !ifu_wr_cumulative_err_data val way_status_mb_ff = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status_rep_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status_mb_in = Mux((scnd_miss_req & !scnd_miss_index_match).asBool, way_status_mb_scnd_ff, Mux((scnd_miss_req & scnd_miss_index_match).asBool, way_status_rep_new, Mux(miss_pending.asBool, way_status_mb_ff, way_status))) val replace_way_mb_any = Wire(Vec(ICACHE_NUM_WAYS, UInt(1.W))) val tagv_mb_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val tagv_mb_in = Mux(scnd_miss_req.asBool, tagv_mb_scnd_ff | (Fill(ICACHE_NUM_WAYS, scnd_miss_index_match) & replace_way_mb_any.reverse.reduce(Cat(_,_))), Mux(miss_pending.asBool, tagv_mb_ff, io.ic_tag_valid & Fill(ICACHE_NUM_WAYS, !reset_all_tags))) val scnd_miss_req_q = WireInit(Bool(), false.B) val reset_ic_ff = WireInit(Bool(), false.B) val reset_ic_in = miss_pending & !scnd_miss_req_q & (reset_all_tags | reset_ic_ff) reset_ic_ff := RegNext(reset_ic_in) val fetch_uncacheable_ff = RegNext(io.ifc_fetch_uncacheable_bf, 0.U) ifu_fetch_addr_int_f := withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_fetch_addr_bf, 0.U)} val vaddr_f = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1, 0) uncacheable_miss_ff := withClock(fetch_bf_f_c1_clk){RegNext(uncacheable_miss_in, 0.U)} imb_ff := withClock(fetch_bf_f_c1_clk){RegNext(imb_in)} val miss_addr = WireInit(UInt((31-ICACHE_BEAT_ADDR_HI).W), 0.U) val miss_addr_in = Mux(!miss_pending, imb_ff(30, ICACHE_BEAT_ADDR_HI), Mux(scnd_miss_req_q.asBool, imb_scnd_ff(30, ICACHE_BEAT_ADDR_HI), miss_addr)) val busclk_reset = rvclkhdr(clock, bus_ifu_bus_clk_en | ic_act_miss_f | io.dec_tlu_force_halt, io.scan_mode) miss_addr := withClock(busclk_reset) {RegNext(miss_addr_in, 0.U)} way_status_mb_ff := withClock(fetch_bf_f_c1_clk){RegNext(way_status_mb_in, 0.U)} tagv_mb_ff := withClock(fetch_bf_f_c1_clk){RegNext(tagv_mb_in, 0.U)} val stream_miss_f = WireInit(Bool(), 0.U) val ifc_fetch_req_qual_bf = io.ifc_fetch_req_bf & !((miss_state===crit_wrd_rdy_C) & flush_final_f) & !stream_miss_f val ifc_fetch_req_f_raw = RegNext(ifc_fetch_req_qual_bf, 0.U) ifc_fetch_req_f := ifc_fetch_req_f_raw & !io.exu_flush_final ifc_iccm_access_f := withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_iccm_access_bf, 0.U)} val ifc_region_acc_fault_final_bf = WireInit(Bool(), 0.U) ifc_region_acc_fault_final_f := withClock(fetch_bf_f_c1_clk){RegNext(ifc_region_acc_fault_final_bf, 0.U)} val ifc_region_acc_fault_f = withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_region_acc_fault_bf, 0.U)} val ifu_ic_req_addr_f = Cat(miss_addr, ic_req_addr_bits_hi_3) io.ifu_ic_mb_empty := (((miss_state===hit_u_miss_C) | (miss_state===stream_C)) & !(bus_ifu_wr_en_ff & last_beat)) | !miss_pending io.ifu_miss_state_idle := miss_state === idle_C val write_ic_16_bytes = WireInit(Bool(), false.B) val reset_tag_valid_for_miss = WireInit(Bool(), false.B) val sel_mb_addr = (miss_pending & write_ic_16_bytes & !uncacheable_miss_ff) | reset_tag_valid_for_miss val ifu_ic_rw_int_addr = Mux1H(Seq(sel_mb_addr -> Cat(imb_ff(30,ICACHE_BEAT_ADDR_HI) , ic_wr_addr_bits_hi_3 , imb_ff(1,0)), !sel_mb_addr -> io.ifc_fetch_addr_bf)) val bus_ifu_wr_en_ff_q = WireInit(Bool(), false.B) val sel_mb_status_addr = miss_pending & write_ic_16_bytes & !uncacheable_miss_ff & last_beat & bus_ifu_wr_en_ff_q val ifu_status_wr_addr = Mux(sel_mb_status_addr, Cat(imb_ff(30, ICACHE_BEAT_ADDR_HI),ic_wr_addr_bits_hi_3, imb_ff(1,0)), ifu_fetch_addr_int_f) io.ic_rw_addr := ifu_ic_rw_int_addr sel_mb_addr_ff := withClock(io.free_clk){RegNext(sel_mb_addr, 0.U)} val ifu_bus_rdata_ff = WireInit(UInt(64.W), 0.U) val ic_miss_buff_half = WireInit(UInt(64.W), 0.U) val ic_wr_ecc = rvecc_encode_64(ifu_bus_rdata_ff) val ic_miss_buff_ecc = rvecc_encode_64(ic_miss_buff_half) val ic_wr_16bytes_data = WireInit(UInt((ICACHE_BANKS_WAY * (if(ICACHE_ECC) 71 else 68)).W), 0.U) io.ic_wr_data := (0 until ICACHE_BANKS_WAY).map(i=>ic_wr_16bytes_data((i*(if(ICACHE_ECC) 71 else 68))+(if(ICACHE_ECC) 70 else 67),(if(ICACHE_ECC) 71 else 68)*i)) io.ic_debug_wr_data := io.dec_tlu_ic_diag_pkt.icache_wrdata val ic_rd_parity_final_err = WireInit(Bool(), 0.U) io.ic_error_start := ((if(ICACHE_ECC)io.ic_eccerr.orR()else io.ic_parerr.orR()) & ic_act_hit_f) | ic_rd_parity_final_err val ic_debug_tag_val_rd_out = WireInit(Bool(), 0.U) val ic_debug_ict_array_sel_ff = WireInit(Bool(), 0.U) val ifu_ic_debug_rd_data_in = Mux(ic_debug_ict_array_sel_ff.asBool, if(ICACHE_ECC) Cat(0.U(2.W),io.ictag_debug_rd_data(25,21),0.U(32.W),io.ictag_debug_rd_data(20,0), 0.U(7-ICACHE_STATUS_BITS), way_status, 0.U(3.W),ic_debug_tag_val_rd_out) else Cat(0.U(6.W),io.ictag_debug_rd_data(21),0.U(32.W),io.ictag_debug_rd_data(20,0),0.U(7-ICACHE_STATUS_BITS),way_status ,0.U(3.W) ,ic_debug_tag_val_rd_out) , io.ic_debug_rd_data) io.ifu_ic_debug_rd_data := withClock(debug_data_clk){RegNext(ifu_ic_debug_rd_data_in, 0.U)} val ic_wr_parity = (0 until 4).map(i=>rveven_paritygen(ifu_bus_rdata_ff((16*i)+15,16*i))).reverse.reduce(Cat(_,_)) val ic_miss_buff_parity = (0 until 4).map(i=>rveven_paritygen(ic_miss_buff_half((16*i)+15,16*i))).reverse.reduce(Cat(_,_)) ic_wr_16bytes_data := Mux(ifu_bus_rid_ff(0).asBool,Cat(if(ICACHE_ECC)ic_wr_ecc else ic_wr_parity, ifu_bus_rdata_ff, if(ICACHE_ECC)ic_miss_buff_ecc else ic_miss_buff_parity, ic_miss_buff_half), Cat(if(ICACHE_ECC)ic_miss_buff_ecc else ic_miss_buff_parity, ic_miss_buff_half, if(ICACHE_ECC)ic_wr_ecc else ic_wr_parity, ifu_bus_rdata_ff)) val bus_ifu_wr_data_error_ff = WireInit(Bool(), 0.U) val ifu_wr_data_comb_err_ff = WireInit(Bool(), 0.U) val reset_beat_cnt = WireInit(Bool(), 0.U) val ifu_wr_data_comb_err = bus_ifu_wr_data_error_ff val ifu_wr_cumulative_err = (ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff) & !reset_beat_cnt ifu_wr_cumulative_err_data := ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff ifu_wr_data_comb_err_ff := withClock(io.free_clk) {RegNext(ifu_wr_cumulative_err, 0.U)} val ic_crit_wd_rdy = WireInit(Bool(), 0.U) val ifu_byp_data_err_new = WireInit(Bool(), 0.U) val sel_byp_data = (ic_crit_wd_rdy | (miss_state===stream_C) | (miss_state===crit_byp_ok_C)) & !ifu_byp_data_err_new val sel_ic_data = !(ic_crit_wd_rdy | (miss_state===stream_C) | (miss_state===crit_byp_ok_C)) & !fetch_req_iccm_f val sel_iccm_data = fetch_req_iccm_f val ic_byp_data_only_new = WireInit(UInt(80.W), 0.U) val ic_final_data = Mux1H(Seq((sel_byp_data | (if(ICCM_ICACHE) (sel_iccm_data | sel_ic_data) else if(ICACHE_ONLY) sel_ic_data else 0.U)).asBool-> (if(ICCM_ICACHE) io.ic_rd_data else ic_byp_data_only_new(63,0)))) val ic_premux_data_temp = if(ICCM_ICACHE) (Fill(64,sel_iccm_data) & io.iccm_rd_data) | (Fill(64, sel_byp_data) & ic_byp_data_only_new) else if(ICACHE_ONLY) Fill(64, sel_byp_data) & ic_byp_data_only_new else 0.U val ic_sel_premux_data_temp = if(ICCM_ICACHE) sel_iccm_data | sel_byp_data else if(ICACHE_ONLY) sel_byp_data else 0.U io.ic_premux_data := ic_premux_data_temp io.ic_sel_premux_data := ic_sel_premux_data_temp val ifc_bus_acc_fault_f = ic_byp_hit_f & ifu_byp_data_err_new io.ic_data_f := ic_final_data val fetch_req_f_qual = io.ic_hit_f & !io.exu_flush_final val ifc_region_acc_fault_memory_f = WireInit(Bool(), 0.U) io.ic_access_fault_f := (ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f) & !io.exu_flush_final io.ic_access_fault_type_f := Mux(io.iccm_rd_ecc_double_err.asBool, 1.U, Mux(ifc_region_acc_fault_f.asBool, 2.U, Mux(ifc_region_acc_fault_memory_f.asBool(), 3.U, 0.U))) io.ic_fetch_val_f := Cat(fetch_req_f_qual & io.ifu_bp_inst_mask_f & !(vaddr_f===Fill(ICACHE_BEAT_ADDR_HI,1.U)) & (err_stop_state=/=err_fetch2_C), fetch_req_f_qual) val two_byte_instr = io.ic_data_f(1,0) =/= 3.U //// Creating full buffer val ifu_bus_rsp_rdata = WireInit(UInt(64.W), 0.U) val ic_miss_buff_data_in = ifu_bus_rsp_rdata val ifu_bus_rsp_tag = WireInit(UInt(IFU_BUS_TAG.W), 0.U) val bus_ifu_wr_en = WireInit(Bool(), false.B) val write_fill_data = (0 until ICACHE_NUM_BEATS).map(i=>bus_ifu_wr_en & (ifu_bus_rsp_tag===i.U)) val ic_miss_buff_data = Wire(Vec(2*ICACHE_NUM_BEATS, UInt(32.W))) for(i<- 0 until ICACHE_NUM_BEATS){ val wr_data_c1_clk = write_fill_data.map(rvclkhdr(clock, _ , io.scan_mode)) ic_miss_buff_data(2*i) := withClock(wr_data_c1_clk(i)){RegNext(ic_miss_buff_data_in(31,0), 0.U)} ic_miss_buff_data(2*i+1) := withClock(wr_data_c1_clk(i)){RegNext(ic_miss_buff_data_in(63,32), 0.U)}} val ic_miss_buff_data_valid = WireInit(UInt(ICACHE_NUM_BEATS.W), 0.U) val ic_miss_buff_data_valid_in = (0 until ICACHE_NUM_BEATS).map(i=>write_fill_data(i)|(ic_miss_buff_data_valid(i)&(!ic_act_miss_f))) ic_miss_buff_data_valid := withClock(io.free_clk){RegNext(ic_miss_buff_data_valid_in.map(i=>i.asUInt()).reverse.reduce(Cat(_,_)), 0.U)} val bus_ifu_wr_data_error = WireInit(Bool(), 0.U) val ic_miss_buff_data_error = WireInit(UInt(ICACHE_NUM_BEATS.W), 0.U) val ic_miss_buff_data_error_in =(0 until ICACHE_NUM_BEATS).map(i=>Mux(write_fill_data(i).asBool,bus_ifu_wr_data_error, ic_miss_buff_data_error(i) & !ic_act_miss_f)) ic_miss_buff_data_error := withClock(io.free_clk){RegNext(ic_miss_buff_data_error_in.reverse.reduce(Cat(_,_)), 0.U)} // New Bypass ready val bypass_index = imb_ff(ICACHE_BEAT_ADDR_HI-1, 0) val bypass_index_5_3_inc = bypass_index(bypass_index.getWidth-1,2) + 1.U val bypass_valid_value_check = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(bypass_index(bypass_index.getWidth-1,2)===i.U).asBool->ic_miss_buff_data_valid_in(i))) val bypass_data_ready_in = (bypass_valid_value_check & !bypass_index(1) & !bypass_index(0)) | (bypass_valid_value_check & !bypass_index(1) & bypass_index(0)) | (bypass_valid_value_check & bypass_index(1) & !bypass_index(0)) | (bypass_valid_value_check & bypass_index(1) & bypass_index(0) & Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(bypass_index_5_3_inc===i.U).asBool->ic_miss_buff_data_valid_in(i)))) | (bypass_valid_value_check & bypass_index(ICACHE_BEAT_ADDR_HI-1,2)===Fill(ICACHE_BEAT_ADDR_HI,1.U)) val ic_crit_wd_rdy_new_ff = WireInit(Bool(), 0.U) val ic_crit_wd_rdy_new_in = (bypass_data_ready_in & crit_wd_byp_ok_ff & uncacheable_miss_ff & !io.exu_flush_final & !ifu_bp_hit_taken_q_f) | ( crit_wd_byp_ok_ff & !uncacheable_miss_ff & !io.exu_flush_final & !ifu_bp_hit_taken_q_f) | (ic_crit_wd_rdy_new_ff & crit_wd_byp_ok_ff & !fetch_req_icache_f & !io.exu_flush_final) ic_crit_wd_rdy_new_ff := withClock(io.free_clk){RegNext(ic_crit_wd_rdy_new_in, 0.U)} val byp_fetch_index = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,0) val byp_fetch_index_0 = Cat(ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2), 0.U) val byp_fetch_index_1 = Cat(ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2), 1.U) val byp_fetch_index_inc = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2) + 1.U val byp_fetch_index_inc_0 = Cat(byp_fetch_index_inc, 0.U) val byp_fetch_index_inc_1 = Cat(byp_fetch_index_inc, 1.U) val ic_miss_buff_data_error_bypass = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(bypass_index(ICACHE_BEAT_ADDR_HI-1,2)===i.U).asBool->ic_miss_buff_data_error(i))) val ic_miss_buff_data_error_bypass_inc = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc===i.U).asBool->ic_miss_buff_data_error(i))) when(ifu_fetch_addr_int_f(1)&ifu_fetch_addr_int_f(0)){ ifu_byp_data_err_new := ic_miss_buff_data_error_bypass } otherwise{ifu_byp_data_err_new := ic_miss_buff_data_error_bypass | ic_miss_buff_data_error_bypass_inc} val ic_byp_data_only_pre_new = Mux(!ifu_fetch_addr_int_f(1).asBool, Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_0===i.U).asBool->ic_miss_buff_data(i)(15,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_1===i.U).asBool->ic_miss_buff_data(i)(31,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_0===i.U).asBool->ic_miss_buff_data(i)(31,0)))), Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_1===i.U).asBool->ic_miss_buff_data(i)(15,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_0===i.U).asBool->ic_miss_buff_data(i)(31,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_1===i.U).asBool->ic_miss_buff_data(i)(31,0))))) ic_byp_data_only_new := Mux(!ifu_fetch_addr_int_f(0).asBool(),ic_byp_data_only_pre_new,Cat(0.U(16.W),ic_byp_data_only_pre_new(79,16))) val miss_wrap_f = imb_ff(ICACHE_TAG_INDEX_LO-1) =/= ifu_fetch_addr_int_f(ICACHE_TAG_INDEX_LO-1) val ic_miss_buff_data_valid_bypass_index = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2)===i.U).asBool->ic_miss_buff_data_valid(i))) val ic_miss_buff_data_valid_inc_bypass_index = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc===i.U).asBool->ic_miss_buff_data_valid(i))) val miss_buff_hit_unq_f = (ic_miss_buff_data_valid_bypass_index & !byp_fetch_index(1) & !byp_fetch_index(0)) | (ic_miss_buff_data_valid_bypass_index & !byp_fetch_index(1) & byp_fetch_index(0)) | (ic_miss_buff_data_valid_bypass_index & byp_fetch_index(1) & !byp_fetch_index(0)) | (ic_miss_buff_data_valid_bypass_index & byp_fetch_index(1) & byp_fetch_index(0) & ic_miss_buff_data_valid_inc_bypass_index) | (ic_miss_buff_data_valid_bypass_index & (byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2) === Fill(ICACHE_BEAT_BITS,1.U))) stream_hit_f := (miss_state===stream_C) & (miss_buff_hit_unq_f & !miss_wrap_f) stream_miss_f := (miss_state===stream_C) & !(miss_buff_hit_unq_f & !miss_wrap_f) & ifc_fetch_req_f stream_eol_f := (byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,1)===Fill(ICACHE_BEAT_BITS+1, 1.U)) & ifc_fetch_req_f & stream_hit_f crit_byp_hit_f := miss_buff_hit_unq_f & ((miss_state===crit_wrd_rdy_C) | (miss_state===crit_byp_ok_C)) val other_tag = Cat(ifu_bus_rid_ff(IFU_BUS_TAG-1,1),!ifu_bus_rid_ff(0)) val second_half_available = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(other_tag===i.U).asBool->ic_miss_buff_data_valid(i))) write_ic_16_bytes := second_half_available & bus_ifu_wr_en_ff ic_miss_buff_half := Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(Cat(other_tag,1.U)===i.U).asBool->ic_miss_buff_data(i))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(Cat(other_tag,0.U)===i.U).asBool->ic_miss_buff_data(i)))) ic_rd_parity_final_err := io.ic_tag_perr & sel_ic_data & !(ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f) val ifu_ic_rw_int_addr_ff = WireInit(UInt((ICACHE_INDEX_HI-ICACHE_TAG_INDEX_LO+1).W), 0.U) val perr_sb_write_status = WireInit(Bool(), false.B) val perr_ic_index_ff = withClock(io.active_clk){RegEnable(ifu_ic_rw_int_addr_ff, 0.U, perr_sb_write_status)} val perr_sel_invalidate = WireInit(Bool(), false.B) val perr_err_inv_way = Fill(ICACHE_NUM_WAYS, perr_sel_invalidate) iccm_correct_ecc := perr_state === ecc_cor_C val dma_sb_err_state = perr_state === dma_sb_err_C val dma_sb_err_state_ff = Wire(Bool()) io.iccm_buf_correct_ecc := iccm_correct_ecc & !dma_sb_err_state_ff dma_sb_err_state_ff := withClock(io.active_clk){RegNext(dma_sb_err_state, false.B)} ///////////////////////////////// ERROR FSM ///////////////////////////////// val perr_nxtstate = WireInit(UInt(3.W), 0.U) val perr_state_en = WireInit(Bool(), false.B) val iccm_error_start = WireInit(Bool(), false.B) switch(perr_state){ is(err_idle_C){ perr_nxtstate := Mux(io.iccm_dma_sb_error, dma_sb_err_C, Mux((io.ic_error_start & !io.exu_flush_final).asBool, ic_wff_C, ecc_wff_C)) perr_state_en := (((iccm_error_start | io.ic_error_start) & !io.exu_flush_final) | io.iccm_dma_sb_error) & !io.dec_tlu_force_halt perr_sb_write_status := perr_state_en } is(ic_wff_C){ perr_nxtstate := err_idle_C perr_state_en := io.dec_tlu_flush_lower_wb | io.dec_tlu_force_halt perr_sel_invalidate := io.dec_tlu_flush_lower_wb & io.dec_tlu_force_halt } is(ecc_wff_C){ perr_nxtstate := Mux(((io.dec_tlu_flush_err_wb & io.dec_tlu_flush_lower_wb ) | io.dec_tlu_force_halt).asBool(), err_idle_C, ecc_cor_C) perr_state_en := io.dec_tlu_flush_lower_wb | io.dec_tlu_force_halt } is(dma_sb_err_C){ perr_nxtstate := Mux(io.dec_tlu_force_halt, err_idle_C, ecc_cor_C) perr_state_en := true.B } is(ecc_cor_C){ perr_nxtstate := err_idle_C perr_state_en := true.B } } perr_state := withClock(io.free_clk){RegEnable(perr_nxtstate, 0.U, perr_state_en)} ///////////////////////////////// STOP FETCH FSM ///////////////////////////////// val err_stop_nxtstate = WireInit(UInt(2.W), 0.U) val err_stop_state_en = WireInit(Bool(), false.B) io.iccm_correction_state := false.B // val err_stop_fetch := WireInit(Bool(), false.B) switch(err_stop_state){ is(err_stop_idle_C){ err_stop_nxtstate := err_fetch1_C err_stop_state_en := io.dec_tlu_flush_err_wb & (perr_state === ecc_wff_C) & !io.dec_tlu_force_halt } is(err_fetch1_C){ err_stop_nxtstate := Mux((io.dec_tlu_flush_lower_wb | io.dec_tlu_i0_commit_cmt | io.dec_tlu_force_halt).asBool(), err_stop_idle_C, Mux(((io.ifu_fetch_val===3.U)|(io.ifu_fetch_val(0)&two_byte_instr)).asBool(), err_stop_fetch_C, Mux(io.ifu_fetch_val(0).asBool(), err_fetch2_C, err_fetch1_C))) err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | ifu_bp_hit_taken_q_f | io.dec_tlu_force_halt err_stop_fetch := ((io.ifu_fetch_val(1,0)===3.U) | (io.ifu_fetch_val(0) & two_byte_instr)) & !(io.exu_flush_final | io.dec_tlu_i0_commit_cmt) io.iccm_correction_state := true.B } is(err_fetch2_C){ err_stop_nxtstate := Mux((io.dec_tlu_flush_lower_wb | io.dec_tlu_i0_commit_cmt | io.dec_tlu_force_halt).asBool, err_stop_idle_C, Mux(io.ifu_fetch_val(0).asBool, err_stop_fetch_C, err_fetch2_C)) err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | io.dec_tlu_force_halt err_stop_fetch := io.ifu_fetch_val(0) & !io.exu_flush_final & !io.dec_tlu_i0_commit_cmt io.iccm_correction_state := true.B } is(err_stop_fetch_C){ err_stop_nxtstate := Mux(((io.dec_tlu_flush_lower_wb & !io.dec_tlu_flush_err_wb) | io.dec_tlu_i0_commit_cmt | io.dec_tlu_force_halt).asBool, err_stop_idle_C, Mux(io.dec_tlu_flush_err_wb.asBool(), err_fetch1_C, err_stop_fetch_C)) err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_tlu_i0_commit_cmt | io.dec_tlu_force_halt err_stop_fetch := true.B io.iccm_correction_state := true.B } } err_stop_state := withClock(io.free_clk){RegEnable(err_stop_nxtstate, 0.U, err_stop_state_en)} bus_ifu_bus_clk_en := io.ifu_bus_clk_en val busclk = rvclkhdr(clock, bus_ifu_bus_clk_en, io.scan_mode) val busclk_force = rvclkhdr(clock, bus_ifu_bus_clk_en | io.dec_tlu_force_halt , io.scan_mode) val bus_ifu_bus_clk_en_ff = withClock(io.free_clk){RegNext(bus_ifu_bus_clk_en, 0.U)} scnd_miss_req_q := withClock(io.free_clk){RegNext(scnd_miss_req_in, 0.U)} val scnd_miss_req_ff2 = withClock(io.free_clk){RegNext(scnd_miss_req, 0.U)} scnd_miss_req := scnd_miss_req_q & (!io.exu_flush_final) val bus_cmd_req_hold = WireInit(Bool(), false.B) val ifu_bus_cmd_valid = WireInit(Bool(), false.B) val bus_cmd_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) val ifu_bus_cmd_ready = WireInit(Bool(), false.B) val ifc_bus_ic_req_ff_in = (ic_act_miss_f | bus_cmd_req_hold | ifu_bus_cmd_valid) & !io.dec_tlu_force_halt & !((bus_cmd_beat_count===Fill(ICACHE_BEAT_BITS,1.U)) & ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending) ifu_bus_cmd_valid := withClock(busclk_force){RegNext(ifc_bus_ic_req_ff_in, 0.U)} val bus_cmd_sent = WireInit(Bool(), false.B) val bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & !bus_cmd_sent & !io.dec_tlu_force_halt bus_cmd_sent := withClock(io.free_clk){RegNext(bus_cmd_req_in, false.B)} // AXI Read-Channel io.ifu_axi_arvalid := ifu_bus_cmd_valid io.ifu_axi_arid := bus_rd_addr_count & Fill(IFU_BUS_TAG, ifu_bus_cmd_valid) io.ifu_axi_araddr := Cat(ifu_ic_req_addr_f, 0.U(3.W)) & Fill(32, ifu_bus_cmd_valid) io.ifu_axi_arsize := 3.U(3.W) io.ifu_axi_arcache := 15.U io.ifu_axi_arregion := ifu_ic_req_addr_f(28,25) io.ifu_axi_arburst := 1.U io.ifu_axi_rready := true.B val ifu_bus_arready_unq = io.ifu_axi_arready val ifu_bus_rvalid_unq = io.ifu_axi_rvalid val ifu_bus_arvalid = io.ifu_axi_arvalid bus_ifu_bus_clk_en val ifu_bus_arready_unq_ff = withClock(busclk){RegNext(ifu_bus_arready_unq, false.B)} val ifu_bus_rvalid_unq_ff = withClock(busclk){RegNext(ifu_bus_rvalid_unq, false.B)} val ifu_bus_arvalid_ff = withClock(busclk){RegNext(ifu_bus_arvalid, false.B)} val ifu_bus_rresp_ff = withClock(busclk){RegNext(io.ifu_axi_rresp, 0.U)} ifu_bus_rdata_ff := withClock(busclk){RegNext(io.ifu_axi_rdata, 0.U)} ifu_bus_rid_ff := withClock(busclk){RegNext(io.ifu_axi_rid, 0.U)} ifu_bus_cmd_ready := io.ifu_axi_arready ifu_bus_rsp_valid := io.ifu_axi_rvalid ifu_bus_rsp_ready := io.ifu_axi_rready ifu_bus_rsp_tag := io.ifu_axi_rid ifu_bus_rsp_rdata := io.ifu_axi_rdata val ifu_bus_rsp_opc = io.ifu_axi_rresp val ifu_bus_rvalid = ifu_bus_rsp_valid & bus_ifu_bus_clk_en val ifu_bus_arready = ifu_bus_arready_unq & bus_ifu_bus_clk_en val ifu_bus_arready_ff = ifu_bus_arready_unq_ff & bus_ifu_bus_clk_en_ff val ifu_bus_rvalid_ff = ifu_bus_rvalid_unq_ff & bus_ifu_bus_clk_en_ff bus_cmd_sent := ifu_bus_arvalid & ifu_bus_arready & miss_pending & !io.dec_tlu_force_halt val bus_last_data_beat = WireInit(Bool(), false.B) val bus_inc_data_beat_cnt = bus_ifu_wr_en_ff & !bus_last_data_beat & !io.dec_tlu_force_halt val bus_reset_data_beat_cnt = ic_act_miss_f | (bus_ifu_wr_en_ff & bus_last_data_beat) | io.dec_tlu_force_halt val bus_hold_data_beat_cnt = !bus_inc_data_beat_cnt & !bus_reset_data_beat_cnt val bus_data_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) bus_new_data_beat_count := Mux1H(Seq(bus_reset_data_beat_cnt->0.U, bus_inc_data_beat_cnt-> (bus_data_beat_count + 1.U), bus_hold_data_beat_cnt->bus_data_beat_count)) bus_data_beat_count := withClock(io.free_clk){RegNext(bus_new_data_beat_count, 0.U)} val last_data_recieved_in = (bus_ifu_wr_en_ff & bus_last_data_beat & !scnd_miss_req) | (last_data_recieved_ff & !ic_act_miss_f) last_data_recieved_ff := withClock(io.free_clk){RegNext(last_data_recieved_in, 0.U)} // Request Address Count val bus_new_rd_addr_count = Mux(!miss_pending, imb_ff(ICACHE_BEAT_ADDR_HI-1, 2), Mux(scnd_miss_req_q, imb_scnd_ff(ICACHE_BEAT_ADDR_HI-1, 2), Mux(bus_cmd_sent, bus_rd_addr_count + 1.U, bus_rd_addr_count))) bus_rd_addr_count := withClock(busclk_reset){RegNext(bus_new_rd_addr_count, 0.U)} // Command beat Count val bus_inc_cmd_beat_cnt = ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending & !io.dec_tlu_force_halt val bus_reset_cmd_beat_cnt_0 = (ic_act_miss_f & !uncacheable_miss_in) | io.dec_tlu_force_halt val bus_reset_cmd_beat_cnt_secondlast = ic_act_miss_f & uncacheable_miss_in val bus_hold_cmd_beat_cnt = !bus_inc_cmd_beat_cnt & !(ic_act_miss_f | scnd_miss_req | io.dec_tlu_force_halt) val bus_cmd_beat_en = bus_inc_cmd_beat_cnt | ic_act_miss_f | io.dec_tlu_force_halt val bus_new_cmd_beat_count = Mux1H(Seq(bus_reset_cmd_beat_cnt_0->0.U, bus_reset_cmd_beat_cnt_secondlast.asBool->ICACHE_SCND_LAST.U, bus_inc_cmd_beat_cnt->(bus_cmd_beat_count+1.U), bus_hold_cmd_beat_cnt->bus_cmd_beat_count)) bus_cmd_beat_count := withClock(busclk_reset){RegEnable(bus_new_cmd_beat_count, 0.U, bus_cmd_beat_en)} bus_last_data_beat := Mux(uncacheable_miss_ff, bus_data_beat_count===1.U, bus_data_beat_count.andR()) bus_ifu_wr_en := ifu_bus_rvalid & miss_pending bus_ifu_wr_en_ff := ifu_bus_rvalid_ff & miss_pending bus_ifu_wr_en_ff_q := ifu_bus_rvalid_ff & miss_pending & !uncacheable_miss_ff & !(ifu_bus_rresp_ff.orR) & write_ic_16_bytes val bus_ifu_wr_en_ff_wo_err = ifu_bus_rvalid_ff & miss_pending & !uncacheable_miss_ff val ic_act_miss_f_delayed = withClock(io.free_clk){RegNext(ic_act_miss_f, false.B)} reset_tag_valid_for_miss := ic_act_miss_f_delayed & (miss_state===crit_byp_ok_C) & !uncacheable_miss_ff bus_ifu_wr_data_error := ifu_bus_rsp_opc.orR() & ifu_bus_rvalid & miss_pending bus_ifu_wr_data_error_ff := ifu_bus_rresp_ff.orR & ifu_bus_rvalid_ff & miss_pending val ifc_dma_access_ok_d = WireInit(Bool(), false.B) val ifc_dma_access_ok_prev = withClock(io.free_clk){RegNext(ifc_dma_access_ok_d, false.B)} ic_crit_wd_rdy := ic_crit_wd_rdy_new_in | ic_crit_wd_rdy_new_ff last_beat := bus_last_data_beat & bus_ifu_wr_en_ff reset_beat_cnt := bus_reset_data_beat_cnt // DMA ifc_dma_access_ok_d := io.ifc_dma_access_ok & !iccm_correct_ecc & !io.iccm_dma_sb_error val ifc_dma_access_q_ok = io.ifc_dma_access_ok & !iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state===err_idle_C) & !io.iccm_dma_sb_error io.iccm_ready := ifc_dma_access_q_ok dma_iccm_req_f := withClock(io.free_clk){RegNext(io.dma_iccm_req, false.B)} io.iccm_wren := (ifc_dma_access_q_ok & io.dma_iccm_req & io.dma_mem_write) | iccm_correct_ecc io.iccm_rden := (ifc_dma_access_q_ok & io.dma_iccm_req & !io.dma_mem_write) | (io.ifc_iccm_access_bf & io.ifc_fetch_req_bf) val iccm_dma_rden = ifc_dma_access_q_ok & io.dma_iccm_req & !io.dma_mem_write io.iccm_wr_size := Fill(3, io.dma_iccm_req) & io.dma_mem_sz val dma_mem_ecc = Cat(rvecc_encode(io.dma_mem_wdata(63,32)), rvecc_encode(io.dma_mem_wdata(31,0))) val iccm_ecc_corr_data_ff = WireInit(UInt(39.W), 0.U) io.iccm_wr_data := Mux(iccm_correct_ecc & !(ifc_dma_access_q_ok & io.dma_iccm_req), Fill(2,iccm_ecc_corr_data_ff), Cat(dma_mem_ecc(13,7),io.dma_mem_wdata(63,32), dma_mem_ecc(6,0), io.dma_mem_wdata(31,0))) val iccm_corrected_data = Wire(Vec(2, UInt(32.W))) iccm_corrected_data(0) := 0.U iccm_corrected_data(1) := 0.U val dma_mem_addr_ff = WireInit(UInt(2.W), 0.U) val iccm_dma_rdata_1_muxed = Mux(dma_mem_addr_ff(0).asBool, iccm_corrected_data(0), iccm_corrected_data(1)) val iccm_double_ecc_error = WireInit(UInt(2.W), 0.U) val iccm_dma_ecc_error_in = iccm_double_ecc_error.orR val iccm_dma_rdata_in = Mux(iccm_dma_ecc_error_in, Fill(2, io.dma_mem_addr), Cat(iccm_dma_rdata_1_muxed, iccm_corrected_data(0))) val dma_mem_tag_ff = withClock(io.free_clk){RegNext(io.dma_mem_tag, 0.U)} val iccm_dma_rtag_temp = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(dma_mem_tag_ff, 0.U)} else 0.U io.iccm_dma_rtag := iccm_dma_rtag_temp dma_mem_addr_ff := withClock(io.free_clk) {RegNext(io.dma_mem_addr(3,2), 0.U)} val iccm_dma_rvalid_in = withClock(io.free_clk) {RegNext(iccm_dma_rden, false.B)} val iccm_dma_rvalid_temp = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(iccm_dma_rvalid_in, false.B)} else 0.U io.iccm_dma_rvalid := iccm_dma_rvalid_temp val iccm_dma_ecc_error = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(iccm_dma_ecc_error_in, false.B)} else 0.U io.iccm_dma_ecc_error := iccm_dma_ecc_error_in val iccm_dma_rdata_temp = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(iccm_dma_rdata_in, 0.U)} else 0.U io.iccm_dma_rdata := iccm_dma_rdata_temp val iccm_ecc_corr_index_ff = WireInit(UInt((ICCM_BITS-2).W), 0.U) io.iccm_rw_addr := Mux(ifc_dma_access_q_ok & io.dma_iccm_req & !iccm_correct_ecc, io.dma_mem_addr(ICCM_BITS-1,1), Mux(!(ifc_dma_access_q_ok & io.dma_iccm_req) & iccm_correct_ecc, Cat(iccm_ecc_corr_index_ff, 0.U), io.ifc_fetch_addr_bf(ICCM_BITS-2,0))) val ic_fetch_val_int_f = Cat(0.U(2.W), io.ic_fetch_val_f) val ic_fetch_val_shift_right = ic_fetch_val_int_f << ifu_fetch_addr_int_f(0) val iccm_rdmux_data = io.iccm_rd_data_ecc val iccm_ecc_word_enable = (0 until 2).map(i=>((ic_fetch_val_shift_right((2*i+1),(2*i)) & !io.exu_flush_final & sel_iccm_data) | iccm_dma_rvalid_in) & !io.dec_tlu_core_ecc_disable).reverse.reduce(Cat(_,_)) val ecc_decoded = (0 until 2).map(i=>rvecc_decode(iccm_ecc_word_enable(i), iccm_rdmux_data((39*i+31),(39*i)), iccm_rdmux_data((39*i+38),(39*i+32)), 0.U)) val iccm_corrected_ecc = Wire(Vec(2, UInt(7.W))) iccm_corrected_ecc := VecInit(ecc_decoded(0)._1,ecc_decoded(1)._1) iccm_corrected_data := VecInit(ecc_decoded(0)._2,ecc_decoded(1)._2) iccm_single_ecc_error := Cat(ecc_decoded(0)._3,ecc_decoded(1)._3) iccm_double_ecc_error := Cat(ecc_decoded(0)._4,ecc_decoded(1)._4) io.iccm_rd_ecc_single_err := iccm_single_ecc_error.orR & ifc_iccm_access_f & ifc_fetch_req_f io.iccm_rd_ecc_double_err := iccm_double_ecc_error.orR & ifc_iccm_access_f val iccm_corrected_data_f_mux = Mux(iccm_single_ecc_error(0).asBool, iccm_corrected_data(0), iccm_corrected_data(1)) val iccm_corrected_ecc_f_mux = Mux(iccm_single_ecc_error(0).asBool, iccm_corrected_ecc(0), iccm_corrected_ecc(1)) val iccm_rd_ecc_single_err_ff = WireInit(Bool(), false.B) val iccm_ecc_write_status = if(ICCM_ENABLE)((io.iccm_rd_ecc_single_err & !iccm_rd_ecc_single_err_ff) & !io.exu_flush_final) | io.iccm_dma_sb_error else 0.U val iccm_rd_ecc_single_err_hold_in = (io.iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & !io.exu_flush_final iccm_error_start := io.iccm_rd_ecc_single_err val iccm_rw_addr_f = WireInit(UInt((ICCM_BITS-2).W), 0.U) val iccm_ecc_corr_index_in = Mux(iccm_single_ecc_error(0).asBool(), iccm_rw_addr_f, iccm_rw_addr_f + 1.U) iccm_rw_addr_f := withClock(io.free_clk){RegNext(io.iccm_rw_addr(ICCM_BITS-2,1), 0.U)} iccm_rd_ecc_single_err_ff := withClock(io.free_clk){RegNext(iccm_rd_ecc_single_err_hold_in, false.B)} iccm_ecc_corr_data_ff := withClock(io.free_clk){RegEnable(Cat(iccm_corrected_ecc_f_mux, iccm_corrected_data_f_mux), 0.U, iccm_ecc_write_status.asBool())} iccm_ecc_corr_index_ff := withClock(io.free_clk){RegEnable(iccm_ecc_corr_index_in, 0.U, iccm_ecc_write_status.asBool())} io.ic_rd_en := (io.ifc_fetch_req_bf & !io.ifc_fetch_uncacheable_bf & !io.ifc_iccm_access_bf & !(((miss_state===stream_C) & !miss_state_en) | ((miss_state===crit_byp_ok_C) & !miss_state_en) | ((miss_state===stall_scnd_miss_C) & !miss_state_en) | ((miss_state===miss_wait_C) & !miss_state_en) | ((miss_state===crit_wrd_rdy_C) & !miss_state_en) | ((miss_state===crit_byp_ok_C) & miss_state_en & (miss_nxtstate===miss_wait_C)) )) | (io.ifc_fetch_req_bf & io.exu_flush_final & !io.ifc_fetch_uncacheable_bf & !io.ifc_iccm_access_bf) val bus_ic_wr_en = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) io.ic_wr_en := bus_ic_wr_en & Fill(ICACHE_NUM_WAYS, write_ic_16_bytes) io.ic_write_stall := write_ic_16_bytes & !((((miss_state===crit_byp_ok_C) | ((miss_state===stream_C) & !(io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ))) & !(bus_ifu_wr_en_ff & last_beat & !uncacheable_miss_ff))) reset_all_tags := withClock(io.active_clk){RegNext(io.dec_tlu_fence_i_wb, false.B)} val ic_valid = !ifu_wr_cumulative_err_data & !(reset_ic_in | reset_ic_ff) & !reset_tag_valid_for_miss val ifu_status_wr_addr_w_debug = Mux((io.ic_debug_rd_en | io.ic_debug_wr_en) & io.ic_debug_tag_array, io.ic_debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3), ifu_status_wr_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1)) val ifu_status_wr_addr_ff = withClock(io.free_clk) { RegNext(ifu_status_wr_addr_w_debug, 0.U) } val way_status_wr_en = WireInit(Bool(), false.B) val way_status_wr_en_w_debug = way_status_wr_en | (io.ic_debug_wr_en & io.ic_debug_tag_array) val way_status_wr_en_ff = withClock(io.free_clk) { RegNext(way_status_wr_en_w_debug, false.B) } val way_status_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status_new_w_debug = Mux(io.ic_debug_wr_en & io.ic_debug_tag_array, if (ICACHE_STATUS_BITS == 1) io.ic_debug_wr_data(4) else io.ic_debug_wr_data(6, 4), way_status_new) val way_status_new_ff = withClock(io.free_clk) { RegNext(way_status_new_w_debug, 0.U) } val way_status_clken = (0 until ICACHE_TAG_DEPTH / 8).map(i => ifu_status_wr_addr_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 3) === i.U) val way_status_clk = way_status_clken.map(rvclkhdr(clock, _, io.scan_mode)) val way_status_out = Wire(Vec(ICACHE_TAG_DEPTH, UInt(ICACHE_STATUS_BITS.W))) for (i <- 0 until ICACHE_TAG_DEPTH / 8; j <- 0 until 8) way_status_out((8 * i) + j) := withClock(way_status_clk(i)){RegEnable(way_status_new_ff, 0.U, (ifu_status_wr_addr_ff(2,0)===j.U) & way_status_wr_en_ff)} val test_way_status_out = (0 until ICACHE_TAG_DEPTH).map(i=>way_status_out(i).asUInt).reverse.reduce(Cat(_,_)) // io.test_way_status_out := test_way_status_out val test_way_status_clken = (0 until ICACHE_TAG_DEPTH/8).map(i=>way_status_clken(i).asUInt()).reverse.reduce(Cat(_,_)) //io.test_way_status_clken := test_way_status_clken way_status := Mux1H((0 until ICACHE_TAG_DEPTH).map(i=>(ifu_ic_rw_int_addr_ff === i.U) -> way_status_out(i))) val ifu_ic_rw_int_addr_w_debug = Mux((io.ic_debug_rd_en | io.ic_debug_wr_en) & io.ic_debug_tag_array, io.ic_debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3), ifu_ic_rw_int_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1)) ifu_ic_rw_int_addr_ff := withClock(io.free_clk) { RegNext(ifu_ic_rw_int_addr_w_debug, 0.U) } val ifu_tag_wren = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val ic_debug_tag_wr_en = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val ifu_tag_wren_w_debug = ifu_tag_wren | ic_debug_tag_wr_en val ifu_tag_wren_ff = withClock(io.free_clk) { RegNext(ifu_tag_wren_w_debug, 0.U) } val ic_valid_w_debug = Mux(io.ic_debug_wr_en & io.ic_debug_tag_array, io.ic_debug_wr_data(0), ic_valid) val ic_valid_ff = withClock(io.free_clk) { RegNext(ic_valid_w_debug, false.B) } val tag_valid_clken = (0 until (ICACHE_TAG_DEPTH / 32)).map(i => (0 until ICACHE_NUM_WAYS).map(j => if (ICACHE_TAG_DEPTH == 32) ifu_tag_wren_ff(j) | perr_err_inv_way(j) | reset_all_tags else ((ifu_ic_rw_int_addr_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 5) === i.U) & ifu_tag_wren_ff(j)) | ((perr_ic_index_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 5) === i.U) & perr_err_inv_way(j)) | reset_all_tags).reverse.reduce(Cat(_, _))) val tag_valid_clk = (0 until ICACHE_TAG_DEPTH / 32).map(i => (0 until ICACHE_NUM_WAYS).map(j => rvclkhdr(clock, tag_valid_clken(i)(j), io.scan_mode))) val ic_tag_valid_out = Wire(Vec(ICACHE_NUM_WAYS, Vec(ICACHE_TAG_DEPTH, Bool()))) // io.valids := Cat((0 until ICACHE_TAG_DEPTH).map(i=>ic_tag_valid_out(1)(i).asUInt()).reverse.reduce(Cat(_,_)), // (0 until ICACHE_TAG_DEPTH).map(i=>ic_tag_valid_out(0)(i).asUInt()).reverse.reduce(Cat(_,_))) for (i <- 0 until (ICACHE_TAG_DEPTH / 32); j <- 0 until ICACHE_NUM_WAYS; k <- 0 until 32) ic_tag_valid_out(j)((32 * i) + k) := withClock(tag_valid_clk(i)(j)){RegEnable(ic_valid_ff & !reset_all_tags.asBool & !perr_sel_invalidate, false.B, ((((ifu_ic_rw_int_addr_ff === (k + (32 * i)).U) & ifu_tag_wren_ff(j)) | ((perr_ic_index_ff === (k + (32 * i)).U) & perr_err_inv_way(j)) | reset_all_tags)).asBool)} val ic_tag_valid_unq = (0 until ICACHE_NUM_WAYS).map(k => (0 until ICACHE_TAG_DEPTH).map(j => Mux(ifu_ic_rw_int_addr_ff === j.U, ic_tag_valid_out(k)(j), false.B).asUInt).reduce(_|_)).reverse.reduce(Cat(_,_)) // Making a sudo LRU // val replace_way_mb_any = Wire(Vec(ICACHE_NUM_WAYS, Bool())) val way_status_hit_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) if (ICACHE_NUM_WAYS == 4) { replace_way_mb_any(3) := (way_status_mb_ff(2) & way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) | (!tagv_mb_ff(3) & tagv_mb_ff(2) & tagv_mb_ff(1) & tagv_mb_ff(0)) replace_way_mb_any(2) := (!way_status_mb_ff(2) & way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) | (!tagv_mb_ff(2) & tagv_mb_ff(1) & tagv_mb_ff(0)) replace_way_mb_any(1) := (way_status_mb_ff(1) & !way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) | (!tagv_mb_ff(1) & tagv_mb_ff(0)) replace_way_mb_any(0) := (!way_status_mb_ff(1) & !way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) | !tagv_mb_ff(0) way_status_hit_new := Mux1H(Seq(io.ic_rd_hit(0) -> Cat(way_status(2), 3.U), io.ic_rd_hit(1) -> Cat(way_status(2), 1.U(2.W)), io.ic_rd_hit(2) -> Cat(1.U, way_status(1), 0.U), io.ic_rd_hit(3) -> Cat(0.U, way_status(1), 0.U))) way_status_rep_new := Mux1H(Seq(io.ic_rd_hit(0) -> Cat(way_status_mb_ff(2), 3.U), io.ic_rd_hit(1) -> Cat(way_status_mb_ff(2), 1.U(2.W)), io.ic_rd_hit(2) -> Cat(1.U, way_status_mb_ff(1), 0.U), io.ic_rd_hit(3) -> Cat(0.U, way_status_mb_ff(1), 0.U))) } else { replace_way_mb_any(0) := (!way_status_mb_ff & tagv_mb_ff(0) & tagv_mb_ff(1)) | !tagv_mb_ff(0) replace_way_mb_any(1) := (way_status_mb_ff & tagv_mb_ff(0) & tagv_mb_ff(1)) | !tagv_mb_ff(1) & tagv_mb_ff(0) way_status_hit_new := io.ic_rd_hit(0) way_status_rep_new := replace_way_mb_any(0) } way_status_new := Mux((bus_ifu_wr_en_ff_q & last_beat).asBool, way_status_rep_new, way_status_hit_new) way_status_wr_en := (bus_ifu_wr_en_ff_q & last_beat) | ic_act_hit_f val bus_wren = (0 until ICACHE_NUM_WAYS).map(i => bus_ifu_wr_en_ff_q & replace_way_mb_any(i) & miss_pending) val bus_wren_last = (0 until ICACHE_NUM_WAYS).map(i => bus_ifu_wr_en_ff_wo_err & replace_way_mb_any(i) & miss_pending & bus_last_data_beat) val wren_reset_miss = (0 until ICACHE_NUM_WAYS).map(i => replace_way_mb_any(i) & reset_tag_valid_for_miss) ifu_tag_wren := (0 until ICACHE_NUM_WAYS).map(i => bus_wren_last(i) | wren_reset_miss(i)).reverse.reduce(Cat(_, _)) bus_ic_wr_en := bus_wren.reverse.reduce(Cat(_,_)) if(!ICACHE_ENABLE){ for(i<- 0 until ICACHE_NUM_WAYS){ bus_wren(i) := 0.U } ic_tag_valid_unq := 0.U way_status := 0.U replace_way_mb_any := 0.U way_status_hit_new := 0.U way_status_rep_new := 0.U way_status_new := 0.U way_status_wr_en := 0.U } io.ic_tag_valid := ic_tag_valid_unq & Fill(ICACHE_NUM_WAYS, !fetch_uncacheable_ff & ifc_fetch_req_f) val ic_debug_way_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) ic_debug_tag_val_rd_out := (ic_tag_valid_unq & (ic_debug_way_ff & Fill(ICACHE_NUM_WAYS, ic_debug_rd_en_ff))).orR() io.ifu_pmu_ic_miss := withClock(io.active_clk){RegNext(ic_act_miss_f, false.B)} io.ifu_pmu_ic_hit := withClock(io.active_clk){RegNext(ic_act_hit_f, false.B)} io.ifu_pmu_bus_error := withClock(io.active_clk){RegNext(ifc_bus_acc_fault_f, false.B)} io.ifu_pmu_bus_busy := withClock(io.active_clk){RegNext(ifu_bus_arvalid_ff & !ifu_bus_arready_ff & miss_pending, false.B)} io.ifu_pmu_bus_trxn := withClock(io.active_clk){RegNext(bus_cmd_sent, false.B)} io.ic_debug_addr := io.dec_tlu_ic_diag_pkt.icache_dicawics io.ic_debug_tag_array := io.dec_tlu_ic_diag_pkt.icache_dicawics(16) io.ic_debug_rd_en := io.dec_tlu_ic_diag_pkt.icache_rd_valid io.ic_debug_wr_en := io.dec_tlu_ic_diag_pkt.icache_wr_valid io.ic_debug_way := Cat(io.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===3.U, io.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===2.U, io.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===1.U, io.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===0.U) ic_debug_tag_wr_en := Fill(ICACHE_NUM_WAYS, io.ic_debug_wr_en & io.ic_debug_tag_array) & io.ic_debug_way val ic_debug_ict_array_sel_in = io.ic_debug_rd_en & io.ic_debug_tag_array ic_debug_way_ff := withClock(debug_c1_clk){RegNext(io.ic_debug_way, 0.U)} ic_debug_ict_array_sel_ff := withClock(debug_c1_clk){RegNext(ic_debug_ict_array_sel_in, 0.U)} ic_debug_rd_en_ff := withClock(io.free_clk){RegNext(io.ic_debug_rd_en, false.B)} io.ifu_ic_debug_rd_data_valid := withClock(io.free_clk){RegEnable(ic_debug_rd_en_ff, 0.U, ic_debug_rd_en_ff.asBool)} val ifc_region_acc_okay = Cat(INST_ACCESS_ENABLE0.U,INST_ACCESS_ENABLE1.U,INST_ACCESS_ENABLE2.U,INST_ACCESS_ENABLE3.U,INST_ACCESS_ENABLE4.U,INST_ACCESS_ENABLE5.U,INST_ACCESS_ENABLE6.U,INST_ACCESS_ENABLE7.U).orR() | INST_ACCESS_ENABLE0.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK0).U) === (aslong(INST_ACCESS_ADDR0).U | aslong(INST_ACCESS_MASK0).U)) | INST_ACCESS_ENABLE1.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK1).U) === (aslong(INST_ACCESS_ADDR1).U | aslong(INST_ACCESS_MASK1).U)) | INST_ACCESS_ENABLE2.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK2).U) === (aslong(INST_ACCESS_ADDR2).U | aslong(INST_ACCESS_MASK2).U)) | INST_ACCESS_ENABLE3.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK3).U) === (aslong(INST_ACCESS_ADDR3).U | aslong(INST_ACCESS_MASK3).U)) | INST_ACCESS_ENABLE4.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK4).U) === (aslong(INST_ACCESS_ADDR4).U | aslong(INST_ACCESS_MASK4).U)) | INST_ACCESS_ENABLE5.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK5).U) === (aslong(INST_ACCESS_ADDR5).U | aslong(INST_ACCESS_MASK5).U)) | INST_ACCESS_ENABLE6.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK6).U) === (aslong(INST_ACCESS_ADDR6).U | aslong(INST_ACCESS_MASK6).U)) | INST_ACCESS_ENABLE7.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK7).U) === (aslong(INST_ACCESS_ADDR7).U | aslong(INST_ACCESS_MASK7).U)) val ifc_region_acc_fault_memory_bf = !io.ifc_iccm_access_bf & !ifc_region_acc_okay & io.ifc_fetch_req_bf ifc_region_acc_fault_final_bf := io.ifc_region_acc_fault_bf | ifc_region_acc_fault_memory_bf ifc_region_acc_fault_memory_f := withClock(io.free_clk){RegNext(ifc_region_acc_fault_memory_bf, false.B)} } object ifu_mem extends App { println((new chisel3.stage.ChiselStage).emitVerilog(new el2_ifu_mem_ctl())) }