1
0

Don't stall the frontend, making it easier to add more features later

This commit is contained in:
Andrew Waterman
2017-04-19 16:51:39 -07:00
committed by Andrew Waterman
parent 061a0adceb
commit d24d8ff84b
4 changed files with 55 additions and 54 deletions

View File

@ -47,7 +47,7 @@ class ICacheBundle(outer: ICache) extends CoreBundle()(outer.p) {
val s1_kill = Bool(INPUT) // delayed one cycle w.r.t. req
val s2_kill = Bool(INPUT) // delayed two cycles; prevents I$ miss emission
val resp = Decoupled(UInt(width = coreInstBits * fetchWidth))
val resp = Valid(UInt(width = coreInstBits * fetchWidth))
val invalidate = Bool(INPUT)
val mem = outer.node.bundleOut
}
@ -65,7 +65,6 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
val s_ready :: s_request :: s_refill :: Nil = Enum(UInt(), 3)
val state = Reg(init=s_ready)
val invalidated = Reg(Bool())
val stall = !io.resp.ready
val refill_addr = Reg(UInt(width = paddrBits))
val s1_tag_hit = Wire(Vec(nWays, Bool()))
@ -78,10 +77,10 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
val s1_hit = out_valid && s1_any_tag_hit
val s1_miss = s1_valid && state === s_ready && !s1_any_tag_hit
val s0_valid = io.req.valid && state === s_ready && !(s1_valid && stall)
val s0_valid = io.req.valid && state === s_ready
val s0_vaddr = io.req.bits.addr
s1_valid := s0_valid || out_valid && stall
s1_valid := s0_valid
when (s1_miss) { refill_addr := io.s1_paddr }
val refill_tag = refill_addr(tagBits+untagBits-1,untagBits)
@ -116,8 +115,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
for (i <- 0 until nWays) {
val s1_vb = vb_array(Cat(UInt(i), io.s1_paddr(untagBits-1,blockOffBits))).toBool
s1_tag_disparity(i) := (code.decode(tag_rdata(i)).error holdUnless s1_dout_valid)
s1_tag_hit(i) := s1_vb && ((code.decode(tag_rdata(i)).uncorrected === s1_tag) holdUnless s1_dout_valid)
s1_tag_disparity(i) := code.decode(tag_rdata(i)).error
s1_tag_hit(i) := s1_vb && code.decode(tag_rdata(i)).uncorrected === s1_tag
}
require(rowBits % wordBits == 0)
@ -131,7 +130,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
}
def wordMatch(addr: UInt) = addr.extract(log2Ceil(rowBytes)-1, log2Ceil(wordBits/8)) === i
val s0_raddr = s0_vaddr(untagBits-1,blockOffBits-log2Ceil(refillCycles))
val dout = data_array.read(s0_raddr, !wen && (s0_valid && wordMatch(s0_vaddr))) holdUnless s1_dout_valid
val dout = data_array.read(s0_raddr, !wen && (s0_valid && wordMatch(s0_vaddr)))
when (wordMatch(io.s1_paddr)) {
s1_dout := dout
}
@ -145,7 +144,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
data_array.write((refill_idx << log2Ceil(refillCycles)) | refill_cnt, e_d)
}
val s0_raddr = s0_vaddr(untagBits-1,blockOffBits-log2Ceil(refillCycles))
s1_dout(i) := data_array.read(s0_raddr, !wen && s0_valid) holdUnless s1_dout_valid
s1_dout(i) := data_array.read(s0_raddr, !wen && s0_valid)
}
*/
@ -156,13 +155,13 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
io.resp.bits := Mux1H(s1_tag_hit, s1_dout)
io.resp.valid := s1_hit
case 2 =>
val s2_valid = RegEnable(out_valid, Bool(false), !stall)
val s2_hit = RegEnable(s1_hit, Bool(false), !stall)
val s2_tag_hit = RegEnable(s1_tag_hit, !stall)
val s2_dout = RegEnable(s1_dout, !stall)
val s2_valid = RegNext(out_valid, Bool(false))
val s2_hit = RegNext(s1_hit, Bool(false))
val s2_tag_hit = RegEnable(s1_tag_hit, s1_valid)
val s2_dout = RegEnable(s1_dout, s1_valid)
val s2_way_mux = Mux1H(s2_tag_hit, s2_dout)
val s2_tag_disparity = RegEnable(s1_tag_disparity, !stall).asUInt.orR
val s2_tag_disparity = RegEnable(s1_tag_disparity, s1_valid).asUInt.orR
val s2_data_disparity = code.decode(s2_way_mux).error
val s2_disparity = s2_tag_disparity || s2_data_disparity
when (s2_valid && s2_disparity) { invalidate := true }