IMC miss-state update
This commit is contained in:
parent
714ccd7092
commit
23bed5142c
51792
el2_ifu_bp_ctl.fir
51792
el2_ifu_bp_ctl.fir
File diff suppressed because it is too large
Load Diff
17432
el2_ifu_bp_ctl.v
17432
el2_ifu_bp_ctl.v
File diff suppressed because it is too large
Load Diff
22641
el2_ifu_mem_ctl.fir
22641
el2_ifu_mem_ctl.fir
File diff suppressed because it is too large
Load Diff
10330
el2_ifu_mem_ctl.v
10330
el2_ifu_mem_ctl.v
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,7 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
val exu_mp_index = Input(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W)) // Misprediction index
|
val exu_mp_index = Input(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W)) // Misprediction index
|
||||||
val exu_mp_btag = Input(UInt(BTB_BTAG_SIZE.W))
|
val exu_mp_btag = Input(UInt(BTB_BTAG_SIZE.W))
|
||||||
val exu_flush_final = Input(Bool())
|
val exu_flush_final = Input(Bool())
|
||||||
|
// Signals to the IFU containing information about brnach
|
||||||
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())
|
||||||
|
@ -41,11 +41,11 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
})
|
})
|
||||||
|
|
||||||
val TAG_START = 16+BTB_BTAG_SIZE
|
val TAG_START = 16+BTB_BTAG_SIZE
|
||||||
val PC4 = 4
|
val PC4 = 4 // Branch = pc + 4 (BTB Index)
|
||||||
val BOFF = 3
|
val BOFF = 3 // Branch offset (BTB Index)
|
||||||
val CALL = 2
|
val CALL = 2 // Branch CALL (BTB Index)
|
||||||
val RET = 1
|
val RET = 1 // Branch RET (BTB Index)
|
||||||
val BV = 0
|
val BV = 0 // Branch Valid (BTB Index)
|
||||||
|
|
||||||
val LRU_SIZE = BTB_ARRAY_DEPTH
|
val LRU_SIZE = BTB_ARRAY_DEPTH
|
||||||
val NUM_BHT_LOOP = if(BHT_ARRAY_DEPTH > 16) 16 else BHT_ARRAY_DEPTH
|
val NUM_BHT_LOOP = if(BHT_ARRAY_DEPTH > 16) 16 else BHT_ARRAY_DEPTH
|
||||||
|
@ -115,8 +115,10 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
val branch_error_bank_conflict_f = branch_error_collision_f & dec_tlu_error_wb
|
val branch_error_bank_conflict_f = branch_error_collision_f & dec_tlu_error_wb
|
||||||
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
|
||||||
val fetch_rd_tag_f = if(BTB_BTAG_FOLD) el2_btb_tag_hash_fold(io.ifc_fetch_addr_f) else el2_btb_tag_hash(io.ifc_fetch_addr_f)
|
val fetch_rd_tag_f = if(BTB_BTAG_FOLD) el2_btb_tag_hash_fold(io.ifc_fetch_addr_f) else el2_btb_tag_hash(io.ifc_fetch_addr_f)
|
||||||
val fetch_rd_tag_p1_f = if(BTB_BTAG_FOLD) el2_btb_tag_hash_fold(Cat(fetch_addr_p1_f,0.U)) else el2_btb_tag_hash(Cat(fetch_addr_p1_f,0.U))
|
val fetch_rd_tag_p1_f = if(BTB_BTAG_FOLD) el2_btb_tag_hash_fold(Cat(fetch_addr_p1_f,0.U)) else el2_btb_tag_hash(Cat(fetch_addr_p1_f,0.U))
|
||||||
|
|
||||||
// There is a misprediction and the exu is writing back
|
// There is a misprediction and the exu is writing back
|
||||||
val fetch_mp_collision_f = (io.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_f = (io.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_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
|
val fetch_mp_collision_p1_f = (io.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
|
||||||
|
@ -126,19 +128,22 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
val exu_mp_way_f = withClock(io.active_clk) {RegNext(exu_mp_way, 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)}
|
val exu_flush_final_d1 = withClock(io.active_clk) {RegNext(io.exu_flush_final, init = 0.U)}
|
||||||
|
|
||||||
// TODO
|
// If there is a flush from the lower pipe wait until the flush gets deasserted from the (decode) side
|
||||||
leak_one_f := (io.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_tlu_flush_leak_one_wb & io.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & io.dec_tlu_flush_lower_wb)
|
||||||
|
|
||||||
// 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
|
||||||
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_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
|
// 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_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
|
// 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_f) & io.ifc_fetch_req_f & !leak_one_f
|
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
// 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_f) & io.ifc_fetch_req_f & !leak_one_f
|
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||||
|
|
||||||
|
@ -149,18 +154,19 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
val tag_match_way1_expanded_f = Cat(tag_match_way1_f & (btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)),
|
val tag_match_way1_expanded_f = Cat(tag_match_way1_f & (btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)),
|
||||||
tag_match_way1_f & !(btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)))
|
tag_match_way1_f & !(btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)))
|
||||||
|
|
||||||
|
|
||||||
val tag_match_way0_expanded_p1_f = Cat(tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)),
|
val tag_match_way0_expanded_p1_f = Cat(tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)),
|
||||||
tag_match_way0_p1_f & !(btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)))
|
tag_match_way0_p1_f & !(btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)))
|
||||||
|
|
||||||
val tag_match_way1_expanded_p1_f = Cat(tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)),
|
val tag_match_way1_expanded_p1_f = Cat(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)))
|
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
|
||||||
|
|
||||||
|
// Final hit calculation
|
||||||
val wayhit_f = tag_match_way0_expanded_f | tag_match_way1_expanded_f
|
val 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
|
val wayhit_p1_f = tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
|
||||||
|
|
||||||
// Chopping off the ways that had a hitbtb_vbank0_rd_data_f
|
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
|
||||||
|
// 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))
|
||||||
|
|
||||||
|
@ -170,23 +176,42 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
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 bit 1 of the pc to check
|
// 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
|
||||||
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))
|
||||||
|
|
||||||
// Implimenting the LRU for a 2-way BTB
|
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
|
||||||
|
// Cases
|
||||||
|
// BANK1 BANK0
|
||||||
|
// -------------------------------
|
||||||
|
// | : | : |
|
||||||
|
// -------------------------------
|
||||||
|
// <------------> : PC4 branch, offset, should be in B1 (indicated on [2])
|
||||||
|
// <------------> : PC4 branch, no offset, indicate PC4, VALID, HIST on [1]
|
||||||
|
// <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0]
|
||||||
|
// <------> : PC2 branch, offset, indicate VALID, HIST on [1]
|
||||||
|
// <------> : PC2 branch, no offset, indicate VALID, HIST on [0]
|
||||||
|
|
||||||
|
|
||||||
|
// Make an LRU value with execution mis-prediction
|
||||||
val mp_wrindex_dec = 1.U << exu_mp_addr
|
val mp_wrindex_dec = 1.U << exu_mp_addr
|
||||||
|
|
||||||
|
// Make an LRU value with current read pc
|
||||||
val fetch_wrindex_dec = 1.U << btb_rd_addr_f
|
val fetch_wrindex_dec = 1.U << btb_rd_addr_f
|
||||||
//io.test1 := fetch_wrindex_dec
|
|
||||||
|
// Make an LRU value with current read pc + 4
|
||||||
val fetch_wrindex_p1_dec = 1.U << btb_rd_addr_p1_f
|
val fetch_wrindex_p1_dec = 1.U << btb_rd_addr_p1_f
|
||||||
//io.test2 := fetch_wrindex_p1_dec
|
|
||||||
|
// 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,
|
|
||||||
|
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))
|
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
|
||||||
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
|
||||||
|
|
||||||
val fetch_wrlru_b0 = fetch_wrindex_dec & Fill(LRU_SIZE, lru_update_valid_f)
|
val fetch_wrlru_b0 = fetch_wrindex_dec & Fill(LRU_SIZE, lru_update_valid_f)
|
||||||
|
@ -194,43 +219,57 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
|
|
||||||
val btb_lru_b0_hold = ~mp_wrlru_b0 & ~fetch_wrlru_b0
|
val btb_lru_b0_hold = ~mp_wrlru_b0 & ~fetch_wrlru_b0
|
||||||
|
|
||||||
|
// If there is a collision the use the mis-predicted value as output and update accordingly
|
||||||
val use_mp_way = fetch_mp_collision_f
|
val use_mp_way = fetch_mp_collision_f
|
||||||
val use_mp_way_p1 = fetch_mp_collision_p1_f
|
val use_mp_way_p1 = fetch_mp_collision_p1_f
|
||||||
|
|
||||||
val btb_lru_b0_ns = Mux1H(Seq(~exu_mp_way.asBool->mp_wrlru_b0,
|
// Calculate the lru next value and flop it
|
||||||
tag_match_way0_f.asBool->fetch_wrlru_b0,
|
val btb_lru_b0_ns = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
|
||||||
tag_match_way0_p1_f.asBool->fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
|
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
|
||||||
|
|
||||||
|
|
||||||
val btb_lru_rd_f = Mux(use_mp_way.asBool, exu_mp_way_f, (fetch_wrindex_dec & btb_lru_b0_f).orR)
|
val btb_lru_rd_f = Mux(use_mp_way.asBool, exu_mp_way_f, (fetch_wrindex_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)
|
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
|
||||||
val btb_vlru_rd_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
|
val 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)))
|
||||||
|
|
||||||
val tag_match_vway1_expanded_f = Mux1H(Seq(~io.ifc_fetch_addr_f(0).asBool->tag_match_way1_expanded_f,
|
// 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,
|
||||||
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))))
|
||||||
|
|
||||||
val way_raw = tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
|
io.ifu_bp_way_f := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
|
||||||
|
|
||||||
|
// update the lru
|
||||||
btb_lru_b0_f := RegEnable(btb_lru_b0_ns, init = 0.U, (io.ifc_fetch_req_f|exu_mp_valid).asBool)
|
btb_lru_b0_f := RegEnable(btb_lru_b0_ns, init = 0.U, (io.ifc_fetch_req_f|exu_mp_valid).asBool)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Mask according to eoc-near and make the hit-final
|
||||||
eoc_mask := !eoc_near | (~io.ifc_fetch_addr_f(1,0)).orR()
|
eoc_mask := !eoc_near | (~io.ifc_fetch_addr_f(1,0)).orR()
|
||||||
|
|
||||||
val btb_sel_data_f = WireInit(UInt(16.W), init = 0.U)
|
val btb_sel_data_f = WireInit(UInt(16.W), init = 0.U)
|
||||||
val hist1_raw = WireInit(UInt(2.W), init = 0.U)
|
val hist1_raw = WireInit(UInt(2.W), init = 0.U)
|
||||||
|
|
||||||
|
// Filteing out portion of BTB read after virtual banking
|
||||||
|
// Entry -> tag[pt.BTB_BTAG_SIZE-1:0], toffset[11:0], pc4, boffset, call, ret, valid
|
||||||
val btb_rd_tgt_f = btb_sel_data_f(15,4)
|
val btb_rd_tgt_f = btb_sel_data_f(15,4)
|
||||||
val btb_rd_pc4_f = btb_sel_data_f(3)
|
val btb_rd_pc4_f = btb_sel_data_f(3)
|
||||||
val btb_rd_call_f = btb_sel_data_f(1)
|
val btb_rd_call_f = btb_sel_data_f(1)
|
||||||
val btb_rd_ret_f = btb_sel_data_f(0)
|
val btb_rd_ret_f = btb_sel_data_f(0)
|
||||||
|
|
||||||
|
// This is 1-index shifted to that of the btb-data-read so we have 1-bit shifted
|
||||||
btb_sel_data_f := Mux1H(Seq(btb_sel_f(1).asBool-> btb_vbank1_rd_data_f(16,1),
|
btb_sel_data_f := Mux1H(Seq(btb_sel_f(1).asBool-> btb_vbank1_rd_data_f(16,1),
|
||||||
btb_sel_f(0).asBool-> btb_vbank0_rd_data_f(16,1)))
|
btb_sel_f(0).asBool-> btb_vbank0_rd_data_f(16,1)))
|
||||||
|
|
||||||
|
// No lower flush or bp-disabple and a fetch request is generated with virtual way hit
|
||||||
io.ifu_bp_hit_taken_f := (vwayhit_f & hist1_raw).orR & io.ifc_fetch_req_f & !leak_one_f_d1 & !io.dec_tlu_bpred_disable
|
io.ifu_bp_hit_taken_f := (vwayhit_f & hist1_raw).orR & io.ifc_fetch_req_f & !leak_one_f_d1 & !io.dec_tlu_bpred_disable
|
||||||
|
|
||||||
|
// If the prediction is a call or ret btb entry then do not check the bht just force a taken with data from the RAS
|
||||||
val bht_force_taken_f = Cat( btb_vbank1_rd_data_f(CALL) | btb_vbank1_rd_data_f(RET) ,
|
val bht_force_taken_f = Cat( btb_vbank1_rd_data_f(CALL) | btb_vbank1_rd_data_f(RET) ,
|
||||||
btb_vbank0_rd_data_f(CALL) | btb_vbank0_rd_data_f(RET))
|
btb_vbank0_rd_data_f(CALL) | btb_vbank0_rd_data_f(RET))
|
||||||
|
|
||||||
|
@ -240,31 +279,38 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
val bht_bank0_rd_data_f =WireInit(UInt(2.W), 0.U)
|
val bht_bank0_rd_data_f =WireInit(UInt(2.W), 0.U)
|
||||||
val bht_bank0_rd_data_p1_f =WireInit(UInt(2.W), 0.U)
|
val bht_bank0_rd_data_p1_f =WireInit(UInt(2.W), 0.U)
|
||||||
|
|
||||||
|
// Depending on pc make the virtual bank as commented above
|
||||||
val bht_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_f,
|
val bht_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_f,
|
||||||
io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f))
|
io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f))
|
||||||
|
|
||||||
val bht_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f,
|
val bht_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f,
|
||||||
io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_p1_f))
|
io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_p1_f))
|
||||||
|
|
||||||
|
// Direction containing data of both banks direction
|
||||||
bht_dir_f := Cat((bht_force_taken_f(1) | bht_vbank1_rd_data_f(1)) & bht_valid_f(1),
|
bht_dir_f := Cat((bht_force_taken_f(1) | bht_vbank1_rd_data_f(1)) & bht_valid_f(1),
|
||||||
(bht_force_taken_f(0) | bht_vbank0_rd_data_f(1)) & bht_valid_f(0))
|
(bht_force_taken_f(0) | bht_vbank0_rd_data_f(1)) & bht_valid_f(0))
|
||||||
|
|
||||||
|
// If the branch is taken then pass btb sel else 0
|
||||||
io.ifu_bp_inst_mask_f := (io.ifu_bp_hit_taken_f & btb_sel_f(1)) | !io.ifu_bp_hit_taken_f
|
io.ifu_bp_inst_mask_f := (io.ifu_bp_hit_taken_f & btb_sel_f(1)) | !io.ifu_bp_hit_taken_f
|
||||||
// Bank explination
|
|
||||||
|
|
||||||
|
// hist 1 shows both banks direction
|
||||||
hist1_raw := bht_force_taken_f | Cat(bht_vbank1_rd_data_f(1), bht_vbank0_rd_data_f(1))
|
hist1_raw := bht_force_taken_f | Cat(bht_vbank1_rd_data_f(1), bht_vbank0_rd_data_f(1))
|
||||||
|
|
||||||
|
// hist 0 shows the both bank strength
|
||||||
val hist0_raw = Cat(bht_vbank1_rd_data_f(0), bht_vbank0_rd_data_f(0))
|
val hist0_raw = Cat(bht_vbank1_rd_data_f(0), bht_vbank0_rd_data_f(0))
|
||||||
|
|
||||||
|
// pc4: if the branch is pc+4
|
||||||
val pc4_raw = Cat(vwayhit_f(1) & btb_vbank1_rd_data_f(PC4),
|
val pc4_raw = Cat(vwayhit_f(1) & btb_vbank1_rd_data_f(PC4),
|
||||||
vwayhit_f(0) & btb_vbank0_rd_data_f(PC4))
|
vwayhit_f(0) & btb_vbank0_rd_data_f(PC4))
|
||||||
|
|
||||||
|
// Its a call call or ret branch
|
||||||
val pret_raw = Cat(vwayhit_f(1) & !btb_vbank1_rd_data_f(CALL) & btb_vbank1_rd_data_f(RET),
|
val pret_raw = Cat(vwayhit_f(1) & !btb_vbank1_rd_data_f(CALL) & btb_vbank1_rd_data_f(RET),
|
||||||
vwayhit_f(0) & !btb_vbank0_rd_data_f(CALL) & btb_vbank0_rd_data_f(RET))
|
vwayhit_f(0) & !btb_vbank0_rd_data_f(CALL) & btb_vbank0_rd_data_f(RET))
|
||||||
|
|
||||||
//GHR
|
// count number of 1's in bht_valid
|
||||||
val num_valids = bht_valid_f(1) +& bht_valid_f(0) // countones
|
val num_valids = bht_valid_f(1) +& bht_valid_f(0)
|
||||||
|
|
||||||
|
// To calculate a merged ghr meaning the is a overlapping 1 in sel and dir
|
||||||
val final_h = (btb_sel_f & bht_dir_f).orR
|
val final_h = (btb_sel_f & bht_dir_f).orR
|
||||||
|
|
||||||
val fghr = WireInit(UInt(BHT_GHR_SIZE.W), 0.U)
|
val fghr = WireInit(UInt(BHT_GHR_SIZE.W), 0.U)
|
||||||
|
@ -275,6 +321,10 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
|
|
||||||
val exu_flush_ghr = io.exu_mp_fghr
|
val exu_flush_ghr = io.exu_mp_fghr
|
||||||
val fghr_ns = Wire(UInt(BHT_GHR_SIZE.W))
|
val fghr_ns = Wire(UInt(BHT_GHR_SIZE.W))
|
||||||
|
|
||||||
|
// If there is a exu-flush use its ghr
|
||||||
|
// If there is a hit and a fetch then use the merged-ghr
|
||||||
|
// If there is no hit or fetch then hold value
|
||||||
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))
|
||||||
|
@ -282,8 +332,6 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
fghr := withClock(io.active_clk) {RegNext(fghr_ns, init = 0.U)}
|
fghr := withClock(io.active_clk) {RegNext(fghr_ns, init = 0.U)}
|
||||||
|
|
||||||
io.ifu_bp_fghr_f := fghr
|
io.ifu_bp_fghr_f := fghr
|
||||||
|
|
||||||
io.ifu_bp_way_f := way_raw
|
|
||||||
io.ifu_bp_hist1_f := hist1_raw
|
io.ifu_bp_hist1_f := hist1_raw
|
||||||
io.ifu_bp_hist0_f := hist0_raw
|
io.ifu_bp_hist0_f := hist0_raw
|
||||||
io.ifu_bp_pc4_f := pc4_raw
|
io.ifu_bp_pc4_f := pc4_raw
|
||||||
|
@ -291,6 +339,7 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
io.ifu_bp_valid_f := vwayhit_f & ~Fill(2, io.dec_tlu_bpred_disable)
|
io.ifu_bp_valid_f := vwayhit_f & ~Fill(2, io.dec_tlu_bpred_disable)
|
||||||
io.ifu_bp_ret_f := pret_raw
|
io.ifu_bp_ret_f := pret_raw
|
||||||
|
|
||||||
|
// block fetch to calculate if there is a hit with fetch request and a taken branch then compute the branch offset
|
||||||
val bloc_f = Cat((bht_dir_f(0) & !fetch_start_f(0)) | (!bht_dir_f(0) & fetch_start_f(0)),
|
val bloc_f = Cat((bht_dir_f(0) & !fetch_start_f(0)) | (!bht_dir_f(0) & fetch_start_f(0)),
|
||||||
(bht_dir_f(0) & fetch_start_f(0)) | (!bht_dir_f(0) & !fetch_start_f(0)))
|
(bht_dir_f(0) & fetch_start_f(0)) | (!bht_dir_f(0) & !fetch_start_f(0)))
|
||||||
|
|
||||||
|
@ -302,15 +351,18 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
val ifc_fetch_adder_prior = RegEnable(io.ifc_fetch_addr_f(30,1), 0.U, (io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool)
|
val ifc_fetch_adder_prior = RegEnable(io.ifc_fetch_addr_f(30,1), 0.U, (io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool)
|
||||||
|
|
||||||
io.ifu_bp_poffset_f := btb_rd_tgt_f
|
io.ifu_bp_poffset_f := btb_rd_tgt_f
|
||||||
|
|
||||||
val adder_pc_in_f = Mux1H(Seq(use_fa_plus.asBool -> fetch_addr_p1_f,
|
val adder_pc_in_f = Mux1H(Seq(use_fa_plus.asBool -> fetch_addr_p1_f,
|
||||||
btb_fg_crossing_f.asBool -> ifc_fetch_adder_prior,
|
btb_fg_crossing_f.asBool -> ifc_fetch_adder_prior,
|
||||||
(!btb_fg_crossing_f & !use_fa_plus).asBool-> io.ifc_fetch_addr_f(30,1)))
|
(!btb_fg_crossing_f & !use_fa_plus).asBool-> io.ifc_fetch_addr_f(30,1)))
|
||||||
|
|
||||||
|
// Calculate the branch target by adding the offset
|
||||||
val bp_btb_target_adder_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(btb_rd_tgt_f,0.U))
|
val bp_btb_target_adder_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(btb_rd_tgt_f,0.U))
|
||||||
|
|
||||||
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
|
||||||
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 := Mux((btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)).asBool,
|
||||||
rets_out(0)(31,1),bp_btb_target_adder_f(31,1))
|
rets_out(0)(31,1),bp_btb_target_adder_f(31,1))
|
||||||
|
|
||||||
|
@ -323,6 +375,7 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
|
|
||||||
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
|
||||||
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),
|
||||||
rs_pop.asBool -> rets_out(1)))
|
rs_pop.asBool -> rets_out(1)))
|
||||||
|
@ -330,24 +383,31 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
else Mux1H(Seq(rs_push.asBool->rets_out(i-1),
|
else Mux1H(Seq(rs_push.asBool->rets_out(i-1),
|
||||||
rs_pop.asBool ->rets_out(i+1))))
|
rs_pop.asBool ->rets_out(i+1))))
|
||||||
|
|
||||||
|
// Make flops for poping the data
|
||||||
rets_out := (0 until RET_STACK_SIZE).map(i=>RegEnable(rets_in(i),0.U,rsenable(i).asBool))
|
rets_out := (0 until RET_STACK_SIZE).map(i=>RegEnable(rets_in(i),0.U,rsenable(i).asBool))
|
||||||
|
|
||||||
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_mp_btag
|
val btb_wr_tag = io.exu_mp_btag
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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_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_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 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
|
||||||
val bht_wr_en0 = Fill(2, exu_mp_valid & !exu_mp_call & !exu_mp_ret & !exu_mp_ja) & Cat(middle_of_bank, ~middle_of_bank)
|
val bht_wr_en0 = Fill(2, exu_mp_valid & !exu_mp_call & !exu_mp_ret & !exu_mp_ja) & Cat(middle_of_bank, ~middle_of_bank)
|
||||||
val bht_wr_en2 = Fill(2, dec_tlu_br0_v_wb) & Cat(dec_tlu_br0_middle_wb, ~dec_tlu_br0_middle_wb)
|
val bht_wr_en2 = Fill(2, dec_tlu_br0_v_wb) & Cat(dec_tlu_br0_middle_wb, ~dec_tlu_br0_middle_wb)
|
||||||
val bht_wr_data0 = exu_mp_hist
|
val bht_wr_data0 = exu_mp_hist
|
||||||
val bht_wr_data2 = dec_tlu_br0_hist_wb
|
val bht_wr_data2 = dec_tlu_br0_hist_wb
|
||||||
|
|
||||||
|
// Hash each read and write address
|
||||||
val mp_hashed = el2_btb_ghr_hash(Cat(exu_mp_addr,0.U(2.W)), io.exu_mp_eghr)
|
val mp_hashed = el2_btb_ghr_hash(Cat(exu_mp_addr,0.U(2.W)), io.exu_mp_eghr)
|
||||||
val br0_hashed_wb = el2_btb_ghr_hash(Cat(dec_tlu_br0_addr_wb,0.U(2.W)), exu_i0_br_fghr_wb)
|
val br0_hashed_wb = el2_btb_ghr_hash(Cat(dec_tlu_br0_addr_wb,0.U(2.W)), exu_i0_br_fghr_wb)
|
||||||
val bht_rd_addr_hashed_f = el2_btb_ghr_hash(Cat(btb_rd_addr_f,0.U(2.W)), fghr)
|
val bht_rd_addr_hashed_f = el2_btb_ghr_hash(Cat(btb_rd_addr_f,0.U(2.W)), fghr)
|
||||||
|
@ -367,36 +427,41 @@ class el2_ifu_bp_ctl extends Module with el2_lib with RequireAsyncReset {
|
||||||
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_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)))
|
||||||
|
|
||||||
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())))
|
||||||
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
|
||||||
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)) |
|
||||||
(bht_wr_en2(i) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B))
|
(bht_wr_en2(i) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Writing data into the BHT (DEC-side) or (EXU-side)
|
||||||
val bht_bank_wr_data = (0 until 2).map(i=>(0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP).map(k=>(0 until NUM_BHT_LOOP).map(j=>
|
val bht_bank_wr_data = (0 until 2).map(i=>(0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP).map(k=>(0 until NUM_BHT_LOOP).map(j=>
|
||||||
Mux((bht_wr_en2(i)&(bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.U)&(bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.U)|BHT_NO_ADDR_MATCH.B).asBool, bht_wr_data2, bht_wr_data0))))
|
Mux((bht_wr_en2(i)&(bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.U)&(bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.U)|BHT_NO_ADDR_MATCH.B).asBool, bht_wr_data2, bht_wr_data0))))
|
||||||
|
|
||||||
val bht_bank_sel = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Vec(NUM_BHT_LOOP, Bool()))))
|
val bht_bank_sel = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Vec(NUM_BHT_LOOP, Bool()))))
|
||||||
|
|
||||||
|
// We have a 2 way bht with BHT_ARRAY_DEPTH/NUM_BHT_LOOP blocks and NUM_BHT_LOOP->offset in each block
|
||||||
|
// Make enables of each flop according to the address dividing the address in 2-blocks upper block for BHT-Block and
|
||||||
|
// the lower block for the offset and run this on both of the ways
|
||||||
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_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
|
||||||
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) := RegEnable(bht_bank_wr_data(i)(k)(j), 0.U, bht_bank_sel(i)(k)(j) & bht_bank_clken(i)(k))
|
bht_bank_rd_data_out(i)((16*k)+j) := RegEnable(bht_bank_wr_data(i)(k)(j), 0.U, bht_bank_sel(i)(k)(j) & bht_bank_clken(i)(k))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 ifu_bp extends App {
|
object ifu_bp extends App {
|
||||||
|
|
|
@ -22,6 +22,31 @@ class mem_ctl_bundle extends Bundle with el2_lib{
|
||||||
val dec_tlu_fence_i_wb = Input(Bool())
|
val dec_tlu_fence_i_wb = Input(Bool())
|
||||||
val ifu_bp_hit_taken_f = Input(Bool())
|
val ifu_bp_hit_taken_f = Input(Bool())
|
||||||
val ifu_bp_inst_mask_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_miss_state_idle = Output(Bool())
|
||||||
val ifu_ic_mb_empty = Output(Bool())
|
val ifu_ic_mb_empty = Output(Bool())
|
||||||
val ic_dma_active = Output(Bool())
|
val ic_dma_active = Output(Bool())
|
||||||
|
@ -48,7 +73,6 @@ class mem_ctl_bundle extends Bundle with el2_lib{
|
||||||
val ifu_axi_wlast = Output(Bool())
|
val ifu_axi_wlast = Output(Bool())
|
||||||
val ifu_axi_bready = Output(Bool())
|
val ifu_axi_bready = Output(Bool())
|
||||||
val ifu_axi_arvalid = Output(Bool())
|
val ifu_axi_arvalid = Output(Bool())
|
||||||
val ifu_axi_arready = Input(Bool())
|
|
||||||
val ifu_axi_arid = Output(UInt(IFU_BUS_TAG.W))
|
val ifu_axi_arid = Output(UInt(IFU_BUS_TAG.W))
|
||||||
val ifu_axi_araddr = Output(UInt(32.W))
|
val ifu_axi_araddr = Output(UInt(32.W))
|
||||||
val ifu_axi_arregion = Output(UInt(4.W))
|
val ifu_axi_arregion = Output(UInt(4.W))
|
||||||
|
@ -59,18 +83,7 @@ class mem_ctl_bundle extends Bundle with el2_lib{
|
||||||
val ifu_axi_arcache = Output(UInt(4.W))
|
val ifu_axi_arcache = Output(UInt(4.W))
|
||||||
val ifu_axi_arprot = Output(UInt(3.W))
|
val ifu_axi_arprot = Output(UInt(3.W))
|
||||||
val ifu_axi_arqos = Output(UInt(4.W))
|
val ifu_axi_arqos = Output(UInt(4.W))
|
||||||
val ifu_axi_rvalid = Input(Bool())
|
|
||||||
val ifu_axi_rready = Output(Bool())
|
val ifu_axi_rready = Output(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 iccm_dma_ecc_error = Output(Bool())
|
val iccm_dma_ecc_error = Output(Bool())
|
||||||
val iccm_dma_rvalid = Output(Bool())
|
val iccm_dma_rvalid = Output(Bool())
|
||||||
val iccm_dma_rdata = Output(UInt(64.W))
|
val iccm_dma_rdata = Output(UInt(64.W))
|
||||||
|
@ -80,29 +93,19 @@ class mem_ctl_bundle extends Bundle with el2_lib{
|
||||||
val ic_wr_en = Output(UInt(ICACHE_NUM_WAYS.W))
|
val ic_wr_en = Output(UInt(ICACHE_NUM_WAYS.W))
|
||||||
val ic_rd_en = Output(Bool())
|
val ic_rd_en = Output(Bool())
|
||||||
val ic_wr_data = Output(Vec(ICACHE_BANKS_WAY, UInt(71.W)))
|
val ic_wr_data = Output(Vec(ICACHE_BANKS_WAY, UInt(71.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_debug_wr_data = Output(UInt(71.W))
|
val ic_debug_wr_data = Output(UInt(71.W))
|
||||||
val ifu_ic_debug_rd_data = Output(UInt(71.W))
|
val ifu_ic_debug_rd_data = Output(UInt(71.W))
|
||||||
val ic_eccerr = Input(UInt(ICACHE_BANKS_WAY.W))
|
|
||||||
val ic_parerr = Input(UInt(ICACHE_BANKS_WAY.W))
|
|
||||||
val ic_debug_addr = Output(UInt((ICACHE_INDEX_HI-2).W))
|
val ic_debug_addr = Output(UInt((ICACHE_INDEX_HI-2).W))
|
||||||
val ic_debug_rd_en = Output(Bool())
|
val ic_debug_rd_en = Output(Bool())
|
||||||
val ic_debug_wr_en = Output(Bool())
|
val ic_debug_wr_en = Output(Bool())
|
||||||
val ic_debug_tag_array = Output(Bool())
|
val ic_debug_tag_array = Output(Bool())
|
||||||
val ic_debug_way = Output(UInt(ICACHE_NUM_WAYS.W))
|
val ic_debug_way = Output(UInt(ICACHE_NUM_WAYS.W))
|
||||||
val ic_tag_valid = Output(UInt(ICACHE_NUM_WAYS.W))
|
val ic_tag_valid = Output(UInt(ICACHE_NUM_WAYS.W))
|
||||||
val ic_rd_hit = Input(UInt(ICACHE_NUM_WAYS.W))
|
|
||||||
val ic_tag_perr = Input(Bool())
|
|
||||||
val iccm_rw_addr = Output(UInt((ICCM_BITS-1).W))
|
val iccm_rw_addr = Output(UInt((ICCM_BITS-1).W))
|
||||||
val iccm_wren = Output(Bool())
|
val iccm_wren = Output(Bool())
|
||||||
val iccm_rden = Output(Bool())
|
val iccm_rden = Output(Bool())
|
||||||
val iccm_wr_data = Output(UInt(78.W))
|
val iccm_wr_data = Output(UInt(78.W))
|
||||||
val iccm_wr_size = Output(UInt(3.W))
|
val iccm_wr_size = Output(UInt(3.W))
|
||||||
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 ic_hit_f = Output(Bool())
|
val ic_hit_f = Output(Bool())
|
||||||
val ic_access_fault_f = Output(Bool())
|
val ic_access_fault_f = Output(Bool())
|
||||||
val ic_access_fault_type_f = Output(UInt(2.W))
|
val ic_access_fault_type_f = Output(UInt(2.W))
|
||||||
|
@ -115,7 +118,6 @@ class mem_ctl_bundle extends Bundle with el2_lib{
|
||||||
val ic_data_f = Output(UInt(32.W))
|
val ic_data_f = Output(UInt(32.W))
|
||||||
val ic_premux_data = Output(UInt(64.W))
|
val ic_premux_data = Output(UInt(64.W))
|
||||||
val ic_sel_premux_data = Output(Bool())
|
val ic_sel_premux_data = Output(Bool())
|
||||||
val dec_tlu_ic_diag_pkt = Input(new el2_cache_debug_pkt_t)
|
|
||||||
val dec_tlu_core_ecc_disable = Input(Bool())
|
val dec_tlu_core_ecc_disable = Input(Bool())
|
||||||
val ifu_ic_debug_rd_data_valid = Output(Bool())
|
val ifu_ic_debug_rd_data_valid = Output(Bool())
|
||||||
val iccm_buf_correct_ecc = Output(Bool())
|
val iccm_buf_correct_ecc = Output(Bool())
|
||||||
|
@ -535,6 +537,7 @@ class el2_ifu_mem_ctl extends Module with el2_lib {
|
||||||
val bus_ifu_bus_clk_en_ff = withClock(io.free_clk){RegNext(bus_ifu_bus_clk_en, 0.U)}
|
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)}
|
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)}
|
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 bus_cmd_req_hold = WireInit(Bool(), false.B)
|
||||||
val ifu_bus_cmd_valid = 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 bus_cmd_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.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.
Loading…
Reference in New Issue