From 2e37d2ce3f7359aa4ca47a46c6df66c6d3c38214 Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Mon, 23 Oct 2023 20:31:00 -0700 Subject: [PATCH] Only check opcode validity when fire ... otherwise assertion goes off with garbage-value opcode during reset. --- src/main/scala/tilelink/Coalescing.scala | 43 +++++++++++++----------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 1b4d71a..85a24f3 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -233,9 +233,9 @@ class Response(sourceWidth: Int, sizeWidth: Int, dataWidth: Int) Mux(this.op.asBool, apBits, agBits) } - def fromTLD(bundle: TLBundleD): Unit = { + def fromTLD(bundle: TLBundleD, checkOpcode: Bool): Unit = { this.source := bundle.source - this.op := TLUtils.DOpcodeIsStore(bundle.opcode) + this.op := TLUtils.DOpcodeIsStore(bundle.opcode, checkOpcode) this.size := bundle.size this.data := bundle.data this.error := bundle.denied @@ -864,7 +864,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) // Request queue val req = Wire(nonCoalReqT) - req.op := TLUtils.AOpcodeIsStore(tlIn.a.bits.opcode) + req.op := TLUtils.AOpcodeIsStore(tlIn.a.bits.opcode, tlIn.a.fire) req.source := tlIn.a.bits.source req.address := tlIn.a.bits.address req.data := tlIn.a.bits.data @@ -1012,7 +1012,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) // coalesced responses and serve them back to the core side. val respQueue = respQueues(lane) val resp = Wire(respQueueEntryT) - resp.fromTLD(tlOut.d.bits) + resp.fromTLD(tlOut.d.bits, tlOut.d.fire) // Queue up responses that didn't get coalesced originally ("noncoalesced" responses). // Coalesced (but uncoalesced back) responses will also be enqueued into the same queue. @@ -1050,7 +1050,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) // // Connect coalesced response uncoalescer.io.coalResp.valid := tlCoal.d.valid - uncoalescer.io.coalResp.bits.fromTLD(tlCoal.d.bits) + uncoalescer.io.coalResp.bits.fromTLD(tlCoal.d.bits, tlCoal.d.fire) // Connect lookup result from InflightTable uncoalescer.io.inflightLookup <> inflightTable.io.lookup // InflightTable IO: Look up the table with incoming coalesced responses @@ -1340,19 +1340,24 @@ class InFlightTableEntry( } object TLUtils { - def AOpcodeIsStore(opcode: UInt): Bool = { + def AOpcodeIsStore(opcode: UInt, checkOpcode: Bool): Bool = { // 0: PutFullData, 1: PutPartialData, 4: Get - assert( - opcode === TLMessages.PutFullData || opcode === TLMessages.Get, - "unhandled TL A opcode found" - ) + when(checkOpcode) { + assert( + opcode === TLMessages.PutFullData || opcode === TLMessages.Get, + "unhandled TL A opcode found" + ) + } Mux(opcode === TLMessages.PutFullData, true.B, false.B) } - def DOpcodeIsStore(opcode: UInt): Bool = { - assert( - opcode === TLMessages.AccessAck || opcode === TLMessages.AccessAckData, - "unhandled TL D opcode found" - ) + def DOpcodeIsStore(opcode: UInt, checkOpcode: Bool): Bool = { + printf("DOpcodeIsStore: opcode=%d\n", opcode) + when(checkOpcode) { + assert( + opcode === TLMessages.AccessAck || opcode === TLMessages.AccessAckData, + "unhandled TL D opcode found" + ) + } Mux(opcode === TLMessages.AccessAck, true.B, false.B) } } @@ -1711,7 +1716,7 @@ class MemTraceLogger( // and transaction happened. req.valid := tlIn.a.fire req.size := tlIn.a.bits.size - req.is_store := TLUtils.AOpcodeIsStore(tlIn.a.bits.opcode) + req.is_store := TLUtils.AOpcodeIsStore(tlIn.a.bits.opcode, tlIn.a.fire) req.source := tlIn.a.bits.source // TL always carries the exact unaligned address that the client // originally requested, so no postprocessing required @@ -1761,7 +1766,7 @@ class MemTraceLogger( // and transaction happened. resp.valid := tlOut.d.fire resp.size := tlOut.d.bits.size - resp.is_store := TLUtils.DOpcodeIsStore(tlOut.d.bits.opcode) + resp.is_store := TLUtils.DOpcodeIsStore(tlOut.d.bits.opcode, tlOut.d.fire) resp.source := tlOut.d.bits.source // NOTE: TL D channel doesn't carry address nor mask, so there's no easy // way to figure out which bytes the master actually use. Since we @@ -2250,7 +2255,7 @@ class CoalescerXbarImpl(outer: CoalescerXbar, case(node,resp) => val (tlOut, _) = node.out(0) val nonCoalResp = Wire(respNonCoalEntryT) - nonCoalResp.fromTLD(tlOut.d.bits) + nonCoalResp.fromTLD(tlOut.d.bits, tlOut.d.fire) tlOut.d.ready := resp.ready resp.valid := tlOut.d.valid resp.bits := nonCoalResp @@ -2271,7 +2276,7 @@ class CoalescerXbarImpl(outer: CoalescerXbar, io.coalResp.valid := coalRespRRArbiter.io.out.valid coalRespRRArbiter.io.out.ready := io.coalResp.ready val coalRespBundle = Wire(respCoalBundleT) - coalRespBundle.fromTLD(coalRespRRArbiter.io.out.bits) + coalRespBundle.fromTLD(coalRespRRArbiter.io.out.bits, coalRespRRArbiter.io.out.fire) io.coalResp.bits := coalRespBundle