Introduction
The MyHDL project contains an extensive test suite. The tests are critical to the quality and expansion of the project. As a developer (new or not) one of the first things you will do is write a test. This document is an introduction to the MyHDL test suite.
MyHDL test suite
The test suite contains two main sets of tests:
-
Core: The core tests all the hardware description types and extensions in the package. In the repository core tests can be found under: myhdl/test/core
-
Conversion: The conversion tests verify the conversion from MyHDL to Verilog and VHDL. In the repository conversion tests can be found under: myhdl/test/conversion
The conversion tests are most often added under myhdl/test/conversion/general and make use of convertible testbenches There are additional conversion tests that use cosimulation but these tests are not covered in this document.
The test suite uses pytest as a test framework and test runner. The MyHDL development follows a test-driven-design (TDD) methodology, in most cases this involves having a test generated before a feature is added or a bug is fixed.
The pytest package will need to be installed to run the tests.
As bugs or issues are discovered tests are created to reproduce the issue. An issue description is first entered into the Issue Tracker. Then a test can be created in myhdl/test/bugs/ The test name should contain the github issue number:
test_issue_<github issue #>.py
The tests in the bugs directory are a mix of core and conversion tests depending on the issue. The tests in this directory need to be invoked similar to the tests in the conversion/general (see below).
HDL simulators
In addition to pytest an HDL simulator will be required to run the conversion tests. The following is a list of simulators commonly used with the conversion tests. A simulator or analyzer will need to be installed to run the conversion tests.
-
Icarus Verilog (iverilog): Icarus Verilog is a Verilog simulation and synthesis tool. Icarus is an open-source project
-
GHDL (ghdl): GHDL is an open source VHDL simulator. An installation guide is available.
-
Modelsim (vcom, vlog): vcom and vlog are VHDL and Verilog compilers, respectively. They ship with ModelSim by MentorGraphics. For installation tips this guide is useful.
Other simulators are supported and it is not difficult to add a new simulator or analyzer.
Running core tests
>> python setup.py develop >> cd myhdl/test/core >> py.test # or make
The above command will run all the tests present in core folder. If you only want to run a specific test you can do the following.
>> py.test <name_of_test>
Running conversion tests
>> cd myhdl/test/conversion/general >> py.test --sim=('iverilog', 'ghdl', 'vlog', 'vcom')
The --sim
command line argument is used to select the simulator
used in the tests. Many of the tests in the test/bugs
also verify converted results. The bug/issue tests will need the
--sim
argument.
Writing tests
General guidelines
-
Keep it Simple: tests do not have to be complex hardware designs. They should be simple enough to quickly understand.
-
Focus on a specific feature/function: a test should target a specific feature or issue. This reduces complicated tests that can be difficult to understand and maintain.
-
Fully tested: for the feature/issue being tested make sure all aspects are tested. Test expected failures as well as expected success.
-
Debug friendly: Try and provide as much information as possible when a test detects an error. This will assist in future debugging.
Using py.test
The following is a brief overview of the test structure using the pytest style. Refer to the pytest site for more information on the pytest framework and test structure.
-
Files with names
test_*.py
and functions with namestest_*
will be executed by thepy.test
runner. -
Functions with names
test_*
will be executed as tests by the test runner. -
Use Python's
assert
statements in the functions to validate expected results and responses.
Example
The following is a toy example to test the intbv
assignment
and bounds.
import pytest import myhdl from myhdl import intbv def test_intbv_assign(): x = intbv(0, min=-8, max=8) x[:] = 4 assert x == 4 with pytest.raises(ValueError): x[:] = -9
Writing conversion tests
The MyHDL package has simulators that are registered in the code
base. As mentioned above a registered simulator is selected by
using the --sim=<sim>
argument with py.test
. Two functions
can be used with the registered simulators to verify converted code.
The analyze and verify functions.
The analyze function is used to verify the converted code passes the analysis stage (compilation). The analyze function is invoked similar to the conversion functions and the traceSignals.
Example using analyze
The following example has a valid module and we can check the
conversion using the analyze
function. As mentioned with will
invoke the simulator’s analysis.
def my_valid_module(a, b): @always_comb def digital_logic(): b.next = a return rtl def test_valid_analyze(): a, b = [Signal(bool(0) for _ in range(2)] assert analyze(my_module_exposes_issue, a, b) == 0
The above can be run with:
>> py.test —sim=iverilog test_valid_module.py
Example using verify
The verify function will use a convertible test bench and run the converted code with the Verilog or VHDL simulator. First a convertible test bench is created.
def tb_valid_module(): a, b = [Signal(bool(0)) for _ in range(2)] tbdut = my_valid_module(a, b) @instance def tbstim(): yield delay(2) assert a == b == False a.next = True yield delay(2) assert a == b == True return tbdut, tbstim def test_valid_verify(): assert verify(tb_valid_module) == 0
If the above is added to the same file, we can invoke py.test test same as above and the second test will be run as well.
A template that can be used with Eclipse and othe editors can be found here