BP added
This commit is contained in:
parent
5ac08982de
commit
ed92fad092
|
@ -0,0 +1,158 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_hist1_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_inst_mask_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_hit_taken_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_bpred_disable",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_hist0_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_btb_target_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_hit_taken_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_bpred_disable",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_pc4_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_valid_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_bpred_disable",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_ret_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_way_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_mp_index",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_mp_btag",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_mp_pkt_bits_misp",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_poffset_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.CombinationalPath",
|
||||||
|
"sink":"~ifu_bp_ctl|ifu_bp_ctl>io_ifu_bp_hit_taken_f",
|
||||||
|
"sources":[
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_bpred_disable",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_req_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_ifc_fetch_addr_f",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_flush_leak_one_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_tlu_flush_lower_wb",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_way",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_start_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_dec_bp_dec_tlu_br0_r_pkt_bits_br_error",
|
||||||
|
"~ifu_bp_ctl|ifu_bp_ctl>io_exu_bp_exu_i0_br_index_r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.EmitCircuitAnnotation",
|
||||||
|
"emitter":"firrtl.VerilogEmitter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.BlackBoxResourceAnno",
|
||||||
|
"target":"ifu_bp_ctl.gated_latch",
|
||||||
|
"resourceId":"/vsrc/gated_latch.sv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.options.TargetDirAnnotation",
|
||||||
|
"directory":"."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.options.OutputAnnotationFileAnnotation",
|
||||||
|
"file":"ifu_bp_ctl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class":"firrtl.transforms.BlackBoxTargetDirAnno",
|
||||||
|
"targetDir":"."
|
||||||
|
}
|
||||||
|
]
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -17,6 +17,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val dec_bp = new dec_bp()
|
val dec_bp = new dec_bp()
|
||||||
val dec_tlu_flush_lower_wb = Input(Bool())
|
val dec_tlu_flush_lower_wb = Input(Bool())
|
||||||
val exu_bp = Flipped(new exu_bp())
|
val exu_bp = Flipped(new exu_bp())
|
||||||
|
val dec_fa_error_index = Input(UInt(log2Ceil(BTB_SIZE).W))// Fully associative btb error index
|
||||||
val ifu_bp_hit_taken_f = Output(Bool())
|
val ifu_bp_hit_taken_f = Output(Bool())
|
||||||
val ifu_bp_btb_target_f = Output(UInt(31.W))
|
val ifu_bp_btb_target_f = Output(UInt(31.W))
|
||||||
val ifu_bp_inst_mask_f = Output(Bool())
|
val ifu_bp_inst_mask_f = Output(Bool())
|
||||||
|
@ -28,10 +29,19 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val ifu_bp_pc4_f = Output(UInt(2.W))
|
val ifu_bp_pc4_f = Output(UInt(2.W))
|
||||||
val ifu_bp_valid_f = Output(UInt(2.W))
|
val ifu_bp_valid_f = Output(UInt(2.W))
|
||||||
val ifu_bp_poffset_f = Output(UInt(12.W))
|
val ifu_bp_poffset_f = Output(UInt(12.W))
|
||||||
|
val ifu_bp_fa_index_f = Output(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))// predicted branch index (fully associative option)
|
||||||
val scan_mode = Input(Bool())
|
val scan_mode = Input(Bool())
|
||||||
})
|
})
|
||||||
|
io.ifu_bp_fa_index_f := io.ifu_bp_fa_index_f.map(i=> 0.U)
|
||||||
|
val BTB_DWIDTH = BTB_TOFFSET_SIZE+ BTB_BTAG_SIZE + 5
|
||||||
|
val BTB_DWIDTH_TOP = BTB_TOFFSET_SIZE + BTB_BTAG_SIZE + 4
|
||||||
|
val BTB_FA_INDEX = log2Ceil(BTB_SIZE) - 1
|
||||||
|
val FA_CMP_LOWER = log2Ceil(ICACHE_LN_SZ)
|
||||||
|
val FA_TAG_END_UPPER = 5 + BTB_TOFFSET_SIZE + FA_CMP_LOWER - 1 // must cast to int or vcs build fails
|
||||||
|
val FA_TAG_START_LOWER =3 + BTB_TOFFSET_SIZE + FA_CMP_LOWER
|
||||||
|
val FA_TAG_END_LOWER = 5 + BTB_TOFFSET_SIZE
|
||||||
|
|
||||||
val TAG_START = 16+BTB_BTAG_SIZE
|
val TAG_START = BTB_DWIDTH - 1
|
||||||
val PC4 = 4 // Branch = pc + 4 (BTB Index)
|
val PC4 = 4 // Branch = pc + 4 (BTB Index)
|
||||||
val BOFF = 3 // Branch offset (BTB Index)
|
val BOFF = 3 // Branch offset (BTB Index)
|
||||||
val CALL = 2 // Branch CALL (BTB Index)
|
val CALL = 2 // Branch CALL (BTB Index)
|
||||||
|
@ -45,16 +55,28 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val BHT_NO_ADDR_MATCH = BHT_ARRAY_DEPTH <= 16
|
val BHT_NO_ADDR_MATCH = BHT_ARRAY_DEPTH <= 16
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
val leak_one_f = WireInit(Bool(), 0.U)
|
val leak_one_f = WireInit(Bool(), 0.U)
|
||||||
|
val leak_one_f_d1 = WireInit(Bool(), 0.U)
|
||||||
val bht_dir_f = WireInit(UInt(2.W), 0.U)
|
val bht_dir_f = WireInit(UInt(2.W), 0.U)
|
||||||
val dec_tlu_error_wb = WireInit(Bool(), 0.U)
|
val dec_tlu_error_wb = WireInit(Bool(), 0.U)
|
||||||
val btb_error_addr_wb = WireInit(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W), 0.U)
|
val btb_error_addr_wb = WireInit(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W), 0.U)
|
||||||
val btb_bank0_rd_data_way0_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
|
||||||
val btb_bank0_rd_data_way1_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
val btb_vbank0_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||||
val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
val btb_vbank1_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||||
val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
val btb_bank0_rd_data_way0_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||||
|
val btb_bank0_rd_data_way1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||||
|
val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||||
|
val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||||
val eoc_mask = WireInit(Bool(), 0.U)
|
val eoc_mask = WireInit(Bool(), 0.U)
|
||||||
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 0.U)
|
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 0.U)
|
||||||
val dec_tlu_way_wb = WireInit(Bool(), 0.U)
|
val dec_tlu_way_wb = WireInit(Bool(), 0.U)
|
||||||
|
|
||||||
|
val btb_vlru_rd_f = WireInit(UInt(2.W), 0.U)
|
||||||
|
val vwayhit_f = WireInit(UInt(2.W), 0.U)
|
||||||
|
val tag_match_vway1_expanded_f = WireInit(UInt(2.W), 0.U)
|
||||||
|
val wayhit_f = WireInit(UInt(2.W), 0.U)
|
||||||
|
val wayhit_p1_f = WireInit(UInt(2.W), 0.U)
|
||||||
|
val way_raw = WireInit(UInt(2.W), 0.U)
|
||||||
|
val exu_flush_final_d1 = WireInit(Bool(), 0.U)
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// Misprediction packet
|
// Misprediction packet
|
||||||
val exu_mp_valid = io.exu_bp.exu_mp_pkt.bits.misp & !leak_one_f
|
val exu_mp_valid = io.exu_bp.exu_mp_pkt.bits.misp & !leak_one_f
|
||||||
|
@ -68,6 +90,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val exu_mp_tgt = io.exu_bp.exu_mp_pkt.bits.toffset
|
val exu_mp_tgt = io.exu_bp.exu_mp_pkt.bits.toffset
|
||||||
val exu_mp_addr = io.exu_bp.exu_mp_index
|
val exu_mp_addr = io.exu_bp.exu_mp_index
|
||||||
val exu_mp_ataken = io.exu_bp.exu_mp_pkt.bits.ataken
|
val exu_mp_ataken = io.exu_bp.exu_mp_pkt.bits.ataken
|
||||||
|
val exu_mp_way_f = WireInit(Bool(), 0.U)
|
||||||
|
|
||||||
// Its a commit or update packet
|
// Its a commit or update packet
|
||||||
val dec_tlu_br0_v_wb = io.dec_bp.dec_tlu_br0_r_pkt.valid
|
val dec_tlu_br0_v_wb = io.dec_bp.dec_tlu_br0_r_pkt.valid
|
||||||
|
@ -107,36 +130,30 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val branch_error_bank_conflict_p1_f = branch_error_collision_p1_f & dec_tlu_error_wb
|
val branch_error_bank_conflict_p1_f = branch_error_collision_p1_f & dec_tlu_error_wb
|
||||||
|
|
||||||
// Hashing the PC to generate the index for the btb
|
// Hashing the PC to generate the index for the btb
|
||||||
val fetch_rd_tag_f = if(BTB_BTAG_FOLD) btb_tag_hash_fold(io.ifc_fetch_addr_f) else btb_tag_hash(io.ifc_fetch_addr_f)
|
|
||||||
val fetch_rd_tag_p1_f = if(BTB_BTAG_FOLD) btb_tag_hash_fold(Cat(fetch_addr_p1_f,0.U)) else btb_tag_hash(Cat(fetch_addr_p1_f,0.U))
|
|
||||||
|
|
||||||
// There is a misprediction and the exu is writing back
|
|
||||||
val fetch_mp_collision_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_f)
|
|
||||||
val fetch_mp_collision_p1_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
|
|
||||||
|
|
||||||
val leak_one_f_d1 = withClock(io.active_clk) {RegNext(leak_one_f, init = 0.U)}
|
|
||||||
val dec_tlu_way_wb_f = withClock(io.active_clk) {RegNext(dec_tlu_way_wb, init = 0.U)}
|
|
||||||
val exu_mp_way_f = withClock(io.active_clk) {RegNext(exu_mp_way, init = 0.U)}
|
|
||||||
val exu_flush_final_d1 = withClock(io.active_clk) {RegNext(io.exu_flush_final, init = 0.U)}
|
|
||||||
|
|
||||||
// If there is a flush from the lower pipe wait until the flush gets deasserted from the (decode) side
|
// If there is a flush from the lower pipe wait until the flush gets deasserted from the (decode) side
|
||||||
leak_one_f := (io.dec_bp.dec_tlu_flush_leak_one_wb & io.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & !io.dec_tlu_flush_lower_wb)
|
leak_one_f := (io.dec_bp.dec_tlu_flush_leak_one_wb & io.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & !io.dec_tlu_flush_lower_wb)
|
||||||
|
if(!BTB_FULLYA) {
|
||||||
|
val fetch_rd_tag_f = if (BTB_BTAG_FOLD) btb_tag_hash_fold(io.ifc_fetch_addr_f) else btb_tag_hash(io.ifc_fetch_addr_f)
|
||||||
|
val fetch_rd_tag_p1_f = if (BTB_BTAG_FOLD) btb_tag_hash_fold(Cat(fetch_addr_p1_f, 0.U)) else btb_tag_hash(Cat(fetch_addr_p1_f, 0.U))
|
||||||
|
// There is a misprediction and the exu is writing back
|
||||||
|
val fetch_mp_collision_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_f)
|
||||||
|
val fetch_mp_collision_p1_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
|
||||||
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
|
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
|
||||||
// Also there should be no bank conflict or leak-one
|
// Also there should be no bank conflict or leak-one
|
||||||
val tag_match_way0_f = btb_bank0_rd_data_way0_f(BV) & (btb_bank0_rd_data_way0_f(TAG_START,17) === fetch_rd_tag_f) &
|
val tag_match_way0_f = btb_bank0_rd_data_way0_f(BV) & (btb_bank0_rd_data_way0_f(TAG_START, 17) === fetch_rd_tag_f) &
|
||||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
!(dec_tlu_way_wb & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
// Similar to the way-0 -> way-1
|
// Similar to the way-0 -> way-1
|
||||||
val tag_match_way1_f = btb_bank0_rd_data_way1_f(BV) & (btb_bank0_rd_data_way1_f(TAG_START,17) === fetch_rd_tag_f) &
|
val tag_match_way1_f = btb_bank0_rd_data_way1_f(BV) & (btb_bank0_rd_data_way1_f(TAG_START, 17) === fetch_rd_tag_f) &
|
||||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
!(dec_tlu_way_wb & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
// Similar to above matches
|
// Similar to above matches
|
||||||
val tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f(BV) & (btb_bank0_rd_data_way0_p1_f(TAG_START,17) === fetch_rd_tag_p1_f) &
|
val tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f(BV) & (btb_bank0_rd_data_way0_p1_f(TAG_START, 17) === fetch_rd_tag_p1_f) &
|
||||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
!(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
// Similar to above matches
|
// Similar to above matches
|
||||||
val tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f(BV) & (btb_bank0_rd_data_way1_p1_f(TAG_START,17) === fetch_rd_tag_p1_f) &
|
val tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f(BV) & (btb_bank0_rd_data_way1_p1_f(TAG_START, 17) === fetch_rd_tag_p1_f) &
|
||||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
!(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
// Reordering to avoid multiple hit
|
// Reordering to avoid multiple hit
|
||||||
val tag_match_way0_expanded_f = Cat(tag_match_way0_f & (btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)),
|
val tag_match_way0_expanded_f = Cat(tag_match_way0_f & (btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)),
|
||||||
|
@ -152,27 +169,29 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
|
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
|
||||||
|
|
||||||
// Final hit calculation
|
// Final hit calculation
|
||||||
val wayhit_f = tag_match_way0_expanded_f | tag_match_way1_expanded_f
|
wayhit_f := tag_match_way0_expanded_f | tag_match_way1_expanded_f
|
||||||
|
|
||||||
val wayhit_p1_f = tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
|
wayhit_p1_f := tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
|
||||||
|
|
||||||
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
|
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
|
||||||
// e-> Lower half o-> Upper half
|
// e-> Lower half o-> Upper half
|
||||||
val btb_bank0e_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(0).asBool->btb_bank0_rd_data_way0_f,
|
val btb_bank0e_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(0).asBool -> btb_bank0_rd_data_way0_f,
|
||||||
tag_match_way1_expanded_f(0).asBool->btb_bank0_rd_data_way1_f))
|
tag_match_way1_expanded_f(0).asBool -> btb_bank0_rd_data_way1_f))
|
||||||
|
|
||||||
val btb_bank0o_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(1).asBool->btb_bank0_rd_data_way0_f,
|
val btb_bank0o_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(1).asBool -> btb_bank0_rd_data_way0_f,
|
||||||
tag_match_way1_expanded_f(1).asBool->btb_bank0_rd_data_way1_f))
|
tag_match_way1_expanded_f(1).asBool -> btb_bank0_rd_data_way1_f))
|
||||||
|
|
||||||
val btb_bank0e_rd_data_p1_f = Mux1H(Seq(tag_match_way0_expanded_p1_f(0).asBool->btb_bank0_rd_data_way0_p1_f,
|
val btb_bank0e_rd_data_p1_f = Mux1H(Seq(tag_match_way0_expanded_p1_f(0).asBool -> btb_bank0_rd_data_way0_p1_f,
|
||||||
tag_match_way1_expanded_p1_f(0).asBool->btb_bank0_rd_data_way1_p1_f))
|
tag_match_way1_expanded_p1_f(0).asBool -> btb_bank0_rd_data_way1_p1_f))
|
||||||
|
|
||||||
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank
|
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank
|
||||||
// and the upper half of the bank-0 in vbank 1
|
// and the upper half of the bank-0 in vbank 1
|
||||||
val btb_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_f,
|
val btb_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> btb_bank0e_rd_data_f,
|
||||||
io.ifc_fetch_addr_f(0)->btb_bank0o_rd_data_f))
|
io.ifc_fetch_addr_f(0) -> btb_bank0o_rd_data_f))
|
||||||
val btb_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0)->btb_bank0o_rd_data_f,
|
val btb_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> btb_bank0o_rd_data_f,
|
||||||
io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_p1_f))
|
io.ifc_fetch_addr_f(0) -> btb_bank0e_rd_data_p1_f))
|
||||||
|
|
||||||
|
way_raw := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
|
||||||
|
|
||||||
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
|
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
|
||||||
// Cases
|
// Cases
|
||||||
|
@ -199,9 +218,6 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
// Checking if the mis-prediction was valid or not and make a new LRU value
|
// Checking if the mis-prediction was valid or not and make a new LRU value
|
||||||
val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
|
val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
|
||||||
|
|
||||||
val vwayhit_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->wayhit_f,
|
|
||||||
io.ifc_fetch_addr_f(0).asBool->Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
|
|
||||||
|
|
||||||
// Is the update of the lru valid or not
|
// Is the update of the lru valid or not
|
||||||
val lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
|
val lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
|
@ -215,7 +231,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val use_mp_way_p1 = fetch_mp_collision_p1_f
|
val use_mp_way_p1 = fetch_mp_collision_p1_f
|
||||||
|
|
||||||
// Calculate the lru next value and flop it
|
// Calculate the lru next value and flop it
|
||||||
val btb_lru_b0_ns : UInt = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
|
val btb_lru_b0_ns: UInt = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
|
||||||
tag_match_way0_f.asBool -> fetch_wrlru_b0,
|
tag_match_way0_f.asBool -> fetch_wrlru_b0,
|
||||||
tag_match_way0_p1_f.asBool -> fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
|
tag_match_way0_p1_f.asBool -> fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
|
||||||
|
|
||||||
|
@ -225,17 +241,17 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val btb_lru_rd_p1_f = Mux(use_mp_way_p1.asBool, exu_mp_way_f, (fetch_wrindex_p1_dec & btb_lru_b0_f).orR)
|
val btb_lru_rd_p1_f = Mux(use_mp_way_p1.asBool, exu_mp_way_f, (fetch_wrindex_p1_dec & btb_lru_b0_f).orR)
|
||||||
|
|
||||||
// Similar to the vbank make vlru
|
// Similar to the vbank make vlru
|
||||||
val btb_vlru_rd_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
|
btb_vlru_rd_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
|
||||||
io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
|
io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
|
||||||
|
|
||||||
// virtual way depending on pc value
|
// virtual way depending on pc value
|
||||||
val tag_match_vway1_expanded_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->tag_match_way1_expanded_f,
|
tag_match_vway1_expanded_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool -> tag_match_way1_expanded_f,
|
||||||
io.ifc_fetch_addr_f(0).asBool->Cat(tag_match_way1_expanded_p1_f(0),tag_match_way1_expanded_f(1))))
|
io.ifc_fetch_addr_f(0).asBool -> Cat(tag_match_way1_expanded_p1_f(0), tag_match_way1_expanded_f(1))))
|
||||||
|
|
||||||
io.ifu_bp_way_f := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
|
|
||||||
|
|
||||||
// update the lru
|
|
||||||
btb_lru_b0_f := rvdffe(btb_lru_b0_ns, (io.ifc_fetch_req_f|exu_mp_valid).asBool, clock, io.scan_mode)
|
btb_lru_b0_f := rvdffe(btb_lru_b0_ns, (io.ifc_fetch_req_f|exu_mp_valid).asBool, clock, io.scan_mode)
|
||||||
|
}
|
||||||
|
io.ifu_bp_way_f := way_raw
|
||||||
|
// update the lru
|
||||||
//io.test := btb_lru_b0_ns
|
//io.test := btb_lru_b0_ns
|
||||||
// Checking if the end of line is near
|
// Checking if the end of line is near
|
||||||
val eoc_near = io.ifc_fetch_addr_f(ICACHE_BEAT_ADDR_HI-1, 2).andR
|
val eoc_near = io.ifc_fetch_addr_f(ICACHE_BEAT_ADDR_HI-1, 2).andR
|
||||||
|
@ -319,8 +335,11 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
fghr_ns := Mux1H(Seq(exu_flush_final_d1.asBool->exu_flush_ghr,
|
fghr_ns := Mux1H(Seq(exu_flush_final_d1.asBool->exu_flush_ghr,
|
||||||
(!exu_flush_final_d1 & io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1).asBool -> merged_ghr,
|
(!exu_flush_final_d1 & io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1).asBool -> merged_ghr,
|
||||||
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr))
|
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr))
|
||||||
|
leak_one_f_d1 := rvdffie(leak_one_f,clock,reset.asAsyncReset(),io.scan_mode)
|
||||||
fghr := withClock(io.active_clk) {RegNext(fghr_ns, init = 0.U)}
|
//val dec_tlu_way_wb_f = withClock(io.active_clk) {RegNext(dec_tlu_way_wb, init = 0.U)
|
||||||
|
exu_mp_way_f := rvdffie(exu_mp_way,clock,reset.asAsyncReset(),io.scan_mode)
|
||||||
|
exu_flush_final_d1 := rvdffie(io.exu_flush_final,clock,reset.asAsyncReset(),io.scan_mode)
|
||||||
|
fghr := rvdffie(fghr_ns,clock,reset.asAsyncReset(),io.scan_mode)
|
||||||
|
|
||||||
io.ifu_bp_fghr_f := fghr
|
io.ifu_bp_fghr_f := fghr
|
||||||
io.ifu_bp_hist1_f := hist1_raw
|
io.ifu_bp_hist1_f := hist1_raw
|
||||||
|
@ -339,7 +358,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val btb_fg_crossing_f = fetch_start_f(0) & btb_sel_f(0) & btb_rd_pc4_f
|
val btb_fg_crossing_f = fetch_start_f(0) & btb_sel_f(0) & btb_rd_pc4_f
|
||||||
val bp_total_branch_offset_f = bloc_f(1)^btb_rd_pc4_f
|
val bp_total_branch_offset_f = bloc_f(1)^btb_rd_pc4_f
|
||||||
|
|
||||||
val ifc_fetch_adder_prior = rvdffe(io.ifc_fetch_addr_f(30,1), (io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool, clock, io.scan_mode)
|
val ifc_fetch_adder_prior = rvdfflie_UInt(io.ifc_fetch_addr_f(30,1), clock,reset.asAsyncReset,(io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool,io.scan_mode,WIDTH =30, LEFT =19 )
|
||||||
|
|
||||||
io.ifu_bp_poffset_f := btb_rd_tgt_f
|
io.ifu_bp_poffset_f := btb_rd_tgt_f
|
||||||
|
|
||||||
|
@ -352,10 +371,9 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
|
|
||||||
val rets_out = Wire(Vec(RET_STACK_SIZE, UInt(32.W)))
|
val rets_out = Wire(Vec(RET_STACK_SIZE, UInt(32.W)))
|
||||||
rets_out := (0 until RET_STACK_SIZE).map(i=>0.U)
|
rets_out := (0 until RET_STACK_SIZE).map(i=>0.U)
|
||||||
|
|
||||||
// Final target if its a RET then pop else take the target pc
|
// Final target if its a RET then pop else take the target pc
|
||||||
io.ifu_bp_btb_target_f := Mux((btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)).asBool,
|
io.ifu_bp_btb_target_f := ((Fill(31,(btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0) & io.ifu_bp_hit_taken_f)) & rets_out(0)(31,1)) |
|
||||||
rets_out(0)(31,1),bp_btb_target_adder_f(31,1))
|
(Fill(31,(!btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0) & io.ifu_bp_hit_taken_f)) & bp_btb_target_adder_f(31,1)))
|
||||||
|
|
||||||
// Return stack
|
// Return stack
|
||||||
val bp_rs_call_target_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(Fill(11, 0.U),~btb_rd_pc4_f, 0.U))
|
val bp_rs_call_target_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(Fill(11, 0.U),~btb_rd_pc4_f, 0.U))
|
||||||
|
@ -365,7 +383,6 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val rs_hold = !rs_push & !rs_pop
|
val rs_hold = !rs_push & !rs_pop
|
||||||
|
|
||||||
val rsenable = (0 until RET_STACK_SIZE).map(i=> if(i==0) !rs_hold else if(i==RET_STACK_SIZE-1) rs_push else rs_push | rs_pop)
|
val rsenable = (0 until RET_STACK_SIZE).map(i=> if(i==0) !rs_hold else if(i==RET_STACK_SIZE-1) rs_push else rs_push | rs_pop)
|
||||||
|
|
||||||
// Make the input of the RAS
|
// Make the input of the RAS
|
||||||
val rets_in = (0 until RET_STACK_SIZE).map(i=> if(i==0)
|
val rets_in = (0 until RET_STACK_SIZE).map(i=> if(i==0)
|
||||||
Mux1H(Seq(rs_push.asBool -> Cat(bp_rs_call_target_f(31,1),1.U),
|
Mux1H(Seq(rs_push.asBool -> Cat(bp_rs_call_target_f(31,1),1.U),
|
||||||
|
@ -380,16 +397,20 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
val btb_valid = exu_mp_valid & (!dec_tlu_error_wb)
|
val btb_valid = exu_mp_valid & (!dec_tlu_error_wb)
|
||||||
val btb_wr_tag = io.exu_bp.exu_mp_btag
|
val btb_wr_tag = io.exu_bp.exu_mp_btag
|
||||||
|
|
||||||
|
// if(BTB_FULLYA) {
|
||||||
|
// // Enable for write on each way
|
||||||
|
// val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
|
||||||
|
// val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
|
||||||
|
//
|
||||||
|
// // Writing is always done from dec or exu check if the dec have a valid data
|
||||||
|
// val btb_wr_addr = Mux(dec_tlu_error_wb.asBool, btb_error_addr_wb, exu_mp_addr)
|
||||||
|
// vwayhit_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool -> wayhit_f,
|
||||||
|
// io.ifc_fetch_addr_f(0).asBool -> Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
|
||||||
|
// }
|
||||||
|
|
||||||
// Making the data to write into the BTB according the structure discribed above
|
// Making the data to write into the BTB according the structure discribed above
|
||||||
val btb_wr_data = Cat(btb_wr_tag, exu_mp_tgt, exu_mp_pc4, exu_mp_boffset, exu_mp_call | exu_mp_ja, exu_mp_ret | exu_mp_ja, btb_valid)
|
val btb_wr_data = Cat(btb_wr_tag, exu_mp_tgt, exu_mp_pc4, exu_mp_boffset, exu_mp_call | exu_mp_ja, exu_mp_ret | exu_mp_ja, btb_valid)
|
||||||
val exu_mp_valid_write = exu_mp_valid & exu_mp_ataken
|
val exu_mp_valid_write = exu_mp_valid & exu_mp_ataken & !io.exu_bp.exu_mp_pkt.valid
|
||||||
|
|
||||||
// Enable for write on each way
|
|
||||||
val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
|
|
||||||
val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
|
|
||||||
|
|
||||||
// Writing is always done from dec or exu check if the dec have a valid data
|
|
||||||
val btb_wr_addr = Mux(dec_tlu_error_wb.asBool , btb_error_addr_wb, exu_mp_addr)
|
|
||||||
val middle_of_bank = exu_mp_pc4 ^ exu_mp_boffset
|
val middle_of_bank = exu_mp_pc4 ^ exu_mp_boffset
|
||||||
|
|
||||||
// Enable the clk enable according to the exu misprediction where it is not a RAS
|
// Enable the clk enable according to the exu misprediction where it is not a RAS
|
||||||
|
@ -411,19 +432,86 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
|
|
||||||
// BTB
|
// BTB
|
||||||
// Entry -> Tag[BTB-BTAG-SIZE], toffset[12], pc4, boffset, call, ret, valid
|
// Entry -> Tag[BTB-BTAG-SIZE], toffset[12], pc4, boffset, call, ret, valid
|
||||||
|
if(!BTB_FULLYA) {
|
||||||
|
// Enable for write on each way
|
||||||
|
val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
|
||||||
|
val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
|
||||||
|
|
||||||
val btb_bank0_rd_data_way0_out = (0 until LRU_SIZE).map(i=>rvdffe(btb_wr_data, ((btb_wr_addr===i.U) & btb_wr_en_way0).asBool, clock, io.scan_mode))
|
// Writing is always done from dec or exu check if the dec have a valid data
|
||||||
val btb_bank0_rd_data_way1_out = (0 until LRU_SIZE).map(i=>rvdffe(btb_wr_data, ((btb_wr_addr===i.U) & btb_wr_en_way1).asBool, clock, io.scan_mode))
|
val btb_wr_addr = Mux(dec_tlu_error_wb.asBool, btb_error_addr_wb, exu_mp_addr)
|
||||||
|
vwayhit_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool -> wayhit_f,
|
||||||
|
io.ifc_fetch_addr_f(0).asBool -> Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
|
||||||
|
val btb_bank0_rd_data_way0_out = (0 until LRU_SIZE).map(i => rvdffe(btb_wr_data, ((btb_wr_addr === i.U) & btb_wr_en_way0).asBool, clock, io.scan_mode))
|
||||||
|
val btb_bank0_rd_data_way1_out = (0 until LRU_SIZE).map(i => rvdffe(btb_wr_data, ((btb_wr_addr === i.U) & btb_wr_en_way1).asBool, clock, io.scan_mode))
|
||||||
|
|
||||||
btb_bank0_rd_data_way0_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_f===i.U).asBool->btb_bank0_rd_data_way0_out(i)))
|
btb_bank0_rd_data_way0_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_f === i.U).asBool -> btb_bank0_rd_data_way0_out(i)))
|
||||||
btb_bank0_rd_data_way1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_f===i.U).asBool->btb_bank0_rd_data_way1_out(i)))
|
btb_bank0_rd_data_way1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_f === i.U).asBool -> btb_bank0_rd_data_way1_out(i)))
|
||||||
|
|
||||||
// BTB read muxing
|
// BTB read muxing
|
||||||
btb_bank0_rd_data_way0_p1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_p1_f===i.U).asBool->btb_bank0_rd_data_way0_out(i)))
|
btb_bank0_rd_data_way0_p1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_p1_f === i.U).asBool -> btb_bank0_rd_data_way0_out(i)))
|
||||||
btb_bank0_rd_data_way1_p1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_p1_f===i.U).asBool->btb_bank0_rd_data_way1_out(i)))
|
btb_bank0_rd_data_way1_p1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_p1_f === i.U).asBool -> btb_bank0_rd_data_way1_out(i)))
|
||||||
|
}
|
||||||
|
if(BTB_FULLYA){
|
||||||
|
val fetch_mp_collision_f = WireInit(Bool(),init = false.B)
|
||||||
|
val fetch_mp_collision_p1_f = WireInit(Bool() ,init = false.B)
|
||||||
|
|
||||||
|
// Fully Associative tag hash uses bits 31:3. Bits 2:1 are the offset bits used for the 4 tag comp banks
|
||||||
|
// Full tag used to speed up lookup. There is one 31:3 cmp per entry, and 4 2:1 cmps per entry.
|
||||||
|
val ifc_fetch_addr_p1_f = io.ifc_fetch_addr_f(FA_CMP_LOWER-1,1) + 1.U
|
||||||
|
|
||||||
|
// val fetch_mp_collision_f = ((io.exu_bp.exu_mp_btag(BTB_BTAG_SIZE-1,0) === io.ifc_fetch_addr_f) & exu_mp_valid & io.ifc_fetch_req_f & ~io.exu_bp.exu_mp_pkt.bits.way)
|
||||||
|
// val fetch_mp_collision_p1_f = ( (io.exu_bp.exu_mp_btag(BTB_BTAG_SIZE-1,0) === Cat(io.ifc_fetch_addr_f(30,FA_CMP_LOWER), ifc_fetch_addr_p1_f(FA_CMP_LOWER-1,1))) & exu_mp_valid & io.ifc_fetch_req_f & ~io.exu_bp.exu_mp_pkt.bits.way)
|
||||||
|
// val btb_upper_hit = Wire(Vec(BTB_SIZE,Bool()))
|
||||||
|
val btb_offset_0 = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||||
|
val btb_used = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||||
|
val btb_offset_1 = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||||
|
val wr0_en = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||||
|
val btbdata = Wire(Vec(BTB_SIZE,UInt(BTB_DWIDTH.W)))
|
||||||
|
btbdata := btbdata.map(i=> 0.U)
|
||||||
|
val hit0 = WireInit(UInt(1.W) ,init = 0.U)
|
||||||
|
val hit1 = WireInit(UInt(1.W) ,init = 0.U)
|
||||||
|
|
||||||
|
// btb_upper_hit := (0 until BTB_SIZE).map(i=> ((btbdata(i)(BTB_DWIDTH_TOP,FA_TAG_END_UPPER) === io.ifc_fetch_addr_f(30,FA_CMP_LOWER)) & btbdata(i)(0) & ~wr0_en(i)))
|
||||||
|
// val btb_offset_0 = (0 until BTB_SIZE).map(i=> (btbdata(i)(FA_TAG_START_LOWER,FA_TAG_END_LOWER) === io.ifc_fetch_addr_f(FA_CMP_LOWER-1,1)) & btb_upper_hit(i))
|
||||||
|
// val btb_offset_1 = (0 until BTB_SIZE).map(i=> (btbdata(i)(FA_TAG_START_LOWER,FA_TAG_END_LOWER) === ifc_fetch_addr_p1_f(FA_CMP_LOWER-1,1)) & btb_upper_hit(i))
|
||||||
|
|
||||||
|
// hit unless we are also writing this entry at the same time
|
||||||
|
val hit0_index = MuxCase(1.U, (0 until BTB_SIZE).map(i=> btb_offset_0(i) -> i.U))
|
||||||
|
val hit1_index = MuxCase(1.U, (0 until BTB_SIZE).map(i=> btb_offset_1(i) -> i.U))
|
||||||
|
// Mux out the 2 potential branches
|
||||||
|
btb_vbank0_rd_data_f := (0 until BTB_SIZE ).map(i=> if(btb_offset_1(i) == 1) Mux(fetch_mp_collision_f,btb_wr_data,btbdata(i)) else 0.U ).reverse.reduce(Cat(_,_))
|
||||||
|
btb_vbank1_rd_data_f :=(0 until BTB_SIZE).map(i=> if(btb_offset_1(i) == 1) Mux(fetch_mp_collision_p1_f,btb_wr_data,btbdata(i)) else 0.U).reverse.reduce(Cat(_,_))
|
||||||
|
val btb_fa_wr_addr0 = MuxCase(1.U, (0 until BTB_SIZE).map(i=> !btb_used(i) -> i.U))
|
||||||
|
|
||||||
|
vwayhit_f := Cat(hit1,hit0) & Cat(eoc_mask,1.U)
|
||||||
|
way_raw := vwayhit_f | Cat(fetch_mp_collision_p1_f, fetch_mp_collision_f)
|
||||||
|
wr0_en := (0 until BTB_SIZE).map(i=> ((btb_fa_wr_addr0(BTB_FA_INDEX,0) === i.asUInt()) & (exu_mp_valid_write & ~io.exu_bp.exu_mp_pkt.bits.way)) |
|
||||||
|
((io.dec_fa_error_index === i.asUInt()) & dec_tlu_error_wb)).reverse.reduce(Cat(_,_))
|
||||||
|
btbdata := (0 until BTB_SIZE).map(i=> rvdffe(btb_wr_data,wr0_en(i),clock,io.scan_mode))
|
||||||
|
|
||||||
|
io.ifu_bp_fa_index_f(1) := Mux(hit1,hit1_index,0.U)
|
||||||
|
io.ifu_bp_fa_index_f(0) := Mux(hit0,hit0_index,0.U)
|
||||||
|
|
||||||
|
val btb_used_reset = btb_used.andR()
|
||||||
|
val btb_used_ns = Mux1H(Seq(
|
||||||
|
vwayhit_f(1).asBool -> (1.U(32.W) << hit1_index(BTB_FA_INDEX,0)),
|
||||||
|
vwayhit_f(0).asBool() -> (1.U(32.W) << hit0_index(BTB_FA_INDEX,0)),
|
||||||
|
(exu_mp_valid_write & !io.exu_bp.exu_mp_pkt.bits.way & !dec_tlu_error_wb).asBool() -> (1.U(32.W) << btb_fa_wr_addr0(BTB_FA_INDEX,0)),
|
||||||
|
btb_used_reset.asBool -> Fill(BTB_SIZE,0.U),
|
||||||
|
(!btb_used_reset & dec_tlu_error_wb ).asBool -> (btb_used & ~(1.U(32.W) << io.dec_fa_error_index(BTB_FA_INDEX,0))),
|
||||||
|
!(btb_used_reset | dec_tlu_error_wb ).asBool() -> btb_used
|
||||||
|
))
|
||||||
|
val write_used = btb_used_reset | io.ifu_bp_hit_taken_f | exu_mp_valid_write | dec_tlu_error_wb
|
||||||
|
btb_used := rvdffe(btb_used_ns,write_used.asBool(),clock,io.scan_mode)
|
||||||
|
}
|
||||||
|
|
||||||
val bht_bank_clken = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Bool())))
|
val bht_bank_clken = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Bool())))
|
||||||
val bht_bank_clk = (0 until 2).map(i=>(0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)).map(k=>rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)))
|
|
||||||
|
val bht_bank_clk = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Clock())))
|
||||||
|
if(RV_FPGA_OPTIMIZE) {
|
||||||
|
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)) bht_bank_clk(i)(k) := rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)
|
||||||
|
// (0 until 2).map(i=>(0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)).map(k=>rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)))
|
||||||
|
}
|
||||||
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)){
|
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)){
|
||||||
// Checking if there is a write enable with address for the BHT
|
// Checking if there is a write enable with address for the BHT
|
||||||
bht_bank_clken(i)(k) := (bht_wr_en0(i) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B)) |
|
bht_bank_clken(i)(k) := (bht_wr_en0(i) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B)) |
|
||||||
|
@ -443,15 +531,17 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||||
bht_bank_sel(i)(k)(j) := (bht_wr_en0(i) & (bht_wr_addr0(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B)) |
|
bht_bank_sel(i)(k)(j) := (bht_wr_en0(i) & (bht_wr_addr0(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B)) |
|
||||||
(bht_wr_en2(i) & (bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B))
|
(bht_wr_en2(i) & (bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading the BHT with i->way, k->block and the j->offset
|
// Reading the BHT with i->way, k->block and the j->offset
|
||||||
val bht_bank_rd_data_out = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH, UInt(2.W))))
|
val bht_bank_rd_data_out = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH, UInt(2.W))))
|
||||||
for(i<-0 until 2; k<-0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP; j<-0 until NUM_BHT_LOOP){
|
for(i<-0 until 2; k<-0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP; j<-0 until NUM_BHT_LOOP){
|
||||||
bht_bank_rd_data_out(i)((16*k)+j) := withClock(bht_bank_clk(i)(k)){RegEnable(bht_bank_wr_data(i)(k)(j), 0.U, bht_bank_sel(i)(k)(j))}
|
bht_bank_rd_data_out(i)((16*k)+j) := rvdffs_fpga(bht_bank_wr_data(i)(k)(j), bht_bank_sel(i)(k)(j),bht_bank_clk(i)(k),bht_bank_sel(i)(k)(j),clock)}
|
||||||
}
|
|
||||||
|
|
||||||
// Make the final read mux
|
// Make the final read mux
|
||||||
bht_bank0_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
|
bht_bank0_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
|
||||||
bht_bank1_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(1)(i)))
|
bht_bank1_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(1)(i)))
|
||||||
bht_bank0_rd_data_p1_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_p1_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
|
bht_bank0_rd_data_p1_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_p1_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
|
||||||
}
|
}
|
||||||
|
object bp extends App {
|
||||||
|
println((new chisel3.stage.ChiselStage).emitVerilog(new ifu_bp_ctl()))
|
||||||
|
}
|
|
@ -151,6 +151,3 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
|
||||||
|
|
||||||
io.ifc_fetch_addr_f := rvdffpcie(io.ifc_fetch_addr_bf, io.exu_flush_final|io.ifc_fetch_req_f,reset.asAsyncReset(), clock, io.scan_mode)
|
io.ifc_fetch_addr_f := rvdffpcie(io.ifc_fetch_addr_bf, io.exu_flush_final|io.ifc_fetch_req_f,reset.asAsyncReset(), clock, io.scan_mode)
|
||||||
}
|
}
|
||||||
object ifc extends App {
|
|
||||||
println((new chisel3.stage.ChiselStage).emitVerilog(new ifu_ifc_ctl()))
|
|
||||||
}
|
|
|
@ -565,6 +565,11 @@ trait lib extends param{
|
||||||
val LLSB = LMSB-LEFT+1
|
val LLSB = LMSB-LEFT+1
|
||||||
val XMSB = LLSB-1
|
val XMSB = LLSB-1
|
||||||
val XLSB = LLSB-EXTRA
|
val XLSB = LLSB-EXTRA
|
||||||
|
if(RV_FPGA_OPTIMIZE){
|
||||||
|
withClock(clk){
|
||||||
|
RegEnable(din,0.U.asTypeOf(din),en)
|
||||||
|
}
|
||||||
|
}else
|
||||||
Cat(rvdffiee(din(LMSB,LLSB),clk,rst_l,en,scan_mode),rvdffe(din(XMSB,XLSB),en,clk,scan_mode))
|
Cat(rvdffiee(din(LMSB,LLSB),clk,rst_l,en,scan_mode),rvdffe(din(XMSB,XLSB),en,clk,scan_mode))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,5 +159,7 @@ trait param {
|
||||||
val DIV_NEW = 0x1
|
val DIV_NEW = 0x1
|
||||||
val DIV_BIT = 0x4
|
val DIV_BIT = 0x4
|
||||||
val BTB_ENABLE = 0x1
|
val BTB_ENABLE = 0x1
|
||||||
|
val BTB_TOFFSET_SIZE = 0x00C
|
||||||
|
val BTB_FULLYA = 0x00
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,6 +364,7 @@ class lsu_bus_buffer extends Module with RequireAsyncReset with lib {
|
||||||
obuf_wr_timer := rvdff_fpga (obuf_data_done_in,io.lsu_busm_clk,obuf_wr_en,clock)
|
obuf_wr_timer := rvdff_fpga (obuf_data_done_in,io.lsu_busm_clk,obuf_wr_en,clock)
|
||||||
val WrPtr0_m = WireInit(UInt(DEPTH_LOG2.W), 0.U)
|
val WrPtr0_m = WireInit(UInt(DEPTH_LOG2.W), 0.U)
|
||||||
|
|
||||||
|
|
||||||
WrPtr0_m := MuxCase(3.U, (0 until DEPTH).map(i=>((buf_state(i)===idle_C) &
|
WrPtr0_m := MuxCase(3.U, (0 until DEPTH).map(i=>((buf_state(i)===idle_C) &
|
||||||
!((ibuf_valid & (ibuf_tag===i.U)) | (io.lsu_busreq_r &
|
!((ibuf_valid & (ibuf_tag===i.U)) | (io.lsu_busreq_r &
|
||||||
((WrPtr0_r === i.U) | (io.ldst_dual_r & (WrPtr1_r === i.U)))))) -> i.U))
|
((WrPtr0_r === i.U) | (io.ldst_dual_r & (WrPtr1_r === i.U)))))) -> i.U))
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue