Remove rotates and shifts from alu
authorMichael Nolan <mtnolan2640@gmail.com>
Tue, 12 May 2020 17:29:02 +0000 (13:29 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Tue, 12 May 2020 17:29:02 +0000 (13:29 -0400)
src/soc/alu/formal/proof_main_stage.py
src/soc/alu/main_stage.py
src/soc/alu/maskgen.py [deleted file]
src/soc/alu/rotator.py [deleted file]
src/soc/alu/rotl.py [deleted file]
src/soc/alu/test/test_maskgen.py [deleted file]
src/soc/alu/test/test_pipe_caller.py

index 3ce8f19a27abc3ce182a5e703ee4a09e86b2b4c4..e25b1c51fe851bba81b23217a525f998e40dd6cd 100644 (file)
@@ -74,25 +74,6 @@ class Driver(Elaboratable):
                 comb += Assert(dut.o.o == a | b)
             with m.Case(InternalOp.OP_XOR):
                 comb += Assert(dut.o.o == a ^ b)
-            with m.Case(InternalOp.OP_SHL):
-                with m.If(rec.is_32bit):
-                    comb += Assert(o[0:32] == ((a << b[0:6]) & 0xffffffff))
-                    comb += Assert(o[32:64] == 0)
-                with m.Else():
-                    comb += Assert(o == ((a << b[0:7]) & ((1 << 64)-1)))
-            with m.Case(InternalOp.OP_SHR):
-                with m.If(~rec.is_signed):
-                    with m.If(rec.is_32bit):
-                        comb += Assert(o[0:32] == (a[0:32] >> b[0:6]))
-                        comb += Assert(o[32:64] == 0)
-                    with m.Else():
-                        comb += Assert(o == (a >> b[0:7]))
-                with m.Else():
-                    with m.If(rec.is_32bit):
-                        comb += Assert(o[0:32] == (a_signed_32 >> b[0:6]))
-                        comb += Assert(o[32:64] == Repl(a[31], 32))
-                    with m.Else():
-                        comb += Assert(o == (a_signed >> b[0:7]))
 
         return m
 
index 9d8133f1638158f752659c6bfa6261e9d07f171b..b2851015b6eca83cb30fb437ed3751e66da073cf 100644 (file)
@@ -8,18 +8,12 @@ from nmutil.pipemodbase import PipeModBase
 from soc.alu.pipe_data import ALUInputData, ALUOutputData
 from ieee754.part.partsig import PartitionedSignal
 from soc.decoder.power_enums import InternalOp
-from soc.alu.maskgen import MaskGen
-from soc.alu.rotl import ROTL
 
-from soc.decoder.power_fields import DecodeFields
-from soc.decoder.power_fieldsn import SignalBitRange
 
 
 class ALUMainStage(PipeModBase):
     def __init__(self, pspec):
         super().__init__(pspec, "main")
-        self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
-        self.fields.create_specs()
 
     def ispec(self):
         return ALUInputData(self.pspec)
@@ -32,37 +26,12 @@ class ALUMainStage(PipeModBase):
         comb = m.d.comb
 
 
-        fields = self.fields.instrs['M']
-        mb = Signal(fields['MB'][0:-1].shape())
-        comb += mb.eq(fields['MB'][0:-1])
-        me = Signal(fields['ME'][0:-1].shape())
-        comb += me.eq(fields['ME'][0:-1])
-
         # check if op is 32-bit, and get sign bit from operand a
         is_32bit = Signal(reset_less=True)
         sign_bit = Signal(reset_less=True)
         comb += is_32bit.eq(self.i.ctx.op.is_32bit)
         comb += sign_bit.eq(Mux(is_32bit, self.i.a[31], self.i.a[63]))
 
-        # Signals for rotates and shifts
-        rotl_out = Signal.like(self.i.a)
-        mask = Signal.like(self.i.a)
-        m.submodules.maskgen = maskgen = MaskGen(64)
-        m.submodules.rotl = rotl = ROTL(64)
-        m.submodules.rotl32 = rotl32 = ROTL(32)
-        rotate_amt = Signal.like(rotl.b)
-
-        comb += [
-            rotl.a.eq(self.i.a),
-            rotl.b.eq(rotate_amt),
-            rotl32.a.eq(self.i.a[0:32]),
-            rotl32.b.eq(rotate_amt)]
-
-        with m.If(is_32bit):
-            comb += rotl_out.eq(Cat(rotl32.o, Repl(0, 32)))
-        with m.Else():
-            comb += rotl_out.eq(rotl.o)
-
         ##########################
         # main switch-statement for handling arithmetic and logic operations
 
@@ -92,56 +61,6 @@ class ALUMainStage(PipeModBase):
             #### xor ####
             with m.Case(InternalOp.OP_XOR):
                 comb += self.o.o.eq(self.i.a ^ self.i.b)
-
-            #### shift left ####
-            with m.Case(InternalOp.OP_SHL):
-                comb += maskgen.mb.eq(Mux(is_32bit, 32, 0))
-                comb += maskgen.me.eq(63-self.i.b[0:6])
-                comb += rotate_amt.eq(self.i.b[0:6])
-                with m.If(is_32bit):
-                    with m.If(self.i.b[5]):
-                        comb += mask.eq(0)
-                    with m.Else():
-                        comb += mask.eq(maskgen.o)
-                with m.Else():
-                    with m.If(self.i.b[6]):
-                        comb += mask.eq(0)
-                    with m.Else():
-                        comb += mask.eq(maskgen.o)
-                comb += self.o.o.eq(rotl_out & mask)
-
-            #### shift right ####
-            with m.Case(InternalOp.OP_SHR):
-                comb += maskgen.mb.eq(Mux(is_32bit, 32, 0) + self.i.b[0:6])
-                comb += maskgen.me.eq(63)
-                comb += rotate_amt.eq(64-self.i.b[0:6])
-                with m.If(is_32bit):
-                    with m.If(self.i.b[5]):
-                        comb += mask.eq(0)
-                    with m.Else():
-                        comb += mask.eq(maskgen.o)
-                with m.Else():
-                    with m.If(self.i.b[6]):
-                        comb += mask.eq(0)
-                    with m.Else():
-                        comb += mask.eq(maskgen.o)
-                with m.If(self.i.ctx.op.is_signed):
-                    out = rotl_out & mask | Mux(sign_bit, ~mask, 0)
-                    cout = sign_bit & ((rotl_out & mask) != 0)
-                    comb += self.o.o.eq(out)
-                    comb += self.o.carry_out.eq(cout)
-                with m.Else():
-                    comb += self.o.o.eq(rotl_out & mask)
-
-            with m.Case(InternalOp.OP_RLC):
-                with m.If(self.i.ctx.op.imm_data.imm_ok):
-                    comb += rotate_amt.eq(self.i.ctx.op.imm_data.imm[0:5])
-                with m.Else():
-                    comb += rotate_amt.eq(self.i.b[0:5])
-                comb += maskgen.mb.eq(mb+32)
-                comb += maskgen.me.eq(me+32)
-                comb += mask.eq(maskgen.o)
-                comb += self.o.o.eq((rotl_out & mask) | (self.i.b & ~mask))
                 
 
         ###### sticky overflow and context, both pass-through #####
diff --git a/src/soc/alu/maskgen.py b/src/soc/alu/maskgen.py
deleted file mode 100644 (file)
index 89246e0..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-from nmigen import (Elaboratable, Signal, Module)
-import math
-
-class MaskGen(Elaboratable):
-    """MaskGen - create a diff mask
-
-    example: x=5 --> a=0b11111
-             y=3 --> b=0b00111
-             o:        0b11000
-             x=2 --> a=0b00011
-             y=4 --> b=0b01111
-             o:        0b10011
-    """
-    def __init__(self, width):
-        self.width = width
-        self.shiftwidth = math.ceil(math.log2(width))
-        self.mb = Signal(self.shiftwidth, reset_less=True)
-        self.me = Signal(self.shiftwidth, reset_less=True)
-
-        self.o = Signal(width, reset_less=True)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-
-        x = Signal.like(self.mb)
-        y = Signal.like(self.mb)
-
-        comb += x.eq(64 - self.mb)
-        comb += y.eq(63 - self.me)
-
-        mask_a = Signal.like(self.o)
-        mask_b = Signal.like(self.o)
-
-        comb += mask_a.eq((1<<x) - 1)
-        comb += mask_b.eq((1<<y) - 1)
-
-        with m.If(x > y):
-            comb += self.o.eq(mask_a ^ mask_b)
-        with m.Else():
-            comb += self.o.eq(mask_a ^ ~mask_b)
-            
-
-        return m
-
-    def ports(self):
-        return [self.mb, self.me, self.o]
diff --git a/src/soc/alu/rotator.py b/src/soc/alu/rotator.py
deleted file mode 100644 (file)
index 7681692..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-# Manual translation and adaptation of rotator.vhdl from microwatt into nmigen
-#
-
-from nmigen import (Elaboratable, Signal, Module, Const, Cat)
-from soc.alu.rotl import ROTL
-
-# note BE bit numbering
-def right_mask(m, mask_begin):
-    """ this can be replaced by something like (mask_begin << 1) - 1"""
-    ret = Signal(64, name="right_mask", reset_less=True)
-    m.d.comb += ret.eq(0)
-    for i in range(64):
-        with m.If(i >= unsigned(mask_begin)): # set from i upwards
-            m.d.comb += ret[63 - i].eq(1)
-    return ret;
-
-def left_mask(m, mask_end):
-    """ this can be replaced by something like ~((mask_end << 1) - 1)"""
-    ret = Signal(64, name="left_mask", reset_less=True)
-    m.d.comb += ret.eq(0)
-    with m.If(mask_end[6] != 0):
-        return ret
-    for i in range(64):
-        with m.If(i <= unsigned(mask_end)): # set from i downwards
-            m.d.comb += ret[63 - i].eq(1)
-    return ret;
-
-
-class Rotator(Elaboratable):
-    """Rotator: covers multiple POWER9 rotate functions
-
-        supported modes:
-
-        * sl[wd]
-        * rlw*, rldic, rldicr, rldimi
-        * rldicl, sr[wd]
-        * sra[wd][i]
-
-        use as follows:
-
-        * shift = RB[0:7]
-        * arith = 1 when is_signed
-        * right_shift = 1 when insn_type is OP_SHR
-        * clear_left = 1 when insn_type is OP_RLC or OP_RLCL
-        * clear_right = 1 when insn_type is OP_RLC or OP_RLCR
-    """
-    def __init__(self):
-        # input
-        self.rs = Signal(64, reset_less=True)       # RS
-        self.ra = Signal(64, reset_less=True)       # RA
-        self.shift = Signal(7, reset_less=True)     # RB[0:7]
-        self.insn = Signal(32, reset_less=True)     # for mb and me fields
-        self.is_32bit = Signal(reset_less=True)
-        self.right_shift = Signal(reset_less=True)
-        self.arith = Signal(reset_less=True)
-        self.clear_left = Signal(reset_less=True)
-        self.clear_right = Signal(reset_less=True)
-        # output
-        self.result_o = Signal(64, reset_less=True)
-        self.carry_out_o = Signal(reset_less=True)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        ra, rs = self.ra, self.rs
-
-        # temporaries
-        repl32 = Signal(64, reset_less=True)
-        rot_count = Signal(6, reset_less=True)
-        rot = Signal(64, reset_less=True)
-        sh = Signal(7, reset_less=True)
-        mb = Signal(7, reset_less=True)
-        me = Signal(7, reset_less=True)
-        mr = Signal(64, reset_less=True)
-        ml = Signal(64, reset_less=True)
-        output_mode = Signal(2, reset_less=True)
-
-        # First replicate bottom 32 bits to both halves if 32-bit
-        comb += repl32[0:32].eq(rs[0:32])
-        with m.If(self.is_32bit):
-            comb += repl32[32:64].eq(rs[0:32])
-
-        # Negate shift count for right shifts
-        with m.If(self.right_shift):
-            comb += rot_count.eq(-signed(self.shift[0:6]))
-        with m.Else():
-            comb += rot_count.eq(self.shift[0:6])
-
-        # ROTL submodule
-        m.submodules.rotl = rotl = ROTL(64)
-        comb += rotl.a.eq(repl32)
-        comb += rotl.b.eq(rot_count)
-        comb += rot.eq(rotl.o)
-
-        # Trim shift count to 6 bits for 32-bit shifts
-        comb += sh.eq(Cat(shift[0:6], shift[6] & ~self.is_32bit))
-
-        # XXX errr... we should already have these, in Fields?  oh well
-        # Work out mask begin/end indexes (caution, big-endian bit numbering)
-
-        # mask-begin (mb)
-        with m.If(self.clear_left):
-            with m.If(self.is_32bit):
-                comb += mb.eq(Cat(self.insn[6:11], Const(0b01, 2)))
-            with m.Else():
-                comb += mb.eq(Cat(self.insn[6:11], self.insn[5], Const(0b0, 1)))
-        with m.Elif(self.right_shift):
-            # this is basically mb = sh + (is_32bit? 32: 0);
-            with m.If(self.is_32bit):
-                comb += mb.eq(Cat(sh[0:5], ~sh[5], sh[5]))
-            with m.Else():
-                comb += mb.eq(sh)
-        with m.Else():
-            comb += mb.eq(Cat(Const(0b0, 5), self.is_32bit, Const(0b0, 1)))
-
-        # mask-end (me)
-        with m.If(self.clear_right & self.is_32bit):
-            comb += me.eq(Cat(self.insn[1:6], Const(0b01, 2)))
-        with m.Elif(self.clear_right & ~self.clear_left):
-            comb += me.eq(Cat(self.insn[6:11], self.insn[5], Const(0b0, 1)))
-        with m.Else():
-            # effectively, 63 - sh
-            comb += me.eq(Cat(~shift[0:6], shift[6]))
-
-        # Calculate left and right masks
-        comb += mr.eq(right_mask(m, mb))
-        comb += ml.eq(left_mask(m, me))
-
-        # Work out output mode
-        # 00 for sl[wd]
-        # 0w for rlw*, rldic, rldicr, rldimi, where w = 1 iff mb > me
-        # 10 for rldicl, sr[wd]
-        # 1z for sra[wd][i], z = 1 if rs is negative
-        with m.If((self.clear_left & ~self.clear_right) | self.right_shift):
-            comb += output_mode.eq(Cat(self.arith & repl32[63], Const(1, 1))
-        with m.Else():
-            mbgt = self.clear_right & (unsigned(mb[0:6]) > unsigned(me[0:6]))
-            comb += output_mode.eq(Cat(mbgt, Const(0, 1))
-
-        # Generate output from rotated input and masks
-        with m.Switch(output_mode):
-            with m.Case(0b00):
-                comb += self.result_o.eq((rot & (mr & ml)) | (ra & ~(mr & ml)))
-            with m.Case(0b01):
-                comb += self.result_o.eq((rot & (mr | ml)) | (ra & ~(mr | ml)))
-            with m.Case(0b10):
-                comb += self.result_o.eq(rot & mr)
-            with m.Case(0b11):
-                comb += self.result_o.eq(rot | ~mr)
-                # Generate carry output for arithmetic shift right of -ve value
-                comb += self.carry_out_o.eq(rs & ~ml)
-
-        return m
-
diff --git a/src/soc/alu/rotl.py b/src/soc/alu/rotl.py
deleted file mode 100644 (file)
index d2ebfcf..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from nmigen import (Elaboratable, Signal, Module)
-import math
-
-class ROTL(Elaboratable):
-    def __init__(self, width):
-        self.width = width
-        self.shiftwidth = math.ceil(math.log2(width))
-        self.a = Signal(width, reset_less=True)
-        self.b = Signal(self.shiftwidth, reset_less=True)
-
-        self.o = Signal(width, reset_less=True)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-
-        shl = Signal.like(self.a)
-        shr = Signal.like(self.a)
-
-        comb += shl.eq(self.a << self.b)
-        comb += shr.eq(self.a >> (self.width - self.b))
-
-        comb += self.o.eq(shl | shr)
-        return m
diff --git a/src/soc/alu/test/test_maskgen.py b/src/soc/alu/test/test_maskgen.py
deleted file mode 100644 (file)
index f9d28d7..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from nmigen import Signal, Module
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmigen.test.utils import FHDLTestCase
-from soc.alu.maskgen import MaskGen
-from soc.decoder.helpers import MASK
-import random
-import unittest
-
-class MaskGenTestCase(FHDLTestCase):
-    def test_maskgen(self):
-        m = Module()
-        comb = m.d.comb
-        m.submodules.dut = dut = MaskGen(64)
-        mb = Signal.like(dut.mb)
-        me = Signal.like(dut.me)
-        o = Signal.like(dut.o)
-
-        comb += [
-            dut.mb.eq(mb),
-            dut.me.eq(me),
-            o.eq(dut.o)]
-
-        sim = Simulator(m)
-
-        def process():
-            for x in range(0, 64):
-                for y in range(0, 64):
-                    yield mb.eq(x)
-                    yield me.eq(y)
-                    yield Delay(1e-6)
-
-                    expected = MASK(x, y)
-                    result = yield o
-                    self.assertEqual(expected, result)
-
-        sim.add_process(process) # or sim.add_sync_process(process), see below
-        with sim.write_vcd("maskgen.vcd", "maskgen.gtkw", traces=dut.ports()):
-            sim.run()
-
-if __name__ == '__main__':
-    unittest.main()
index 3dcab75bc3e25af78f54abe650fe824801d45fee..a31c5fe3f5d27f58fb81e4041a479becfdaf1211 100644 (file)
@@ -130,50 +130,6 @@ class ALUTestCase(FHDLTestCase):
             initial_regs = [0] * 32
             initial_regs[1] = random.randint(0, (1<<64)-1)
             self.run_tst_program(Program(lst), initial_regs)
-
-    def test_shift(self):
-        insns = ["slw", "sld", "srw", "srd", "sraw", "srad"]
-        for i in range(20):
-            choice = random.choice(insns)
-            lst = [f"{choice} 3, 1, 2"]
-            initial_regs = [0] * 32
-            initial_regs[1] = random.randint(0, (1<<64)-1)
-            initial_regs[2] = random.randint(0, 63)
-            print(initial_regs[1], initial_regs[2])
-            self.run_tst_program(Program(lst), initial_regs)
-
-
-    def test_shift_arith(self):
-        lst = ["sraw 3, 1, 2"]
-        initial_regs = [0] * 32
-        initial_regs[1] = random.randint(0, (1<<64)-1)
-        initial_regs[2] = random.randint(0, 63)
-        print(initial_regs[1], initial_regs[2])
-        self.run_tst_program(Program(lst), initial_regs)
-
-    def test_rlwinm(self):
-        for i in range(10):
-            mb = random.randint(0,31)
-            me = random.randint(0,31)
-            sh = random.randint(0,31)
-            lst = [f"rlwinm 3, 1, {mb}, {me}, {sh}"]
-            initial_regs = [0] * 32
-            initial_regs[1] = random.randint(0, (1<<64)-1)
-            self.run_tst_program(Program(lst), initial_regs)
-
-    def test_rlwimi(self):
-        lst = ["rlwimi 3, 1, 5, 20, 6"]
-        initial_regs = [0] * 32
-        initial_regs[1] = 0xdeadbeef
-        initial_regs[3] = 0x12345678
-        self.run_tst_program(Program(lst), initial_regs)
-
-    def test_rlwnm(self):
-        lst = ["rlwnm 3, 1, 2, 20, 6"]
-        initial_regs = [0] * 32
-        initial_regs[1] = random.randint(0, (1<<64)-1)
-        initial_regs[2] = random.randint(0, 63)
-        self.run_tst_program(Program(lst), initial_regs)
         
     def test_adde(self):
         lst = ["adde. 5, 6, 7"]