minor code-munge on SPR-to-FAST mapping
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 6 Sep 2020 16:35:02 +0000 (17:35 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 6 Sep 2020 16:35:02 +0000 (17:35 +0100)
src/soc/decoder/power_decoder2.py
src/soc/fu/spr/main_stage.py
src/soc/litex/florent/sim.py
src/soc/regfile/regfiles.py
src/soc/regfile/util.py

index e07a78e786b169880df751259060dcfb64ae7ce5..367f49ba2801162034ca12621dd9401f2bc0fb34 100644 (file)
@@ -27,6 +27,7 @@ from soc.consts import MSR
 from soc.regfile.regfiles import FastRegs
 from soc.consts import TT
 from soc.config.state import CoreState
+from soc.regfile.util import spr_to_fast
 
 
 def decode_spr_num(spr):
@@ -51,19 +52,25 @@ def instr_is_priv(m, op, insn):
 
 
 class SPRMap(Elaboratable):
-    """SPRMap: maps POWER9 SPR numbers to internal enum values
+    """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
     """
 
     def __init__(self):
         self.spr_i = Signal(10, reset_less=True)
-        self.spr_o = Signal(SPR, reset_less=True)
+        self.spr_o = Data(SPR, name="spr_o")
+        self.fast_o = Data(3, name="fast_o")
 
     def elaborate(self, platform):
         m = Module()
         with m.Switch(self.spr_i):
             for i, x in enumerate(SPR):
                 with m.Case(x.value):
-                    m.d.comb += self.spr_o.eq(i)
+                    m.d.comb += self.spr_o.data.eq(i)
+                    m.d.comb += self.spr_o.ok.eq(1)
+            for x, v in spr_to_fast.items():
+                with m.Case(x.value):
+                    m.d.comb += self.fast_o.data.eq(v)
+                    m.d.comb += self.fast_o.ok.eq(1)
         return m
 
 
@@ -129,38 +136,9 @@ class DecodeA(Elaboratable):
             with m.Case(MicrOp.OP_MFSPR):
                 spr = Signal(10, reset_less=True)
                 comb += spr.eq(decode_spr_num(self.dec.SPR))  # from XFX
-                with m.Switch(spr):
-                    # fast SPRs
-                    with m.Case(SPR.CTR.value):
-                        comb += self.fast_out.data.eq(FastRegs.CTR)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.LR.value):
-                        comb += self.fast_out.data.eq(FastRegs.LR)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.TAR.value):
-                        comb += self.fast_out.data.eq(FastRegs.TAR)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.SRR0.value):
-                        comb += self.fast_out.data.eq(FastRegs.SRR0)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.SRR1.value):
-                        comb += self.fast_out.data.eq(FastRegs.SRR1)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.XER.value):
-                        comb += self.fast_out.data.eq(FastRegs.XER)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.DEC.value):
-                        comb += self.fast_out.data.eq(FastRegs.DEC)
-                        comb += self.fast_out.ok.eq(1)
-                    with m.Case(SPR.TB.value):
-                        comb += self.fast_out.data.eq(FastRegs.TB)
-                        comb += self.fast_out.ok.eq(1)
-                    # : map to internal SPR numbers
-                    # XXX TODO: dec and tb not to go through mapping.
-                    with m.Default():
-                        comb += sprmap.spr_i.eq(spr)
-                        comb += self.spr_out.data.eq(sprmap.spr_o)
-                        comb += self.spr_out.ok.eq(1)
+                comb += sprmap.spr_i.eq(spr)
+                comb += self.spr_out.eq(sprmap.spr_o)
+                comb += self.fast_out.eq(sprmap.fast_o)
 
         return m
 
@@ -315,40 +293,11 @@ class DecodeOut(Elaboratable):
             with m.Case(OutSel.SPR):
                 spr = Signal(10, reset_less=True)
                 comb += spr.eq(decode_spr_num(self.dec.SPR))  # from XFX
-                # TODO MTSPR 1st spr (fast)
+                # MFSPR move to SPRs - needs mapping
                 with m.If(op.internal_op == MicrOp.OP_MTSPR):
-                    with m.Switch(spr):
-                        # fast SPRs
-                        with m.Case(SPR.CTR.value):
-                            comb += self.fast_out.data.eq(FastRegs.CTR)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.LR.value):
-                            comb += self.fast_out.data.eq(FastRegs.LR)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.TAR.value):
-                            comb += self.fast_out.data.eq(FastRegs.TAR)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.SRR0.value):
-                            comb += self.fast_out.data.eq(FastRegs.SRR0)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.SRR1.value):
-                            comb += self.fast_out.data.eq(FastRegs.SRR1)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.XER.value):
-                            comb += self.fast_out.data.eq(FastRegs.XER)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.TB.value):
-                            comb += self.fast_out.data.eq(FastRegs.TB)
-                            comb += self.fast_out.ok.eq(1)
-                        with m.Case(SPR.DEC.value):
-                            comb += self.fast_out.data.eq(FastRegs.DEC)
-                            comb += self.fast_out.ok.eq(1)
-                        # : map to internal SPR numbers
-                        # XXX TODO: dec and tb not to go through mapping.
-                        with m.Default():
-                            comb += sprmap.spr_i.eq(spr)
-                            comb += self.spr_out.data.eq(sprmap.spr_o)
-                            comb += self.spr_out.ok.eq(1)
+                    comb += sprmap.spr_i.eq(spr)
+                    comb += self.spr_out.eq(sprmap.spr_o)
+                    comb += self.fast_out.eq(sprmap.fast_o)
 
         with m.Switch(op.internal_op):
 
index 523bff25ce116a8b9be994ef1e0d19182e4d0e8f..1a1d5d4ed92afb93c96e5ddcd9c4ff4dad84f51f 100644 (file)
@@ -67,6 +67,9 @@ class SPRMainStage(PipeModBase):
                             comb += ca_o.ok.eq(1)
 
                     # slow SPRs TODO
+                    with m.Default():
+                        comb += spr1_o.data.eq(a_i)
+                        comb += spr1_o.ok.eq(1)
 
             # move from SPRs
             with m.Case(MicrOp.OP_MFSPR):
@@ -93,6 +96,8 @@ class SPRMainStage(PipeModBase):
                         comb += o.data[0:32].eq(fast1_i[32:64])
 
                     # slow SPRs TODO
+                    with m.Default():
+                        comb += o.data.eq(spr1_i)
 
         comb += self.o.ctx.eq(self.i.ctx)
 
index dcae6fbf35db80c5ebfeecd5e252e368927c2def..d102b56de3ed089e3d3a5aafae74e4d811bc8281 100755 (executable)
@@ -59,8 +59,10 @@ class LibreSoCSim(SoCSDRAM):
         #ram_fname = None
         #ram_fname = "/home/lkcl/src/libresoc/microwatt/" \
         #            "micropython/firmware.bin"
+        #ram_fname = "/home/lkcl/src/libresoc/microwatt/" \
+        #            "tests/xics/xics.bin"
         ram_fname = "/home/lkcl/src/libresoc/microwatt/" \
-                    "tests/xics/xics.bin"
+                    "tests/decrementer/decrementer.bin"
         #ram_fname = "/home/lkcl/src/libresoc/microwatt/" \
         #            "hello_world/hello_world.bin"
 
index 23515dd9a31dde5894a0c830e2f24b7a88dce4dd..e4ed80b18138c3d713538aaf9221ea40f2b2a24e 100644 (file)
@@ -97,8 +97,9 @@ class FastRegs(RegFileMem): #RegFileArray):
     XER = 5 # non-XER bits
     DEC = 6
     TB = 7
+    N_REGS = 8 # maximum number of regs
     def __init__(self):
-        super().__init__(64, 8)
+        super().__init__(64, self.N_REGS)
         self.w_ports = {'fast1': self.write_port("dest1"),
                         'issue': self.write_port("issue"), # writing DEC/TB
                        }
index 536c16fbfb53a6b2a4bb7269c5ae001dc2745dbf..cc0170456fe6ed9a910e5d5f03ec4e100767f128 100644 (file)
@@ -1,30 +1,27 @@
 from soc.regfile.regfiles import FastRegs
 from soc.decoder.power_enums import SPR, spr_dict
 
+spr_to_fast = { SPR.CTR: FastRegs.CTR,
+                SPR.LR: FastRegs.LR,
+                SPR.TAR: FastRegs.TAR,
+                SPR.SRR0: FastRegs.SRR0,
+                SPR.SRR1: FastRegs.SRR1,
+                SPR.XER: FastRegs.XER,
+                SPR.DEC: FastRegs.DEC,
+                SPR.TB: FastRegs.TB,
+               }
+
+sprstr_to_fast = {}
+fast_to_spr = {}
+for (k, v) in spr_to_fast.items():
+    sprstr_to_fast[k.name] = v
+    fast_to_spr[v] = k
+
 def fast_reg_to_spr(spr_num):
-    if spr_num == FastRegs.CTR:
-        return SPR.CTR.value
-    elif spr_num == FastRegs.LR:
-        return SPR.LR.value
-    elif spr_num == FastRegs.TAR:
-        return SPR.TAR.value
-    elif spr_num == FastRegs.SRR0:
-        return SPR.SRR0.value
-    elif spr_num == FastRegs.SRR1:
-        return SPR.SRR1.value
+    return fast_to_spr[spr_num].value
 
 
 def spr_to_fast_reg(spr_num):
     if not isinstance(spr_num, str):
         spr_num = spr_dict[spr_num].SPR
-    if spr_num == 'CTR':
-        return FastRegs.CTR
-    elif spr_num == 'LR':
-        return FastRegs.LR
-    elif spr_num == 'TAR':
-        return FastRegs.TAR
-    elif spr_num == 'SRR0':
-        return FastRegs.SRR0
-    elif spr_num == 'SRR1':
-        return FastRegs.SRR1
-    return None
+    return sprstr_to_fast[spr_num]