big convert g/s/r mid --> muxid
[ieee754fpu.git] / src / ieee754 / add / test_inputgroup.py
1 from random import randint
2 from nmigen import Module, Signal
3 from nmigen.compat.sim import run_simulation
4 from nmigen.cli import verilog, rtlil
5
6 from inputgroup import InputGroup
7
8
9 def testbench(dut):
10 stb = yield dut.out_op.stb
11 assert stb == 0
12 ack = yield dut.out_op.ack
13 assert ack == 0
14
15 # set row 1 input 0
16 yield dut.rs[1].in_op[0].eq(5)
17 yield dut.rs[1].stb.eq(0b01) # strobe indicate 1st op ready
18 #yield dut.rs[1].ack.eq(1)
19 yield
20
21 # check row 1 output (should be inactive)
22 decode = yield dut.rs[1].out_decode
23 assert decode == 0
24 if False:
25 op0 = yield dut.rs[1].out_op[0]
26 op1 = yield dut.rs[1].out_op[1]
27 assert op0 == 0 and op1 == 0
28
29 # output should be inactive
30 out_stb = yield dut.out_op.stb
31 assert out_stb == 1
32
33 # set row 0 input 1
34 yield dut.rs[1].in_op[1].eq(6)
35 yield dut.rs[1].stb.eq(0b11) # strobe indicate both ops ready
36
37 # set acknowledgement of output... takes 1 cycle to respond
38 yield dut.out_op.ack.eq(1)
39 yield
40 yield dut.out_op.ack.eq(0) # clear ack on output
41 yield dut.rs[1].stb.eq(0) # clear row 1 strobe
42
43 # output strobe should be active, MID should be 0 until "ack" is set...
44 out_stb = yield dut.out_op.stb
45 assert out_stb == 1
46 out_muxid = yield dut.muxid
47 assert out_muxid == 0
48
49 # ... and output should not yet be passed through either
50 op0 = yield dut.out_op.v[0]
51 op1 = yield dut.out_op.v[1]
52 assert op0 == 0 and op1 == 0
53
54 # wait for out_op.ack to activate...
55 yield dut.rs[1].stb.eq(0b00) # set row 1 strobes to zero
56 yield
57
58 # *now* output should be passed through
59 op0 = yield dut.out_op.v[0]
60 op1 = yield dut.out_op.v[1]
61 assert op0 == 5 and op1 == 6
62
63 # set row 2 input
64 yield dut.rs[2].in_op[0].eq(3)
65 yield dut.rs[2].in_op[1].eq(4)
66 yield dut.rs[2].stb.eq(0b11) # strobe indicate 1st op ready
67 yield dut.out_op.ack.eq(1) # set output ack
68 yield
69 yield dut.rs[2].stb.eq(0) # clear row 2 strobe
70 yield dut.out_op.ack.eq(0) # set output ack
71 yield
72 op0 = yield dut.out_op.v[0]
73 op1 = yield dut.out_op.v[1]
74 assert op0 == 3 and op1 == 4, "op0 %d op1 %d" % (op0, op1)
75 out_muxid = yield dut.muxid
76 assert out_muxid == 2
77
78 # set row 0 and 3 input
79 yield dut.rs[0].in_op[0].eq(9)
80 yield dut.rs[0].in_op[1].eq(8)
81 yield dut.rs[0].stb.eq(0b11) # strobe indicate 1st op ready
82 yield dut.rs[3].in_op[0].eq(1)
83 yield dut.rs[3].in_op[1].eq(2)
84 yield dut.rs[3].stb.eq(0b11) # strobe indicate 1st op ready
85
86 # set acknowledgement of output... takes 1 cycle to respond
87 yield dut.out_op.ack.eq(1)
88 yield
89 yield dut.rs[0].stb.eq(0) # clear row 1 strobe
90 yield
91 out_muxid = yield dut.muxid
92 assert out_muxid == 0, "out muxid %d" % out_muxid
93
94 yield
95 yield dut.rs[3].stb.eq(0) # clear row 1 strobe
96 yield dut.out_op.ack.eq(0) # clear ack on output
97 yield
98 out_muxid = yield dut.muxid
99 assert out_muxid == 3, "out muxid %d" % out_muxid
100
101
102 class InputTest:
103 def __init__(self, dut):
104 self.dut = dut
105 self.di = {}
106 self.do = {}
107 self.tlen = 10
108 for muxid in range(dut.num_rows):
109 self.di[muxid] = {}
110 self.do[muxid] = {}
111 for i in range(self.tlen):
112 self.di[muxid][i] = randint(0, 100)
113 self.do[muxid][i] = self.di[muxid][i]
114
115 def send(self, muxid):
116 for i in range(self.tlen):
117 op2 = self.di[muxid][i]
118 rs = dut.rs[muxid]
119 ack = yield rs.ack
120 while not ack:
121 yield
122 ack = yield rs.ack
123 yield rs.in_op[0].eq(i)
124 yield rs.in_op[1].eq(op2)
125 yield rs.stb.eq(0b11) # strobe indicate 1st op ready
126 ack = yield rs.ack
127 while ack:
128 yield
129 ack = yield rs.ack
130 yield rs.stb.eq(0)
131
132 # wait random period of time before queueing another value
133 for i in range(randint(0, 8)):
134 yield
135
136 def recv(self):
137 while True:
138 stb = yield dut.out_op.stb
139 yield dut.out_op.ack.eq(0)
140 while not stb:
141 yield dut.out_op.ack.eq(1)
142 yield
143 stb = yield dut.out_op.stb
144
145 stb = yield dut.out_op.stb
146 while stb:
147 yield
148 stb = yield dut.out_op.stb
149 muxid = yield dut.muxid
150 out_i = yield dut.out_op.v[0]
151 out_v = yield dut.out_op.v[1]
152
153 # see if this output has occurred already, delete it if it has
154 assert out_i in self.do[muxid]
155 assert self.do[muxid][out_i] == out_v
156 del self.do[muxid][out_i]
157
158 # check if there's any more outputs
159 zerolen = True
160 for (k, v) in self.do.items():
161 if v:
162 zerolen = False
163 if zerolen:
164 break
165
166 if __name__ == '__main__':
167 dut = InputGroup(width=32)
168 vl = rtlil.convert(dut, ports=dut.ports())
169 with open("test_inputgroup.il", "w") as f:
170 f.write(vl)
171 run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd")
172
173 dut = InputGroup(width=16)
174 test = InputTest(dut)
175 run_simulation(dut, [test.send(3), test.send(2),
176 test.send(1), test.send(0),
177 test.recv()],
178 vcd_name="test_inputgroup_parallel.vcd")
179