add grev
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 18 Feb 2022 06:01:41 +0000 (22:01 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Fri, 18 Feb 2022 06:01:41 +0000 (22:01 -0800)
src/soc/fu/shift_rot/formal/proof_main_stage.py
src/soc/fu/shift_rot/main_stage.py

index 7c712a46c00fe776e8f64b7ac701a10647422621..c4dd461d0a2596b7134a595287b19faae092a2c2 100644 (file)
@@ -6,7 +6,7 @@ Links:
 """
 
 from nmigen import (Module, Signal, Elaboratable, Mux, Cat, Repl,
-                    signed)
+                    signed, Array)
 from nmigen.asserts import Assert, AnyConst, Assume, Cover
 from nmutil.formaltest import FHDLTestCase
 from nmigen.cli import rtlil
@@ -242,6 +242,21 @@ class Driver(Elaboratable):
                     for j in range(8):
                         with m.If(j == idx):
                             comb += Assert(dut.o.o.data[i] == lut[j])
+            with m.Case(MicrOp.OP_GREV):
+                ra_bits = Array(dut.i.ra[i] for i in range(64))
+                with m.If(dut.i.ctx.op.is_32bit):
+                    # assert zero-extended
+                    comb += Assert(dut.o.o.data[32:] == 0)
+                    for i in range(32):
+                        idx = dut.i.rb[0:5] ^ i
+                        comb += Assert(dut.o.o.data[i]
+                                       == ra_bits[idx])
+                with m.Else():
+                    for i in range(64):
+                        idx = dut.i.rb[0:6] ^ i
+                        comb += Assert(dut.o.o.data[i]
+                                       == ra_bits[idx])
+
             with m.Default():
                 comb += o_ok.eq(0)
 
index 1d2f173580db527c964c09df961f857ab8a8f504..e249d54d3f126806707becd964c63c565ba6a862 100644 (file)
@@ -12,6 +12,7 @@ from soc.fu.pipe_data import get_pspec_draft_bitmanip
 from soc.fu.shift_rot.pipe_data import (ShiftRotOutputData,
                                         ShiftRotInputData)
 from nmutil.lut import BitwiseLut
+from nmutil.grev import GRev
 from openpower.decoder.power_enums import MicrOp
 from soc.fu.shift_rot.rotator import Rotator
 
@@ -39,12 +40,24 @@ class ShiftRotMainStage(PipeModBase):
         o = self.o.o
 
         bitwise_lut = None
+        grev = None
         if self.draft_bitmanip:
             bitwise_lut = BitwiseLut(input_count=3, width=64)
             m.submodules.bitwise_lut = bitwise_lut
             comb += bitwise_lut.inputs[0].eq(self.i.rb)
             comb += bitwise_lut.inputs[1].eq(self.i.ra)
             comb += bitwise_lut.inputs[2].eq(self.i.rc)
+            # 6 == log2(64) because we have 64-bit values
+            grev = GRev(log2_width=6)
+            m.submodules.grev = grev
+            with m.If(op.is_32bit):
+                # 32-bit, so input is lower 32-bits zero-extended
+                comb += grev.input.eq(self.i.ra[0:32])
+                # 32-bit, so we only feed in log2(32) == 5 bits
+                comb += grev.chunk_sizes.eq(self.i.rb[0:5])
+            with m.Else():
+                comb += grev.input.eq(self.i.ra)
+                comb += grev.chunk_sizes.eq(self.i.rb)
 
         # NOTE: the sh field immediate is read in by PowerDecode2
         # (actually DecodeRB), whereupon by way of rb "immediate" mode
@@ -106,6 +119,9 @@ class ShiftRotMainStage(PipeModBase):
                     comb += bitwise_lut.lut.eq(self.fields.FormTLI.TLI[:])
                     comb += o.data.eq(bitwise_lut.output)
                     comb += self.o.xer_ca.data.eq(0)
+                with m.Case(MicrOp.OP_GREV):
+                    comb += o.data.eq(grev.output)
+                    comb += self.o.xer_ca.data.eq(0)
             with m.Default():
                 comb += o.ok.eq(0)  # otherwise disable