More cleanup and doc
This commit is contained in:
@@ -238,7 +238,7 @@ class VortexBankImp(
|
|||||||
val id = UInt(config.coreTagWidth.W)
|
val id = UInt(config.coreTagWidth.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
val rcvWriteReqInfo = Module(
|
val coreWriteReqQueue = Module(
|
||||||
new Queue(
|
new Queue(
|
||||||
(new WriteReqInfo).cloneType,
|
(new WriteReqInfo).cloneType,
|
||||||
config.writeInfoReqQSize,
|
config.writeInfoReqQSize,
|
||||||
@@ -250,31 +250,31 @@ class VortexBankImp(
|
|||||||
|
|
||||||
// Translate TL request from Coalescer to requests for VX_cache
|
// Translate TL request from Coalescer to requests for VX_cache
|
||||||
def TLReq2VXReq = {
|
def TLReq2VXReq = {
|
||||||
val (coalToBankBundle, _) = outer.coalToVxCacheNode.in.head
|
val (tlInFromCoal, _) = outer.coalToVxCacheNode.in.head
|
||||||
// coal -> vxCache request on channel A
|
|
||||||
val coalToBankA = coalToBankBundle.a;
|
|
||||||
|
|
||||||
coalToBankA.ready := vxCache.io.core_req_ready && rcvWriteReqInfo.io.enq.ready // not optimal
|
// coal -> vxCache
|
||||||
vxCache.io.core_req_valid := coalToBankA.valid
|
tlInFromCoal.a.ready :=
|
||||||
|
vxCache.io.core_req_ready && coreWriteReqQueue.io.enq.ready // not optimal
|
||||||
|
vxCache.io.core_req_valid := tlInFromCoal.a.valid
|
||||||
|
|
||||||
// read = 0, write = 1
|
// read = 0, write = 1
|
||||||
vxCache.io.core_req_rw := !(coalToBankA.bits.opcode === TLMessages.Get)
|
vxCache.io.core_req_rw := !(tlInFromCoal.a.bits.opcode === TLMessages.Get)
|
||||||
// 4 is also hardcoded, it should be log2WordSize
|
// 4 is also hardcoded, it should be log2WordSize
|
||||||
vxCache.io.core_req_addr := coalToBankA.bits.address(
|
vxCache.io.core_req_addr := tlInFromCoal.a.bits.address(
|
||||||
31,
|
31,
|
||||||
log2Ceil(config.wordSize)
|
log2Ceil(config.wordSize)
|
||||||
)
|
)
|
||||||
vxCache.io.core_req_byteen := coalToBankA.bits.mask
|
vxCache.io.core_req_byteen := tlInFromCoal.a.bits.mask
|
||||||
vxCache.io.core_req_data := coalToBankA.bits.data
|
vxCache.io.core_req_data := tlInFromCoal.a.bits.data
|
||||||
|
|
||||||
// combine size and tag field into one big wire, to put into vxCache.io.core_req_tag
|
// combine size and tag field into one big wire, to put into
|
||||||
readReqInfo.id := coalToBankA.bits.source
|
// vxCache.io.core_req_tag
|
||||||
readReqInfo.size := coalToBankA.bits.size
|
readReqInfo.id := tlInFromCoal.a.bits.source
|
||||||
|
readReqInfo.size := tlInFromCoal.a.bits.size
|
||||||
|
// ignore param, size, corrupt
|
||||||
vxCache.io.core_req_tag := readReqInfo.asTypeOf(vxCache.io.core_req_tag)
|
vxCache.io.core_req_tag := readReqInfo.asTypeOf(vxCache.io.core_req_tag)
|
||||||
|
|
||||||
writeInputFire := vxCache.io.core_req_rw && coalToBankA.fire
|
writeInputFire := vxCache.io.core_req_rw && tlInFromCoal.a.fire
|
||||||
|
|
||||||
// ignore param, size, corrupt fields
|
|
||||||
|
|
||||||
// vxCache -> coal response on channel D
|
// vxCache -> coal response on channel D
|
||||||
// ok ... this part is a little tricky, the downstream coalescer requires
|
// ok ... this part is a little tricky, the downstream coalescer requires
|
||||||
@@ -282,50 +282,49 @@ class VortexBankImp(
|
|||||||
// an inflight ID has retired if we don't send ack, the coalescer will run
|
// an inflight ID has retired if we don't send ack, the coalescer will run
|
||||||
// out of IDs, and can't generate new request
|
// out of IDs, and can't generate new request
|
||||||
|
|
||||||
// for read request, we send AckData when the bank has a valid output
|
// Optimization: for write requests from upstream (i.e. coalescer), we send
|
||||||
|
// back ack as soon as we can without waiting for the actual ack from
|
||||||
|
// downstream (i.e. L2).
|
||||||
//
|
//
|
||||||
// for write request, we can ack whenever we have a valid entry in
|
// We still need to store these pending core write requests somewhere,
|
||||||
// rcvWriteReqInfo Queue
|
// because we can't always ack them in the next cycle, ex. when there's a
|
||||||
|
// competing read response.
|
||||||
val coalToBankD = coalToBankBundle.d;
|
|
||||||
|
|
||||||
// FIXME: currently assuming below buffer is never full
|
// FIXME: currently assuming below buffer is never full
|
||||||
rcvWriteReqInfo.io.enq.valid := !(coalToBankA.bits.opcode === TLMessages.Get) && coalToBankA.valid && coalToBankA.ready
|
coreWriteReqQueue.io.enq.valid :=
|
||||||
rcvWriteReqInfo.io.enq.bits.id := coalToBankA.bits.source
|
tlInFromCoal.a.fire && !(tlInFromCoal.a.bits.opcode === TLMessages.Get)
|
||||||
rcvWriteReqInfo.io.enq.bits.size := coalToBankA.bits.size
|
coreWriteReqQueue.io.enq.bits.id := tlInFromCoal.a.bits.source
|
||||||
|
coreWriteReqQueue.io.enq.bits.size := tlInFromCoal.a.bits.size
|
||||||
|
|
||||||
// prioritize Ack for Read, so we only deque from writeReqInfo, if we don't
|
// Prioritize ack for any pending reads over write acks in the queue. Don't
|
||||||
// have a readReq we need to ack
|
// ack write if vxCache has a current valid response for reads (vxCache
|
||||||
//
|
// response is always for reads.)
|
||||||
// vxCache.io.core_rsp_valid means readDataAck
|
coreWriteReqQueue.io.deq.ready := tlInFromCoal.d.ready && ~vxCache.io.core_rsp_valid
|
||||||
rcvWriteReqInfo.io.deq.ready := coalToBankD.ready && ~vxCache.io.core_rsp_valid
|
|
||||||
|
|
||||||
vxCache.io.core_rsp_ready := coalToBankD.ready
|
// handle competition between a pending read ack response and write ack
|
||||||
coalToBankD.valid := vxCache.io.core_rsp_valid || rcvWriteReqInfo.io.deq.valid
|
// response
|
||||||
|
vxCache.io.core_rsp_ready := tlInFromCoal.d.ready
|
||||||
coalToBankD.bits.source := Mux(
|
tlInFromCoal.d.valid := vxCache.io.core_rsp_valid || coreWriteReqQueue.io.deq.valid
|
||||||
|
tlInFromCoal.d.bits.source := Mux(
|
||||||
vxCache.io.core_rsp_valid,
|
vxCache.io.core_rsp_valid,
|
||||||
vxCache.io.core_rsp_tag.asTypeOf(readReqInfo).id,
|
vxCache.io.core_rsp_tag.asTypeOf(readReqInfo).id,
|
||||||
rcvWriteReqInfo.io.deq.bits.id
|
coreWriteReqQueue.io.deq.bits.id
|
||||||
)
|
)
|
||||||
|
tlInFromCoal.d.bits.opcode := Mux(
|
||||||
coalToBankD.bits.opcode := Mux(
|
vxCache.io.core_rsp_valid, // always for reads
|
||||||
vxCache.io.core_rsp_valid,
|
|
||||||
TLMessages.AccessAckData,
|
TLMessages.AccessAckData,
|
||||||
TLMessages.AccessAck
|
TLMessages.AccessAck
|
||||||
)
|
)
|
||||||
|
tlInFromCoal.d.bits.size := Mux(
|
||||||
coalToBankD.bits.size := Mux(
|
|
||||||
vxCache.io.core_rsp_valid,
|
vxCache.io.core_rsp_valid,
|
||||||
vxCache.io.core_rsp_tag.asTypeOf(readReqInfo).size,
|
vxCache.io.core_rsp_tag.asTypeOf(readReqInfo).size,
|
||||||
rcvWriteReqInfo.io.deq.bits.size
|
coreWriteReqQueue.io.deq.bits.size
|
||||||
)
|
)
|
||||||
|
tlInFromCoal.d.bits.param := 0.U
|
||||||
coalToBankD.bits.param := 0.U
|
tlInFromCoal.d.bits.sink := 0.U
|
||||||
coalToBankD.bits.sink := 0.U
|
tlInFromCoal.d.bits.denied := false.B
|
||||||
coalToBankD.bits.denied := false.B
|
tlInFromCoal.d.bits.corrupt := false.B
|
||||||
coalToBankD.bits.corrupt := false.B
|
tlInFromCoal.d.bits.data := vxCache.io.core_rsp_data
|
||||||
coalToBankD.bits.data := vxCache.io.core_rsp_data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since Vortex L1 is a write-through cache, it doesn't bookkeep writes and
|
// Since Vortex L1 is a write-through cache, it doesn't bookkeep writes and
|
||||||
|
|||||||
Reference in New Issue
Block a user