Merge branch 'graphics' of https://github.com/hansungk/rocket-chip into graphics

This commit is contained in:
Richard Yan
2023-05-11 21:50:42 -07:00
2 changed files with 498 additions and 503 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -180,12 +180,12 @@ class DummyCoalescingUnitTBImp(outer: DummyCoalescingUnitTB) extends LazyModuleI
)
val reqQueueEnqReady = peekIn(0).asInstanceOf[Seq[Bool]].map(x => IO(x.cloneType))
val reqQueueEnqBits = peekIn(1).asInstanceOf[Seq[ReqQueueEntry]].map(x => IO(x.cloneType))
val reqQueueEnqBits = peekIn(1).asInstanceOf[Seq[Request]].map(x => IO(x.cloneType))
val reqQueueEnqValid = peekIn(2).asInstanceOf[Seq[Bool]].map(x => IO(x.cloneType))
val reqQueueDeqBits = peekIn(3).asInstanceOf[Seq[ReqQueueEntry]].map(x => IO(Output(x.cloneType)))
val reqQueueDeqBits = peekIn(3).asInstanceOf[Seq[Request]].map(x => IO(Output(x.cloneType)))
val reqQueueDeqValid = peekIn(4).asInstanceOf[Seq[Bool]].map(x => IO(Output(x.cloneType)))
val coalReqReady = IO(Output(peekIn(5).asInstanceOf[Bool].cloneType))
val coalReqBits = IO(Output(peekIn(6).asInstanceOf[ReqQueueEntry].cloneType))
val coalReqBits = IO(Output(peekIn(6).asInstanceOf[Request].cloneType))
val coalReqValid = IO(Output(peekIn(7).asInstanceOf[Bool].cloneType))
val coalInvalidate = IO(Output(peekIn(8).asInstanceOf[Valid[Vec[UInt]]].cloneType))
@@ -759,67 +759,70 @@ class CoalShiftQueueTest extends AnyFlatSpec with ChiselScalatestTester {
}*/
}
object uncoalescerTestConfig extends CoalescerConfig(
enable = true,
numLanes = 4,
queueDepth = 2,
waitTimeout = 8,
addressWidth = 24,
dataBusWidth = 5,
// watermark = 2,
wordSizeInBytes = 4,
numOldSrcIds = 16,
numNewSrcIds = 4,
respQueueDepth = 4,
coalLogSizes = Seq(4),
sizeEnum = DefaultInFlightTableSizeEnum,
numCoalReqs = 1,
numArbiterOutputPorts = 4,
bankStrideInBytes = 64,
)
class UncoalescerUnitTest extends AnyFlatSpec with ChiselScalatestTester {
behavior of "uncoalescer"
val numLanes = 4
val numPerLaneReqs = 2
val sourceWidth = 2
val sizeWidth = 2
// 16B coalescing size
val coalDataWidth = 128
val numInflightCoalRequests = 4
object uncoalescerTestConfig extends CoalescerConfig(
enable = true,
numLanes = 4,
queueDepth = 2,
waitTimeout = 8,
addressWidth = 24,
dataBusWidth = 4, // 128 bit data bus
wordSizeInBytes = 4,
numOldSrcIds = 16,
numNewSrcIds = 4,
respQueueDepth = 4,
coalLogSizes = Seq(4),
sizeEnum = DefaultInFlightTableSizeEnum,
numCoalReqs = 1,
numArbiterOutputPorts = 4,
bankStrideInBytes = 64,
)
val config = uncoalescerTestConfig
val nonCoalReqT = new NonCoalescedRequest(config)
val coalReqT = new CoalescedRequest(config)
it should "work in general case" in {
test(new Uncoalescer(uncoalescerTestConfig))
test(new Uncoalescer(config, nonCoalReqT, coalReqT))
// vcs helps with simulation time, but sometimes errors with
// "mutation occurred during iteration" java error
// .withAnnotations(Seq(VcsBackendAnnotation))
{ c =>
// 4 lanes, queue depth 2
c.io.windowElts(0)(0).op.poke(0.U)
c.io.windowElts(0)(0).source.poke(1.U)
c.io.windowElts(0)(0).address.poke(0x4.U)
c.io.windowElts(0)(0).size.poke(2.U)
c.io.windowElts(0)(1).op.poke(0.U)
c.io.windowElts(0)(1).source.poke(2.U)
c.io.windowElts(0)(1).address.poke(0x4.U) // two reqs from one lane
c.io.windowElts(0)(1).size.poke(2.U)
c.io.windowElts(2)(0).op.poke(0.U)
c.io.windowElts(2)(0).source.poke(2.U)
c.io.windowElts(2)(0).address.poke(0x8.U)
c.io.windowElts(2)(0).size.poke(2.U)
c.io.windowElts(2)(1).op.poke(0.U)
c.io.windowElts(2)(1).source.poke(2.U)
c.io.windowElts(2)(1).address.poke(0xc.U)
c.io.windowElts(2)(1).size.poke(2.U)
// indicate lane 0 and 2 are used for coalescing
c.io.invalidate.valid.poke(true.B)
c.io.invalidate.bits(0).poke(0x3.U) // 2'b11 for depth=2
c.io.invalidate.bits(1).poke(0x0.U)
c.io.invalidate.bits(2).poke(0x3.U)
c.io.invalidate.bits(3).poke(0x0.U)
val sourceId = 0.U
val four = c.io.newEntry.sizeEnumT.FOUR
c.io.coalReqValid.poke(true.B)
c.io.newEntry.source.poke(sourceId)
c.io.newEntry.lanes(0).reqs(0).valid.poke(true.B)
c.io.newEntry.lanes(0).reqs(0).source.poke(1.U)
c.io.newEntry.lanes(0).reqs(0).offset.poke(1.U)
c.io.newEntry.lanes(0).reqs(0).sizeEnum.poke(four)
c.io.newEntry.lanes(0).reqs(1).valid.poke(true.B)
c.io.newEntry.lanes(0).reqs(1).source.poke(2.U)
c.io.newEntry.lanes(0).reqs(1).offset.poke(1.U) // same offset to different lanes
c.io.newEntry.lanes(0).reqs(1).sizeEnum.poke(four)
c.io.newEntry.lanes(1).reqs(0).valid.poke(false.B)
c.io.newEntry.lanes(2).reqs(0).valid.poke(true.B)
c.io.newEntry.lanes(2).reqs(0).source.poke(2.U)
c.io.newEntry.lanes(2).reqs(0).offset.poke(2.U)
c.io.newEntry.lanes(2).reqs(0).sizeEnum.poke(four)
c.io.newEntry.lanes(2).reqs(1).valid.poke(true.B)
c.io.newEntry.lanes(2).reqs(1).source.poke(2.U)
c.io.newEntry.lanes(2).reqs(1).offset.poke(3.U)
c.io.newEntry.lanes(2).reqs(1).sizeEnum.poke(four)
c.io.newEntry.lanes(3).reqs(0).valid.poke(false.B)
c.io.coalReq.valid.poke(true.B)
c.io.coalReq.bits.source.poke(sourceId)
c.io.coalReq.ready.expect(true.B)
c.clock.step()
c.io.coalReqValid.poke(false.B)
c.io.coalReq.valid.poke(false.B)
c.io.invalidate.valid.poke(false.B)
c.clock.step()
@@ -848,37 +851,42 @@ class UncoalescerUnitTest extends AnyFlatSpec with ChiselScalatestTester {
}
it should "uncoalesce when coalesced to the same word offset" in {
test(new Uncoalescer(uncoalescerTestConfig))
test(new Uncoalescer(config, nonCoalReqT, coalReqT))
// .withAnnotations(Seq(VcsBackendAnnotation))
{ c =>
// 4 lanes, queue depth 2
c.io.windowElts(0)(0).op.poke(0.U)
c.io.windowElts(0)(0).source.poke(0.U)
c.io.windowElts(0)(0).address.poke(0x4.U)
c.io.windowElts(0)(0).size.poke(2.U)
c.io.windowElts(1)(0).op.poke(0.U)
c.io.windowElts(1)(0).source.poke(1.U)
c.io.windowElts(1)(0).address.poke(0x4.U) // two reqs from one lane
c.io.windowElts(1)(0).size.poke(2.U)
c.io.windowElts(2)(0).op.poke(0.U)
c.io.windowElts(2)(0).source.poke(2.U)
c.io.windowElts(2)(0).address.poke(0x4.U)
c.io.windowElts(2)(0).size.poke(2.U)
c.io.windowElts(3)(0).op.poke(0.U)
c.io.windowElts(3)(0).source.poke(3.U)
c.io.windowElts(3)(0).address.poke(0x4.U)
c.io.windowElts(3)(0).size.poke(2.U)
// indicate lanes used for coalescing
c.io.invalidate.valid.poke(true.B)
c.io.invalidate.bits(0).poke(0x1.U) // 2'b01 for enabling head
c.io.invalidate.bits(1).poke(0x1.U)
c.io.invalidate.bits(2).poke(0x1.U)
c.io.invalidate.bits(3).poke(0x1.U)
val sourceId = 0.U
val four = c.io.newEntry.sizeEnumT.FOUR
c.io.coalReqValid.poke(true.B)
c.io.newEntry.source.poke(sourceId)
c.io.newEntry.lanes(0).reqs(0).valid.poke(true.B)
c.io.newEntry.lanes(0).reqs(0).source.poke(0.U)
c.io.newEntry.lanes(0).reqs(0).offset.poke(1.U)
c.io.newEntry.lanes(0).reqs(0).sizeEnum.poke(four)
c.io.newEntry.lanes(0).reqs(1).valid.poke(false.B)
c.io.newEntry.lanes(1).reqs(0).valid.poke(true.B)
c.io.newEntry.lanes(1).reqs(0).source.poke(1.U)
c.io.newEntry.lanes(1).reqs(0).offset.poke(1.U)
c.io.newEntry.lanes(1).reqs(0).sizeEnum.poke(four)
c.io.newEntry.lanes(1).reqs(1).valid.poke(false.B)
c.io.newEntry.lanes(2).reqs(0).valid.poke(true.B)
c.io.newEntry.lanes(2).reqs(0).source.poke(2.U)
c.io.newEntry.lanes(2).reqs(0).offset.poke(1.U)
c.io.newEntry.lanes(2).reqs(0).sizeEnum.poke(four)
c.io.newEntry.lanes(2).reqs(1).valid.poke(false.B)
c.io.newEntry.lanes(3).reqs(0).valid.poke(true.B)
c.io.newEntry.lanes(3).reqs(0).source.poke(3.U)
c.io.newEntry.lanes(3).reqs(0).offset.poke(1.U)
c.io.newEntry.lanes(3).reqs(0).sizeEnum.poke(four)
c.io.newEntry.lanes(3).reqs(1).valid.poke(false.B)
c.io.coalReq.valid.poke(true.B)
c.io.coalReq.bits.source.poke(sourceId)
c.io.coalReq.ready.expect(true.B)
c.clock.step()
c.io.coalReqValid.poke(false.B)
c.io.coalReq.valid.poke(false.B)
c.io.invalidate.valid.poke(false.B)
c.clock.step()
@@ -908,138 +916,3 @@ class UncoalescerUnitTest extends AnyFlatSpec with ChiselScalatestTester {
}
}
}
class CoalInflightTableUnitTest extends AnyFlatSpec with ChiselScalatestTester {
behavior of "inflight coalesced request table"
val numLanes = 4
val numPerLaneReqs = 2
val sourceWidth = 2
val entries = 4
val offsetBits = 4
val sizeBits = 2
val inflightCoalReqTableEntry =
new InflightCoalReqTableEntry(
numLanes,
numPerLaneReqs,
sourceWidth,
offsetBits,
testConfig.sizeEnum
)
// it should "stop enqueueing when full" in {
// test(new InflightCoalReqTable(numLanes, sourceWidth, entries)) { c =>
// // fill up the table
// for (i <- 0 until entries) {
// val sourceId = i
// c.io.enq.ready.expect(true.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(sourceId.U)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.io.lookup.ready.poke(false.B)
// c.clock.step()
// }
// // now cannot enqueue any more
// c.io.enq.ready.expect(false.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(0.U)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.clock.step()
// c.io.enq.ready.expect(false.B)
// // try to lookup all existing entries
// for (i <- 0 until entries) {
// val sourceId = i
// c.io.enq.valid.poke(false.B)
// c.io.lookup.ready.poke(true.B)
// c.io.lookupSourceId.poke(sourceId)
// c.io.lookup.valid.expect(true.B)
// c.io.lookup.bits.expect(sourceId)
// c.clock.step()
// }
// // now the table should be empty
// for (i <- 0 until entries) {
// val sourceId = i
// c.io.enq.valid.poke(false.B)
// c.io.lookup.ready.poke(true.B)
// c.io.lookupSourceId.poke(sourceId)
// c.io.lookup.valid.expect(false.B)
// c.clock.step()
// }
// }
// }
// it should "lookup matching entry" in {
// test(new InflightCoalReqTable(numLanes, sourceWidth, entries))
// .withAnnotations(Seq(WriteVcdAnnotation)) { c =>
// c.reset.poke(true.B)
// c.clock.step(10)
// c.reset.poke(false.B)
// // enqueue one entry to not match at 0th index
// c.io.enq.ready.expect(true.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(0.U)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.clock.step()
// val targetSourceId = 1.U
// c.io.enq.ready.expect(true.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(targetSourceId)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.clock.step()
// c.io.lookup.ready.poke(true.B)
// c.io.lookupSourceId.poke(targetSourceId)
// c.io.lookup.valid.expect(true.B)
// c.io.lookup.bits.expect(targetSourceId)
// c.clock.step()
// // test if matching entry dequeues after 1 cycle
// c.io.lookup.ready.poke(true.B)
// c.io.lookupSourceId.poke(targetSourceId)
// c.io.lookup.valid.expect(false.B)
// }
// }
// it should "handle lookup and enqueue at the same time" in {
// test(new InflightCoalReqTable(numLanes, sourceWidth, entries)) { c =>
// // fill up the table
// val targetSourceId = 1.U
// c.io.enq.ready.expect(true.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(0.U)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.clock.step()
// c.io.enq.ready.expect(true.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(targetSourceId)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.clock.step()
// // do both enqueue and lookup at the same cycle
// val enqSourceId = 2.U
// c.io.enq.ready.expect(true.B)
// c.io.enq.valid.poke(true.B)
// c.io.enq.bits.fromLane.poke(0.U)
// c.io.enq.bits.respSourceId.poke(enqSourceId)
// c.io.enq.bits.reqSourceIds.foreach { id => id.poke(0.U) }
// c.io.lookup.ready.poke(true.B)
// c.io.lookupSourceId.poke(targetSourceId)
// c.clock.step()
// }
// }
}