Uncoalesce using table size enum
This commit is contained in:
@@ -11,17 +11,24 @@ import freechips.rocketchip.diplomacy._
|
|||||||
import freechips.rocketchip.util.MultiPortQueue
|
import freechips.rocketchip.util.MultiPortQueue
|
||||||
import freechips.rocketchip.unittest._
|
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 INVALID = Value(0.U)
|
||||||
val FOUR = Value(1.U)
|
val FOUR = Value(1.U)
|
||||||
|
|
||||||
def log2Enum(x: UInt): Type = {
|
def logSizeToEnum(x: UInt): Type = {
|
||||||
MuxCase(INVALID, Seq(
|
MuxCase(INVALID, Seq(
|
||||||
(x === 2.U) -> FOUR
|
(x === 2.U) -> FOUR
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def enum2log(x: Type): UInt = {
|
def enumToLogSize(x: Type): UInt = {
|
||||||
MuxCase(0.U, Seq(
|
MuxCase(0.U, Seq(
|
||||||
(x === FOUR) -> 2.U
|
(x === FOUR) -> 2.U
|
||||||
))
|
))
|
||||||
@@ -41,7 +48,7 @@ case class CoalescerConfig(
|
|||||||
NUM_OLD_IDS: Int, // num of outstanding requests per lane, from processor
|
NUM_OLD_IDS: Int, // num of outstanding requests per lane, from processor
|
||||||
NUM_NEW_IDS: Int, // num of outstanding coalesced requests
|
NUM_NEW_IDS: Int, // num of outstanding coalesced requests
|
||||||
COAL_SIZES: Seq[Int],
|
COAL_SIZES: Seq[Int],
|
||||||
SizeEnum: ChiselEnum
|
SizeEnum: InFlightTableSizeEnum
|
||||||
)
|
)
|
||||||
|
|
||||||
object defaultConfig extends CoalescerConfig(
|
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_OLD_IDS = 16, // num of outstanding requests per lane, from processor
|
||||||
NUM_NEW_IDS = 4, // num of outstanding coalesced requests
|
NUM_NEW_IDS = 4, // num of outstanding coalesced requests
|
||||||
COAL_SIZES = Seq(3),
|
COAL_SIZES = Seq(3),
|
||||||
SizeEnum = InFlightTableSizeEnum
|
SizeEnum = DefaultInFlightTableSizeEnum
|
||||||
)
|
)
|
||||||
|
|
||||||
class CoalescingUnit(config: CoalescerConfig)(implicit p: Parameters) extends LazyModule {
|
class CoalescingUnit(config: CoalescerConfig)(implicit p: Parameters) extends LazyModule {
|
||||||
@@ -436,7 +443,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
dontTouch(tlOut.d)
|
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
|
// FIXME: don't instantiate inflight table entry type here. It leaks the table's impl
|
||||||
// detail to the coalescer
|
// detail to the coalescer
|
||||||
|
|
||||||
@@ -446,13 +453,13 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
// this also reduces top level clutter.
|
// this also reduces top level clutter.
|
||||||
|
|
||||||
val offsetBits = 4 // FIXME hardcoded
|
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
|
// but the width of the size enum
|
||||||
val newEntry = Wire(
|
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 sourceWidth: ${sourceWidth}")
|
||||||
println(s"=========== table sizeBits: ${sizeBits}")
|
// println(s"=========== table sizeEnumBits: ${newEntry.sizeEnumBits}")
|
||||||
newEntry.source := coalescer.io.out_req.bits.source
|
newEntry.source := coalescer.io.out_req.bits.source
|
||||||
|
|
||||||
// TODO: richard to write table fill logic
|
// TODO: richard to write table fill logic
|
||||||
@@ -465,7 +472,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
r.valid := false.B
|
r.valid := false.B
|
||||||
r.source := origReqs(i).source
|
r.source := origReqs(i).source
|
||||||
r.offset := (origReqs(i).address % (1 << config.MAX_SIZE).U) >> config.WORD_WIDTH
|
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
|
newEntry.lanes(0).reqs(0).valid := true.B
|
||||||
@@ -562,12 +569,15 @@ class UncoalescingUnit(config: CoalescerConfig) extends Module {
|
|||||||
// Un-coalescing logic
|
// Un-coalescing logic
|
||||||
//
|
//
|
||||||
def getCoalescedDataChunk(data: UInt, dataWidth: Int, offset: UInt, logSize: UInt): UInt = {
|
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
|
val sizeInBits = (1.U << logSize) << 3.U
|
||||||
assert(
|
assert(
|
||||||
(dataWidth > 0).B && (dataWidth.U % sizeInBits === 0.U),
|
(dataWidth > 0).B && (dataWidth.U % sizeInBits === 0.U),
|
||||||
s"coalesced data width ($dataWidth) not evenly divisible by core req size ($sizeInBits)"
|
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 numChunks = dataWidth / 32
|
||||||
val chunks = Wire(Vec(numChunks, UInt(32.W)))
|
val chunks = Wire(Vec(numChunks, UInt(32.W)))
|
||||||
val offsets = (0 until numChunks)
|
val offsets = (0 until numChunks)
|
||||||
@@ -594,9 +604,14 @@ class UncoalescingUnit(config: CoalescerConfig) extends Module {
|
|||||||
when(inflightTable.io.lookup.valid) {
|
when(inflightTable.io.lookup.valid) {
|
||||||
ioOldReq.valid := oldReq.valid
|
ioOldReq.valid := oldReq.valid
|
||||||
ioOldReq.bits.source := oldReq.source
|
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 :=
|
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 offsetBits = 4 // FIXME hardcoded
|
||||||
val sizeBits = 2 // FIXME hardcoded
|
val sizeBits = 2 // FIXME hardcoded
|
||||||
val entryT = new InflightCoalReqTableEntry(config.NUM_LANES, config.DEPTH,
|
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 entries = config.NUM_NEW_IDS
|
||||||
val sourceWidth = log2Ceil(config.NUM_OLD_IDS)
|
val sourceWidth = log2Ceil(config.NUM_OLD_IDS)
|
||||||
@@ -640,7 +655,7 @@ class InflightCoalReqTable(config: CoalescerConfig) extends Module {
|
|||||||
r.valid := false.B
|
r.valid := false.B
|
||||||
r.source := 0.U
|
r.source := 0.U
|
||||||
r.offset := 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 numPerLaneReqs: Int,
|
||||||
val sourceWidth: Int,
|
val sourceWidth: Int,
|
||||||
val offsetBits: Int,
|
val offsetBits: Int,
|
||||||
val sizeBits: Int
|
val sizeEnumType: InFlightTableSizeEnum
|
||||||
) extends Bundle {
|
) extends Bundle {
|
||||||
class PerCoreReq extends Bundle {
|
class PerCoreReq extends Bundle {
|
||||||
val valid = Bool()
|
val valid = Bool()
|
||||||
// FIXME: oldId and newId shares the same width
|
// FIXME: oldId and newId shares the same width
|
||||||
val source = UInt(sourceWidth.W)
|
val source = UInt(sourceWidth.W)
|
||||||
val offset = UInt(offsetBits.W)
|
val offset = UInt(offsetBits.W)
|
||||||
val size = UInt(sizeBits.W)
|
val sizeEnum = sizeEnumType()
|
||||||
}
|
}
|
||||||
class PerLane extends Bundle {
|
class PerLane extends Bundle {
|
||||||
val reqs = Vec(numPerLaneReqs, new PerCoreReq)
|
val reqs = Vec(numPerLaneReqs, new PerCoreReq)
|
||||||
|
|||||||
@@ -264,13 +264,8 @@ class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
val coalDataWidth = 128
|
val coalDataWidth = 128
|
||||||
val numInflightCoalRequests = 4
|
val numInflightCoalRequests = 4
|
||||||
|
|
||||||
val hey = new TLBundleParameters(64, 64, 64, 64, 64)
|
|
||||||
it should "work" in {
|
it should "work" in {
|
||||||
test(
|
test(new UncoalescingUnit(defaultConfig))
|
||||||
new UncoalescingUnit(
|
|
||||||
defaultConfig,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
// vcs helps with simulation time, but sometimes errors with
|
// vcs helps with simulation time, but sometimes errors with
|
||||||
// "mutation occurred during iteration" java error
|
// "mutation occurred during iteration" java error
|
||||||
// .withAnnotations(Seq(VcsBackendAnnotation))
|
// .withAnnotations(Seq(VcsBackendAnnotation))
|
||||||
@@ -301,10 +296,10 @@ class UncoalescingUnitTest extends AnyFlatSpec with ChiselScalatestTester {
|
|||||||
|
|
||||||
c.clock.step()
|
c.clock.step()
|
||||||
|
|
||||||
c.io.coalRespValid.poke(true.B)
|
c.io.coalResp.valid.poke(true.B)
|
||||||
c.io.coalRespSrcId.poke(sourceId)
|
c.io.coalResp.bits.source.poke(sourceId)
|
||||||
val lit = (BigInt(0x0123456789abcdefL) << 64) | BigInt(0x5ca1ab1edeadbeefL)
|
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
|
// table lookup is combinational at the same cycle
|
||||||
c.io.uncoalResps(0)(0).valid.expect(true.B)
|
c.io.uncoalResps(0)(0).valid.expect(true.B)
|
||||||
|
|||||||
Reference in New Issue
Block a user