-
Notifications
You must be signed in to change notification settings - Fork 30
/
EyerissTopSpecTest.scala
126 lines (122 loc) · 5.39 KB
/
EyerissTopSpecTest.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package dla.tests.diplomatictest
import chisel3._
import chisel3.tester._
import chiseltest.internal.{VerilatorBackendAnnotation, WriteVcdAnnotation}
import chisel3.tester.experimental.TestOptionBuilder._
import dla.cluster.{ClusterConfig, GNMFCS1Config, GNMFCS2Config}
import dla.diplomatic.{EyerissMemCtrlBundle, EyerissTop, EyerissTopParam}
import dla.pe.MCRENFConfig
import dla.tests.GenOneStreamData
import org.scalatest._
import scala.util.Random
object EyerissTLBundleDriver {
def readReqAndResp(peekIO: EyerissMemCtrlBundle, respData: Seq[List[Int]], sourceIdNum: Int, starAdr: Int)
(implicit theClock: Clock): Unit = {
var respSourceId: List[Int] = Nil
var reqSourceIdMap: Map[Int, Int] = Map() // sourceId -> respDataIdx
peekIO.legal.poke(true.B)
fork.withName("manage requirement") {
while (reqSourceIdMap.size < sourceIdNum) {
peekIO.a.ready.poke(true.B)
while (!peekIO.a.valid.peek().litToBoolean) {
theClock.step()
}
val currentReqSource = peekIO.a.bits.source.peek().litValue().toInt
if (reqSourceIdMap.contains(currentReqSource)) {
peekIO.reqFirst.poke(false.B)
} else {
peekIO.reqFirst.poke(true.B)
val reqSize = peekIO.reqSize.peek().litValue().toInt
val address = peekIO.address.peek().litValue().toInt
val reqDataIdx = (address - starAdr)/reqSize
reqSourceIdMap = reqSourceIdMap.++(Map(currentReqSource -> reqDataIdx))
}
println(s"[req@${reqSourceIdMap.size}] the require source Id is $currentReqSource, reqSourceId = $reqSourceIdMap")
theClock.step()
peekIO.reqFirst.poke(false.B)
peekIO.a.ready.poke(false.B)
}
}.fork.withName("manage response").withRegion(Monitor) {
theClock.step((new Random).nextInt(30) + 1) // transferring time
while (respSourceId.length < sourceIdNum) {
peekIO.d.valid.poke(true.B)
while (!peekIO.d.ready.peek().litToBoolean) {
theClock.step()
}
val diffIdList = reqSourceIdMap.filter(map => !respSourceId.contains(map._1)).keys.toList
if (diffIdList.isEmpty) {
println(Console.RED + s"[Error] there is no difference between reqList and respList" + Console.RESET)
} else {
val respId = diffIdList((new Random).nextInt(diffIdList.length))
val peekRespDataIdx = reqSourceIdMap(respId)
peekIO.d.bits.source.poke(respId.U)
respSourceId = respSourceId:::List(respId)
println(s"[resp@${respSourceId.length}] the response source id is $respId, respSourceId = $respSourceId")
/** now peek data */
peekIO.respFirst.poke(true.B)
for (dataIdx <- respData(peekRespDataIdx).indices) {
peekIO.d.valid.poke(true.B)
peekIO.d.bits.data.poke(respData(peekRespDataIdx)(dataIdx).U)
while (!peekIO.d.ready.peek().litToBoolean) {
theClock.step()
}
theClock.step()
peekIO.respFirst.poke(false.B)
peekIO.d.valid.poke(false.B)
}
}
theClock.step()
}
}.joinAndStep(theClock)
}
}
class EyerissTopSpecTest extends FlatSpec with ChiselScalatestTester with Matchers
with ClusterConfig {
private val param = EyerissTopParam(
addressBits = 32,
inActDataBits = 32,
inActSourceBits = 3,
weightDataBits = 32,
weightSourceBits = 3,
pSumDataBits = 32,
pSumSourceBits = 3
)
private val decoderSequencer = DecoderSequencer
private val dataSequencer = new GenOneStreamData
private val dataDriver = EyerissTLBundleDriver
behavior of "test the spec of EyerissTop"
it should "work well on cal" in {
test(new EyerissTop(param = param)).withAnnotations(Seq(WriteVcdAnnotation, VerilatorBackendAnnotation)) { eyeriss =>
val theTopIO = eyeriss.io
implicit val theClock: Clock = eyeriss.clock
eyeriss.reset.poke(true.B)
theClock.step()
eyeriss.reset.poke(false.B)
theTopIO.ctrlPath.instructions.poke(decoderSequencer.loadPart0.U)
theClock.step(cycles = (new Random).nextInt(15) + 1)
theTopIO.ctrlPath.instructions.poke(decoderSequencer.loadPart1.U)
theClock.step(cycles = (new Random).nextInt(15) + 1)
theTopIO.ctrlPath.instructions.poke(decoderSequencer.loadPart2.U)
theClock.step(cycles = (new Random).nextInt(15) + 1)
theTopIO.ctrlPath.instructions.poke(decoderSequencer.loadPart3.U)
theClock.step(2)
/** then it will begins to load GLB */
dataDriver.readReqAndResp(theTopIO.ctrlPath.bundles.memInActBundles,
dataSequencer.inActStreamGLBOrder.map(x => x.flatten.flatten.toList), sourceIdNum = inActRouterNum,
starAdr = decoderSequencer.inActAdr.hex)
println("[INFO] inAct Former Finish")
/** load later inActGLB */
dataDriver.readReqAndResp(theTopIO.ctrlPath.bundles.memInActBundles,
dataSequencer.inActStreamGLBOrder.map(x => x.flatten.flatten.toList), sourceIdNum = inActRouterNum,
starAdr = decoderSequencer.inActAdr.hex)
println("[INFO] inAct later Finish")
/** load weight */
for (i <- 0 until 10) {
dataDriver.readReqAndResp(theTopIO.ctrlPath.bundles.memWeightBundles,
dataSequencer.weightStreamGLBOrder.flatten.map(x => x.flatten), sourceIdNum = weightRouterNum,
starAdr = decoderSequencer.weightAdr.hex)
println(s"[INFO] $i-th weight Finish")
}
}
}
}