1 from random
import randint
2 from nmigen
import Module
, Signal
3 from nmigen
.compat
.sim
import run_simulation
5 from ieee754
.fpcommon
.fpbase
import MultiShift
, MultiShiftR
, MultiShiftRMerge
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
)
14 def elaborate(self
, platform
=None):
17 m
.d
.comb
+= self
.x
.eq(self
.ms
.lshift(self
.a
, self
.b
))
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
)
28 def elaborate(self
, platform
=None):
31 m
.d
.comb
+= self
.x
.eq(self
.ms
.rshift(self
.a
, self
.b
))
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
)
42 def elaborate(self
, platform
=None):
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
)
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
)
59 def elaborate(self
, platform
=None):
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
)
70 def check_case(dut
, width
, a
, b
):
75 x
= (a
<< b
) & ((1<<width
)-1)
78 assert out_x
== x
, "Output x 0x%x not equal to expected 0x%x" % (out_x
, x
)
80 def check_caser(dut
, width
, a
, b
):
85 x
= (a
>> b
) & ((1<<width
)-1)
88 assert out_x
== x
, "Output x 0x%x not equal to expected 0x%x" % (out_x
, x
)
91 def check_case_merge(dut
, width
, a
, b
):
96 x
= (a
>> b
) & ((1<<width
)-1) # actual shift
97 if (a
& ((2<<b
)-1)) != 0: # mask for sticky bit
102 "\nshift %d\nInput\n%+32s\nOutput x\n%+32s != \n%+32s" % \
103 (b
, bin(a
), bin(out_x
), bin(x
))
107 for j
in range(1000):
108 a
= randint(0, (1<<32)-1)
109 yield from check_case_merge(dut
, 32, a
, i
)
113 for j
in range(1000):
114 a
= randint(0, (1<<32)-1)
115 yield from check_case(dut
, 32, a
, i
)
119 for j
in range(1000):
120 a
= randint(0, (1<<32)-1)
121 yield from check_caser(dut
, 32, a
, i
)
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")
129 dut
= MultiShiftModR(width
=32)
130 run_simulation(dut
, testbenchr(dut
), vcd_name
="test_multishift.vcd")
132 dut
= MultiShiftModL(width
=32)
133 run_simulation(dut
, testbench(dut
), vcd_name
="test_multishift.vcd")