move add to ieee754 directory
[ieee754fpu.git] / src / ieee754 / add / test_multishift.py
1 from random import randint
2 from nmigen import Module, Signal
3 from nmigen.compat.sim import run_simulation
4
5 from fpbase import MultiShift, MultiShiftR, MultiShiftRMerge
6
7 class MultiShiftModL:
8 def __init__(self, width):
9 self.ms = MultiShift(width)
10 self.a = Signal(width)
11 self.b = Signal(self.ms.smax)
12 self.x = Signal(width)
13
14 def elaborate(self, platform=None):
15
16 m = Module()
17 m.d.comb += self.x.eq(self.ms.lshift(self.a, self.b))
18
19 return m
20
21 class MultiShiftModR:
22 def __init__(self, width):
23 self.ms = MultiShift(width)
24 self.a = Signal(width)
25 self.b = Signal(self.ms.smax)
26 self.x = Signal(width)
27
28 def elaborate(self, platform=None):
29
30 m = Module()
31 m.d.comb += self.x.eq(self.ms.rshift(self.a, self.b))
32
33 return m
34
35 class MultiShiftModRMod:
36 def __init__(self, width):
37 self.ms = MultiShiftR(width)
38 self.a = Signal(width)
39 self.b = Signal(self.ms.smax)
40 self.x = Signal(width)
41
42 def elaborate(self, platform=None):
43
44 m = Module()
45 m.submodules += self.ms
46 m.d.comb += self.ms.i.eq(self.a)
47 m.d.comb += self.ms.s.eq(self.b)
48 m.d.comb += self.x.eq(self.ms.o)
49
50 return m
51
52 class MultiShiftRMergeMod:
53 def __init__(self, width):
54 self.ms = MultiShiftRMerge(width)
55 self.a = Signal(width)
56 self.b = Signal(self.ms.smax)
57 self.x = Signal(width)
58
59 def elaborate(self, platform=None):
60
61 m = Module()
62 m.submodules += self.ms
63 m.d.comb += self.ms.inp.eq(self.a)
64 m.d.comb += self.ms.diff.eq(self.b)
65 m.d.comb += self.x.eq(self.ms.m)
66
67 return m
68
69
70 def check_case(dut, width, a, b):
71 yield dut.a.eq(a)
72 yield dut.b.eq(b)
73 yield
74
75 x = (a << b) & ((1<<width)-1)
76
77 out_x = yield dut.x
78 assert out_x == x, "Output x 0x%x not equal to expected 0x%x" % (out_x, x)
79
80 def check_caser(dut, width, a, b):
81 yield dut.a.eq(a)
82 yield dut.b.eq(b)
83 yield
84
85 x = (a >> b) & ((1<<width)-1)
86
87 out_x = yield dut.x
88 assert out_x == x, "Output x 0x%x not equal to expected 0x%x" % (out_x, x)
89
90
91 def check_case_merge(dut, width, a, b):
92 yield dut.a.eq(a)
93 yield dut.b.eq(b)
94 yield
95
96 x = (a >> b) & ((1<<width)-1) # actual shift
97 if (a & ((2<<b)-1)) != 0: # mask for sticky bit
98 x |= 1 # set LSB
99
100 out_x = yield dut.x
101 assert out_x == x, \
102 "\nshift %d\nInput\n%+32s\nOutput x\n%+32s != \n%+32s" % \
103 (b, bin(a), bin(out_x), bin(x))
104
105 def testmerge(dut):
106 for i in range(32):
107 for j in range(1000):
108 a = randint(0, (1<<32)-1)
109 yield from check_case_merge(dut, 32, a, i)
110
111 def testbench(dut):
112 for i in range(32):
113 for j in range(1000):
114 a = randint(0, (1<<32)-1)
115 yield from check_case(dut, 32, a, i)
116
117 def testbenchr(dut):
118 for i in range(32):
119 for j in range(1000):
120 a = randint(0, (1<<32)-1)
121 yield from check_caser(dut, 32, a, i)
122
123 if __name__ == '__main__':
124 dut = MultiShiftRMergeMod(width=32)
125 run_simulation(dut, testmerge(dut), vcd_name="test_multishiftmerge.vcd")
126 dut = MultiShiftModRMod(width=32)
127 run_simulation(dut, testbenchr(dut), vcd_name="test_multishift.vcd")
128
129 dut = MultiShiftModR(width=32)
130 run_simulation(dut, testbenchr(dut), vcd_name="test_multishift.vcd")
131
132 dut = MultiShiftModL(width=32)
133 run_simulation(dut, testbench(dut), vcd_name="test_multishift.vcd")
134