with m.Switch(points.as_sig()):
with m.Case(0b00):
+ comb += Assert(out[0:24] == (data[0:24] << shifter) & 0xffffff)
+
+ with m.Case(0b01):
comb += Assert(out[0:8] == expected[0:8])
- comb += Assert(out[8:16] == expected[8:16])
+ comb += Assert(out[8:24] == (data[8:24] << shifter) & 0xffff)
+
+ with m.Case(0b10):
+ comb += Assert(out[16:24] == (data[16:24] << shifter) & 0xff)
+ comb += Assert(out[0:16] == (data[0:16] << shifter) & 0xffff)
+ with m.Case(0b11):
+ comb += Assert(out[0:8] == expected[0:8])
+ comb += Assert(out[8:16] == (data[8:16] << shifter) & 0xff)
+ comb += Assert(out[16:24] == (data[16:24] << shifter) & 0xff)
return m
* http://libre-riscv.org/3d_gpu/architecture/dynamic_simd/shift/
* http://bugs.libre-riscv.org/show_bug.cgi?id=173
"""
-from nmigen import Signal, Module, Elaboratable, Cat, C
+from nmigen import Signal, Module, Elaboratable, Cat, Mux
from ieee754.part_mul_add.partpoints import PartitionPoints
import math
comb = m.d.comb
width = self.width
shiftbits = self.shiftbits
-
shifted = Signal(self.data.width)
+ gates = self.partition_points.as_sig()
comb += shifted.eq(self.data << self.shifter)
- comb += self.output[0:8].eq(shifted[0:8])
- comb += self.output[8:16].eq(shifted[8:16])
+ parts = []
+ outputs = []
+ shiftparts = []
+ intervals = []
+ keys = list(self.partition_points.keys()) + [self.width]
+ start = 0
+ for i in range(len(keys)):
+ end = keys[i]
+ parts.append(self.data[start:end])
+ outputs.append(self.output[start:end])
+ intervals.append((start,end))
+
+ sp = Signal(width)
+ comb += sp[start:].eq(self.data[start:end] << self.shifter)
+ shiftparts.append(sp)
+
+ start = end # for next time round loop
+
+ for i, interval in enumerate(intervals):
+ start, end = interval
+ if i == 0:
+ intermed = shiftparts[i]
+ else:
+ intermed = shiftparts[i] | Mux(gates[i-1], 0, prev)
+ comb += outputs[i].eq(intermed[start:end])
+ prev = intermed
return m
-
-