add XER to fastregs and "construct" it in mfspr/mtspr
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 31 Aug 2020 11:06:24 +0000 (12:06 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 31 Aug 2020 11:06:24 +0000 (12:06 +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

index 1bdcd3ffc83a791e6b13905551e86f5209f19635..4405cf2c2631a33a934f70d57964859b71941f93 100644 (file)
@@ -147,6 +147,8 @@ class DecodeA(Elaboratable):
                         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.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)
                         pass  # do nothing
                     # : map to internal SPR numbers
                     # XXX TODO: dec and tb not to go through mapping.
                         pass  # do nothing
                     # : map to internal SPR numbers
                     # XXX TODO: dec and tb not to go through mapping.
@@ -328,6 +330,8 @@ class DecodeOut(Elaboratable):
                             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.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)
                             pass  # do nothing
                         # : map to internal SPR numbers
                         # XXX TODO: dec and tb not to go through mapping.
                             pass  # do nothing
                         # : map to internal SPR numbers
                         # XXX TODO: dec and tb not to go through mapping.
index f4261b62a2b2d104c9edfa88262f27a97d9498a3..de1ab2f229bf0abba6435e4968b6a19ab26f6fee 100644 (file)
@@ -48,22 +48,23 @@ class SPRMainStage(PipeModBase):
             with m.Case(MicrOp.OP_MTSPR):
                 with m.Switch(spr):
                     # fast SPRs first
             with m.Case(MicrOp.OP_MTSPR):
                 with m.Switch(spr):
                     # fast SPRs first
-                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1):
+                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0,
+                                SPR.SRR1, SPR.XER):
                         comb += fast1_o.data.eq(a_i)
                         comb += fast1_o.ok.eq(1)
                         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)
+                        # XER is constructed
+                        with m.If(spr == 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
                     # slow SPRs TODO
 
             # move from SPRs
@@ -71,18 +72,22 @@ class SPRMainStage(PipeModBase):
                 comb += o.ok.eq(1)
                 with m.Switch(spr):
                     # fast SPRs first
                 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):
+                    with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1,
+                                SPR.XER):
                         comb += o.data.eq(fast1_i)
                         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])
+                        with m.If(spr == SPR.XER):
+                            # bits 0:31 and 35:43 are treated as reserved
+                            # and return 0s when read using mfxer
+                            comb += o[32:64].eq(0)       # MBS0 bits 0-31
+                            comb += o[63-43:64-35].eq(0) # MSB0 bits 35-43
+                            # 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)
                     # slow SPRs TODO
 
         comb += self.o.ctx.eq(self.i.ctx)
index d3c7901738f74b5af3f2276cd3bb33f5bee3cb8b..4fee28f4e5aa1acbfe48ee753aebd39249c40426 100755 (executable)
@@ -308,7 +308,7 @@ class LibreSoCSim(SoCSDRAM):
         )
 
         if cpu == "libresoc":
         )
 
         if cpu == "libresoc":
-            self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x10e00))
+            self.comb += active_dbg_cr.eq((0x10300 <= pc) & (pc <= 0x11700))
             #self.comb += active_dbg_cr.eq(1)
 
             # get the CR
             #self.comb += active_dbg_cr.eq(1)
 
             # get the CR
index 505fb587d135ae98ad685916b1a8ab9e5e88f01d..0dce110eefe10b71be2fd84168acab70263b8955 100644 (file)
@@ -79,9 +79,9 @@ class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
 class FastRegs(RegFileMem): #RegFileArray):
     """FastRegs
 
 class FastRegs(RegFileMem): #RegFileArray):
     """FastRegs
 
-    FAST regfile  - CTR, LR, TAR, SRR1, SRR2
+    FAST regfile  - CTR, LR, TAR, SRR1, SRR2, XER
 
 
-    * QTY 5of 64-bit registers
+    * QTY 6of 64-bit registers
     * 2R1W
     * Array-based unary-indexed (not binary-indexed)
     * write-through capability (read on same cycle as write)
     * 2R1W
     * Array-based unary-indexed (not binary-indexed)
     * write-through capability (read on same cycle as write)
@@ -91,8 +91,9 @@ class FastRegs(RegFileMem): #RegFileArray):
     TAR = 2
     SRR0 = 3
     SRR1 = 4
     TAR = 2
     SRR0 = 3
     SRR1 = 4
+    XER = 5 # non-XER bits
     def __init__(self):
     def __init__(self):
-        super().__init__(64, 5)
+        super().__init__(64, 6)
         self.w_ports = {'fast1': self.write_port("dest1"),
                        }
         self.r_ports = {'fast1': self.read_port("src1"),
         self.w_ports = {'fast1': self.write_port("dest1"),
                        }
         self.r_ports = {'fast1': self.read_port("src1"),