add spr main stage
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 4 Jul 2020 12:22:09 +0000 (13:22 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 4 Jul 2020 12:22:09 +0000 (13:22 +0100)
src/soc/fu/spr/main_stage.py [new file with mode: 0644]
src/soc/fu/spr/pipe_data.py

diff --git a/src/soc/fu/spr/main_stage.py b/src/soc/fu/spr/main_stage.py
new file mode 100644 (file)
index 0000000..5786eff
--- /dev/null
@@ -0,0 +1,94 @@
+"""SPR Pipeline
+
+* https://bugs.libre-soc.org/show_bug.cgi?id=348
+* https://libre-soc.org/openpower/isa/sprset/
+"""
+
+from nmigen import (Module, Signal, Cat, Mux, Const, signed)
+from nmutil.pipemodbase import PipeModBase
+from nmutil.extend import exts
+from soc.fu.spr.pipe_data import SPRInputData, SPROutputData
+from soc.fu.branch.main_stage import br_ext
+from soc.decoder.power_enums import InternalOp
+
+from soc.decoder.power_fields import DecodeFields
+from soc.decoder.power_fieldsn import SignalBitRange
+
+def decode_spr_num(spr):
+    return Cat(spr[5:10], spr[0:5])
+
+
+class SPRMainStage(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 SPRInputData(self.pspec)
+
+    def ospec(self):
+        return SPROutputData(self.pspec)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+        op = self.i.ctx.op
+
+        # convenience variables
+        a_i, spr1_i, fast1_i = self.i.a, self.i.spr1, self.i.fast1
+        so_i, ov_i, ca_i = self.i.xer_so, self.i.xer_ov, self.i.xer_ca
+        so_o, ov_o, ca_o = self.o.xer_so, self.o.xer_ov, self.o.xer_ca
+        o, spr1_o, fast1_o = self.o.o, self.o.spr1, self.o.fast1
+
+        # take copy of D-Form TO field
+        x_fields = self.fields.FormXFX
+        spr = Signal(x_fields.SPR[0:-1].shape())
+        comb += spr.eq(decode_spr_num(i_fields.SPR[0:-1]))
+
+        # TODO: some #defines for the bits n stuff.
+        with m.Switch(op.insn_type):
+            #### MTSPR ####
+            with m.Case(InternalOp.OP_MTSPR):
+                with m.Switch(spr):
+                    # fast SPRs first
+                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1):
+                        comb += fast1_o.data.eq(a_i)
+                        comb += fast1_o.ok.eq(1)
+                    # XER is constructed
+                    with m.Case(SPR.XER):
+                        # sticky
+                        comb += so_o.data.eq(a_i[63-XER_bits['SO']])
+                        comb += so_o.ok.eq(1)
+                        # overflow
+                        comb += ov_o.data[0].eq(a_i[63-XER_bits['OV']])
+                        comb += ov_o.data[1].eq(a_i[63-XER_bits['OV32']])
+                        comb += ov_o.ok.eq(1)
+                        # carry
+                        comb += ca_o.data[0].eq(a_i[63-XER_bits['CA']])
+                        comb += ca_o.data[1].eq(a_i[63-XER_bits['CA32']])
+                        comb += ca_o.ok.eq(1)
+                    # slow SPRs TODO
+
+            # move from SPRs
+            with m.Case(InternalOp.OP_MFSPR):
+                comb += o.ok.eq(1)
+                with m.Switch(spr):
+                    # fast SPRs first
+                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1):
+                        comb += o.data.eq(fast1_i)
+                    # XER is constructed
+                    with m.Case(SPR.XER):
+                        # sticky
+                        comb += o[63-XER_bits['SO']].eq(so_i)
+                        # overflow
+                        comb += o[63-XER_bits['OV']].eq(ov_i[0])
+                        comb += o[63-XER_bits['OV32']].eq(ov_i[1])
+                        # carry
+                        comb += o[63-XER_bits['CA']].eq(ca_i[0])
+                        comb += o[63-XER_bits['CA32']].eq(ca_i[1])
+                    # slow SPRs TODO
+
+        comb += self.o.ctx.eq(self.i.ctx)
+
+        return m
index 48439200b33e1170a8840c19e646e222010dd845..1054b147f53b676eb8b13af6c059f2d23e08db4d 100644 (file)
@@ -16,7 +16,7 @@ from soc.fu.spr.spr_input_record import CompSPROpSubset
 class SPRInputData(IntegerData):
     regspec = [('INT', 'ra', '0:63'),        # RA
                ('SPR', 'spr1', '0:63'),      # SPR (slow)
-               ('FAST', 'spr2', '0:63'),     # SPR (fast: MSR, LR, CTR etc)
+               ('FAST', 'fast1', '0:63'),    # SPR (fast: MSR, LR, CTR etc)
                ('XER', 'xer_so', '32'),      # XER bit 32: SO
                ('XER', 'xer_ov', '33,44'),   # XER bit 34/45: CA/CA32
                ('XER', 'xer_ca', '34,45')]   # bit0: ov, bit1: ov32
@@ -29,7 +29,7 @@ class SPRInputData(IntegerData):
 class SPROutputData(IntegerData):
     regspec = [('INT', 'o', '0:63'),        # RT
                ('SPR', 'spr1', '0:63'),     # SPR (slow)
-               ('FAST', 'spr2', '0:63'),    # SPR (fast: MSR, LR, CTR etc)
+               ('FAST', 'fast1', '0:63'),   # SPR (fast: MSR, LR, CTR etc)
                ('XER', 'xer_so', '32'),     # XER bit 32: SO
                ('XER', 'xer_ov', '33,44'),  # XER bit 34/45: CA/CA32
                ('XER', 'xer_ca', '34,45')]  # bit0: ov, bit1: ov32