From d3310bb8821607054fbca1bff9d996f3e56f3261 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 18 Dec 2021 12:05:15 +0000 Subject: [PATCH] add icache/dcache/mmu unit test for TestIssuer this is a work-in-progress --- src/soc/experiment/dcache.py | 10 ++- src/soc/simple/issuer.py | 7 +- src/soc/simple/test/test_issuer_mmu_ifetch.py | 86 +++++++++++++++++++ src/soc/simple/test/teststate.py | 5 +- 4 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/soc/simple/test/test_issuer_mmu_ifetch.py diff --git a/src/soc/experiment/dcache.py b/src/soc/experiment/dcache.py index 1a34aa2c..6dd9303a 100644 --- a/src/soc/experiment/dcache.py +++ b/src/soc/experiment/dcache.py @@ -1180,7 +1180,9 @@ class DCache(Elaboratable): # a Binary-to-Unary one-hots here. replace-way one-hot is gated # (enabled) by bus.ack, not-write-bram, and state RELOAD_WAIT_ACK m.submodules.rams_replace_way_e = rwe = Decoder(NUM_WAYS) - comb += rwe.n.eq(~((r1.state == State.RELOAD_WAIT_ACK) & bus.ack & + bus_ack = Signal() + comb += bus_ack.eq(bus.ack) # o dear - Simulation bug.... + comb += rwe.n.eq(~((r1.state == State.RELOAD_WAIT_ACK) & bus_ack & ~r1.write_bram)) comb += rwe.i.eq(replace_way) @@ -1623,6 +1625,8 @@ class DCache(Elaboratable): comb += st_stbs_done.eq(1) # Got ack ? See if complete. + sync += Display("got ack %d %d stbs %d adjust_acks %d", + bus_ack, bus.ack, st_stbs_done, adjust_acks) with m.If(bus.ack): with m.If(st_stbs_done & (adjust_acks == 1)): sync += r1.state.eq(State.IDLE) @@ -1745,7 +1749,9 @@ class DCache(Elaboratable): # deal with litex not doing wishbone pipeline mode # XXX in wrong way. FIFOs are needed in the SRAM test # so that stb/ack match up. same thing done in icache.py - comb += self.bus.stall.eq(self.bus.cyc & ~self.bus.ack) + bus_ack = Signal() + comb += bus_ack.eq(self.bus.ack) # o dear - Simulation bug.... + comb += self.bus.stall.eq(self.bus.cyc & ~bus_ack) # Wire up wishbone request latch out of stage 1 comb += self.bus.we.eq(r1.wb.we) diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 1dedcdba..3a5b394f 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -733,7 +733,12 @@ class FetchFSM(ControlBase): # not busy (or fetch failed!): instruction fetched # when fetch failed, the instruction gets ignored # by the decoder - insn = get_insn(self.imem.f_instr_o, cur_state.pc) + if hasattr(core, "icache"): + # blech, icache returns actual instruction + insn = self.imem.f_instr_o + else: + # but these return raw memory + insn = get_insn(self.imem.f_instr_o, cur_state.pc) if self.svp64_en: svp64 = self.svp64 # decode the SVP64 prefix, if any diff --git a/src/soc/simple/test/test_issuer_mmu_ifetch.py b/src/soc/simple/test/test_issuer_mmu_ifetch.py new file mode 100644 index 00000000..5775872e --- /dev/null +++ b/src/soc/simple/test/test_issuer_mmu_ifetch.py @@ -0,0 +1,86 @@ +"""simple core test, runs instructions from a TestMemory + +related bugs: + + * https://bugs.libre-soc.org/show_bug.cgi?id=363 +""" + +# NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell +# Also, check out the cxxsim nmigen branch, and latest yosys from git + +import unittest +import sys + +# here is the logic which takes test cases and "executes" them. +# in this instance (TestRunner) its job is to instantiate both +# a Libre-SOC nmigen-based HDL instance and an ISACaller python +# simulator. it's also responsible for performing the single +# step and comparison. +from soc.simple.test.test_runner import TestRunner + +#@platen:bookmarks +#src/openpower/test/runner.py:class TestRunnerBase(FHDLTestCase): + +# test with MMU +from openpower.test.mmu.mmu_cases import MMUTestCase +from openpower.test.mmu.mmu_rom_cases import MMUTestCaseROM, default_mem +from openpower.test.ldst.ldst_cases import LDSTTestCase +from openpower.test.ldst.ldst_exc_cases import LDSTExceptionTestCase +#from openpower.simulator.test_sim import (GeneralTestCases, AttnTestCase) + +from openpower.simulator.program import Program +from openpower.endian import bigendian +from openpower.test.common import TestAccumulatorBase + +from openpower.consts import MSR + +from soc.experiment.test import pagetables + + +class MMUTestCase(TestAccumulatorBase): + + # MMUTEST: initial_msr= 16384 + # msr 16384 + # ISACaller initial_msr 16384 + # FIXME msr does not get passed to LoadStore1 + def case_5_ldst_exception(self): + lst = [#"mtspr 720,1", # mtspr PRTBL,r1 + "stb 10,0(2)", + "addi 10,0, 2", + "lbz 6,0(2)", + ] + initial_regs = [0] * 32 + initial_regs[1] = 0x1000000 + initial_regs[2] = 0x3456 + initial_regs[3] = 0x4321 + initial_regs[4] = 0x6543 + initial_regs[10] = 0xfe + initial_mem = {} + initial_msr = 0 << MSR.PR # must set "problem" state + initial_msr |= 1 << MSR.DR # set "virtual" state + initial_sprs = {720: 0x1000000} # PRTBL + print("MMUTEST: initial_msr=",initial_msr) + self.add_case(Program(lst, bigendian), initial_regs, + initial_mem=initial_mem, + initial_sprs=initial_sprs, + initial_msr=initial_msr) + +if __name__ == "__main__": + svp64 = True + if len(sys.argv) == 2: + if sys.argv[1] == 'nosvp64': + svp64 = False + sys.argv.pop() + + print ("SVP64 test mode enabled", svp64) + + unittest.main(exit=False) + suite = unittest.TestSuite() + + # MMU/DCache integration tests + suite.addTest(TestRunner(MMUTestCase().test_data, svp64=svp64, + microwatt_mmu=True, + rom=pagetables.test1)) + + runner = unittest.TextTestRunner() + runner.run(suite) diff --git a/src/soc/simple/test/teststate.py b/src/soc/simple/test/teststate.py index 7da358ea..95650bab 100644 --- a/src/soc/simple/test/teststate.py +++ b/src/soc/simple/test/teststate.py @@ -54,9 +54,12 @@ class HDLState(State): log("class hdl pc", hex(self.pc)) def get_mem(self): + self.mem = {} # get the underlying HDL-simulated memory from the L0CacheBuffer + if hasattr(self.core, "icache"): + # err temporarily ignore memory + return # XXX have to work out how to deal with wb_get hdlmem = get_l0_mem(self.core.l0) - self.mem = {} for i in range(hdlmem.depth): value = yield hdlmem._array[i] # should not really do this self.mem[i*8] = value -- 2.30.2