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)
33 res
= Float32(op1
) + Float32(op2
)
34 self
.di
[mid
][i
] = (op1
, op2
)
35 self
.do
[mid
].append(res
.bits
)
38 for i
in range(self
.tlen
):
39 op1
, op2
= self
.di
[mid
][i
]
41 yield rs
.i_valid
.eq(1)
42 yield rs
.i_data
.a
.eq(op1
)
43 yield rs
.i_data
.b
.eq(op2
)
44 yield rs
.i_data
.mid
.eq(mid
)
46 o_p_ready
= yield rs
.o_ready
49 o_p_ready
= yield rs
.o_ready
54 print ("send", mid
, i
, hex(op1
), hex(op2
), hex(res
.bits
),
57 yield rs
.i_valid
.eq(0)
58 # wait random period of time before queueing another value
59 for i
in range(randint(0, 3)):
62 yield rs
.i_valid
.eq(0)
65 print ("send ended", mid
)
67 ## wait random period of time before queueing another value
68 #for i in range(randint(0, 3)):
71 #send_range = randint(0, 3)
75 # send = randint(0, send_range) != 0
79 #stall_range = randint(0, 3)
80 #for j in range(randint(1,10)):
81 # stall = randint(0, stall_range) != 0
82 # yield self.dut.n[0].i_ready.eq(stall)
87 o_n_valid
= yield n
.o_valid
88 i_n_ready
= yield n
.i_ready
89 if not o_n_valid
or not i_n_ready
:
92 out_mid
= yield n
.o_data
.mid
93 out_z
= yield n
.o_data
.z
97 print ("recv", out_mid
, hex(out_z
), "expected",
98 hex(self
.do
[mid
][out_i
] ))
100 # see if this output has occurred already, delete it if it has
101 assert mid
== out_mid
, "out_mid %d not correct %d" % (out_mid
, mid
)
102 assert self
.do
[mid
][out_i
] == out_z
103 del self
.do
[mid
][out_i
]
105 # check if there's any more outputs
106 if len(self
.do
[mid
]) == 0:
108 print ("recv ended", mid
)
112 if __name__
== '__main__':
113 dut
= FPADDMuxInOut(32, 4)
114 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
115 with
open("test_fpadd_pipe.il", "w") as f
:
117 #run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd")
119 test
= InputTest(dut
)
120 run_simulation(dut
, [test
.rcv(1), test
.rcv(0),
121 test
.rcv(3), test
.rcv(2),
122 test
.send(0), test
.send(1),
123 test
.send(3), test
.send(2),
125 vcd_name
="test_fpadd_pipe.vcd")