提交 cd4b0298 编写于 作者: Z Zihao Yu

noop,Cache: latch dataArray read result once it is available

* this will create output registers of BRAM to imporve timing
上级 a927bb53
......@@ -113,7 +113,6 @@ sealed class CacheStage1(implicit val cacheConfig: CacheConfig) extends CacheMod
sealed class Stage2IO(implicit val cacheConfig: CacheConfig) extends CacheBundle {
val req = new SimpleBusReqBundle(userBits = userBits)
val metas = Vec(Ways, new MetaBundle)
val datas = Vec(Ways, new DataBundle)
val hit = Output(Bool())
val waymask = Output(UInt(Ways.W))
val mmio = Output(Bool())
......@@ -127,7 +126,6 @@ sealed class CacheStage2(implicit val cacheConfig: CacheConfig) extends CacheMod
val in = Flipped(Decoupled(new Stage1IO))
val out = Decoupled(new Stage2IO)
val metaReadResp = Flipped(Vec(Ways, new MetaBundle))
val dataReadResp = Flipped(Vec(Ways, new DataBundle))
val metaWriteBus = Input(CacheMetaArrayWriteBus())
val dataWriteBus = Input(CacheDataArrayWriteBus())
})
......@@ -142,7 +140,7 @@ sealed class CacheStage2(implicit val cacheConfig: CacheConfig) extends CacheMod
val forwardMetaReg = RegEnable(io.metaWriteBus.req.bits, isForwardMeta)
val metaWay = Wire(Vec(Ways, chiselTypeOf(forwardMetaReg.data)))
forwardMetaReg.waymask.getOrElse("1b".U).asBools.zipWithIndex.map { case (w, i) =>
forwardMetaReg.waymask.getOrElse("b1".U).asBools.zipWithIndex.map { case (w, i) =>
metaWay(i) := Mux(isForwardMetaReg && w, forwardMetaReg.data, io.metaReadResp(i))
}
......@@ -154,7 +152,6 @@ sealed class CacheStage2(implicit val cacheConfig: CacheConfig) extends CacheMod
io.out.bits.metas := metaWay
io.out.bits.hit := io.in.valid && hitVec.orR
io.out.bits.waymask := waymask
io.out.bits.datas := io.dataReadResp
io.out.bits.mmio := AddressSpace.isMMIO(req.addr)
val isForwardData = io.in.valid && (io.dataWriteBus.req match { case r =>
......@@ -180,6 +177,7 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod
val isFinish = Output(Bool())
val flush = Input(Bool())
val dataReadBus = CacheDataArrayReadBus()
val dataReadFromS1 = Flipped(Vec(Ways, new DataBundle))
val dataWriteBus = CacheDataArrayWriteBus()
val metaWriteBus = CacheMetaArrayWriteBus()
......@@ -200,8 +198,20 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod
val meta = Mux1H(io.in.bits.waymask, io.in.bits.metas)
assert(!(mmio && hit), "MMIO request should not hit in cache")
val useForwardData = io.in.bits.isForwardData && io.in.bits.waymask === io.in.bits.forwardData.waymask.getOrElse("1b".U)
val dataReadArray = Mux1H(io.in.bits.waymask, io.in.bits.datas).data
val s_idle :: s_memReadReq :: s_memReadResp :: s_memWriteReq :: s_memWriteResp :: s_mmioReq :: s_mmioResp :: s_wait_resp :: s_release :: Nil = Enum(9)
val state = RegInit(s_idle)
val needFlush = RegInit(false.B)
when (io.flush && (state =/= s_idle)) { needFlush := true.B }
when (io.out.fire() && needFlush) { needFlush := false.B }
val firstCycle = RegInit(true.B)
when (io.isFinish || io.flush || needFlush) { firstCycle := true.B }
.elsewhen (io.in.valid) { firstCycle := false.B }
// latch the data array result to avoid being overwritten by new s1 request
val dataReadArray = HoldUnless(Mux1H(io.in.bits.waymask, io.dataReadFromS1).data, firstCycle)
val useForwardData = io.in.bits.isForwardData && io.in.bits.waymask === io.in.bits.forwardData.waymask.getOrElse("b1".U)
val dataRead = Mux(useForwardData, io.in.bits.forwardData.data.data, dataReadArray)
val wordMask = Mux(!ro.B && req.isWrite(), MaskExpand(req.wmask), 0.U(DataBits.W))
......@@ -215,12 +225,6 @@ sealed class CacheStage3(implicit val cacheConfig: CacheConfig) extends CacheMod
data = Wire(new MetaBundle).apply(tag = meta.tag, valid = true.B, dirty = (!ro).B)
)
val s_idle :: s_memReadReq :: s_memReadResp :: s_memWriteReq :: s_memWriteResp :: s_mmioReq :: s_mmioResp :: s_wait_resp :: s_release :: Nil = Enum(9)
val state = RegInit(s_idle)
val needFlush = RegInit(false.B)
when (io.flush && (state =/= s_idle)) { needFlush := true.B }
when (io.out.fire() && needFlush) { needFlush := false.B }
val readBeatCnt = Counter(LineBeats)
val writeBeatCnt = Counter(LineBeats)
......@@ -371,7 +375,7 @@ class Cache(implicit val cacheConfig: CacheConfig) extends CacheModule {
val s2 = Module(new CacheStage2)
val s3 = Module(new CacheStage3)
val metaArray = Module(new SRAMTemplateWithArbiter(nRead = 1, new MetaBundle, set = Sets, way = Ways, shouldReset = true))
val dataArray = Module(new SRAMTemplateWithArbiter(nRead = 2, new DataBundle, set = Sets * LineBeats, way = Ways))
val dataArray = Module(new SRAMTemplate(new DataBundle, set = Sets * LineBeats, way = Ways))
if (cacheName == "icache") {
// flush icache when executing fence.i
......@@ -408,14 +412,20 @@ class Cache(implicit val cacheConfig: CacheConfig) extends CacheModule {
}
metaArray.io.r(0) <> s1.io.metaReadBus
dataArray.io.r(0) <> s1.io.dataReadBus
dataArray.io.r(1) <> s3.io.dataReadBus
val dataArrayReadArb = Module(new Arbiter(chiselTypeOf(dataArray.io.r.req.bits), 2))
dataArrayReadArb.io.in(0) <> s3.io.dataReadBus.req
dataArrayReadArb.io.in(1) <> s1.io.dataReadBus.req
dataArray.io.r.req <> dataArrayReadArb.io.out
s3.io.dataReadBus.resp := dataArray.io.r.resp
s1.io.dataReadBus.resp := dataArray.io.r.resp
metaArray.io.w <> s3.io.metaWriteBus
dataArray.io.w <> s3.io.dataWriteBus
s2.io.metaReadResp := s1.io.metaReadBus.resp.data
s2.io.dataReadResp := s1.io.dataReadBus.resp.data
s3.io.dataReadFromS1 := RegEnable(s1.io.dataReadBus.resp.data, RegNext(s1.io.dataReadBus.req.fire()))
s2.io.dataWriteBus := s3.io.dataWriteBus
s2.io.metaWriteBus := s3.io.metaWriteBus
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册