1 """ key strategic example showing how to do multi-input fan-in into a
2 multi-stage pipeline, then multi-output fanout.
4 the multiplex ID from the fan-in is passed in to the pipeline, preserved,
5 and used as a routing ID on the fanout.
8 from random
import randint
9 from nmigen
.compat
.sim
import run_simulation
10 from nmigen
.cli
import verilog
, rtlil
14 def __init__(self
, dut
, width
, fpkls
, fpop
):
22 for mid
in range(dut
.num_rows
):
25 for i
in range(self
.tlen
):
26 op1
= randint(0, (1<<self
.width
)-1)
27 op2
= randint(0, (1<<self
.width
)-1)
35 #op2 = 0xb4658540 # expect 0x8016147c
38 res
= self
.fpop(self
.fpkls(op1
), self
.fpkls(op2
))
39 self
.di
[mid
][i
] = (op1
, op2
)
40 self
.do
[mid
].append(res
.bits
)
43 for i
in range(self
.tlen
):
44 op1
, op2
= self
.di
[mid
][i
]
46 yield rs
.valid_i
.eq(1)
47 yield rs
.data_i
.a
.eq(op1
)
48 yield rs
.data_i
.b
.eq(op2
)
49 yield rs
.data_i
.mid
.eq(mid
)
51 o_p_ready
= yield rs
.ready_o
54 o_p_ready
= yield rs
.ready_o
56 fop1
= self
.fpkls(op1
)
57 fop2
= self
.fpkls(op2
)
58 res
= self
.fpop(fop1
, fop2
)
59 print ("send", mid
, i
, hex(op1
), hex(op2
), hex(res
.bits
),
62 yield rs
.valid_i
.eq(0)
63 # wait random period of time before queueing another value
64 for i
in range(randint(0, 3)):
67 yield rs
.valid_i
.eq(0)
70 print ("send ended", mid
)
72 ## wait random period of time before queueing another value
73 #for i in range(randint(0, 3)):
76 #send_range = randint(0, 3)
80 # send = randint(0, send_range) != 0
84 #stall_range = randint(0, 3)
85 #for j in range(randint(1,10)):
86 # stall = randint(0, stall_range) != 0
87 # yield self.dut.n[0].ready_i.eq(stall)
92 o_n_valid
= yield n
.valid_o
93 i_n_ready
= yield n
.ready_i
94 if not o_n_valid
or not i_n_ready
:
97 out_mid
= yield n
.data_o
.mid
98 out_z
= yield n
.data_o
.z
102 print ("recv", out_mid
, hex(out_z
), "expected",
103 hex(self
.do
[mid
][out_i
] ))
105 # see if this output has occurred already, delete it if it has
106 assert mid
== out_mid
, "out_mid %d not correct %d" % (out_mid
, mid
)
107 assert self
.do
[mid
][out_i
] == out_z
108 del self
.do
[mid
][out_i
]
110 # check if there's any more outputs
111 if len(self
.do
[mid
]) == 0:
113 print ("recv ended", mid
)
116 def runfp(dut
, width
, name
, fpkls
, fpop
):
117 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
118 with
open("%s.il" % name
, "w") as f
:
121 test
= InputTest(dut
, width
, fpkls
, fpop
)
122 run_simulation(dut
, [test
.rcv(1), test
.rcv(0),
123 test
.rcv(3), test
.rcv(2),
124 test
.send(0), test
.send(1),
125 test
.send(3), test
.send(2),
127 vcd_name
="%s.vcd" % name
)