Source code for elasticai.creator.testing.cocotb_runner

from collections.abc import Iterable
from functools import partial
from os import environ
from pathlib import Path
from typing import Any

from cocotb.runner import get_runner  # type: ignore

from elasticai.creator.file_generation import find_project_root


[docs] def get_and_create_sim_build_dir(folder_name: str) -> Path: build = find_project_root() / folder_name build.mkdir(exist_ok=True) return build
[docs] def run_cocotb_sim_for_src_dir( src_files: Iterable[str] | Iterable[Path], top_module_name: str, cocotb_test_module: str, path2src: str = "", defines: dict = {}, params: dict = {}, timescale: tuple[str, str] = ("1ps", "1fs"), en_debug_mode: bool = True, build_waveforms: bool = False, ) -> None: """Function for running Verilog/VHDL Simulation using COCOTB environment :param src_files: List with source files of each used Verilog/VHDL file :param top_module_name: Name of the top module (from file) :param cocotb_test_module: Fully qualified name of python module containing cotName of the cocotb testbench in Python :param path2src: Path to the folder in which all src files are available for testing :param defines: Dictionary of parameters to pass to the module [key: value, ...] - usable only in Verilog :param params: Dictionary of parameters to pass to the module [key: value, ...] - value will be ignored :param timescale: Tuple with Timescale value for simulation (step, accuracy) :param en_debug_mode: Enable debug mode :param build_waveforms: Boolean for building the waveforms of the stimuli (will be saved in build_sim folder) :return: None """ _path2src = Path(path2src) return run_cocotb_sim( src_files=[_path2src / f for f in src_files], top_module_name=top_module_name, cocotb_test_module=cocotb_test_module, defines=defines, params=params, timescale=timescale, en_debug_mode=en_debug_mode, build_waveforms=build_waveforms, )
def _build_language_map() -> dict[str, str]: language_mapping = {} for ks, language in [((".v", ".sv"), "verilog"), ((".vhd", ".vhdl"), "vhdl")]: for k in ks: language_mapping[k] = language return language_mapping
[docs] def run_cocotb_sim( src_files: Iterable[str] | Iterable[Path], top_module_name: str, cocotb_test_module: str, defines: dict[str, Any] = {}, params: dict[str, Any] = {}, timescale: tuple[str, str] = ("1ps", "1fs"), en_debug_mode: bool = True, build_waveforms: bool = False, ) -> None: """Function for running Verilog/VHDL Simulation using COCOTB environment :param src_files: List with source files of each used Verilog/VHDL file :param top_module_name: Name of the top module (from file) :param cocotb_test_module: Fully qualified name of python module containing cotName of the cocotb testbench in Python :param defines: Dictionary of parameters to pass to the module [key: value, ...] - usable only in Verilog :param params: Dictionary of parameters to pass to the module [key: value, ...] - value will be ignored :param timescale: Tuple with Timescale value for simulation (step, accuracy) :param en_debug_mode: Enable debug mode :param build_waveforms: Boolean for building the waveforms of the stimuli (will be saved in build_sim folder) :return: None """ design_sources = [Path(m) for m in src_files] project_root = find_project_root() if len(design_sources) == 0: raise ValueError("no design sources specified") if any(map(lambda x: not x.exists(), design_sources)): raise FileNotFoundError(f"Design file does not exist {design_sources}") runner_mapping = {"verilog": "icarus", "vhdl": "ghdl"} suffix = design_sources[0].suffix language_mapping = _build_language_map() if suffix not in language_mapping: raise ValueError(f"File ending {suffix} not supported") language = language_mapping[suffix] runner = get_runner(runner_mapping[language]) environ["COCOTB_RESOLVE_X"] = "ZEROS" environ["COCOTB_LOG_LEVEL"] = "INFO" if en_debug_mode else "WARNING" environ["COCOTB_REDUCED_LOG_FMT"] = "0" if en_debug_mode else "1" environ["MACOSX_DEPLOYMENT_TARGET"] = "15.0" build_sim_dir = project_root / "build_sim" if language == "verilog": build_call = partial(runner.build, verilog_sources=design_sources) plus_args = [] else: top_module_name = top_module_name.lower() plus_args = [f"--vcd={top_module_name}.vcd"] if build_waveforms else [] build_call = partial(runner.build, vhdl_sources=design_sources) build_call( hdl_toplevel=top_module_name, always=True, clean=True, waves=build_waveforms, defines=defines, parameters=params, timescale=timescale, build_dir=build_sim_dir, ) runner.test( hdl_toplevel=top_module_name, test_module=[cocotb_test_module], hdl_toplevel_lang=language, gui=False, plusargs=plus_args, waves=build_waveforms, parameters=params, timescale=timescale, build_dir=build_sim_dir, test_dir=build_sim_dir, )