# Copyright (C) Jonathan P Dawson 2013
# 2013-12-12
-from nmigen import Signal, Cat, Const, Mux
+from nmigen import Signal, Cat, Const, Mux, Module
from math import log
from operator import or_
from functools import reduce
+class MultiShiftR:
+
+ def __init__(self, width):
+ self.width = width
+ self.smax = int(log(width) / log(2))
+ self.i = Signal(width)
+ self.s = Signal(self.smax)
+ self.o = Signal(width)
+
+ def elaborate(self, platform):
+ m = Module()
+ m.d.comb += self.o.eq(self.i >> self.s)
+ return m
+
+
class MultiShift:
""" Generates variable-length single-cycle shifter from a series
of conditional tests on each bit of the left/right shift operand.
self.smax = int(log(width) / log(2))
def lshift(self, op, s):
+ res = op << s
+ return res[:len(op)]
res = op
for i in range(self.smax):
zeros = [0] * (1<<i)
return res
def rshift(self, op, s):
+ res = op >> s
+ return res[:len(op)]
res = op
for i in range(self.smax):
zeros = [0] * (1<<i)
from nmigen import Module, Signal
from nmigen.compat.sim import run_simulation
-from fpbase import MultiShift
+from fpbase import MultiShift, MultiShiftR
class MultiShiftModL:
def __init__(self, width):
return m
+class MultiShiftModRMod:
+ def __init__(self, width):
+ self.ms = MultiShiftR(width)
+ self.a = Signal(width)
+ self.b = Signal(self.ms.smax)
+ self.x = Signal(width)
+
+ def get_fragment(self, platform=None):
+
+ m = Module()
+ m.submodules += self.ms
+ m.d.comb += self.ms.i.eq(self.a)
+ m.d.comb += self.ms.s.eq(self.b)
+ m.d.comb += self.x.eq(self.ms.o)
+
+ return m
+
def check_case(dut, width, a, b):
yield dut.a.eq(a)
yield dut.b.eq(b)
yield from check_caser(dut, 32, a, i)
if __name__ == '__main__':
+ dut = MultiShiftModRMod(width=32)
+ run_simulation(dut, testbenchr(dut), vcd_name="test_multishift.vcd")
+
dut = MultiShiftModR(width=32)
run_simulation(dut, testbenchr(dut), vcd_name="test_multishift.vcd")