67a6f9ebabe1399ea980d35beb1495c39ab13913
[ieee754fpu.git] / src / add / test_fpadd_pipe.py
1 """ key strategic example showing how to do multi-input fan-in into a
2 multi-stage pipeline, then multi-output fanout.
3
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.
6 """
7
8 from random import randint
9 from math import log
10 from nmigen import Module, Signal, Cat, Value
11 from nmigen.compat.sim import run_simulation
12 from nmigen.cli import verilog, rtlil
13
14 from nmigen_add_experiment import (FPADDMuxInOut,)
15
16 from sfpy import Float32
17
18 class InputTest:
19 def __init__(self, dut):
20 self.dut = dut
21 self.di = {}
22 self.do = {}
23 self.tlen = 10
24 self.width = 32
25 for mid in range(dut.num_rows):
26 self.di[mid] = {}
27 self.do[mid] = []
28 for i in range(self.tlen):
29 op1 = randint(0, (1<<self.width)-1)
30 op2 = randint(0, (1<<self.width)-1)
31 #op1 = 0x40900000
32 #op2 = 0x40200000
33 res = Float32(op1) + Float32(op2)
34 self.di[mid][i] = (op1, op2)
35 self.do[mid].append(res.bits)
36
37 def send(self, mid):
38 for i in range(self.tlen):
39 op1, op2 = self.di[mid][i]
40 rs = dut.p[mid]
41 yield rs.valid_i.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)
45 yield
46 o_p_ready = yield rs.ready_o
47 while not o_p_ready:
48 yield
49 o_p_ready = yield rs.ready_o
50
51 fop1 = Float32(op1)
52 fop2 = Float32(op2)
53 res = fop1 + fop2
54 print ("send", mid, i, hex(op1), hex(op2), hex(res.bits),
55 fop1, fop2, res)
56
57 yield rs.valid_i.eq(0)
58 # wait random period of time before queueing another value
59 for i in range(randint(0, 3)):
60 yield
61
62 yield rs.valid_i.eq(0)
63 yield
64
65 print ("send ended", mid)
66
67 ## wait random period of time before queueing another value
68 #for i in range(randint(0, 3)):
69 # yield
70
71 #send_range = randint(0, 3)
72 #if send_range == 0:
73 # send = True
74 #else:
75 # send = randint(0, send_range) != 0
76
77 def rcv(self, mid):
78 while True:
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].ready_i.eq(stall)
83 # yield
84 n = self.dut.n[mid]
85 yield n.ready_i.eq(1)
86 yield
87 o_n_valid = yield n.valid_o
88 i_n_ready = yield n.ready_i
89 if not o_n_valid or not i_n_ready:
90 continue
91
92 out_mid = yield n.o_data.mid
93 out_z = yield n.o_data.z
94
95 out_i = 0
96
97 print ("recv", out_mid, hex(out_z), "expected",
98 hex(self.do[mid][out_i] ))
99
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]
104
105 # check if there's any more outputs
106 if len(self.do[mid]) == 0:
107 break
108 print ("recv ended", mid)
109
110
111
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:
116 f.write(vl)
117 #run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd")
118
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),
124 ],
125 vcd_name="test_fpadd_pipe.vcd")
126