Generate both Put/Get for non-coalesced requests
This commit is contained in:
@@ -37,14 +37,21 @@ class CoalescingUnit(numLanes: Int = 1)(implicit p: Parameters) extends LazyModu
|
|||||||
lazy val module = new CoalescingUnitImp(this, numLanes)
|
lazy val module = new CoalescingUnitImp(this, numLanes)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReqQueueEntry(val sourceWidth: Int, val addressWidth: Int) extends Bundle {
|
// FIXME: this overlaps a lot with HasTraceLine
|
||||||
|
class ReqQueueEntry(val sourceWidth: Int, val addressWidth: Int, val sizeWidth: Int)
|
||||||
|
extends Bundle {
|
||||||
val source = UInt(sourceWidth.W)
|
val source = UInt(sourceWidth.W)
|
||||||
|
val isStore = Bool()
|
||||||
val address = UInt(addressWidth.W)
|
val address = UInt(addressWidth.W)
|
||||||
|
val size = UInt(sizeWidth.W) // log(sizeInBytes)
|
||||||
val data = UInt(64.W /* FIXME hardcoded */ ) // write data
|
val data = UInt(64.W /* FIXME hardcoded */ ) // write data
|
||||||
}
|
}
|
||||||
|
|
||||||
class RespQueueEntry(val sourceWidth: Int, val dataWidthInBits: Int) extends Bundle {
|
class RespQueueEntry(val sourceWidth: Int, val dataWidthInBits: Int, val sizeWidth: Int)
|
||||||
|
extends Bundle {
|
||||||
val source = UInt(sourceWidth.W)
|
val source = UInt(sourceWidth.W)
|
||||||
|
val isStore = Bool()
|
||||||
|
val size = UInt(sizeWidth.W) // log(sizeInBytes)
|
||||||
val data = UInt(dataWidthInBits.W) // read data
|
val data = UInt(dataWidthInBits.W) // read data
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +60,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
// coalescer TL master node
|
// coalescer TL master node
|
||||||
assert(outer.node.in.length >= 2)
|
assert(outer.node.in.length >= 2)
|
||||||
|
|
||||||
|
// 32-bit system. FIXME hardcoded
|
||||||
val wordSize = 4
|
val wordSize = 4
|
||||||
|
|
||||||
val reqQueueDepth = 1
|
val reqQueueDepth = 1
|
||||||
@@ -60,7 +68,8 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
|
|
||||||
val sourceWidth = outer.node.in(1)._1.params.sourceBits
|
val sourceWidth = outer.node.in(1)._1.params.sourceBits
|
||||||
val addressWidth = outer.node.in(1)._1.params.addressBits
|
val addressWidth = outer.node.in(1)._1.params.addressBits
|
||||||
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, addressWidth)
|
val sizeWidth = outer.node.in(1)._1.params.sizeBits
|
||||||
|
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, addressWidth, sizeWidth)
|
||||||
val reqQueues = Seq.tabulate(numLanes) { _ =>
|
val reqQueues = Seq.tabulate(numLanes) { _ =>
|
||||||
Module(new CoalShiftQueue(reqQueueEntryT, reqQueueDepth))
|
Module(new CoalShiftQueue(reqQueueEntryT, reqQueueDepth))
|
||||||
}
|
}
|
||||||
@@ -69,7 +78,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
// coalesced request. Upper bound is request queue depth.
|
// coalesced request. Upper bound is request queue depth.
|
||||||
val numPerLaneReqs = 1
|
val numPerLaneReqs = 1
|
||||||
|
|
||||||
val respQueueEntryT = new RespQueueEntry(sourceWidth, wordSize * 8)
|
val respQueueEntryT = new RespQueueEntry(sourceWidth, wordSize * 8, sizeWidth)
|
||||||
val respQueues = Seq.tabulate(numLanes) { _ =>
|
val respQueues = Seq.tabulate(numLanes) { _ =>
|
||||||
Module(
|
Module(
|
||||||
new MultiPortQueue(
|
new MultiPortQueue(
|
||||||
@@ -122,7 +131,9 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
val reqQueue = reqQueues(lane)
|
val reqQueue = reqQueues(lane)
|
||||||
val req = Wire(reqQueueEntryT)
|
val req = Wire(reqQueueEntryT)
|
||||||
req.source := tlIn.a.bits.source
|
req.source := tlIn.a.bits.source
|
||||||
|
req.isStore := TLUtils.AOpcodeIsStore(tlIn.a.bits.opcode)
|
||||||
req.address := tlIn.a.bits.address
|
req.address := tlIn.a.bits.address
|
||||||
|
req.size := tlIn.a.bits.size
|
||||||
req.data := tlIn.a.bits.data
|
req.data := tlIn.a.bits.data
|
||||||
|
|
||||||
assert(reqQueue.io.enq.ready, "reqQueue is supposed to be always ready")
|
assert(reqQueue.io.enq.ready, "reqQueue is supposed to be always ready")
|
||||||
@@ -139,15 +150,22 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
tlOut.a.valid := reqQueue.io.deq.valid && !invalidate
|
tlOut.a.valid := reqQueue.io.deq.valid && !invalidate
|
||||||
|
|
||||||
val reqHead = reqQueue.io.deq.bits
|
val reqHead = reqQueue.io.deq.bits
|
||||||
// FIXME: generate Get or Put according to read/write
|
val (plegal, pbits) = edgeOut.Put(
|
||||||
val (reqLegal, reqBits) = edgeOut.Get(
|
|
||||||
fromSource = reqHead.source,
|
fromSource = reqHead.source,
|
||||||
// `toAddress` should be aligned to 2**lgSize
|
|
||||||
toAddress = reqHead.address,
|
toAddress = reqHead.address,
|
||||||
lgSize = 0.U
|
lgSize = reqHead.size,
|
||||||
|
// data should be aligned to beatBytes
|
||||||
|
data = reqHead.data
|
||||||
)
|
)
|
||||||
assert(reqLegal, "unhandled illegal TL req gen")
|
val (glegal, gbits) = edgeOut.Get(
|
||||||
tlOut.a.bits := reqBits
|
fromSource = reqHead.source,
|
||||||
|
toAddress = reqHead.address,
|
||||||
|
lgSize = reqHead.size
|
||||||
|
)
|
||||||
|
val legal = Mux(reqHead.isStore, plegal, glegal)
|
||||||
|
val bits = Mux(reqHead.isStore, pbits, gbits)
|
||||||
|
assert(legal, "unhandled illegal TL req gen")
|
||||||
|
tlOut.a.bits := bits
|
||||||
|
|
||||||
// Response queue
|
// Response queue
|
||||||
//
|
//
|
||||||
@@ -156,8 +174,9 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
val respQueue = respQueues(lane)
|
val respQueue = respQueues(lane)
|
||||||
val resp = Wire(respQueueEntryT)
|
val resp = Wire(respQueueEntryT)
|
||||||
resp.source := tlOut.d.bits.source
|
resp.source := tlOut.d.bits.source
|
||||||
|
resp.isStore := TLUtils.DOpcodeIsStore(tlOut.d.bits.opcode)
|
||||||
|
resp.size := tlOut.d.bits.size
|
||||||
resp.data := tlOut.d.bits.data
|
resp.data := tlOut.d.bits.data
|
||||||
// TODO: read/write bit?
|
|
||||||
|
|
||||||
// Queue up responses that didn't get coalesced originally ("noncoalesced" responses).
|
// Queue up responses that didn't get coalesced originally ("noncoalesced" responses).
|
||||||
// Coalesced (but uncoalesced back) responses will also be enqueued into the same queue.
|
// Coalesced (but uncoalesced back) responses will also be enqueued into the same queue.
|
||||||
@@ -172,6 +191,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
|
|
||||||
tlIn.d.valid := respQueue.io.deq(respQueueNoncoalPort).valid
|
tlIn.d.valid := respQueue.io.deq(respQueueNoncoalPort).valid
|
||||||
val respHead = respQueue.io.deq(respQueueNoncoalPort).bits
|
val respHead = respQueue.io.deq(respQueueNoncoalPort).bits
|
||||||
|
// TODO: AccessAckData for Get
|
||||||
val respBits = edgeIn.AccessAck(
|
val respBits = edgeIn.AccessAck(
|
||||||
toSource = respHead.source,
|
toSource = respHead.source,
|
||||||
lgSize = 0.U,
|
lgSize = 0.U,
|
||||||
@@ -271,6 +291,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, numLanes: Int) extends LazyModule
|
|||||||
numLanes,
|
numLanes,
|
||||||
numPerLaneReqs,
|
numPerLaneReqs,
|
||||||
sourceWidth,
|
sourceWidth,
|
||||||
|
sizeWidth,
|
||||||
coalDataWidth,
|
coalDataWidth,
|
||||||
outer.numInflightCoalRequests
|
outer.numInflightCoalRequests
|
||||||
)
|
)
|
||||||
@@ -313,6 +334,7 @@ class UncoalescingUnit(
|
|||||||
val numLanes: Int,
|
val numLanes: Int,
|
||||||
val numPerLaneReqs: Int,
|
val numPerLaneReqs: Int,
|
||||||
val sourceWidth: Int,
|
val sourceWidth: Int,
|
||||||
|
val sizeWidth: Int,
|
||||||
val coalDataWidth: Int,
|
val coalDataWidth: Int,
|
||||||
val numInflightCoalRequests: Int
|
val numInflightCoalRequests: Int
|
||||||
) extends Module {
|
) extends Module {
|
||||||
@@ -328,7 +350,10 @@ class UncoalescingUnit(
|
|||||||
val coalRespSrcId = Input(UInt(sourceWidth.W))
|
val coalRespSrcId = Input(UInt(sourceWidth.W))
|
||||||
val coalRespData = Input(UInt(coalDataWidth.W))
|
val coalRespData = Input(UInt(coalDataWidth.W))
|
||||||
val uncoalResps = Output(
|
val uncoalResps = Output(
|
||||||
Vec(numLanes, Vec(numPerLaneReqs, ValidIO(new RespQueueEntry(sourceWidth, wordSize * 8))))
|
Vec(
|
||||||
|
numLanes,
|
||||||
|
Vec(numPerLaneReqs, ValidIO(new RespQueueEntry(sourceWidth, wordSize * 8, sizeWidth)))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -692,7 +717,7 @@ class MemTraceDriverImp(outer: MemTraceDriver, numLanes: Int, traceFile: String)
|
|||||||
fromSource = sourceIdCounter,
|
fromSource = sourceIdCounter,
|
||||||
toAddress = hashToValidPhyAddr(req.address),
|
toAddress = hashToValidPhyAddr(req.address),
|
||||||
lgSize = req.size, // trace line already holds log2(size)
|
lgSize = req.size, // trace line already holds log2(size)
|
||||||
// Need to construct data that is correctly aligned to beatBytes
|
// data should be aligned to beatBytes
|
||||||
data = (req.data << (8.U * (req.address % edge.manager.beatBytes.U)))
|
data = (req.data << (8.U * (req.address % edge.manager.beatBytes.U)))
|
||||||
)
|
)
|
||||||
val (glegal, gbits) = edge.Get(
|
val (glegal, gbits) = edge.Get(
|
||||||
|
|||||||
Reference in New Issue
Block a user