I am working on a project in SystemC and want to incorporate unit testing. Is it possible to use existing unit test frameworks with SystemC?
I ask this because it seems like the SystemC modules only get executed with the simulation kernel, and I want to use unit tests on the modules themselves.
I have a second solution to this question that uses CMkae and CTest (http://cmake.org/). The setup I used creates a binary for each test. Here's the
CMakeLists.txt
file I used:Each
test_*.cxx
file has asc_main
method that executes the test and the return value indicates whether or not the test passed or failed. To run the tests simply do:If you don't want to run the simulator, you can simply skip the call to
sc_start
and exit the application after doing whatever specific testing you want on a particular module.I was able to run 2 SystemC tests using the fork system call. I used the tutorial example on doulos.com and the Google Test framework. I was able to run the test twice, but I get an error printed out by the SystemC simulator about starting the test after calling sc_stop. However, regardless of the error, the simulator runs fine the second time around.
UPDATE: Code sample as requested:
Very often SystemC Device-under-test (DUT) can be resetted to initial state by asserting some signal. You can utilize this fact and enable any C++ unit testing framework you want. Just reset you DUT before running each test, so you don't need to elaborate it twice.
Here is an example with Google Test, and a simple "Accumulator" DUT
::testing::InitGoogleTest(&argc, argv);
) fromsc_main
sc_module
by callingRUN_ALL_TESTS()
Source:
CMakeLists.txt (requires installed SystemC 2.3.2 )
You must create all necessary SystemC signals, SystemC modules and make connection between them before you run any test in GTest. This requires to create own
gtest_main.cc
implementation. Naturally in SystemC you must put everything insc_main
function.For this, I would use registry design pattern.
First create registry class (registry + factory + singleton). This class will be responsible for storing registered constructors using dynamic allocation with new and smart pointer in lambda expression (see
factory::add
class). Create all objects usingfactory::create()
method before running all tests. Then you can get object usingfactory::get()
method in you test execution.factory.hpp
factory.cpp
Create your own version of
gtest_main.cc
implementation. Callfactory::create()
method to create all SystemC signals and SystemC modules before running any testsRUN_ALL_TESTS()
. Because factory class is a singleton design pattern, callfactory::destroy()
method after finishing all tests to destroy all created SystemC objects.main.cpp
Then define dut class in your test than will create SystemC signals and SystemC modules. In constructor do connection between created SystemC signals and modules. Register defined dut class to registry object using global constructor like this factory::add g. After than you can get your dut object using simple factory::get() method.
test.cpp
For more inspiration, you can check my logic library for SystemC verification: https://github.com/tymonx/logic