Testing Framework¶
Since there is no robust and reliable unit testing framework for SystemC code, we decide to implement our own testing framework. The goals for the design of the testing framework were;
- Similar to other existing unit testing frameworks like googletest and Junit.
- Intuitive timing specifications checking APIs
- Centralized mechanism to run all unit tests
This goals helped us to overcome the following disadvantages inherit from SystemC traditional testing methodologies;
- sc_start() and sc_stop() calls affect the entire process.
- There’s no API to reset simulation time
- Every unit test has to be written inside a sc_main(...). Meaning a separate executable per test.
- An entire SC_MODULE has to be developed for introducing stimuli to the Module Under Test and an other for verifying it’s output.
Based on this goals we developed a unit testing framework with the following features;
- Centralized method to run all tests through CTest. Review ctest for a full set of features and capabilities inherited from ctest.
- Easy, Intuitive, and Powerful building system.
- Intuitive timing specification checking.
- Simplified test writing structure.
- Simplified tracing APIs and automatic VCD files creation.
- Easy to integrate C++ headers library.
Testing Building System¶
The our building system for testing is based on our project’s Building System. The entire tests building system is based on the following CMake macros;
# Add test sources directory
add_test_sources_directory(dir1 dir2 ...)
# Add test source file
add_test_sources(file1 file2 ...)
The usage of both macros is analog to the usage of add_sources_directory(...) and add_sources(...), respectively. Review Building System for more information.
Note
All tests source code have to be located at <your-sc_viterbi-src-code-path>/test/src.
Furthermore, add_test_sources(...) also registers every test source file as a test in CTest. This makes it easier for test running through ctest command or make test.
APIs¶
-
SC_TEST
(test_name)¶ Define a test with a given test name
Parameters: - test_name (string) – The name or label of the test
-
SC_EXPECT_AT
(expected, actual, time_val, time_unit)¶ Check that actual equals expected at a given moment
Parameters: - expected – Expected value
- actual – Actual value
- time_val (double) – Time value
- time_unit (sc_time_unit) – Time unit
Tracing¶
-
SC_TRACE
(signal, name)¶ Add a signal to the test’s trace file with the provided name
Parameters: - signal (sc_signal) – The signal to be added to the trace
- name (string) – The given name for the signal
-
SC_STRACE
(signal)¶ Add a signal to the test’s trace file
Parameters: - signal (sc_signal) – The signal to be added to the trace (the name of the signal will be name of the variable)
Test Example¶
The following code was taken from our clock divider’s test. It is a good example to show how our testing framework works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <sc_test_framework.h>
...
SC_TEST(clock_divider) {
sc_clock sys_clock("sys_clock", clock_period, clock_duty, clock_start, false);
sc_signal<bool> div_clock_4;
# Trace signals
SC_TRACE(sys_clock, "sys_clk");
SC_STRACE(div_clock_4);
# Create clock divider
clock_divider<4> div_4 ("DivideBy4");
# Connect Signals
div_4.clk_in (sys_clock);
div_4.clk_out (div_clock_4);
# Verify output at a certain point in time
SC_EXPECT_AT(sc_logic(0), div_clock_4, 200, SC_NS);
SC_EXPECT_AT(sc_logic(1), div_clock_4, 220, SC_NS);
sc_start(350, SC_NS);
}
|
Here is a short explanation on what the code does;
- In line 1 the framework headers library is included.
- In line 5 the test is defined with the name clock_divider.
- In line 10 the signal sys_clock is added to the trace file with a given name that differs from the sc_signal variable name.
- In line 11 the signal div_clock_4 is added to the trace file using with with the name div_clock_4.
- In line 21 and 22 the time specification for the signal div_clock_4 is done. If the signal div_clock_4 differs from ‘0’ at 200ns or from ‘1’ at 220ns the test will fail.
Future Work¶
This testing framework is planned to be developed as a separate project because of its usability and scope. It was incubated in within this project.
APIs¶
-
SC_EXPECT_AFTER
(expected, actual, time_val, time_unit)¶ Check that actual equals expected after a specific time interval
Parameters: - expected – Expected value
- actual – Actual value
- time_val (double) – Time value
- time_unit (sc_time_unit) – Time unit
-
SC_SIGNAL_SET
(signal, value, time_val, time_unit)¶ Set the signal to a specific value at a specific point in time
Parameters: - signal – The signal to be set
- value – The value to be taken
- time_val (double) – Time value
- time_unit (sc_time_unit) – Time unit
-
SC_SETUP
¶ Set up everything before the test run
-
SC_TEARDOWN
¶ Clean everything up after the test run