From 8cee61a591b5d72fa10bc1fd240ae959c39c57f1 Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Sun, 23 Apr 2023 14:42:10 -0700 Subject: [PATCH] Uncoalesce using table size enum --- src/main/scala/tilelink/Coalescing.scala | 49 ++++++++++++------- .../scala/coalescing/CoalescingUnitTest.scala | 13 ++--- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index 996a24a..1806b0b 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -11,17 +11,24 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util.MultiPortQueue import freechips.rocketchip.unittest._ -object InFlightTableSizeEnum extends ChiselEnum { +trait InFlightTableSizeEnum extends ChiselEnum { + val INVALID: Type + val FOUR: Type + def logSizeToEnum(x: UInt): Type + def enumToLogSize(x: Type): UInt +} + +object DefaultInFlightTableSizeEnum extends InFlightTableSizeEnum { val INVALID = Value(0.U) val FOUR = Value(1.U) - def log2Enum(x: UInt): Type = { + def logSizeToEnum(x: UInt): Type = { MuxCase(INVALID, Seq( (x === 2.U) -> FOUR )) } - def enum2log(x: Type): UInt = { + def enumToLogSize(x: Type): UInt = { MuxCase(0.U, Seq( (x === FOUR) -> 2.U )) @@ -41,7 +48,7 @@ case class CoalescerConfig( NUM_OLD_IDS: Int, // num of outstanding requests per lane, from processor NUM_NEW_IDS: Int, // num of outstanding coalesced requests COAL_SIZES: Seq[Int], - SizeEnum: ChiselEnum + SizeEnum: InFlightTableSizeEnum ) object defaultConfig extends CoalescerConfig( @@ -58,7 +65,7 @@ object defaultConfig extends CoalescerConfig( NUM_OLD_IDS = 16, // num of outstanding requests per lane, from processor NUM_NEW_IDS = 4, // num of outstanding coalesced requests COAL_SIZES = Seq(3), - SizeEnum = InFlightTableSizeEnum + SizeEnum = DefaultInFlightTableSizeEnum ) class CoalescingUnit(config: CoalescerConfig)(implicit p: Parameters) extends LazyModule { @@ -436,7 +443,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends dontTouch(tlOut.d) } - // Construct new entry for the inflight table + // Construct new entry for the inflight table // FIXME: don't instantiate inflight table entry type here. It leaks the table's impl // detail to the coalescer @@ -446,13 +453,13 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends // this also reduces top level clutter. val offsetBits = 4 // FIXME hardcoded - val sizeBits = log2Ceil(config.MAX_SIZE) // FIXME This is should be not the TL size bits // but the width of the size enum val newEntry = Wire( - new InflightCoalReqTableEntry(config.NUM_LANES, numPerLaneReqs, sourceWidth, offsetBits, sizeBits) + new InflightCoalReqTableEntry(config.NUM_LANES, numPerLaneReqs, sourceWidth, offsetBits, + config.SizeEnum) ) println(s"=========== table sourceWidth: ${sourceWidth}") - println(s"=========== table sizeBits: ${sizeBits}") + // println(s"=========== table sizeEnumBits: ${newEntry.sizeEnumBits}") newEntry.source := coalescer.io.out_req.bits.source // TODO: richard to write table fill logic @@ -465,7 +472,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends r.valid := false.B r.source := origReqs(i).source r.offset := (origReqs(i).address % (1 << config.MAX_SIZE).U) >> config.WORD_WIDTH - r.size := origReqs(i).size + r.sizeEnum := config.SizeEnum.logSizeToEnum(origReqs(i).size) } } newEntry.lanes(0).reqs(0).valid := true.B @@ -562,12 +569,15 @@ class UncoalescingUnit(config: CoalescerConfig) extends Module { // Un-coalescing logic // def getCoalescedDataChunk(data: UInt, dataWidth: Int, offset: UInt, logSize: UInt): UInt = { + assert(logSize === 2.U, "currently only supporting 4-byte accesses. TODO") + + // sizeInBits should be simulation-only construct val sizeInBits = (1.U << logSize) << 3.U assert( (dataWidth > 0).B && (dataWidth.U % sizeInBits === 0.U), s"coalesced data width ($dataWidth) not evenly divisible by core req size ($sizeInBits)" ) - assert(logSize === 2.U, "currently only supporting 4-byte accesses. TODO") + val numChunks = dataWidth / 32 val chunks = Wire(Vec(numChunks, UInt(32.W))) val offsets = (0 until numChunks) @@ -594,9 +604,14 @@ class UncoalescingUnit(config: CoalescerConfig) extends Module { when(inflightTable.io.lookup.valid) { ioOldReq.valid := oldReq.valid ioOldReq.bits.source := oldReq.source - ioOldReq.bits.size := oldReq.size + // FIXME: this is janky. We can't use config.SizeEnum.enumToLogSize for + // some reason because type checker complains that config.SizeEnum.Type + // is different from found.sizeEnumType.type + // val logSize = config.SizeEnum.enumToLogSize(oldReq.sizeEnum) + val logSize = found.sizeEnumType.enumToLogSize(oldReq.sizeEnum) + ioOldReq.bits.size := logSize ioOldReq.bits.data := - getCoalescedDataChunk(io.coalResp.bits.data, io.coalResp.bits.data.getWidth, oldReq.offset, oldReq.size) + getCoalescedDataChunk(io.coalResp.bits.data, io.coalResp.bits.data.getWidth, oldReq.offset, logSize) } } } @@ -611,7 +626,7 @@ class InflightCoalReqTable(config: CoalescerConfig) extends Module { val offsetBits = 4 // FIXME hardcoded val sizeBits = 2 // FIXME hardcoded val entryT = new InflightCoalReqTableEntry(config.NUM_LANES, config.DEPTH, - log2Ceil(config.NUM_OLD_IDS), config.MAX_SIZE, config.SizeEnum.getWidth) + log2Ceil(config.NUM_OLD_IDS), config.MAX_SIZE, config.SizeEnum) val entries = config.NUM_NEW_IDS val sourceWidth = log2Ceil(config.NUM_OLD_IDS) @@ -640,7 +655,7 @@ class InflightCoalReqTable(config: CoalescerConfig) extends Module { r.valid := false.B r.source := 0.U r.offset := 0.U - r.size := 0.U + r.sizeEnum := config.SizeEnum.INVALID } } } @@ -688,14 +703,14 @@ class InflightCoalReqTableEntry( val numPerLaneReqs: Int, val sourceWidth: Int, val offsetBits: Int, - val sizeBits: Int + val sizeEnumType: InFlightTableSizeEnum ) extends Bundle { class PerCoreReq extends Bundle { val valid = Bool() // FIXME: oldId and newId shares the same width val source = UInt(sourceWidth.W) val offset = UInt(offsetBits.W) - val size = UInt(sizeBits.W) + val sizeEnum = sizeEnumType() } class PerLane extends Bundle { val reqs = Vec(numPerLaneReqs, new PerCoreReq) diff --git a/src/test/scala/coalescing/CoalescingUnitTest.scala b/src/test/scala/coalescing/CoalescingUnitTest.scala index 61d1de9..c37396c 100644 --- a/src/test/scala/coalescing/CoalescingUnitTest.scala +++ b/src/test/scala/coalescing/CoalescingUnitTest.scala @@ -264,13 +264,8 @@ class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester { val coalDataWidth = 128 val numInflightCoalRequests = 4 - val hey = new TLBundleParameters(64, 64, 64, 64, 64) it should "work" in { - test( - new UncoalescingUnit( - defaultConfig, - ) - ) + test(new UncoalescingUnit(defaultConfig)) // vcs helps with simulation time, but sometimes errors with // "mutation occurred during iteration" java error // .withAnnotations(Seq(VcsBackendAnnotation)) @@ -301,10 +296,10 @@ class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester { c.clock.step() - c.io.coalRespValid.poke(true.B) - c.io.coalRespSrcId.poke(sourceId) + c.io.coalResp.valid.poke(true.B) + c.io.coalResp.bits.source.poke(sourceId) val lit = (BigInt(0x0123456789abcdefL) << 64) | BigInt(0x5ca1ab1edeadbeefL) - c.io.coalRespData.poke(lit.U) + c.io.coalResp.bits.data.poke(lit.U) // table lookup is combinational at the same cycle c.io.uncoalResps(0)(0).valid.expect(true.B)