From 55e264c82e140f3baff106023d31d666d75ef363 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 20 Feb 2021 12:03:35 +0000 Subject: [PATCH] remove massive code-duplication, move simple "self.rom" to test_runner.py the fu rom mmu unit test does seem to still work --- src/soc/experiment/test/test_mmu_dcache.py | 5 + src/soc/simple/test/test_runner.py | 12 +- src/soc/simple/test/test_runner_mmu_rom.py | 407 +-------------------- 3 files changed, 22 insertions(+), 402 deletions(-) diff --git a/src/soc/experiment/test/test_mmu_dcache.py b/src/soc/experiment/test/test_mmu_dcache.py index dac90d16..d7b65cec 100644 --- a/src/soc/experiment/test/test_mmu_dcache.py +++ b/src/soc/experiment/test/test_mmu_dcache.py @@ -26,6 +26,11 @@ import random stop = False +def set_stop(newval): + global stop + stop = newval + + def b(x): return int.from_bytes(x.to_bytes(8, byteorder='little'), byteorder='big', signed=False) diff --git a/src/soc/simple/test/test_runner.py b/src/soc/simple/test/test_runner.py index dfc444a9..23d49e28 100644 --- a/src/soc/simple/test/test_runner.py +++ b/src/soc/simple/test/test_runner.py @@ -119,10 +119,11 @@ def get_dmi(dmi, addr): class TestRunner(FHDLTestCase): - def __init__(self, tst_data, microwatt_mmu=False): + def __init__(self, tst_data, microwatt_mmu=False, rom=None): super().__init__("run_all") self.test_data = tst_data self.microwatt_mmu = microwatt_mmu + self.rom = None def run_all(self): m = Module() @@ -392,6 +393,15 @@ class TestRunner(FHDLTestCase): "issuer_simulator.vcd", traces, styles, module='top.issuer') + # add run of instructions sim.add_sync_process(process) + + # optionally, if a wishbone-based ROM is passed in, run that as an + # extra emulated process + if self.rom is not None: + dcache = core.fus.fus["mmu0"].alu.dcache + default_mem = self.rom + sim.add_sync_process(wrap(wb_get(dcache, default_mem, "DCACHE"))) + with sim.write_vcd("issuer_simulator.vcd"): sim.run() diff --git a/src/soc/simple/test/test_runner_mmu_rom.py b/src/soc/simple/test/test_runner_mmu_rom.py index fe055ef9..1a254007 100644 --- a/src/soc/simple/test/test_runner_mmu_rom.py +++ b/src/soc/simple/test/test_runner_mmu_rom.py @@ -31,405 +31,10 @@ from soc.fu.compunits.test.test_compunit import (setup_test_memory, check_sim_memory) from soc.debug.dmi import DBGCore, DBGCtrl, DBGStat from nmutil.util import wrap +from soc.experiment.test.test_mmu_dcache import (set_stop, wb_get) +from soc.simple.test.test_runner import set_dmi, get_dmi +from soc.simple.test.test_runner import setup_i_memory +from soc.simple.test.test_runner import TestRunner -stop = False - -def wb_get(c, mem, name): - """simulator process for getting memory load requests - """ - global stop - # mem = mem - - while not stop: - while True: # wait for dc_valid - if stop: - return - cyc = yield (c.wb_out.cyc) - stb = yield (c.wb_out.stb) - if cyc and stb: - break - yield - addr = (yield c.wb_out.adr) << 3 - if addr not in mem.rom: - mem.debug.write("%s LOOKUP FAIL %x\n" % (name, addr)) - stop = True - return - - yield - data = mem.rom[addr] - yield c.wb_in.dat.eq(data) - mem.debug.write("%s get %x data %x\n" % (name, addr, data)) - yield c.wb_in.ack.eq(1) - yield - yield c.wb_in.ack.eq(0) - - -def setup_i_memory(imem, startaddr, instructions): - mem = imem - print("insn before, init mem", mem.depth, mem.width, mem, - len(instructions)) - for i in range(mem.depth): - yield mem._array[i].eq(0) - yield Settle() - startaddr //= 4 # instructions are 32-bit - if mem.width == 32: - mask = ((1 << 32)-1) - for ins in instructions: - if isinstance(ins, tuple): - insn, code = ins - else: - insn, code = ins, '' - insn = insn & 0xffffffff - yield mem._array[startaddr].eq(insn) - yield Settle() - if insn != 0: - print("instr: %06x 0x%x %s" % (4*startaddr, insn, code)) - startaddr += 1 - startaddr = startaddr & mask - return - - # 64 bit - mask = ((1 << 64)-1) - for ins in instructions: - if isinstance(ins, tuple): - insn, code = ins - else: - insn, code = ins, '' - insn = insn & 0xffffffff - msbs = (startaddr >> 1) & mask - val = yield mem._array[msbs] - if insn != 0: - print("before set", hex(4*startaddr), - hex(msbs), hex(val), hex(insn)) - lsb = 1 if (startaddr & 1) else 0 - val = (val | (insn << (lsb*32))) - val = val & mask - yield mem._array[msbs].eq(val) - yield Settle() - if insn != 0: - print("after set", hex(4*startaddr), hex(msbs), hex(val)) - print("instr: %06x 0x%x %s %08x" % (4*startaddr, insn, code, val)) - startaddr += 1 - startaddr = startaddr & mask - - -def set_dmi(dmi, addr, data): - yield dmi.req_i.eq(1) - yield dmi.addr_i.eq(addr) - yield dmi.din.eq(data) - yield dmi.we_i.eq(1) - while True: - ack = yield dmi.ack_o - if ack: - break - yield - yield - yield dmi.req_i.eq(0) - yield dmi.addr_i.eq(0) - yield dmi.din.eq(0) - yield dmi.we_i.eq(0) - yield - - -def get_dmi(dmi, addr): - yield dmi.req_i.eq(1) - yield dmi.addr_i.eq(addr) - yield dmi.din.eq(0) - yield dmi.we_i.eq(0) - while True: - ack = yield dmi.ack_o - if ack: - break - yield - yield # wait one - data = yield dmi.dout # get data after ack valid for 1 cycle - yield dmi.req_i.eq(0) - yield dmi.addr_i.eq(0) - yield dmi.we_i.eq(0) - yield - return data - - -class TestRunner(FHDLTestCase): - def __init__(self, tst_data, rom): - super().__init__("run_all") - self.test_data = tst_data - self.rom = rom - - def run_all(self): - m = Module() - comb = m.d.comb - pc_i = Signal(32) - - pspec = TestMemPspec(ldst_ifacetype='test_bare_wb', - imem_ifacetype='test_bare_wb', - addr_wid=48, - mask_wid=8, - imem_reg_wid=64, - # wb_data_width=32, - use_pll=False, - nocore=False, - xics=False, - gpio=False, - mmu=True, - reg_wid=64) - m.submodules.issuer = issuer = TestIssuerInternal(pspec) - imem = issuer.imem._get_memory() - core = issuer.core - dmi = issuer.dbg.dmi - pdecode2 = issuer.pdecode2 - l0 = core.l0 - - # copy of the decoder for simulator - simdec = create_pdecode() - simdec2 = PowerDecode2(simdec) - m.submodules.simdec2 = simdec2 # pain in the neck - - # run core clock at same rate as test clock - intclk = ClockSignal("coresync") - comb += intclk.eq(ClockSignal()) - - comb += issuer.pc_i.data.eq(pc_i) - - # nmigen Simulation - sim = Simulator(m) - sim.add_clock(1e-6) - - def process(): - global stop - - # start in stopped - yield from set_dmi(dmi, DBGCore.CTRL, 1<= len(instructions): - print ("index over, send dmi stop") - # stop at end - yield from set_dmi(dmi, DBGCore.CTRL, 1<