Fix misleading maxSize param in Req/RespQueueEntry
This commit is contained in:
@@ -53,7 +53,6 @@ case class CoalescerConfig(
|
|||||||
// the coalescer to perform well
|
// the coalescer to perform well
|
||||||
// watermark = 2, // minimum buffer occupancy to start coalescing
|
// watermark = 2, // minimum buffer occupancy to start coalescing
|
||||||
wordSizeInBytes: Int, // 32-bit system
|
wordSizeInBytes: Int, // 32-bit system
|
||||||
wordWidth: Int, // log(WORD_SIZE)
|
|
||||||
numOldSrcIds: Int, // num of outstanding requests per lane, from processor
|
numOldSrcIds: Int, // num of outstanding requests per lane, from processor
|
||||||
numNewSrcIds: Int, // num of outstanding coalesced requests
|
numNewSrcIds: Int, // num of outstanding coalesced requests
|
||||||
respQueueDepth: Int, // depth of the response fifo queues
|
respQueueDepth: Int, // depth of the response fifo queues
|
||||||
@@ -67,6 +66,12 @@ case class CoalescerConfig(
|
|||||||
) {
|
) {
|
||||||
// maximum coalesced size
|
// maximum coalesced size
|
||||||
def maxCoalLogSize: Int = coalLogSizes.max
|
def maxCoalLogSize: Int = coalLogSizes.max
|
||||||
|
def wordSizeWidth: Int = {
|
||||||
|
val w = log2Ceil(wordSizeInBytes)
|
||||||
|
require(wordSizeInBytes == 1 << w,
|
||||||
|
s"wordSizeInBytes (${wordSizeInBytes}) is not power of two")
|
||||||
|
w
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -79,7 +84,6 @@ object defaultConfig extends CoalescerConfig(
|
|||||||
dataBusWidth = 3, // 2^3=8 bytes, 64 bit bus
|
dataBusWidth = 3, // 2^3=8 bytes, 64 bit bus
|
||||||
// watermark = 2,
|
// watermark = 2,
|
||||||
wordSizeInBytes = 4,
|
wordSizeInBytes = 4,
|
||||||
wordWidth = 2,
|
|
||||||
// when attaching to SoC, 16 source IDs are not enough due to longer latency
|
// when attaching to SoC, 16 source IDs are not enough due to longer latency
|
||||||
numOldSrcIds = 16,
|
numOldSrcIds = 16,
|
||||||
numNewSrcIds = 4,
|
numNewSrcIds = 4,
|
||||||
@@ -131,13 +135,14 @@ class CoalescingUnit(config: CoalescerConfig)(implicit p: Parameters) extends La
|
|||||||
lazy val module = new CoalescingUnitImp(this, config)
|
lazy val module = new CoalescingUnitImp(this, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReqQueueEntry(sourceWidth: Int, sizeWidth: Int, addressWidth: Int, maxSize: Int) extends Bundle {
|
class ReqQueueEntry(sourceWidth: Int, sizeWidth: Int, addressWidth: Int, dataWidth: Int) extends Bundle {
|
||||||
|
require(dataWidth % 8 == 0, s"dataWidth (${dataWidth} bits) is not multiple of 8")
|
||||||
val op = UInt(1.W) // 0=READ 1=WRITE
|
val op = UInt(1.W) // 0=READ 1=WRITE
|
||||||
val address = UInt(addressWidth.W)
|
val address = UInt(addressWidth.W)
|
||||||
val size = UInt(sizeWidth.W)
|
val size = UInt(sizeWidth.W)
|
||||||
val source = UInt(sourceWidth.W)
|
val source = UInt(sourceWidth.W)
|
||||||
val mask = UInt((1 << maxSize).W) // write only
|
val mask = UInt((dataWidth / 8).W) // write only
|
||||||
val data = UInt((8 * (1 << maxSize)).W) // write only
|
val data = UInt(dataWidth.W) // write only
|
||||||
|
|
||||||
def toTLA(edgeOut: TLEdgeOut): TLBundleA = {
|
def toTLA(edgeOut: TLEdgeOut): TLBundleA = {
|
||||||
val (plegal, pbits) = edgeOut.Put(
|
val (plegal, pbits) = edgeOut.Put(
|
||||||
@@ -158,11 +163,11 @@ class ReqQueueEntry(sourceWidth: Int, sizeWidth: Int, addressWidth: Int, maxSize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RespQueueEntry(sourceWidth: Int, sizeWidth: Int, maxSize: Int) extends Bundle {
|
class RespQueueEntry(sourceWidth: Int, sizeWidth: Int, dataWidth: Int) extends Bundle {
|
||||||
val op = UInt(1.W) // 0=READ 1=WRITE
|
val op = UInt(1.W) // 0=READ 1=WRITE
|
||||||
val size = UInt(sizeWidth.W)
|
val size = UInt(sizeWidth.W)
|
||||||
val source = UInt(sourceWidth.W)
|
val source = UInt(sourceWidth.W)
|
||||||
val data = UInt((8 * (1 << maxSize)).W) // read only
|
val data = UInt(dataWidth.W) // read only
|
||||||
val error = Bool()
|
val error = Bool()
|
||||||
|
|
||||||
def toTLD(edgeIn: TLEdgeIn): TLBundleD = {
|
def toTLD(edgeIn: TLEdgeIn): TLBundleD = {
|
||||||
@@ -254,6 +259,11 @@ class CoalShiftQueue[T <: Data](gen: T, entries: Int, config: CoalescerConfig) e
|
|||||||
val empty = Bool()
|
val empty = Bool()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// io.coalescable will first turn on for all coalescable chunks, and turn off
|
||||||
|
// incrementally as time goes on. Therefore, when io.coalescable is all
|
||||||
|
// turned off, that means we have processed all coalescable chunks at the
|
||||||
|
// current cycle.
|
||||||
|
//
|
||||||
// shift hint is when the heads have no more coalescable left this or next cycle
|
// shift hint is when the heads have no more coalescable left this or next cycle
|
||||||
val shiftHint = !(io.coalescable zip io.invalidate.bits.map(_(0))).map { case (c, inv) =>
|
val shiftHint = !(io.coalescable zip io.invalidate.bits.map(_(0))).map { case (c, inv) =>
|
||||||
c && !(io.invalidate.valid && inv)
|
c && !(io.invalidate.valid && inv)
|
||||||
@@ -341,7 +351,7 @@ class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
|
|||||||
// number of entries matched with this leader lane's head.
|
// number of entries matched with this leader lane's head.
|
||||||
// maximum is numLanes * queueDepth
|
// maximum is numLanes * queueDepth
|
||||||
val matchCount = Output(UInt(log2Ceil(config.numLanes * config.queueDepth + 1).W))
|
val matchCount = Output(UInt(log2Ceil(config.numLanes * config.queueDepth + 1).W))
|
||||||
val coverageHits = Output(UInt((config.maxCoalLogSize - config.wordWidth + 1).W))
|
val coverageHits = Output(UInt((config.maxCoalLogSize - config.wordSizeWidth + 1).W))
|
||||||
val canCoalesce = Output(Vec(config.numLanes, Bool()))
|
val canCoalesce = Output(Vec(config.numLanes, Bool()))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -419,7 +429,7 @@ class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
|
|||||||
val chosenMatchCount = VecInit(matchCounts)(chosenLeaderIdx)
|
val chosenMatchCount = VecInit(matchCounts)(chosenLeaderIdx)
|
||||||
|
|
||||||
// coverage calculation
|
// coverage calculation
|
||||||
def getOffsetSlice(addr: UInt) = addr(size - 1, config.wordWidth)
|
def getOffsetSlice(addr: UInt) = addr(size - 1, config.wordSizeWidth)
|
||||||
// 2-D table flattened to 1-D
|
// 2-D table flattened to 1-D
|
||||||
val offsets = io.window.elts.flatMap(_.map(req => getOffsetSlice(req.address)))
|
val offsets = io.window.elts.flatMap(_.map(req => getOffsetSlice(req.address)))
|
||||||
val valids = chosenMatches.flatMap(_.asBools)
|
val valids = chosenMatches.flatMap(_.asBools)
|
||||||
@@ -427,7 +437,7 @@ class MonoCoalescer(coalLogSize: Int, windowT: CoalShiftQueue[ReqQueueEntry],
|
|||||||
// any of the requests in the queue. e.g. if [ 1 1 1 1 ], all of the four
|
// any of the requests in the queue. e.g. if [ 1 1 1 1 ], all of the four
|
||||||
// words in the coalesced data coming back will be accessed by some request
|
// words in the coalesced data coming back will be accessed by some request
|
||||||
// and we've reached 100% bandwidth utilization.
|
// and we've reached 100% bandwidth utilization.
|
||||||
val hits = Seq.tabulate(1 << (size - config.wordWidth)) { target =>
|
val hits = Seq.tabulate(1 << (size - config.wordSizeWidth)) { target =>
|
||||||
(offsets zip valids).map { case (offset, valid) => valid && (offset === target.U) }.reduce(_ || _)
|
(offsets zip valids).map { case (offset, valid) => valid && (offset === target.U) }.reduce(_ || _)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +509,7 @@ class MultiCoalescer(windowT: CoalShiftQueue[ReqQueueEntry], coalReqT: ReqQueueE
|
|||||||
val chosenSizeIdx = Wire(UInt(log2Ceil(config.coalLogSizes.size).W))
|
val chosenSizeIdx = Wire(UInt(log2Ceil(config.coalLogSizes.size).W))
|
||||||
val chosenValid = Wire(Bool())
|
val chosenValid = Wire(Bool())
|
||||||
// minimum 25% coverage
|
// minimum 25% coverage
|
||||||
val minCoverage = 1.max(1 << ((config.maxCoalLogSize - config.wordWidth) - 2))
|
val minCoverage = 1.max(1 << ((config.maxCoalLogSize - config.wordSizeWidth) - 2))
|
||||||
|
|
||||||
when (normalizedHits.map(_ > minCoverage.U).reduce(_ || _)) {
|
when (normalizedHits.map(_ > minCoverage.U).reduce(_ || _)) {
|
||||||
chosenSizeIdx := argMax(normalizedHits)
|
chosenSizeIdx := argMax(normalizedHits)
|
||||||
@@ -531,13 +541,13 @@ class MultiCoalescer(windowT: CoalShiftQueue[ReqQueueEntry], coalReqT: ReqQueueE
|
|||||||
val flatMatches = chosenBundle.matchOH.flatMap(_.asBools)
|
val flatMatches = chosenBundle.matchOH.flatMap(_.asBools)
|
||||||
|
|
||||||
// check for word alignment in addresses
|
// check for word alignment in addresses
|
||||||
assert(io.window.elts.flatMap(_.map(req => req.address(config.wordWidth - 1, 0) === 0.U)).zip(
|
assert(io.window.elts.flatMap(_.map(req => req.address(config.wordSizeWidth - 1, 0) === 0.U)).zip(
|
||||||
io.window.mask.flatMap(_.asBools)).map { case (aligned, valid) => (!valid) || aligned }.reduce(_ || _),
|
io.window.mask.flatMap(_.asBools)).map { case (aligned, valid) => (!valid) || aligned }.reduce(_ || _),
|
||||||
"one or more addresses used for coalescing is not word-aligned")
|
"one or more addresses used for coalescing is not word-aligned")
|
||||||
|
|
||||||
// note: this is word-level coalescing. if finer granularity is needed, need to modify code
|
// note: this is word-level coalescing. if finer granularity is needed, need to modify code
|
||||||
val numWords = (1.U << (chosenSize - config.wordWidth.U)).asUInt
|
val numWords = (1.U << (chosenSize - config.wordSizeWidth.U)).asUInt
|
||||||
val maxWords = 1 << (config.maxCoalLogSize - config.wordWidth)
|
val maxWords = 1 << (config.maxCoalLogSize - config.wordSizeWidth)
|
||||||
val addrMask = Wire(UInt(config.maxCoalLogSize.W))
|
val addrMask = Wire(UInt(config.maxCoalLogSize.W))
|
||||||
addrMask := (1.U << chosenSize).asUInt - 1.U
|
addrMask := (1.U << chosenSize).asUInt - 1.U
|
||||||
|
|
||||||
@@ -548,7 +558,7 @@ class MultiCoalescer(windowT: CoalShiftQueue[ReqQueueEntry], coalReqT: ReqQueueE
|
|||||||
val sel = flatReqs.zip(flatMatches).map { case (req, m) =>
|
val sel = flatReqs.zip(flatMatches).map { case (req, m) =>
|
||||||
// note: ANDing against addrMask is to conform to active byte lanes requirements
|
// note: ANDing against addrMask is to conform to active byte lanes requirements
|
||||||
// if aligning to LSB suffices, we should add the bitwise AND back
|
// if aligning to LSB suffices, we should add the bitwise AND back
|
||||||
m && ((req.address(config.maxCoalLogSize - 1, config.wordWidth)/* & addrMask*/) === i.U)
|
m && ((req.address(config.maxCoalLogSize - 1, config.wordSizeWidth)/* & addrMask*/) === i.U)
|
||||||
}
|
}
|
||||||
// TODO: SW uses priority encoder, not sure about behavior of MuxCase
|
// TODO: SW uses priority encoder, not sure about behavior of MuxCase
|
||||||
data(i) := MuxCase(DontCare, flatReqs.zip(sel).map { case (req, s) =>
|
data(i) := MuxCase(DontCare, flatReqs.zip(sel).map { case (req, s) =>
|
||||||
@@ -602,11 +612,12 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
|
|
||||||
val sourceWidth = outer.cpuNode.in.head._1.params.sourceBits
|
val sourceWidth = outer.cpuNode.in.head._1.params.sourceBits
|
||||||
// note we are using word size. assuming all coalescer inputs are word sized
|
// note we are using word size. assuming all coalescer inputs are word sized
|
||||||
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, config.wordWidth, config.addressWidth, config.wordSizeInBytes)
|
val reqQueueEntryT = new ReqQueueEntry(sourceWidth, config.wordSizeWidth,
|
||||||
|
config.addressWidth, (config.wordSizeInBytes * 8))
|
||||||
val reqQueues = Module(new CoalShiftQueue(reqQueueEntryT, config.queueDepth, config))
|
val reqQueues = Module(new CoalShiftQueue(reqQueueEntryT, config.queueDepth, config))
|
||||||
|
|
||||||
val coalReqT = new ReqQueueEntry(log2Ceil(config.numNewSrcIds), log2Ceil(config.maxCoalLogSize),
|
val coalReqT = new ReqQueueEntry(log2Ceil(config.numNewSrcIds), log2Ceil(config.maxCoalLogSize),
|
||||||
config.addressWidth, config.maxCoalLogSize)
|
config.addressWidth, (1 << config.maxCoalLogSize) * 8)
|
||||||
val coalescer = Module(new MultiCoalescer(reqQueues, coalReqT, config))
|
val coalescer = Module(new MultiCoalescer(reqQueues, coalReqT, config))
|
||||||
coalescer.io.window := reqQueues.io
|
coalescer.io.window := reqQueues.io
|
||||||
reqQueues.io.coalescable := coalescer.io.coalescable
|
reqQueues.io.coalescable := coalescer.io.coalescable
|
||||||
@@ -692,7 +703,8 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
// coalesced request. Upper bound is min(DEPTH, 2**sourceWidth).
|
// coalesced request. Upper bound is min(DEPTH, 2**sourceWidth).
|
||||||
val numPerLaneReqs = config.queueDepth
|
val numPerLaneReqs = config.queueDepth
|
||||||
|
|
||||||
val respQueueEntryT = new RespQueueEntry(sourceWidth, log2Ceil(config.maxCoalLogSize), config.maxCoalLogSize)
|
val respQueueEntryT = new RespQueueEntry(sourceWidth, log2Ceil(config.maxCoalLogSize),
|
||||||
|
(1 << config.maxCoalLogSize) * 8)
|
||||||
val respQueues = Seq.tabulate(config.numLanes) { _ =>
|
val respQueues = Seq.tabulate(config.numLanes) { _ =>
|
||||||
Module(
|
Module(
|
||||||
new MultiPortQueue(
|
new MultiPortQueue(
|
||||||
@@ -798,7 +810,7 @@ class CoalescingUnitImp(outer: CoalescingUnit, config: CoalescerConfig) extends
|
|||||||
}
|
}
|
||||||
reqEntry.valid := (coalescer.io.invalidate.valid && inv)
|
reqEntry.valid := (coalescer.io.invalidate.valid && inv)
|
||||||
reqEntry.source := req.source
|
reqEntry.source := req.source
|
||||||
reqEntry.offset := ((req.address % (1 << config.maxCoalLogSize).U) >> config.wordWidth)
|
reqEntry.offset := ((req.address % (1 << config.maxCoalLogSize).U) >> config.wordSizeWidth)
|
||||||
reqEntry.sizeEnum := config.sizeEnum.logSizeToEnum(req.size)
|
reqEntry.sizeEnum := config.sizeEnum.logSizeToEnum(req.size)
|
||||||
// TODO: load/store op
|
// TODO: load/store op
|
||||||
}
|
}
|
||||||
@@ -879,7 +891,8 @@ class Uncoalescer(config: CoalescerConfig) extends Module {
|
|||||||
Vec(
|
Vec(
|
||||||
config.queueDepth,
|
config.queueDepth,
|
||||||
ValidIO(
|
ValidIO(
|
||||||
new RespQueueEntry(log2Ceil(config.numOldSrcIds), config.wordWidth, config.wordSizeInBytes)
|
new RespQueueEntry(log2Ceil(config.numOldSrcIds), config.wordSizeWidth,
|
||||||
|
config.wordSizeInBytes * 8)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -959,7 +972,7 @@ class Uncoalescer(config: CoalescerConfig) extends Module {
|
|||||||
// split the coalesced response back to individual per-lane responses with the
|
// split the coalesced response back to individual per-lane responses with the
|
||||||
// right metadata.
|
// right metadata.
|
||||||
class InflightCoalReqTable(config: CoalescerConfig) extends Module {
|
class InflightCoalReqTable(config: CoalescerConfig) extends Module {
|
||||||
val offsetBits = config.maxCoalLogSize - config.wordWidth // assumes word offset
|
val offsetBits = config.maxCoalLogSize - config.wordSizeWidth // assumes word offset
|
||||||
val entryT = new InflightCoalReqTableEntry(
|
val entryT = new InflightCoalReqTableEntry(
|
||||||
config.numLanes,
|
config.numLanes,
|
||||||
config.queueDepth,
|
config.queueDepth,
|
||||||
@@ -1257,8 +1270,8 @@ class MemTraceDriverImp(outer: MemTraceDriver, config: CoalescerConfig, filename
|
|||||||
dontTouch(tlOut.d)
|
dontTouch(tlOut.d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give some slack time after trace EOF to the downstream system so that we
|
// Give some slack time after trace EOF to the downstream system to make sure
|
||||||
// make sure to receive all outstanding responses.
|
// we receive all (hopefully) outstanding responses back.
|
||||||
val finishCounter = RegInit(200.U(64.W))
|
val finishCounter = RegInit(200.U(64.W))
|
||||||
when(sim.io.trace_read.finished) {
|
when(sim.io.trace_read.finished) {
|
||||||
finishCounter := finishCounter - 1.U
|
finishCounter := finishCounter - 1.U
|
||||||
@@ -1319,6 +1332,7 @@ class MemTraceLogger(
|
|||||||
reqEnable: Boolean = true,
|
reqEnable: Boolean = true,
|
||||||
respEnable: Boolean = true,
|
respEnable: Boolean = true,
|
||||||
// filename suffix that is unique to this logger module.
|
// filename suffix that is unique to this logger module.
|
||||||
|
// This will be appended to the filename of the generated trace.
|
||||||
loggerName: String = ".logger"
|
loggerName: String = ".logger"
|
||||||
)(implicit
|
)(implicit
|
||||||
p: Parameters
|
p: Parameters
|
||||||
@@ -1626,7 +1640,7 @@ class DummyDriverImp(outer: DummyDriver, config: CoalescerConfig)
|
|||||||
// generate dummy traffic to coalescer to prevent it from being optimized
|
// generate dummy traffic to coalescer to prevent it from being optimized
|
||||||
// out during synthesis
|
// out during synthesis
|
||||||
val address = Wire(UInt(config.addressWidth.W))
|
val address = Wire(UInt(config.addressWidth.W))
|
||||||
address := Cat((finishCounter + (lane.U % 3.U)), 0.U(config.wordWidth.W))
|
address := Cat((finishCounter + (lane.U % 3.U)), 0.U(config.wordSizeWidth.W))
|
||||||
val (tl, edge) = node.out(0)
|
val (tl, edge) = node.out(0)
|
||||||
val (legal, bits) = edge.Put(
|
val (legal, bits) = edge.Put(
|
||||||
fromSource = sourceIdCounter,
|
fromSource = sourceIdCounter,
|
||||||
@@ -1841,20 +1855,20 @@ class CoalescerXbar(config: CoalescerConfig) (implicit p: Parameters) extends La
|
|||||||
|
|
||||||
val nonCoalEntryT = new ReqQueueEntry(
|
val nonCoalEntryT = new ReqQueueEntry(
|
||||||
log2Ceil(config.numOldSrcIds),
|
log2Ceil(config.numOldSrcIds),
|
||||||
config.wordWidth,
|
config.wordSizeWidth,
|
||||||
config.addressWidth,
|
config.addressWidth,
|
||||||
log2Ceil(config.wordSizeInBytes)
|
config.wordSizeInBytes * 8
|
||||||
)
|
)
|
||||||
val coalEntryT = new ReqQueueEntry(
|
val coalEntryT = new ReqQueueEntry(
|
||||||
log2Ceil(config.numOldSrcIds),
|
log2Ceil(config.numOldSrcIds),
|
||||||
log2Ceil(config.maxCoalLogSize),
|
log2Ceil(config.maxCoalLogSize),
|
||||||
config.addressWidth,
|
config.addressWidth,
|
||||||
config.maxCoalLogSize //already log 2
|
(1 << config.maxCoalLogSize) * 8
|
||||||
)
|
)
|
||||||
val respNonCoalEntryT = new RespQueueEntry(
|
val respNonCoalEntryT = new RespQueueEntry(
|
||||||
log2Ceil(config.numOldSrcIds),
|
log2Ceil(config.numOldSrcIds),
|
||||||
config.wordWidth,
|
config.wordSizeWidth,
|
||||||
log2Ceil(config.wordSizeInBytes)
|
config.wordSizeInBytes * 8
|
||||||
)
|
)
|
||||||
|
|
||||||
val respCoalBundleT = new CoalescedResponseBundle(config)
|
val respCoalBundleT = new CoalescedResponseBundle(config)
|
||||||
|
|||||||
@@ -186,7 +186,6 @@ object testConfig extends CoalescerConfig(
|
|||||||
dataBusWidth = 5,
|
dataBusWidth = 5,
|
||||||
// watermark = 2,
|
// watermark = 2,
|
||||||
wordSizeInBytes = 4,
|
wordSizeInBytes = 4,
|
||||||
wordWidth = 2,
|
|
||||||
numOldSrcIds = 16,
|
numOldSrcIds = 16,
|
||||||
numNewSrcIds = 4,
|
numNewSrcIds = 4,
|
||||||
respQueueDepth = 4,
|
respQueueDepth = 4,
|
||||||
@@ -716,7 +715,6 @@ object uncoalescerTestConfig extends CoalescerConfig(
|
|||||||
dataBusWidth = 5,
|
dataBusWidth = 5,
|
||||||
// watermark = 2,
|
// watermark = 2,
|
||||||
wordSizeInBytes = 4,
|
wordSizeInBytes = 4,
|
||||||
wordWidth = 2,
|
|
||||||
numOldSrcIds = 16,
|
numOldSrcIds = 16,
|
||||||
numNewSrcIds = 4,
|
numNewSrcIds = 4,
|
||||||
respQueueDepth = 4,
|
respQueueDepth = 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user