--- /dev/null
+from nmigen import Signal, Module, Elaboratable, Cat, Mux
+
+class GatedBitReverse(Elaboratable):
+ def __init__(self, width):
+ self.width = width
+ self.data = Signal(width, reset_less=True)
+ self.reverse_en = Signal(reset_less=True)
+ self.output = Signal(width, reset_less=True)
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+ width = self.width
+
+ for i in range(width):
+ with m.If(self.reverse_en):
+ comb += self.output[i].eq(self.data[width-i-1])
+ with m.Else():
+ comb += self.output[i].eq(self.data[i])
+
+ return m
shifter = Signal(shifterwidth)
points = PartitionPoints()
gates = Signal(mwidth-1)
+ bitrev = Signal()
step = int(width/mwidth)
for i in range(mwidth-1):
points[(i+1)*step] = gates[i]
print(points)
comb += [data.eq(AnyConst(width)),
+ bitrev.eq(AnyConst(1)),
shifter.eq(AnyConst(shifterwidth)),
gates.eq(AnyConst(mwidth-1))]
comb += [dut.data.eq(data),
dut.shifter.eq(shifter),
+ dut.bitrev.eq(bitrev),
out.eq(dut.output)]
expected = Signal(width)
- with m.Switch(points.as_sig()):
- with m.Case(0b00):
- comb += Assert(
- out[0:24] == (data[0:24] << (shifter & 0x1f)) & 0xffffff)
-
- with m.Case(0b01):
- comb += Assert(out[0:8] ==
- (data[0:8] << (shifter & 0x7)) & 0xFF)
- comb += Assert(out[8:24] ==
- (data[8:24] << (shifter & 0xf)) & 0xffff)
-
- with m.Case(0b10):
- comb += Assert(out[16:24] ==
- (data[16:24] << (shifter & 0x7)) & 0xff)
- comb += Assert(out[0:16] ==
- (data[0:16] << (shifter & 0xf)) & 0xffff)
-
- with m.Case(0b11):
- comb += Assert(out[0:8] ==
- (data[0:8] << (shifter & 0x7)) & 0xFF)
- comb += Assert(out[8:16] ==
- (data[8:16] << (shifter & 0x7)) & 0xff)
- comb += Assert(out[16:24] ==
- (data[16:24] << (shifter & 0x7)) & 0xff)
+ with m.If(bitrev == 0):
+ with m.Switch(points.as_sig()):
+ with m.Case(0b00):
+ comb += Assert(
+ out[0:24] == (data[0:24] << (shifter & 0x1f)) &
+ 0xffffff)
+
+ with m.Case(0b01):
+ comb += Assert(out[0:8] ==
+ (data[0:8] << (shifter & 0x7)) & 0xFF)
+ comb += Assert(out[8:24] ==
+ (data[8:24] << (shifter & 0xf)) & 0xffff)
+
+ with m.Case(0b10):
+ comb += Assert(out[16:24] ==
+ (data[16:24] << (shifter & 0x7)) & 0xff)
+ comb += Assert(out[0:16] ==
+ (data[0:16] << (shifter & 0xf)) & 0xffff)
+
+ with m.Case(0b11):
+ comb += Assert(out[0:8] ==
+ (data[0:8] << (shifter & 0x7)) & 0xFF)
+ comb += Assert(out[8:16] ==
+ (data[8:16] << (shifter & 0x7)) & 0xff)
+ comb += Assert(out[16:24] ==
+ (data[16:24] << (shifter & 0x7)) & 0xff)
return m
class PartitionedScalarShiftTestCase(FHDLTestCase):
from nmigen import Signal, Module, Elaboratable, Cat, Mux
from ieee754.part_mul_add.partpoints import PartitionPoints
from ieee754.part_shift.part_shift_dynamic import ShifterMask
+from ieee754.part_shift.bitrev import GatedBitReverse
import math
self.shiftbits = math.ceil(math.log2(width))
self.shifter = Signal(self.shiftbits, reset_less=True)
self.output = Signal(width, reset_less=True)
+ self.bitrev = Signal(reset_less=True) # Whether to bit-reverse the
+ # input and output
def elaborate(self, platform):
m = Module()
width = self.width
pwid = self.partition_points.get_max_partition_count(width)-1
shiftbits = self.shiftbits
- shifted = Signal(self.data.width, reset_less=True)
gates = self.partition_points.as_sig()
- comb += shifted.eq(self.data << self.shifter)
parts = []
outputs = []
shiftparts = []
intervals = []
keys = list(self.partition_points.keys()) + [self.width]
+
+ m.submodules.in_br = in_br = GatedBitReverse(self.data.width)
+ comb += in_br.data.eq(self.data)
+ comb += in_br.reverse_en.eq(self.bitrev)
+
+ m.submodules.out_br = out_br = GatedBitReverse(self.data.width)
+ comb += out_br.reverse_en.eq(self.bitrev)
+ comb += self.output.eq(out_br.output)
start = 0
for i in range(len(keys)):
end = keys[i]
- parts.append(self.data[start:end])
- outputs.append(self.output[start:end])
+ parts.append(in_br.output[start:end])
+ outputs.append(out_br.data[start:end])
intervals.append((start,end))
start = end # for next time round loop
_shifter = Signal(self.shifter.width, name="shifter%d" % i,
reset_less=True)
comb += _shifter.eq(self.shifter & shifter_masks[i])
- comb += sp[s:].eq(self.data[s:e] << _shifter)
+ comb += sp[s:].eq(in_br.output[s:e] << _shifter)
shiftparts.append(sp)