from typing import Optional, List import unittest import os import glob import shutil import inspect import pathlib import pytest from systemrdl import RDLCompiler from peakrdl.regblock import RegblockExporter from .cpuifs.base import CpuifTestMode from .cpuifs.apb3 import APB3 class BaseTestCase(unittest.TestCase): #: Path to the testcase's RDL file. #: Relative to the testcase's dir. If unset, the first RDL file found in the #: testcase dir will be used rdl_file = None # type: Optional[str] #: RDL type name to elaborate. If unset, compiler will automatically choose #: the top. rdl_elab_target = None # type: Optional[str] #: Parameters to pass into RDL elaboration rdl_elab_params = {} #: Define what CPUIF to use for this testcase cpuif = APB3() # type: CpuifTestMode # Other exporter args: retime_read_fanin = False retime_read_response = False #: this gets auto-loaded via the _load_request autouse fixture request = None # type: pytest.FixtureRequest exporter = RegblockExporter() @pytest.fixture(autouse=True) def _load_request(self, request): self.request = request @classmethod def get_testcase_dir(cls) -> str: class_dir = os.path.dirname(inspect.getfile(cls)) return class_dir @classmethod def get_run_dir(cls) -> str: this_dir = cls.get_testcase_dir() run_dir = os.path.join(this_dir, "run.out", cls.__name__) return run_dir @classmethod def _write_params(cls) -> None: """ Write out the class parameters to a file so that it is easier to debug how a testcase was parameterized """ path = os.path.join(cls.get_run_dir(), "params.txt") with open(path, 'w') as f: for k, v in cls.__dict__.items(): if k.startswith("_") or callable(v): continue f.write(f"{k}: {repr(v)}\n") @classmethod def _export_regblock(cls): """ Call the peakrdl.regblock exporter to generate the DUT """ this_dir = cls.get_testcase_dir() if cls.rdl_file: rdl_file = cls.rdl_file else: # Find any *.rdl file in testcase dir rdl_file = glob.glob(os.path.join(this_dir, "*.rdl"))[0] rdlc = RDLCompiler() rdlc.compile_file(rdl_file) root = rdlc.elaborate(cls.rdl_elab_target, "regblock", cls.rdl_elab_params) cls.exporter.export( root, cls.get_run_dir(), module_name="regblock", package_name="regblock_pkg", cpuif_cls=cls.cpuif.cpuif_cls, retime_read_fanin=cls.retime_read_fanin, retime_read_response=cls.retime_read_response, ) @classmethod def setUpClass(cls): # Create fresh build dir run_dir = cls.get_run_dir() if os.path.exists(run_dir): shutil.rmtree(run_dir) pathlib.Path(run_dir).mkdir(parents=True, exist_ok=True) cls._write_params() # Convert testcase RDL file --> SV cls._export_regblock() def setUp(self) -> None: # cd into the run directory self.original_cwd = os.getcwd() os.chdir(self.get_run_dir()) def run_test(self, plusargs:List[str] = None) -> None: simulator = self.simulator_cls(testcase_cls_inst=self) simulator.run(plusargs)