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
10 from nmigen
import Module
, Signal
, Cat
, Value
11 from nmigen
.compat
.sim
import run_simulation
12 from nmigen
.cli
import verilog
, rtlil
14 from nmigen_add_experiment
import (FPADDMuxInOut
,)
16 from sfpy
import Float32
19 def __init__(self
, dut
):
25 for mid
in range(dut
.num_rows
):
28 for i
in range(self
.tlen
):
29 op1
= randint(0, (1<<self
.width
)-1)
30 op2
= randint(0, (1<<self
.width
)-1)
31 res
= Float32(op1
) + Float32(op2
)
32 self
.di
[mid
][i
] = (op1
, op2
)
33 self
.do
[mid
].append(res
.bits
)
36 for i
in range(self
.tlen
):
37 op1
, op2
= self
.di
[mid
][i
]
39 yield rs
.i_valid
.eq(1)
40 yield rs
.i_data
.a
.eq(op1
)
41 yield rs
.i_data
.b
.eq(op2
)
42 yield rs
.i_data
.mid
.eq(mid
)
44 o_p_ready
= yield rs
.o_ready
47 o_p_ready
= yield rs
.o_ready
52 print ("send", mid
, i
, hex(op1
), hex(op2
), hex(res
.bits
),
55 yield rs
.i_valid
.eq(0)
56 # wait random period of time before queueing another value
57 for i
in range(randint(0, 3)):
60 yield rs
.i_valid
.eq(0)
63 print ("send ended", mid
)
65 ## wait random period of time before queueing another value
66 #for i in range(randint(0, 3)):
69 #send_range = randint(0, 3)
73 # send = randint(0, send_range) != 0
77 #stall_range = randint(0, 3)
78 #for j in range(randint(1,10)):
79 # stall = randint(0, stall_range) != 0
80 # yield self.dut.n[0].i_ready.eq(stall)
85 o_n_valid
= yield n
.o_valid
86 i_n_ready
= yield n
.i_ready
87 if not o_n_valid
or not i_n_ready
:
90 out_mid
= yield n
.o_data
.mid
91 out_z
= yield n
.o_data
.z
95 print ("recv", out_mid
, hex(out_z
), "expected",
96 hex(self
.do
[mid
][out_i
] ))
98 # see if this output has occurred already, delete it if it has
99 assert mid
== out_mid
, "out_mid %d not correct %d" % (out_mid
, mid
)
100 assert self
.do
[mid
][out_i
] == out_z
101 del self
.do
[mid
][out_i
]
103 # check if there's any more outputs
104 if len(self
.do
[mid
]) == 0:
106 print ("recv ended", mid
)
110 if __name__
== '__main__':
111 dut
= FPADDMuxInOut(32, 2, 4)
112 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
113 with
open("test_fpadd_pipe.il", "w") as f
:
115 #run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd")
117 test
= InputTest(dut
)
118 run_simulation(dut
, [test
.rcv(1), test
.rcv(0),
119 test
.rcv(3), test
.rcv(2),
120 test
.send(0), test
.send(1),
121 test
.send(3), test
.send(2),
123 vcd_name
="test_inoutmux_pipe.vcd")