add icache/dcache/mmu unit test for TestIssuer
[soc.git] / src / soc / simple / inorder.py
index b930ecb923f0286d28baddad1f251f7043c62dfa..510bd2dad70da2131f8a4456d3633d8d749a2a17 100644 (file)
@@ -15,7 +15,7 @@ way, and to at provide something that can be further incrementally
 improved.
 """
 
-from nmigen import (Elaboratable, Module, Signal, 
+from nmigen import (Elaboratable, Module, Signal,
                     Mux, Const, Repl, Cat)
 from nmigen.cli import rtlil
 from nmigen.cli import main
@@ -24,6 +24,7 @@ import sys
 from nmutil.singlepipe import ControlBase
 from soc.simple.core_data import FetchOutput, FetchInput
 
+from openpower.consts import MSR
 from openpower.decoder.power_enums import MicrOp
 from openpower.state import CoreState
 from soc.regfile.regfiles import StateRegs
@@ -49,11 +50,10 @@ def get_insn(f_instr_o, pc):
 # not only that: TestIssuerInternal.imem can entirely move into here
 # because imem is only ever accessed inside the FetchFSM.
 class FetchFSM(ControlBase):
-    def __init__(self, allow_overlap, svp64_en, imem, core_rst,
+    def __init__(self, allow_overlap, imem, core_rst,
                  pdecode2, cur_state,
-                 dbg, core, svstate, nia, is_svp64_mode):
+                 dbg, core, svstate, nia):
         self.allow_overlap = allow_overlap
-        self.svp64_en = svp64_en
         self.imem = imem
         self.core_rst = core_rst
         self.pdecode2 = pdecode2
@@ -62,7 +62,6 @@ class FetchFSM(ControlBase):
         self.core = core
         self.svstate = svstate
         self.nia = nia
-        self.is_svp64_mode = is_svp64_mode
 
         # set up pipeline ControlBase and allocate i/o specs
         # (unusual: normally done by the Pipeline API)
@@ -95,7 +94,6 @@ class FetchFSM(ControlBase):
         msr = self.i.msr
         svstate = self.svstate
         nia = self.nia
-        is_svp64_mode = self.is_svp64_mode
         fetch_pc_o_ready = self.p.o_ready
         fetch_pc_i_valid = self.p.i_valid
         fetch_insn_o_valid = self.n.o_valid
@@ -115,6 +113,11 @@ class FetchFSM(ControlBase):
             fetch_failed = Const(0, 1)
             flush_needed = False
 
+        # set priv / virt mode on I-Cache, sigh
+        if isinstance(self.imem, ICache):
+            comb += self.imem.i_in.priv_mode.eq(~msr[MSR.PR])
+            comb += self.imem.i_in.virt_mode.eq(msr[MSR.DR])
+
         with m.FSM(name='fetch_fsm'):
 
             # waiting (zzz)
@@ -154,48 +157,11 @@ class FetchFSM(ControlBase):
                         # when fetch failed, the instruction gets ignored
                         # by the decoder
                         insn = get_insn(self.imem.f_instr_o, cur_state.pc)
-                        if self.svp64_en:
-                            svp64 = self.svp64
-                            # decode the SVP64 prefix, if any
-                            comb += svp64.raw_opcode_in.eq(insn)
-                            comb += svp64.bigendian.eq(self.core_bigendian_i)
-                            # pass the decoded prefix (if any) to PowerDecoder2
-                            sync += pdecode2.sv_rm.eq(svp64.svp64_rm)
-                            sync += pdecode2.is_svp64_mode.eq(is_svp64_mode)
-                            # remember whether this is a prefixed instruction,
-                            # so the FSM can readily loop when VL==0
-                            sync += is_svp64_mode.eq(svp64.is_svp64_mode)
-                            # calculate the address of the following instruction
-                            insn_size = Mux(svp64.is_svp64_mode, 8, 4)
-                            sync += nia.eq(cur_state.pc + insn_size)
-                            with m.If(~svp64.is_svp64_mode):
-                                # with no prefix, store the instruction
-                                # and hand it directly to the next FSM
-                                sync += dec_opcode_o.eq(insn)
-                                m.next = "INSN_READY"
-                            with m.Else():
-                                # fetch the rest of the instruction from memory
-                                comb += self.imem.a_pc_i.eq(cur_state.pc + 4)
-                                comb += self.imem.a_i_valid.eq(1)
-                                comb += self.imem.f_i_valid.eq(1)
-                                m.next = "INSN_READ2"
-                        else:
-                            # not SVP64 - 32-bit only
-                            sync += nia.eq(cur_state.pc + 4)
-                            sync += dec_opcode_o.eq(insn)
+                        # not SVP64 - 32-bit only
+                        sync += nia.eq(cur_state.pc + 4)
+                        sync += dec_opcode_o.eq(insn)
                             m.next = "INSN_READY"
 
-            with m.State("INSN_READ2"):
-                with m.If(self.imem.f_busy_o):  # zzz...
-                    # busy: stay in wait-read
-                    comb += self.imem.a_i_valid.eq(1)
-                    comb += self.imem.f_i_valid.eq(1)
-                with m.Else():
-                    # not busy: instruction fetched
-                    insn = get_insn(self.imem.f_instr_o, cur_state.pc+4)
-                    sync += dec_opcode_o.eq(insn)
-                    m.next = "INSN_READY"
-
             with m.State("INSN_READY"):
                 # hand over the instruction, to be decoded
                 comb += fetch_insn_o_valid.eq(1)
@@ -218,7 +184,7 @@ class TestIssuerInternalInOrder(TestIssuerBase):
     """
 
     def issue_fsm(self, m, core, nia,
-                  dbg, core_rst, is_svp64_mode,
+                  dbg, core_rst,
                   fetch_pc_o_ready, fetch_pc_i_valid,
                   fetch_insn_o_valid, fetch_insn_i_ready,
                   exec_insn_i_valid, exec_insn_o_ready,
@@ -275,15 +241,6 @@ class TestIssuerInternalInOrder(TestIssuerBase):
                 with m.Else():
                     # tell core it's stopped, and acknowledge debug handshake
                     comb += dbg.core_stopped_i.eq(1)
-                    # while stopped, allow updating the MSR, PC and SVSTATE
-                    with m.If(self.pc_i.ok):
-                        comb += self.state_w_pc.wen.eq(1 << StateRegs.PC)
-                        comb += self.state_w_pc.i_data.eq(self.pc_i.data)
-                        sync += self.pc_changed.eq(1)
-                    with m.If(self.msr_i.ok):
-                        comb += self.state_w_msr.wen.eq(1 << StateRegs.MSR)
-                        comb += self.state_w_msr.i_data.eq(self.msr_i.data)
-                        sync += self.msr_changed.eq(1)
 
             # wait for an instruction to arrive from Fetch
             with m.State("INSN_WAIT"):
@@ -510,7 +467,7 @@ class TestIssuerInternalInOrder(TestIssuerBase):
         # signalling is used to communicate between the four.
 
         # set up Fetch FSM
-        fetch = FetchFSM(self.allow_overlap, self.svp64_en,
+        fetch = FetchFSM(self.allow_overlap,
                          self.imem, core_rst, pdecode2, cur_state,
                          dbg, core,
                          dbg.state.svstate, # combinatorially same
@@ -526,7 +483,7 @@ class TestIssuerInternalInOrder(TestIssuerBase):
         comb += fetch.n.i_ready.eq(fetch_insn_i_ready)
 
         self.issue_fsm(m, core, nia,
-                       dbg, core_rst, 
+                       dbg, core_rst,
                        fetch_pc_o_ready, fetch_pc_i_valid,
                        fetch_insn_o_valid, fetch_insn_i_ready,
                        exec_insn_i_valid, exec_insn_o_ready,
@@ -539,6 +496,8 @@ class TestIssuerInternalInOrder(TestIssuerBase):
         return m
 
 
+# XXX TODO: update this
+
 if __name__ == '__main__':
     units = {'alu': 1, 'cr': 1, 'branch': 1, 'trap': 1, 'logical': 1,
              'spr': 1,