From 1cc665717d22432c9b1584d7aebe9f26ed457ea3 Mon Sep 17 00:00:00 2001 From: Scott Johnson Date: Thu, 4 May 2017 00:07:08 -0700 Subject: [PATCH 1/3] Wes fix for AXI2TL timeout when writes backed up --- src/main/scala/uncore/axi4/ToTL.scala | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/scala/uncore/axi4/ToTL.scala b/src/main/scala/uncore/axi4/ToTL.scala index bce1c60b..9a5872f5 100644 --- a/src/main/scala/uncore/axi4/ToTL.scala +++ b/src/main/scala/uncore/axi4/ToTL.scala @@ -50,9 +50,11 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => val numIds = edgeIn.master.endId val beatBytes = edgeOut.manager.beatBytes - val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 + val beatCountBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 val maxFlight = edgeIn.master.masters.map(_.maxFlight.get).max - val addedBits = log2Ceil(maxFlight) + 1 + val logFlight = log2Ceil(maxFlight) + val txnCountBits = log2Ceil(maxFlight+1) // wrap-around must not block b_allow + val addedBits = logFlight + 1 // +1 for read vs. write source ID require (edgeIn.master.userBits == 0, "AXI4 user bits cannot be transported by TL") require (edgeIn.master.masters(0).aligned) @@ -72,10 +74,10 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule val r_size = OH1ToUInt(r_size1) val r_ok = edgeOut.manager.supportsGetSafe(in.ar.bits.addr, r_size) val r_addr = Mux(r_ok, in.ar.bits.addr, UInt(error) | in.ar.bits.addr(log2Up(beatBytes)-1, 0)) - val r_count = RegInit(Vec.fill(numIds) { UInt(0, width = log2Ceil(maxFlight)) }) - val r_id = Cat(in.ar.bits.id, r_count(in.ar.bits.id), UInt(0, width=1)) + val r_count = RegInit(Vec.fill(numIds) { UInt(0, width = txnCountBits) }) + val r_id = Cat(in.ar.bits.id, r_count(in.ar.bits.id)(logFlight-1,0), UInt(0, width=1)) - assert (!in.ar.valid || r_size1 === UIntToOH1(r_size, countBits)) // because aligned + assert (!in.ar.valid || r_size1 === UIntToOH1(r_size, beatCountBits)) // because aligned in.ar.ready := r_out.ready r_out.valid := in.ar.valid r_out.bits := edgeOut.Get(r_id, r_addr, r_size)._2 @@ -90,10 +92,10 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule val w_size = OH1ToUInt(w_size1) val w_ok = edgeOut.manager.supportsPutPartialSafe(in.aw.bits.addr, w_size) val w_addr = Mux(w_ok, in.aw.bits.addr, UInt(error) | in.aw.bits.addr(log2Up(beatBytes)-1, 0)) - val w_count = RegInit(Vec.fill(numIds) { UInt(0, width = log2Ceil(maxFlight)) }) - val w_id = Cat(in.aw.bits.id, w_count(in.aw.bits.id), UInt(1, width=1)) + val w_count = RegInit(Vec.fill(numIds) { UInt(0, width = txnCountBits) }) + val w_id = Cat(in.aw.bits.id, w_count(in.aw.bits.id)(logFlight-1,0), UInt(1, width=1)) - assert (!in.aw.valid || w_size1 === UIntToOH1(w_size, countBits)) // because aligned + assert (!in.aw.valid || w_size1 === UIntToOH1(w_size, beatCountBits)) // because aligned assert (!in.aw.valid || in.aw.bits.len === UInt(0) || in.aw.bits.size === UInt(log2Ceil(beatBytes))) // because aligned in.aw.ready := w_out.ready && in.w.valid && in.w.bits.last in.w.ready := w_out.ready && in.aw.valid @@ -134,7 +136,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule // We need to prevent sending B valid before the last W beat is accepted // TileLink allows early acknowledgement of a write burst, but AXI does not. - val b_count = RegInit(Vec.fill(numIds) { UInt(0, width = log2Ceil(maxFlight)) }) + val b_count = RegInit(Vec.fill(numIds) { UInt(0, width = txnCountBits) }) val b_allow = b_count(in.b.bits.id) =/= w_count(in.b.bits.id) val b_sel = UIntToOH(in.b.bits.id, numIds) From 398600d4dad56fd200e0df41f21b762113bba1e3 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 4 May 2017 00:24:13 -0700 Subject: [PATCH 2/3] Interlock to prevent ITIM hazard when tl.a.valid & tl.d.valid & !tl.d.ready --- src/main/scala/rocket/ICache.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index ef766d93..bb8f3824 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -226,7 +226,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) io.resp.valid := s2_valid && s2_hit && !s2_disparity tl_in.map { tl => - tl.a.ready := !(tl_out.d.valid || s1_slaveValid || s2_slaveValid || s3_slaveValid) + val respValid = RegInit(false.B) + tl.a.ready := !(tl_out.d.valid || s1_slaveValid || s2_slaveValid || s3_slaveValid || respValid) val s1_a = RegEnable(tl.a.bits, s0_slaveValid) when (s0_slaveValid) { val a = tl.a.bits @@ -243,7 +244,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) } assert(!s2_valid || RegNext(RegNext(s0_vaddr)) === io.s2_vaddr) - when (!(tl.a.valid || s1_slaveValid || s2_slaveValid) + when (!(tl.a.valid || s1_slaveValid || s2_slaveValid || respValid) && s2_valid && s2_data_decoded.correctable && !s2_tag_disparity) { // handle correctable errors on CPU accesses to the scratchpad. // if there is an in-flight slave-port access to the scratchpad, @@ -254,7 +255,6 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) s1s3_slaveAddr := Cat(OHToUInt(s2_tag_hit), io.s2_vaddr(untagBits-1, log2Ceil(wordBits/8)), s1s3_slaveAddr(log2Ceil(wordBits/8)-1, 0)) } - val respValid = RegInit(false.B) respValid := s2_slaveValid || (respValid && !tl.d.ready) when (s2_slaveValid) { when (edge_in.get.hasData(s1_a) || s2_data_decoded.correctable) { s3_slaveValid := true } From 1b3b228790aa4b10916198be2236cf9d2a5690b2 Mon Sep 17 00:00:00 2001 From: Scott Johnson Date: Wed, 3 May 2017 19:29:47 -0700 Subject: [PATCH 3/3] ITIM supports PutPartial --- src/main/scala/rocket/ICache.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index bb8f3824..bba36801 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -47,6 +47,7 @@ class ICache(val latency: Int, val hartid: Int)(implicit p: Parameters) extends regionType = RegionType.UNCACHED, executable = true, supportsPutFull = TransferSizes(1, wordBytes), + supportsPutPartial = TransferSizes(1, wordBytes), supportsGet = TransferSizes(1, wordBytes), fifoId = Some(0))), // requests handled in FIFO order beatBytes = wordBytes,