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)
 
     * 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.
     will probably have to also add one so it can get at the MSR as well.
+    (d_rd2)
     """
     PC = 0
     MSR = 1
     """
     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"),
                         '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"),
         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
 
 
 # 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)
 
         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'
         # 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)
 
         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)
         # 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
         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):
 
         # 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 += 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.
                         # 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
                         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
                         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
                         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!
                         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):
                             # 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
                             m.next = "IDLE" # back to idle
 
         return m