In older post, I went through cocotb Makefile and i wished if there python runner. Well, I should have wished for something better because I found there is already a runner. I just didn’t see it :)
The runner is called as follows to build and run test
runner = get_runner(sim)()
runner.build(
verilog_sources=verilog_sources, vhdl_sources=vhdl_sources, toplevel="dff"
)
runner.test(toplevel="dff", py_module="test_dff")
Build Link to heading
In runner.py
, get_runner
returns the runner depending on simulator string. In case of icarus, Icarus
is used
sim_name = simulator_name.lower()
supported_sims: Dict[str, Type[Simulator]] = {
"icarus": Icarus,
"questa": Questa,
"ghdl": Ghdl,
"riviera": Riviera,
"verilator": Verilator,
"xcelium": Xcelium,
# TODO: "vcs": Vcs,
}
try:
return supported_sims[sim_name]
and Icarus
extends Simulator
class Icarus(Simulator):
To build the files, runner.build
is called which is defined in Simulator
. In build()
, build_command
is called.
cmds = self.build_command()
build_command
is defined in Icarus
to construct
def build_command(self) -> List[Command]:
if self.vhdl_sources:
raise ValueError("This simulator does not support VHDL")
cmd = []
if outdated(self.sim_file, self.verilog_sources) or self.always:
cmd = [
["iverilog", "-o", self.sim_file, "-D", "COCOTB_SIM=1", "-g2012"]
+ self.get_define_options(self.defines)
+ self.get_include_options(self.includes)
+ self.get_parameter_options(self.parameters)
+ self.compile_args
+ self.verilog_sources
]
else:
print("WARNING: Skipping compilation:" + self.sim_file)
return cmd
Run Link to heading
runner.test
is used to run the test which follows the same pattern as build
. In this case, test
calls _test_command
after setting some log files
if pytest_current_test:
self.current_test_name = pytest_current_test.split(":")[-1].split(" ")[0]
results_xml_name = f"{self.current_test_name}.results.xml"
else:
self.current_test_name = "test"
results_xml_name = "results.xml"
results_xml_file = os.getenv(
"COCOTB_RESULTS_FILE", os.path.join(self.build_dir, results_xml_name)
)
self.env["COCOTB_RESULTS_FILE"] = results_xml_file
with suppress(OSError):
os.remove(results_xml_file)
cmds = self.test_command()
And test_command
build iverilog command to run the build executable
def test_command(self) -> List[Command]:
return [
[
"vvp",
"-M",
cocotb.config.libs_dir,
"-m",
cocotb.config.lib_name("vpi", "icarus"),
]
+ self.sim_args
+ [self.sim_file]
+ self.plus_args
]