add SVSTATE (SVSRR0) to TRAP pipeline
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 4 May 2021 17:40:35 +0000 (18:40 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 4 May 2021 18:33:40 +0000 (19:33 +0100)
involves adding svstate to TrapOutputData regspec, and a corresponding
write port to StateRegs, and adding svstate to CompTrapOpSubset

src/soc/fu/trap/main_stage.py
src/soc/fu/trap/pipe_data.py
src/soc/fu/trap/trap_input_record.py
src/soc/regfile/regfiles.py

index c720a184b464d8f79b13cf076366b32f3250df80..c597b75e7e01f57375ff20d2fd05cb1f6e8c686e 100644 (file)
@@ -64,6 +64,7 @@ class TrapMainStage(PipeModBase):
         comb  = m.d.comb
         op = self.i.ctx.op
         msr_i = op.msr
+        svstate_i = op.svstate
         nia_o = self.o.nia
         svsrr0_o, srr0_o, srr1_o = self.o.svsrr0, self.o.srr0, self.o.srr1
 
@@ -75,10 +76,14 @@ class TrapMainStage(PipeModBase):
         comb += srr0_o.data.eq(return_addr)
         comb += srr0_o.ok.eq(1)
 
-        # take a copy of the current MSR in SRR1
+        # take a copy of the current MSR into SRR1
         comb += msr_copy(srr1_o.data, msr_i) # old MSR
         comb += srr1_o.ok.eq(1)
 
+        # take a copy of the current SVSTATE into SVSRR0
+        comb += svsrr0_o.data.eq(svstate_i) # old SVSTATE
+        comb += svsrr0_o.ok.eq(1)
+
     def msr_exception(self, m, trap_addr, msr_hv=None):
         """msr_exception - sets bits in MSR specific to an exception.
         the full list of what needs to be done is given in V3.0B
@@ -124,10 +129,12 @@ class TrapMainStage(PipeModBase):
         op = self.i.ctx.op
 
         # convenience variables
-        a_i, b_i, cia_i, msr_i = self.i.a, self.i.b, op.cia, op.msr
-        srr0_i, srr1_i = self.i.srr0, self.i.srr1
-        o, msr_o, nia_o = self.o.o, self.o.msr, self.o.nia
-        srr0_o, srr1_o = self.o.srr0, self.o.srr1
+        a_i, b_i = self.i.a, self.i.b
+        cia_i, msr_i, svstate_i = op.cia, op.msr, op.svstate
+        srr0_i, srr1_i, svsrr0_i = self.i.srr0, self.i.srr1, self.i.svsrr0
+        o = self.o.o
+        msr_o, nia_o, svstate_o = self.o.msr, self.o.nia, self.o.svstate
+        srr0_o, srr1_o, svsrr0_o = self.o.srr0, self.o.srr1, self.o.svsrr0
         traptype, trapaddr = op.traptype, op.trapaddr
 
         # take copy of D-Form TO field
@@ -218,6 +225,10 @@ class TrapMainStage(PipeModBase):
                     # when SRR1 is written to, update MSR bits
                     self.msr_exception(m, trapaddr)
 
+                    # and store SVSTATE in SVSRR0
+                    comb += svsrr0_o.data.eq(svstate_i)
+                    comb += svsrr0_o.ok.eq(1)
+
             ###################
             # MTMSR/D.  v3.0B p TODO - move to MSR
 
@@ -277,6 +288,10 @@ class TrapMainStage(PipeModBase):
                 comb += nia_o.data.eq(br_ext(srr0_i[2:]))
                 comb += nia_o.ok.eq(1)
 
+                # svstate was in svsrr0
+                comb += svstate_o.data.eq(svstate_i)
+                comb += svstate_o.ok.eq(1)
+
                 # MSR was in srr1: copy it over, however *caveats below*
                 comb += msr_copy(msr_o.data, srr1_i, zero_me=False) # don't zero
 
index 3ab8451d8a09dbbca06c8c8e77e3c4d99270106f..44c63654f6b01fdb080189f30bfdbe2ba460808d 100644 (file)
@@ -8,8 +8,9 @@ class TrapInputData(FUBaseData):
                ('FAST', 'fast1', '0:63'), # SRR0
                ('FAST', 'fast2', '0:63'), # SRR1
                ('FAST', 'fast3', '0:63'), # SVSRR0
-                # note here that neither MSR nor CIA are read as regs: they are
-                # passed in as incoming "State", via the CompTrapOpSubset
+                # note here that MSR CIA and SVSTATE are *not* read as regs:
+                # they are passed in as incoming "State", via the
+                # CompTrapOpSubset
                ] 
     def __init__(self, pspec):
         super().__init__(pspec, False)
@@ -23,8 +24,10 @@ class TrapOutputData(FUBaseData):
                ('FAST', 'fast1', '0:63'), # SRR0 SPR
                ('FAST', 'fast2', '0:63'), # SRR1 SPR
                ('FAST', 'fast3', '0:63'), # SRR2 SPR
+               # ... however we *do* need to *write* MSR, NIA, SVSTATE (RFID)
                ('STATE', 'nia', '0:63'),  # NIA (Next PC)
-               ('STATE', 'msr', '0:63')]  # MSR
+               ('STATE', 'msr', '0:63'),  # MSR
+               ('STATE', 'svstate', '0:31')]  # SVSTATE
     def __init__(self, pspec):
         super().__init__(pspec, True)
         # convenience
index 7bdae248e94a833a1d77c673b03f9b7ffddd62c7..4d3d66e8d8980af2ea55b6a32ae7b80d90ba0aba 100644 (file)
@@ -14,8 +14,9 @@ class CompTrapOpSubset(CompOpSubsetBase):
         layout = [('insn_type', MicrOp),
                   ('fn_unit', Function),
                   ('insn', 32),
-                  ('msr', 64), # from core.state
-                  ('cia', 64), # likewise
+                  ('msr', 64),     # from core.state
+                  ('cia', 64),     # likewise
+                  ('svstate', 32), # likewise
                   ('is_32bit', 1),
                   ('traptype', TT.size), # see trap main_stage.py, PowerDecoder2
                   ('trapaddr', 13),
index 26abc7797cb044dae28a541e5cb7d67519481cf5..8f881423e4aedfc38b4f35d78c842aec908cf990 100644 (file)
@@ -52,6 +52,7 @@ class StateRegs(RegFileArray, StateRegsEnum):
         super().__init__(64, StateRegsEnum.N_REGS)
         self.w_ports = {'nia': self.write_port("nia"),
                         'msr': self.write_port("msr"),
+                        'svstate': self.write_port("svstate"),
                         'sv': self.write_port("sv"), # writing SVSTATE (issuer)
                         'd_wr1': self.write_port("d_wr1")} # writing PC (issuer)
         self.r_ports = {'cia': self.read_port("cia"), # reading PC (issuer)