add MSR reading to issue FSM
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 14 Jul 2020 11:43:53 +0000 (12:43 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 14 Jul 2020 11:43:53 +0000 (12:43 +0100)
src/soc/regfile/regfiles.py
src/soc/simple/issuer.py

index 74c283f3e036c8c79545795a49bc15b37088af3f..be47754e30969aecef3f67982e53d112ab3b1de7 100644 (file)
@@ -56,8 +56,9 @@ class FastRegs(RegFileArray):
     * Array-based unary-indexed (not binary-indexed)
     * write-through capability (read on same cycle as write)
 
-    Note: d_wr1 and d_rd1 are for use by the decoder, to get at the PC.
+    Note: d_wr1 d_rd1 are for use by the decoder, to get at the PC.
     will probably have to also add one so it can get at the MSR as well.
+    (d_rd2)
     """
     PC = 0
     MSR = 1
@@ -72,12 +73,13 @@ class FastRegs(RegFileArray):
                         'msr': self.write_port("dest2"),
                         'fast1': self.write_port("dest3"),
                         'fast2': self.write_port("dest4"),
-                        'd_wr1': self.write_port("d_wr1")}
+                        'd_wr1': self.write_port("d_wr1")} # writing PC
         self.r_ports = {'cia': self.read_port("src1"),
                         'msr': self.read_port("src2"),
                         'fast1': self.read_port("src3"),
                         'fast2': self.read_port("src4"),
-                        'd_rd1': self.read_port("d_rd1")}
+                        'd_rd1': self.read_port("d_rd1"), # reading PC
+                        'd_rd2': self.read_port("d_rd2")} # reading MSR
 
 
 # CR Regfile
index 0f90943d85b0cdcbaed6137573f1afe27a797c85..3f7ed3a7288ce2d438ccee4ee9771139de9b96f8 100644 (file)
@@ -49,9 +49,11 @@ class TestIssuer(Elaboratable):
         self.busy_o = core.busy_o
         self.memerr_o = Signal(reset_less=True)
 
-        # FAST regfile read /write ports
-        self.fast_rd1 = self.core.regs.rf['fast'].r_ports['d_rd1']
-        self.fast_wr1 = self.core.regs.rf['fast'].w_ports['d_wr1']
+        # FAST regfile read /write ports for PC and MSR
+        self.fast_r_pc = self.core.regs.rf['fast'].r_ports['d_rd1'] # PC rd
+        self.fast_w_pc = self.core.regs.rf['fast'].w_ports['d_wr1'] # PC wr
+        self.fast_r_msr = self.core.regs.rf['fast'].r_ports['d_rd2'] # MSR rd
+
         # hack method of keeping an eye on whether branch/trap set the PC
         self.fast_nia = self.core.regs.rf['fast'].w_ports['nia']
         self.fast_nia.wen.name = 'fast_nia_wen'
@@ -76,6 +78,10 @@ class TestIssuer(Elaboratable):
         comb += self.pc_o.eq(cur_pc)
         ilatch = Signal(32)
 
+        # MSR (temp and latched)
+        cur_msr = Signal(64) # current MSR (note it is reset/sync)
+        msr = Signal(64, reset_less=True)
+
         # next instruction (+4 on current)
         nia = Signal(64, reset_less=True)
         comb += nia.eq(cur_pc + 4)
@@ -88,6 +94,7 @@ class TestIssuer(Elaboratable):
         core_opcode_i = core.raw_opcode_i # raw opcode
 
         insn_type = core.pdecode2.e.do.insn_type
+        insn_msr = core.pdecode2.msr
 
         # only run if not in halted state
         with m.If(~core.core_terminated_o):
@@ -110,8 +117,8 @@ class TestIssuer(Elaboratable):
                             comb += pc.eq(self.pc_i.data)
                         with m.Else():
                             # otherwise read FastRegs regfile for PC
-                            comb += self.fast_rd1.ren.eq(1<<FastRegs.PC)
-                            comb += pc.eq(self.fast_rd1.data_o)
+                            comb += self.fast_r_pc.ren.eq(1<<FastRegs.PC)
+                            comb += pc.eq(self.fast_r_pc.data_o)
                         # capture the PC and also drop it into Insn Memory
                         # we have joined a pair of combinatorial memory
                         # lookups together.  this is Generally Bad.
@@ -135,6 +142,13 @@ class TestIssuer(Elaboratable):
                         comb += core_issue_i.eq(1)  # and issued 
                         comb += core_opcode_i.eq(current_insn) # actual opcode
                         sync += ilatch.eq(current_insn) # latch current insn
+
+                        # read MSR
+                        comb += self.fast_r_msr.ren.eq(1<<FastRegs.MSR)
+                        comb += msr.eq(self.fast_r_msr.data_o)
+                        comb += insn_msr.eq(msr)
+                        sync += cur_msr.eq(msr) # latch current MSR
+
                         m.next = "INSN_ACTIVE" # move to "wait completion" 
 
                 # instruction started: must wait till it finishes
@@ -145,6 +159,7 @@ class TestIssuer(Elaboratable):
                         with m.If(insn_type != MicrOp.OP_NOP):
                             comb += core_ivalid_i.eq(1) # instruction is valid
                         comb += core_opcode_i.eq(ilatch) # actual opcode
+                        comb += insn_msr.eq(cur_msr)     # and MSR
                         with m.If(self.fast_nia.wen):
                             sync += pc_changed.eq(1)
                         with m.If(~core_busy_o): # instruction done!
@@ -152,8 +167,8 @@ class TestIssuer(Elaboratable):
                             # this just blithely overwrites whatever pipeline
                             # updated the PC
                             with m.If(~pc_changed):
-                                comb += self.fast_wr1.wen.eq(1<<FastRegs.PC)
-                                comb += self.fast_wr1.data_i.eq(nia)
+                                comb += self.fast_w_pc.wen.eq(1<<FastRegs.PC)
+                                comb += self.fast_w_pc.data_i.eq(nia)
                             m.next = "IDLE" # back to idle
 
         return m