Skip to content

Commit

Permalink
ICache: init registers to prevent x-state
Browse files Browse the repository at this point in the history
  • Loading branch information
ngc7331 committed Jun 19, 2024
1 parent 1a28e60 commit 63f7f8b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 40 deletions.
26 changes: 17 additions & 9 deletions src/main/scala/xiangshan/frontend/icache/ICache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ trait HasICacheParameters extends HasL1CacheParameters with HasInstrMMIOConst wi
Mux(valid, data, RegEnable(data, valid))
}

def ResultHoldBypass[T <: Data](data: T, init: T, valid: Bool): T = {
Mux(valid, data, RegEnable(data, init, valid))
}

def holdReleaseLatch(valid: Bool, release: Bool, flush: Bool): Bool ={
val bit = RegInit(false.B)
when(flush) { bit := false.B }
Expand Down Expand Up @@ -135,6 +139,10 @@ trait HasICacheParameters extends HasL1CacheParameters with HasInstrMMIOConst wi
val bankIdxLow = Cat(0.U(1.W), blkOffset) >> log2Ceil(blockBytes/ICacheDataBanks)
val bankIdxHigh = (Cat(0.U(1.W), blkOffset) + 32.U) >> log2Ceil(blockBytes/ICacheDataBanks)
val bankSel = VecInit((0 until ICacheDataBanks * 2).map(i => (i.U >= bankIdxLow) && (i.U <= bankIdxHigh)))
/* FIXME: when blkOffset is invalid, it can be anything and causing fake assertion-fails
* maybe it's better to do this assert outside getBankSel(), or pass a valid signal here
* the current solution is ensuring blkOffset is valid by defaulting it to 0.U
*/
assert(PopCount(bankSel) === ICacheBankVisitNum.U, "The number of bank visits must be %d, but bankSel=0x%x", ICacheBankVisitNum.U, bankSel.asUInt)
bankSel.asTypeOf(UInt((ICacheDataBanks * 2).W)).asTypeOf(Vec(2, UInt(ICacheDataBanks.W)))
}
Expand Down Expand Up @@ -193,10 +201,10 @@ class ICacheMetaArray()(implicit p: Parameters) extends ICacheArray
val port_1_read_1 = io.read.valid && io.read.bits.vSetIdx(1)(0) && io.read.bits.isDoubleLine
val port_1_read_0 = io.read.valid && !io.read.bits.vSetIdx(1)(0) && io.read.bits.isDoubleLine

val port_0_read_0_reg = RegEnable(port_0_read_0, io.read.fire)
val port_0_read_1_reg = RegEnable(port_0_read_1, io.read.fire)
val port_1_read_1_reg = RegEnable(port_1_read_1, io.read.fire)
val port_1_read_0_reg = RegEnable(port_1_read_0, io.read.fire)
val port_0_read_0_reg = RegEnable(port_0_read_0, 0.U.asTypeOf(port_0_read_0), io.read.fire)
val port_0_read_1_reg = RegEnable(port_0_read_1, 0.U.asTypeOf(port_0_read_1), io.read.fire)
val port_1_read_1_reg = RegEnable(port_1_read_1, 0.U.asTypeOf(port_1_read_1), io.read.fire)
val port_1_read_0_reg = RegEnable(port_1_read_0, 0.U.asTypeOf(port_1_read_0), io.read.fire)

val bank_0_idx = Mux(port_0_read_0, io.read.bits.vSetIdx(0), io.read.bits.vSetIdx(1))
val bank_1_idx = Mux(port_0_read_1, io.read.bits.vSetIdx(0), io.read.bits.vSetIdx(1))
Expand Down Expand Up @@ -234,7 +242,7 @@ class ICacheMetaArray()(implicit p: Parameters) extends ICacheArray
tagArray
}

val read_set_idx_next = RegEnable(io.read.bits.vSetIdx, io.read.fire)
val read_set_idx_next = RegEnable(io.read.bits.vSetIdx, 0.U.asTypeOf(io.read.bits.vSetIdx), io.read.fire)
val valid_array = RegInit(VecInit(Seq.fill(nWays)(0.U(nSets.W))))
val valid_metas = Wire(Vec(PortNumber, Vec(nWays, Bool())))
// valid read
Expand All @@ -256,7 +264,7 @@ class ICacheMetaArray()(implicit p: Parameters) extends ICacheArray
val read_meta_wrong = read_meta_decoded.map{ way_bits_decoded => way_bits_decoded.error}
val read_meta_corrected = VecInit(read_meta_decoded.map{ way_bits_decoded => way_bits_decoded.corrected})
read_metas(i) := read_meta_corrected.asTypeOf(Vec(nWays,new ICacheMetadata()))
(0 until nWays).foreach{ w => io.readResp.errors(i)(w) := RegEnable(read_meta_wrong(w), read_fire_delay1) && read_fire_delay2}
(0 until nWays).foreach{ w => io.readResp.errors(i)(w) := RegEnable(read_meta_wrong(w), 0.U.asTypeOf(read_meta_wrong(w)), read_fire_delay1) && read_fire_delay2}
}

//Parity Encode
Expand Down Expand Up @@ -373,7 +381,7 @@ class ICacheDataArray(implicit p: Parameters) extends ICacheArray
* read logic
******************************************************************************
*/
val masksReg = RegEnable(masks, io.read(0).valid)
val masksReg = RegEnable(masks, 0.U.asTypeOf(masks), io.read(0).valid)
val readDataWithCode = (0 until ICacheDataBanks).map(bank =>
Mux1H(VecInit(masksReg.map(_(bank))).asTypeOf(UInt(nWays.W)),
dataArrays.map(_(bank).io.r.resp.asUInt)))
Expand Down Expand Up @@ -420,8 +428,8 @@ class ICacheReplacer(implicit p: Parameters) extends ICacheModule {
replacers(0).way(io.victim.vSetIdx.bits(highestIdxBit, 1)))

// touch the victim in next cycle
val victim_vSetIdx_reg = RegEnable(io.victim.vSetIdx.bits, io.victim.vSetIdx.valid)
val victim_way_reg = RegEnable(io.victim.way, io.victim.vSetIdx.valid)
val victim_vSetIdx_reg = RegEnable(io.victim.vSetIdx.bits, 0.U.asTypeOf(io.victim.vSetIdx.bits), io.victim.vSetIdx.valid)
val victim_way_reg = RegEnable(io.victim.way, 0.U.asTypeOf(io.victim.way), io.victim.vSetIdx.valid)
(0 until PortNumber).foreach {i =>
touch_sets(i)(1) := victim_vSetIdx_reg(highestIdxBit, 1)
touch_ways(i)(1).bits := victim_way_reg
Expand Down
42 changes: 21 additions & 21 deletions src/main/scala/xiangshan/frontend/icache/ICacheMainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,15 @@ class ICacheMainPipe(implicit p: Parameters) extends ICacheModule
*/
val s1_valid = generatePipeControl(lastFire = s0_fire, thisFire = s1_fire, thisFlush = s1_flush, lastFlush = false.B)

val s1_req_vaddr = RegEnable(s0_req_vaddr, s0_fire)
val s1_req_ptags = RegEnable(s0_req_ptags, s0_fire)
val s1_req_gpaddr = RegEnable(s0_req_gpaddr, s0_fire)
val s1_doubleline = RegEnable(s0_doubleline, s0_fire)
val s1_SRAMhits = RegEnable(s0_hits, s0_fire)
val s1_excp_tlb_af = RegEnable(s0_excp_tlb_af, s0_fire)
val s1_excp_tlb_pf = RegEnable(s0_excp_tlb_pf, s0_fire)
val s1_excp_tlb_gpf = RegEnable(s0_excp_tlb_gpf, s0_fire)
val s1_waymasks = RegEnable(s0_waymasks, s0_fire)
val s1_req_vaddr = RegEnable(s0_req_vaddr, 0.U.asTypeOf(s0_req_vaddr), s0_fire)
val s1_req_ptags = RegEnable(s0_req_ptags, 0.U.asTypeOf(s0_req_ptags), s0_fire)
val s1_req_gpaddr = RegEnable(s0_req_gpaddr, 0.U.asTypeOf(s0_req_gpaddr), s0_fire)
val s1_doubleline = RegEnable(s0_doubleline, 0.U.asTypeOf(s0_doubleline), s0_fire)
val s1_SRAMhits = RegEnable(s0_hits, 0.U.asTypeOf(s0_hits), s0_fire)
val s1_excp_tlb_af = RegEnable(s0_excp_tlb_af, 0.U.asTypeOf(s0_excp_tlb_af), s0_fire)
val s1_excp_tlb_pf = RegEnable(s0_excp_tlb_pf, 0.U.asTypeOf(s0_excp_tlb_pf), s0_fire)
val s1_excp_tlb_gpf = RegEnable(s0_excp_tlb_gpf, 0.U.asTypeOf(s0_excp_tlb_gpf), s0_fire)
val s1_waymasks = RegEnable(s0_waymasks, 0.U.asTypeOf(s0_waymasks), s0_fire)

val s1_req_vSetIdx = s1_req_vaddr.map(get_idx(_))
val s1_req_paddr = s1_req_vaddr.zip(s1_req_ptags).map{case(vaddr, ptag) => get_paddr_from_ptag(vaddr, ptag)}
Expand Down Expand Up @@ -296,23 +296,23 @@ class ICacheMainPipe(implicit p: Parameters) extends ICacheModule

val s2_valid = generatePipeControl(lastFire = s1_fire, thisFire = s2_fire, thisFlush = s2_flush, lastFlush = false.B)

val s2_req_vaddr = RegEnable(s1_req_vaddr, s1_fire)
val s2_req_ptags = RegEnable(s1_req_ptags, s1_fire)
val s2_req_gpaddr = RegEnable(s1_req_gpaddr, s0_fire)
val s2_doubleline = RegEnable(s1_doubleline, s1_fire)
val s2_excp_tlb_af = RegEnable(s1_excp_tlb_af, s1_fire)
val s2_excp_tlb_pf = RegEnable(s1_excp_tlb_pf, s1_fire)
val s2_excp_tlb_gpf = RegEnable(s1_excp_tlb_gpf, s1_fire)
val s2_excp_pmp_af = RegEnable(VecInit(fromPMP.map(_.instr)), s1_fire)
val s2_excp_pmp_mmio = RegEnable(VecInit(fromPMP.map(_.mmio)), s1_fire)
// val s2_data_errors = RegEnable(s1_data_errors, s1_fire)
val s2_req_vaddr = RegEnable(s1_req_vaddr, 0.U.asTypeOf(s1_req_vaddr), s1_fire)
val s2_req_ptags = RegEnable(s1_req_ptags, 0.U.asTypeOf(s1_req_ptags), s1_fire)
val s2_req_gpaddr = RegEnable(s1_req_gpaddr, 0.U.asTypeOf(s1_req_gpaddr), s0_fire)
val s2_doubleline = RegEnable(s1_doubleline, 0.U.asTypeOf(s1_doubleline), s1_fire)
val s2_excp_tlb_af = RegEnable(s1_excp_tlb_af, 0.U.asTypeOf(s1_excp_tlb_af), s1_fire)
val s2_excp_tlb_pf = RegEnable(s1_excp_tlb_pf, 0.U.asTypeOf(s1_excp_tlb_pf), s1_fire)
val s2_excp_tlb_gpf = RegEnable(s1_excp_tlb_gpf, 0.U.asTypeOf(s1_excp_tlb_gpf), s1_fire)
val s2_excp_pmp_af = RegEnable(VecInit(fromPMP.map(_.instr)), 0.U.asTypeOf(VecInit(fromPMP.map(_.instr))), s1_fire)
val s2_excp_pmp_mmio = RegEnable(VecInit(fromPMP.map(_.mmio)), 0.U.asTypeOf(VecInit(fromPMP.map(_.mmio))), s1_fire)
// val s2_data_errors = RegEnable(s1_data_errors, 0.U.asTypeOf(s1_data_errors), s1_fire)

val s2_req_vSetIdx = s2_req_vaddr.map(get_idx(_))
val s2_req_offset = s2_req_vaddr(0)(log2Ceil(blockBytes)-1, 0)
val s2_req_paddr = s2_req_vaddr.zip(s2_req_ptags).map{case(vaddr, ptag) => get_paddr_from_ptag(vaddr, ptag)}

val s2_SRAMhits = RegEnable(s1_SRAMhits, s1_fire)
val s2_codes = RegEnable(s1_codes, s1_fire)
val s2_SRAMhits = RegEnable(s1_SRAMhits, 0.U.asTypeOf(s1_SRAMhits), s1_fire)
val s2_codes = RegEnable(s1_codes, 0.U.asTypeOf(s1_codes), s1_fire)
val s2_hits = RegInit(VecInit(Seq.fill(PortNumber)(false.B)))
val s2_datas = RegInit(VecInit(Seq.fill(ICacheDataBanks)(0.U((blockBits/ICacheDataBanks).W))))

Expand Down
20 changes: 10 additions & 10 deletions src/main/scala/xiangshan/frontend/icache/IPrefetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,13 @@ class IPrefetchPipe(implicit p: Parameters) extends IPrefetchModule
val s1_req_paddr = VecInit((0 until PortNumber).map(i =>
Mux(tlb_valid_pulse(i), s1_req_paddr_wire(i), s1_req_paddr_reg(i))))
val s1_req_gpaddr = VecInit((0 until PortNumber).map(i =>
ResultHoldBypass(valid = tlb_valid_pulse(i), data = fromITLB(i).bits.gpaddr(0))))
ResultHoldBypass(valid = tlb_valid_pulse(i), init = 0.U.asTypeOf(fromITLB(i).bits.gpaddr(0)), data = fromITLB(i).bits.gpaddr(0))))
val itlbExcpPF = VecInit((0 until PortNumber).map(i =>
ResultHoldBypass(valid = tlb_valid_pulse(i), data = fromITLB(i).bits.excp(0).pf.instr)))
ResultHoldBypass(valid = tlb_valid_pulse(i), init = 0.U.asTypeOf(fromITLB(i).bits.excp(0).pf.instr), data = fromITLB(i).bits.excp(0).pf.instr)))
val itlbExcpGPF = VecInit((0 until PortNumber).map(i =>
ResultHoldBypass(valid = tlb_valid_pulse(i), data = fromITLB(i).bits.excp(0).gpf.instr)))
ResultHoldBypass(valid = tlb_valid_pulse(i), init = 0.U.asTypeOf(fromITLB(i).bits.excp(0).gpf.instr), data = fromITLB(i).bits.excp(0).gpf.instr)))
val itlbExcpAF = VecInit((0 until PortNumber).map(i =>
ResultHoldBypass(valid = tlb_valid_pulse(i), data = fromITLB(i).bits.excp(0).af.instr)))
ResultHoldBypass(valid = tlb_valid_pulse(i), init = 0.U.asTypeOf(fromITLB(i).bits.excp(0).af.instr), data = fromITLB(i).bits.excp(0).af.instr)))
val itlbExcp = VecInit((0 until PortNumber).map(i => itlbExcpAF(i) || itlbExcpPF(i) || itlbExcpGPF(i)))

/**
Expand Down Expand Up @@ -335,13 +335,13 @@ class IPrefetchPipe(implicit p: Parameters) extends IPrefetchModule
*/
val s2_valid = generatePipeControl(lastFire = s1_fire, thisFire = s2_fire, thisFlush = s2_flush, lastFlush = false.B)

val s2_req_vaddr = RegEnable(s1_req_vaddr, s1_fire)
val s2_doubleline = RegEnable(s1_doubleline, s1_fire)
val s2_req_paddr = RegEnable(s1_req_paddr, s1_fire)
val s2_req_vaddr = RegEnable(s1_req_vaddr, 0.U.asTypeOf(s1_req_vaddr), s1_fire)
val s2_doubleline = RegEnable(s1_doubleline, 0.U.asTypeOf(s1_doubleline), s1_fire)
val s2_req_paddr = RegEnable(s1_req_paddr, 0.U.asTypeOf(s1_req_paddr), s1_fire)

val s2_pmpExcp = RegEnable(pmpExcp, s1_fire)
val s2_itlbExcp = RegEnable(itlbExcp, s1_fire)
val s2_waymasks = RegEnable(s1_waymasks, s1_fire)
val s2_pmpExcp = RegEnable(pmpExcp, 0.U.asTypeOf(pmpExcp), s1_fire)
val s2_itlbExcp = RegEnable(itlbExcp, 0.U.asTypeOf(itlbExcp), s1_fire)
val s2_waymasks = RegEnable(s1_waymasks, 0.U.asTypeOf(s1_waymasks), s1_fire)

val s2_req_vSetIdx = s2_req_vaddr.map(get_idx(_))
val s2_req_ptags = s2_req_paddr.map(get_phy_tag(_))
Expand Down

0 comments on commit 63f7f8b

Please sign in to comment.