Skip to content

Commit b507e6b

Browse files
committed
sim: improve ux
1 parent 9ffdeb3 commit b507e6b

File tree

2 files changed

+120
-106
lines changed

2 files changed

+120
-106
lines changed

pifo-hardware/hw/spinal/rio/sim/PifoMeshSim.scala

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,27 @@ object PifoMeshSim extends App {
2424

2525
controller.start
2626

27-
val flow0 = 0xE
28-
val flow1 = 0xF
29-
30-
val vPifo_A = 0xA
31-
val vPifo_B = 0xB
32-
val vPifo_C = 0xC
33-
34-
val engine1 = 1
35-
val engine2 = 2
27+
import RioPredefinedPifos._
3628

3729
val tree1 = TreeController(
3830
controller,
39-
pifos = Seq((engine1, vPifo_A), (engine2, vPifo_B), (engine2, vPifo_C))
31+
pifos = Seq((1, rPifo(0)), (2, rPifo(1)), (2, rPifo(2)))
4032
)
4133

42-
val configThread = tree1.async_config { tc => {
43-
tc.addFlow(flow0, Seq(vPifo_A, vPifo_B))
44-
tc.addFlow(flow1, Seq(vPifo_A, vPifo_C))
4534

46-
tc.setBrainSP(vPifo_A)
47-
tc.setBrainState(vPifo_A, flow0, 10) // prio flow0 -> 10
48-
tc.setBrainState(vPifo_A, flow1, 20) // prio flow1 -> 20
49-
tc.setBrainFIFO(vPifo_B)
50-
tc.setBrainFIFO(vPifo_C)
51-
}}
35+
// use controller.transaction if you want transactional configuration
36+
val configThread = controller.config { cf =>
37+
cf.tree(tree1)
38+
.addFlow(rFlow(0), Seq(rPifo(0), rPifo(1)))
39+
.addFlow(rFlow(1), Seq(rPifo(0), rPifo(2)))
40+
41+
.brainSP(rPifo(0))
42+
.brainState(rPifo(0), rFlow(0), 10) // prio flow0 -> 10
43+
.brainState(rPifo(0), rFlow(1), 20) // prio flow1 -> 20
44+
45+
.brainFIFO(rPifo(1))
46+
.brainFIFO(rPifo(2))
47+
}
5248

5349
// join here to ensure configuration completes before proceeding
5450
// but you could let it run in parallel with other testbench activity!
@@ -57,17 +53,16 @@ object PifoMeshSim extends App {
5753
println("=== PifoMesh Simulation: Multi-Engine Test ===")
5854
dut.clockDomain.waitRisingEdge(4)
5955

60-
println(s"Enqueueing packets to Engine $engine1")
6156
for (i <- 0 until 3) {
62-
controller.enque(flow0)
57+
controller.enque(rFlow(0))
6358
dut.clockDomain.waitRisingEdge(1)
64-
controller.enque(flow1)
59+
controller.enque(rFlow(1))
6560
dut.clockDomain.waitRisingEdge(1)
6661
}
6762

6863
dut.clockDomain.waitRisingEdge(6)
6964

70-
println(s"Requesting dequeue from Engine $engine1 (root vPifo=$vPifo_A):")
65+
println(s"Requesting dequeue (root vPifo=${rPifo(0)}):")
7166
for (_ <- 0 until 8) {
7267
tree1.deque
7368
}

pifo-hardware/hw/spinal/rio/sim/Utils.scala

Lines changed: 102 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,18 @@ object SimUtils {
1212
.withFstWave
1313
}
1414

15+
// TODO(zhiyuang): check the pifos and flow ids are valid
16+
object RioPredefinedPifos {
17+
// pifos are 0xA to 0xF
18+
val rPifo : Seq[Int] = 10 until 16
19+
// flows are 1 to 9
20+
val rFlow : Seq[Int] = 1 until 10
21+
}
22+
1523
case class PifoMeshSimController(
1624
config: EngineConfig,
1725
dut: PifoMesh
1826
) {
19-
// high-level functions
20-
def setBrainFIFO(engineId: Int, vPifoId: Int) = {
21-
sendControl(ControlCommand.UpdateBrainEngine, engineId, 3, vPifoId = vPifoId) // FIFO
22-
}
23-
def setBrainSP(engineId: Int, vPifoId: Int) = {
24-
sendControl(ControlCommand.UpdateBrainEngine, engineId, 2, vPifoId = vPifoId) // SP
25-
}
26-
def setBrainWFQ(engineId: Int, vPifoId: Int) = {
27-
sendControl(ControlCommand.UpdateBrainEngine, engineId, 1, vPifoId = vPifoId) // WFQ
28-
}
29-
30-
def setBrainState(engineId: Int, vPifoId: Int, flowId: Int, state: Int) = {
31-
sendControl(ControlCommand.UpdateBrainFlowState, engineId, state, vPifoId = vPifoId, flowId = mkFlowId(engineId, flowId))
32-
}
3327

3428
// compound functions
3529
def enque(vPifoId: Int) = {
@@ -102,6 +96,100 @@ case class PifoMeshSimController(
10296
}
10397
}
10498

99+
// high-level configuration interface
100+
case class Configer(transactional: Boolean = false) {
101+
// high-level functions
102+
def setBrainFIFO(engineId: Int, vPifoId: Int) = {
103+
sendControl(ControlCommand.UpdateBrainEngine, engineId, 3, vPifoId = vPifoId) // FIFO
104+
}
105+
def setBrainSP(engineId: Int, vPifoId: Int) = {
106+
sendControl(ControlCommand.UpdateBrainEngine, engineId, 2, vPifoId = vPifoId) // SP
107+
}
108+
def setBrainWFQ(engineId: Int, vPifoId: Int) = {
109+
sendControl(ControlCommand.UpdateBrainEngine, engineId, 1, vPifoId = vPifoId) // WFQ
110+
}
111+
112+
def setBrainState(engineId: Int, vPifoId: Int, flowId: Int, state: Int) = {
113+
sendControl(ControlCommand.UpdateBrainFlowState, engineId, state, vPifoId = vPifoId, flowId = mkFlowId(engineId, flowId))
114+
}
115+
116+
case class TreeConfiger(tree : TreeController) {
117+
def addPifo(engineId : Int, pifoId : Int) : TreeConfiger = {
118+
assert(engineId <= config.numEngines, s"Invalid engineId: $engineId")
119+
assert(!tree.pifoMap.contains(pifoId), s"pifoId $pifoId already exists in the tree")
120+
tree.pifoMap(pifoId) = engineId
121+
this
122+
}
123+
124+
def addFlow(flowId : Int, vPifos : Seq[Int]) : TreeConfiger = {
125+
for (i <- 0 until vPifos.length) {
126+
val engine = tree.pifoMap(vPifos(i))
127+
val vPifo = vPifos(i)
128+
129+
sendControl(ControlCommand.UpdateMapperPre, engine, vPifo, vPifoId = flowId)
130+
val nextvPifo = if (i + 1 < vPifos.length) vPifos(i + 1) else flowId
131+
val nextEngine = if (i + 1 < vPifos.length) tree.pifoMap(nextvPifo) else 0
132+
sendControl(
133+
ControlCommand.UpdateMapperPost,
134+
engine, mkFlowId(nextEngine, nextvPifo),
135+
flowId = mkFlowId(engine, flowId)
136+
)
137+
}
138+
this
139+
}
140+
// apply the non-exist rewrite at the root pifo
141+
def rootNonExistRewrite(newEngineId : Int, newPifoId : Int) : TreeConfiger = {
142+
sendControl(
143+
ControlCommand.UpdateMapperPost,
144+
tree.rootEngine,
145+
mkFlowId(newEngineId, newPifoId),
146+
flowId = mkFlowId(tree.rootEngine, tree.rootPifo)
147+
)
148+
this
149+
}
150+
151+
// brain operations
152+
// TODO(zhiyuang): limitations on transactional updates
153+
def brainFIFO(vPifoId: Int) : TreeConfiger = {
154+
// assert(!transactional, "setBrainFIFO is not supported in transactional mode")
155+
val engineId = tree.pifoMap(vPifoId)
156+
setBrainFIFO(engineId, vPifoId)
157+
this
158+
}
159+
def brainSP(vPifoId: Int) : TreeConfiger = {
160+
val engineId = tree.pifoMap(vPifoId)
161+
setBrainSP(engineId, vPifoId)
162+
this
163+
}
164+
def brainWFQ(vPifoId: Int) : TreeConfiger = {
165+
val engineId = tree.pifoMap(vPifoId)
166+
setBrainWFQ(engineId, vPifoId)
167+
this
168+
}
169+
def brainState(vPifoId: Int, flowId: Int, state: Int) : TreeConfiger = {
170+
val engineId = tree.pifoMap(vPifoId)
171+
setBrainState(engineId, vPifoId, flowId, state)
172+
this
173+
}
174+
}
175+
176+
def tree(tree : TreeController) : TreeConfiger = TreeConfiger(tree)
177+
}
178+
179+
// Transactional configuration process.
180+
// TODO(zhiyuang): make this async and transactional
181+
def transaction(F : Configer => Unit) : SimThread = {
182+
assert(false, "Transactional configuration is not yet implemented")
183+
val configer = Configer(transactional = true)
184+
fork { F(configer) }
185+
}
186+
187+
def config(F : Configer => Unit) : SimThread = {
188+
val configer = Configer(transactional = false)
189+
fork { F(configer) }
190+
}
191+
192+
///////////////////////////////////
105193
// Initialize all inputs
106194
for (i <- 0 until config.numEngines) {
107195
dut.io.insert(i).valid #= false
@@ -142,75 +230,6 @@ case class TreeController(
142230
meshController.requestDequeue(rootEngine, rootPifo)
143231
}
144232

145-
// configuration interface
146-
case class TreeConfiger(transactional : Boolean = false) {
147-
def addPifo(engineId : Int, pifoId : Int) = {
148-
assert(engineId <= meshController.config.numEngines, s"Invalid engineId: $engineId")
149-
assert(!pifoMap.contains(pifoId), s"pifoId $pifoId already exists in the tree")
150-
pifoMap(pifoId) = engineId
151-
}
152-
153-
def addFlow(flowId : Int, vPifos : Seq[Int]) = {
154-
for (i <- 0 until vPifos.length) {
155-
val engine = pifoMap(vPifos(i))
156-
val vPifo = vPifos(i)
157-
158-
meshController.sendControl(ControlCommand.UpdateMapperPre, engine, vPifo, vPifoId = flowId)
159-
val nextvPifo = if (i + 1 < vPifos.length) vPifos(i + 1) else flowId
160-
val nextEngine = if (i + 1 < vPifos.length) pifoMap(nextvPifo) else 0
161-
meshController.sendControl(
162-
ControlCommand.UpdateMapperPost,
163-
engine, meshController.mkFlowId(nextEngine, nextvPifo),
164-
flowId = meshController.mkFlowId(engine, flowId)
165-
)
166-
}
167-
}
168-
// apply the non-exist rewrite at the root pifo
169-
def rootNonExistRewrite(newEngineId : Int, newPifoId : Int) = {
170-
meshController.sendControl(
171-
ControlCommand.UpdateMapperPost,
172-
rootEngine,
173-
meshController.mkFlowId(newEngineId, newPifoId),
174-
flowId = meshController.mkFlowId(rootEngine, rootPifo)
175-
)
176-
}
177-
178-
// brain operations
179-
// TODO(zhiyuang): limitations on transactional updates
180-
def setBrainFIFO(vPifoId: Int) = {
181-
// assert(!transactional, "setBrainFIFO is not supported in transactional mode")
182-
val engineId = pifoMap(vPifoId)
183-
meshController.setBrainFIFO(engineId, vPifoId)
184-
}
185-
def setBrainSP(vPifoId: Int) = {
186-
val engineId = pifoMap(vPifoId)
187-
meshController.setBrainSP(engineId, vPifoId)
188-
}
189-
def setBrainWFQ(vPifoId: Int) = {
190-
val engineId = pifoMap(vPifoId)
191-
meshController.setBrainWFQ(engineId, vPifoId)
192-
}
193-
def setBrainState(vPifoId: Int, flowId: Int, state: Int) = {
194-
val engineId = pifoMap(vPifoId)
195-
meshController.setBrainState(engineId, vPifoId, flowId, state)
196-
}
197-
}
198-
199-
// Transactional configuration process.
200-
// TODO(zhiyuang): make this async and transactional
201-
def transaction(F : TreeConfiger => Unit) : SimThread = {
202-
val configer = TreeConfiger(true)
203-
fork { F(configer) }
204-
}
205-
206-
def async_config(F : TreeConfiger => Unit) : SimThread = {
207-
val configer = TreeConfiger(false)
208-
fork { F(configer) }
209-
}
210-
def config(F : TreeConfiger => Unit) : Unit = {
211-
async_config(F).join()
212-
}
213-
214233
// init code
215234
pifos.foreach { case (engineId, pifoId) =>
216235
// insert the pifo into the map

0 commit comments

Comments
 (0)