From 66620a91bac731f6745fa33a7fe122b0aa7d3485 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 17 Feb 2022 22:01:41 -0800 Subject: [PATCH] add grev --- src/soc/fu/shift_rot/formal/proof_main_stage.py | 17 ++++++++++++++++- src/soc/fu/shift_rot/main_stage.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/soc/fu/shift_rot/formal/proof_main_stage.py b/src/soc/fu/shift_rot/formal/proof_main_stage.py index 7c712a46..c4dd461d 100644 --- a/src/soc/fu/shift_rot/formal/proof_main_stage.py +++ b/src/soc/fu/shift_rot/formal/proof_main_stage.py @@ -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) diff --git a/src/soc/fu/shift_rot/main_stage.py b/src/soc/fu/shift_rot/main_stage.py index 1d2f1735..e249d54d 100644 --- a/src/soc/fu/shift_rot/main_stage.py +++ b/src/soc/fu/shift_rot/main_stage.py @@ -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 -- 2.30.2