From 96845f04045c47f7e1768d7d033b60860f51bce6 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 28 Jul 2020 16:49:10 -0700 Subject: [PATCH] clean up div pipe tests to allow them to be run in parallel --- src/soc/fu/div/test/{runner.py => helper.py} | 56 ++++--------------- src/soc/fu/div/test/test_pipe_caller.py | 27 +++++---- ...ipe_caller.py => test_pipe_caller_long.py} | 30 +++++----- 3 files changed, 44 insertions(+), 69 deletions(-) rename src/soc/fu/div/test/{runner.py => helper.py} (81%) rename src/soc/fu/div/test/{test_all_pipe_caller.py => test_pipe_caller_long.py} (70%) diff --git a/src/soc/fu/div/test/runner.py b/src/soc/fu/div/test/helper.py similarity index 81% rename from src/soc/fu/div/test/runner.py rename to src/soc/fu/div/test/helper.py index ff2a1385..38a41c91 100644 --- a/src/soc/fu/div/test/runner.py +++ b/src/soc/fu/div/test/helper.py @@ -1,20 +1,17 @@ import random import unittest +import power_instruction_analyzer as pia from nmigen import Module, Signal from nmigen.back.pysim import Simulator, Delay -from nmigen.cli import rtlil from soc.decoder.power_decoder import (create_pdecode) from soc.decoder.power_decoder2 import (PowerDecode2) from soc.decoder.power_enums import XER_bits, Function -from soc.simulator.program import Program from soc.decoder.isa.all import ISA from soc.config.endian import bigendian from soc.fu.test.common import ALUHelpers from soc.fu.div.pipeline import DivBasePipe -from soc.fu.div.pipe_data import DivPipeSpec, DivPipeKind - -import power_instruction_analyzer as pia +from soc.fu.div.pipe_data import DivPipeSpec def log_rand(n, min_val=1): @@ -80,33 +77,8 @@ def set_alu_inputs(alu, dec2, sim): return pia.InstructionInput(ra=inp["ra"], rb=inp["rb"], rc=0) -# This test bench is a bit different than is usual. Initially when I -# was writing it, I had all of the tests call a function to create a -# device under test and simulator, initialize the dut, run the -# simulation for ~2 cycles, and assert that the dut output what it -# should have. However, this was really slow, since it needed to -# create and tear down the dut and simulator for every test case. - -# Now, instead of doing that, every test case in DivTestCase puts some -# data into the test_data list below, describing the instructions to -# be tested and the initial state. Once all the tests have been run, -# test_data gets passed to TestRunner which then sets up the DUT and -# simulator once, runs all the data through it, and asserts that the -# results match the pseudocode sim at every cycle. - -# By doing this, I've reduced the time it takes to run the test suite -# massively. Before, it took around 1 minute on my computer, now it -# takes around 3 seconds - - -class DivRunner(unittest.TestCase): - def __init__(self, test_data, div_pipe_kind=None): - print("DivRunner", test_data, div_pipe_kind) - super().__init__("run_all") - self.test_data = test_data - self.div_pipe_kind = div_pipe_kind - - def execute(self, alu, instruction, pdecode2, test): +class DivTestHelper(unittest.TestCase): + def execute(self, alu, instruction, pdecode2, test, div_pipe_kind): prog = test.program isa_sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem, test.msr, @@ -195,22 +167,14 @@ class DivRunner(unittest.TestCase): # TODO: raise bugreport with whitequark # requesting a public API to access this "officially" # XXX print("time:", sim._state.timeline.now) - msg = "%s: %s" % (self.div_pipe_kind.name, code) + msg = "%s: %s" % (div_pipe_kind.name, code) msg += " %s" % (repr(prog.assembly)) msg += " %s" % (repr(test.regs)) yield from self.check_alu_outputs(alu, pdecode2, isa_sim, msg, pia_res) - def run_all(self): - # *sigh* this is a mess. unit test gets added by code-walking - # (unittest module) and picked up with a test name. - # we don't want that: we want it explicitly called - # (see div test_pipe_caller.py) - don't know what to do, - # so "fix" it by adding default param and returning here - if self.div_pipe_kind is None: - return - + def run_all(self, test_data, div_pipe_kind, file_name_prefix): m = Module() comb = m.d.comb instruction = Signal(32) @@ -219,7 +183,7 @@ class DivRunner(unittest.TestCase): m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode) - pspec = DivPipeSpec(id_wid=2, div_pipe_kind=self.div_pipe_kind) + pspec = DivPipeSpec(id_wid=2, div_pipe_kind=div_pipe_kind) m.submodules.alu = alu = DivBasePipe(pspec) comb += alu.p.data_i.ctx.op.eq_from_execute1(pdecode2.e) @@ -230,13 +194,13 @@ class DivRunner(unittest.TestCase): sim.add_clock(1e-6) def process(): - for test in self.test_data: + for test in test_data: print(test.name) with self.subTest(test.name): - yield from self.execute(alu, instruction, pdecode2, test) + yield from self.execute(alu, instruction, pdecode2, test, div_pipe_kind) sim.add_sync_process(process) - with sim.write_vcd(f"div_simulator_{self.div_pipe_kind.name}.vcd"): + with sim.write_vcd(f"{file_name_prefix}_{div_pipe_kind.name}.vcd"): sim.run() def check_alu_outputs(self, alu, dec2, sim, code, pia_res): diff --git a/src/soc/fu/div/test/test_pipe_caller.py b/src/soc/fu/div/test/test_pipe_caller.py index 88e72155..55180261 100644 --- a/src/soc/fu/div/test/test_pipe_caller.py +++ b/src/soc/fu/div/test/test_pipe_caller.py @@ -6,8 +6,8 @@ from soc.config.endian import bigendian from soc.fu.test.common import (TestCase, TestAccumulatorBase) from soc.fu.div.pipe_data import DivPipeKind -from soc.fu.div.test.runner import (log_rand, get_cu_inputs, - set_alu_inputs, DivRunner) +from soc.fu.div.test.helper import (log_rand, get_cu_inputs, + set_alu_inputs, DivTestHelper) class DivTestCases(TestAccumulatorBase): @@ -164,12 +164,19 @@ class DivTestCases(TestAccumulatorBase): self.add_case(prog, initial_regs) +class TestPipe(DivTestHelper): + def test_div_pipe_core(self): + self.run_all(DivTestCases().test_data, + DivPipeKind.DivPipeCore, "div_pipe_caller") + + def test_fsm_div_core(self): + self.run_all(DivTestCases().test_data, + DivPipeKind.FSMDivCore, "div_pipe_caller") + + def test_sim_only(self): + self.run_all(DivTestCases().test_data, + DivPipeKind.SimOnly, "div_pipe_caller") + + if __name__ == "__main__": - unittest.main(exit=False) - suite = unittest.TestSuite() - suite.addTest(DivRunner(DivTestCases().test_data, DivPipeKind.DivPipeCore)) - suite.addTest(DivRunner(DivTestCases().test_data, DivPipeKind.FSMDivCore)) - suite.addTest(DivRunner(DivTestCases().test_data, DivPipeKind.SimOnly)) - - runner = unittest.TextTestRunner() - runner.run(suite) + unittest.main() diff --git a/src/soc/fu/div/test/test_all_pipe_caller.py b/src/soc/fu/div/test/test_pipe_caller_long.py similarity index 70% rename from src/soc/fu/div/test/test_all_pipe_caller.py rename to src/soc/fu/div/test/test_pipe_caller_long.py index bf62cd5f..5a8d205f 100644 --- a/src/soc/fu/div/test/test_all_pipe_caller.py +++ b/src/soc/fu/div/test/test_pipe_caller_long.py @@ -1,16 +1,13 @@ -import random -import inspect import unittest from soc.simulator.program import Program from soc.config.endian import bigendian -from soc.fu.test.common import TestCase, TestAccumulatorBase -from soc.fu.div.test.runner import DivRunner +from soc.fu.test.common import TestAccumulatorBase +from soc.fu.div.test.helper import DivTestHelper from soc.fu.div.pipe_data import DivPipeKind class DivTestLong(TestAccumulatorBase): - def case_all(self): instrs = [] for width in ("w", "d"): @@ -46,12 +43,19 @@ class DivTestLong(TestAccumulatorBase): self.add_case(prog, initial_regs) +class TestPipeLong(DivTestHelper): + def test_div_pipe_core(self): + self.run_all(DivTestLong().test_data, + DivPipeKind.DivPipeCore, "div_pipe_caller_long") + + def test_fsm_div_core(self): + self.run_all(DivTestLong().test_data, + DivPipeKind.FSMDivCore, "div_pipe_caller_long") + + def test_sim_only(self): + self.run_all(DivTestLong().test_data, + DivPipeKind.SimOnly, "div_pipe_caller_long") + + if __name__ == "__main__": - unittest.main(exit=False) - suite = unittest.TestSuite() - suite.addTest(DivRunner(DivTestLong().test_data, DivPipeKind.DivPipeCore)) - suite.addTest(DivRunner(DivTestLong().test_data, DivPipeKind.FSMDivCore)) - suite.addTest(DivRunner(DivTestLong().test_data, DivPipeKind.SimOnly)) - - runner = unittest.TextTestRunner() - runner.run(suite) + unittest.main() -- 2.30.2