This commit is contained in:
​Laraib Khan 2021-01-20 15:46:13 +05:00
parent 5ac08982de
commit ed92fad092
83 changed files with 74753 additions and 86 deletions

158
ifu_bp_ctl.anno.json Normal file
View File

@ -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":"."
}
]

46081
ifu_bp_ctl.fir Normal file

File diff suppressed because it is too large Load Diff

28333
ifu_bp_ctl.v Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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()))
}

View File

@ -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()))
}

View File

@ -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))
} }

View File

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

View File

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