sort out instruction stop/cancel when adding a new issuer FSM state
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 Aug 2020 13:57:54 +0000 (14:57 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 Aug 2020 13:57:54 +0000 (14:57 +0100)
src/soc/fu/compunits/test/test_compunit.py
src/soc/simple/issuer.py
src/soc/simple/test/test_issuer.py

index 3af4bb501ea8dc31a585b28e4b7299b7b998cb96..b1d4b0fdf4b9f94d947c32433182ca2d8ec30b2c 100644 (file)
@@ -3,8 +3,8 @@ from nmigen.back.pysim import Simulator, Delay, Settle
 from nmutil.formaltest import FHDLTestCase
 from nmigen.cli import rtlil
 import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_decoder2 import (PowerDecode2)
+from soc.decoder.power_decoder import create_pdecode
+from soc.decoder.power_decoder2 import PowerDecode2
 from soc.decoder.power_enums import Function
 from soc.decoder.isa.all import ISA
 
index bf28f86f60e099421ba1fe412b9abe99558f9f3f..ae6ec356b8f43c94156970a4665d6b4795eed8f6 100644 (file)
@@ -114,7 +114,6 @@ class TestIssuer(Elaboratable):
         m.d.comb += ldst.st.go_i.eq(st_go_edge) # link store-go to rising rel
 
         # PC and instruction from I-Memory
-        current_insn = Signal(32) # current fetched instruction (note sync)
         pc_changed = Signal() # note write to PC
         comb += self.pc_o.eq(cur_state.pc)
         ilatch = Signal(32)
@@ -184,9 +183,11 @@ class TestIssuer(Elaboratable):
 
                     m.next = "INSN_READ" # move to "wait for bus" phase
 
-            # waiting for instruction bus (stays there until not busy)
+            # dummy pause to find out why simulation is not keeping up
             with m.State("INSN_READ"):
-                with m.If(self.imem.f_busy_o): # zzz...
+                with m.If(dbg.core_stop_o):
+                    m.next = "IDLE" # back to idle
+                with m.Elif(self.imem.f_busy_o): # zzz...
                     # busy: stay in wait-read
                     comb += self.imem.a_valid_i.eq(1)
                     comb += self.imem.f_valid_i.eq(1)
@@ -197,16 +198,20 @@ class TestIssuer(Elaboratable):
                         insn = f_instr_o
                     else:
                         insn = f_instr_o.word_select(cur_state.pc[2], 32)
-                    comb += current_insn.eq(insn)
-                    comb += core_ivalid_i.eq(1) # instruction is valid
-                    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_opcode_i.eq(insn) # actual opcode
+                    sync += ilatch.eq(insn) # latch current insn
+                    m.next = "INSN_START" # move to "start"
+
+            # waiting for instruction bus (stays there until not busy)
+            with m.State("INSN_START"):
+                comb += core_ivalid_i.eq(1) # instruction is valid
+                comb += core_issue_i.eq(1)  # and issued
+                comb += core_opcode_i.eq(ilatch) # actual opcode
 
-                    # also drop PC and MSR into decode "state"
-                    comb += insn_state.eq(cur_state)
+                # also drop PC and MSR into decode "state"
+                comb += insn_state.eq(cur_state)
 
-                    m.next = "INSN_ACTIVE" # move to "wait completion"
+                m.next = "INSN_ACTIVE" # move to "wait completion"
 
             # instruction started: must wait till it finishes
             with m.State("INSN_ACTIVE"):
index 270416a586fd8628eaca2d44ecd6a408b71c84f5..f25b61ce75788681cc19d6071070f99ebc22bf5a 100644 (file)
@@ -14,6 +14,9 @@ from soc.decoder.isa.all import ISA
 from soc.decoder.power_enums import Function, XER_bits
 from soc.config.endian import bigendian
 
+from soc.decoder.power_decoder import create_pdecode
+from soc.decoder.power_decoder2 import PowerDecode2
+
 from soc.simple.issuer import TestIssuer
 from soc.experiment.compalu_multi import find_ok  # hack
 
@@ -144,6 +147,11 @@ class TestRunner(FHDLTestCase):
         pdecode2 = core.pdecode2
         l0 = core.l0
 
+        # copy of the decoder for simulator
+        simdec = create_pdecode()
+        simdec2 = PowerDecode2(simdec)
+        m.submodules.simdec2 = simdec2  # pain in the neck
+
         comb += issuer.pc_i.data.eq(pc_i)
 
         # nmigen Simulation
@@ -183,7 +191,7 @@ class TestRunner(FHDLTestCase):
                 gen = list(program.generate_instructions())
                 insncode = program.assembly.splitlines()
                 instructions = list(zip(gen, insncode))
-                sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
+                sim = ISA(simdec2, test.regs, test.sprs, test.cr, test.mem,
                           test.msr,
                           initial_insns=gen, respect_pc=True,
                           disassembly=insncode,
@@ -198,6 +206,7 @@ class TestRunner(FHDLTestCase):
 
                 yield pc_i.eq(pc)
                 yield issuer.pc_i.ok.eq(1)
+                yield
 
                 print("instructions", instructions)
 
@@ -222,16 +231,22 @@ class TestRunner(FHDLTestCase):
                     yield from wait_for_busy_hi(core)
                     yield from wait_for_busy_clear(core)
 
-                    terminated = yield issuer.dbg.terminated_o
-                    print("terminated", terminated)
+                    # set up simulated instruction (in simdec2)
+                    try:
+                        yield from sim.setup_one()
+                    except KeyError:  # indicates instruction not in imem: stop
+                        break
+                    yield Settle()
 
-                    print("sim", code)
                     # call simulated operation
-                    opname = code.split(' ')[0]
-                    yield from sim.call(opname)
+                    print("sim", code)
+                    yield from sim.execute_one()
                     yield Settle()
                     index = sim.pc.CIA.value//4
 
+                    terminated = yield issuer.dbg.terminated_o
+                    print("terminated", terminated)
+
                     # register check
                     yield from check_regs(self, sim, core, test, code)