From aa58ec0fa76a7d371a75e883f65d72205b01f0de Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 2 Oct 2022 11:39:06 +0200 Subject: [PATCH] reworkes test infrastructure and tests --- .cproject | 14 ++- CMakeLists.txt | 3 +- src/CMakeLists.txt | 1 + {tests/axi4_pin_level => src}/sc_main.cpp | 18 ++-- tests/axi4_pin_level/CMakeLists.txt | 4 +- tests/axi4_pin_level/narrow_burst_test.cpp | 73 ++++++++++---- tests/ordered_semaphore/CMakeLists.txt | 20 ++-- tests/ordered_semaphore/sc_main.cpp | 110 --------------------- tests/ordered_semaphore/test.cpp | 32 ++++++ 9 files changed, 121 insertions(+), 154 deletions(-) rename {tests/axi4_pin_level => src}/sc_main.cpp (58%) delete mode 100644 tests/ordered_semaphore/sc_main.cpp create mode 100644 tests/ordered_semaphore/test.cpp diff --git a/.cproject b/.cproject index 61da564..0e6693c 100644 --- a/.cproject +++ b/.cproject @@ -40,14 +40,22 @@ - - - + + + + + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fe20db..c15ef09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,13 +61,14 @@ endif() endif() conan_check() -conan_configure(REQUIRES fmt/6.1.2 boost/1.75.0 gsl-lite/0.37.0 systemc/2.3.3 systemc-cci/1.0.0 catch2/3.1.0 +conan_configure(REQUIRES fmt/6.1.2 boost/1.75.0 gsl-lite/0.37.0 systemc/2.3.3 systemc-cci/1.0.0 catch2/3.1.0 zlib/1.2.11 lz4/1.9.4 GENERATORS cmake_find_package OPTIONS fmt:header_only=True ) conan_install() find_package(ZLIB) +find_package(lz4) # This line finds the boost lib and headers. set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install. find_package(Boost COMPONENTS program_options filesystem system thread REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 286932a..0b0d479 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,3 +2,4 @@ project (test_util) add_library(${PROJECT_NAME} factory.cpp) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries (${PROJECT_NAME} PUBLIC scc Catch2::Catch2) diff --git a/tests/axi4_pin_level/sc_main.cpp b/src/sc_main.cpp similarity index 58% rename from tests/axi4_pin_level/sc_main.cpp rename to src/sc_main.cpp index cb38fd8..5af6c4b 100644 --- a/tests/axi4_pin_level/sc_main.cpp +++ b/src/sc_main.cpp @@ -7,19 +7,25 @@ #include "factory.h" #include -#include "../axi4_pin_level/testbench.h" +#include +#include +#include +#include using namespace scc; -int sc_main(int argc, char* argv[]) { - sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); - scc::init_logging(LogConfig().logLevel(log::INFO).logAsync(false)); - scc::tracer trace("axi4_tlm_pin_tlm", scc::tracer::file_type::NONE, true); +using namespace sc_core; - factory::add tb; +int sc_main(int argc, char* argv[]) { + scc::init_logging(LogConfig().logLevel(log::INFO).logAsync(false)); + auto token = util::split(argv[0], '/'); + auto trc = scc::create_fst_trace_file(token.back().c_str()); + scc::tracer trace(token.back(), scc::tracer::file_type::NONE, trc); factory::get_instance().create(); int result = Catch::Session().run( argc, argv ); factory::get_instance().destroy(); + scc::close_fst_trace_file(trc); + return result + sc_report_handler::get_count(SC_ERROR) + sc_report_handler::get_count(SC_WARNING); } diff --git a/tests/axi4_pin_level/CMakeLists.txt b/tests/axi4_pin_level/CMakeLists.txt index 368643e..ae8d9b6 100644 --- a/tests/axi4_pin_level/CMakeLists.txt +++ b/tests/axi4_pin_level/CMakeLists.txt @@ -1,9 +1,9 @@ project (axi4_pin_level) add_executable(${PROJECT_NAME} - sc_main.cpp narrow_burst_test.cpp + ${test_util_SOURCE_DIR}/sc_main.cpp ) -target_link_libraries (${PROJECT_NAME} PUBLIC scc test_util Catch2::Catch2) +target_link_libraries (${PROJECT_NAME} PUBLIC test_util) add_test(NAME narrow_burst COMMAND ${PROJECT_NAME}) \ No newline at end of file diff --git a/tests/axi4_pin_level/narrow_burst_test.cpp b/tests/axi4_pin_level/narrow_burst_test.cpp index 69872c3..5dc2d81 100644 --- a/tests/axi4_pin_level/narrow_burst_test.cpp +++ b/tests/axi4_pin_level/narrow_burst_test.cpp @@ -1,12 +1,31 @@ #define SC_INCLUDE_DYNAMIC_PROCESSES -#include "../axi4_pin_level/testbench.h" +#include "testbench.h" #include - +#include #include using namespace sc_core; +factory::add tb; + +bool operator==(tlm::tlm_generic_payload const& a, tlm::tlm_generic_payload const& b){ + auto ret = true; + ret &= a.get_command() == b.get_command(); + ret &= a.get_address() == b.get_address(); + ret &= a.get_data_length() == b.get_data_length(); + for(auto i=0u; i tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, size_t len, unsigned id_offs = 0, unsigned addr_offs = 0) { @@ -40,22 +59,26 @@ inline void randomize(tlm::tlm_generic_payload& gp) { req_cnt++; } -TEST_CASE("AXI", "[axi]") { +TEST_CASE("pin level narrow burst", "[AXI][pin-level]") { struct { unsigned int ResetCycles{10}; unsigned int BurstLengthByte{16}; unsigned int NumberOfIterations{10}; + std::vector sent_read_tx, sent_write_tx; + std::vector rcv_read_tx, rcv_write_tx; unsigned resp_cnt{0}; - } setup; + } state; auto& dut = factory::get(); - dut.tgt_pe.set_operation_cb([&setup](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned { + dut.tgt_pe.set_operation_cb([&state](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned { auto addr = trans.get_address(); uint8_t const* src = reinterpret_cast(&addr); for(size_t i = 0; i < trans.get_data_length(); ++i) { - *(trans.get_data_ptr() + i) = i % 2 ? i : setup.resp_cnt; + *(trans.get_data_ptr() + i) = i % 2 ? i : state.resp_cnt; } - setup.resp_cnt++; + if(trans.is_read()) state.rcv_read_tx.emplace_back(&trans); + if(trans.is_write()) state.rcv_write_tx.emplace_back(&trans); + state.resp_cnt++; return 0; }); @@ -64,56 +87,66 @@ TEST_CASE("AXI", "[axi]") { dut.rst.write(true); sc_start(3*dut.clk.period()); - auto run1 = sc_spawn([&dut, &setup](){ + auto run1 = sc_spawn([&dut, &state](){ unsigned int StartAddr{0x20}; - for(int i = 0; i < setup.NumberOfIterations; ++i) { + for(int i = 0; i < state.NumberOfIterations; ++i) { SCCDEBUG("test") << "run0 executing transactions in iteration " << i; { // 1 - tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte); + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, state.BurstLengthByte); randomize(*trans); trans->set_command(tlm::TLM_READ_COMMAND); dut.intor_pe.transport(*trans, false); + state.sent_read_tx.emplace_back(trans); if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) SCCERR() << "Invalid response status" << trans->get_response_string(); } - StartAddr += setup.BurstLengthByte; + StartAddr += state.BurstLengthByte; { // 2 - tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte); + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, state.BurstLengthByte); trans->set_command(tlm::TLM_WRITE_COMMAND); randomize(*trans); dut.intor_pe.transport(*trans, false); + state.sent_read_tx.emplace_back(trans); if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) SCCERR() << "Invalid response status" << trans->get_response_string(); } - StartAddr += setup.BurstLengthByte; + StartAddr += state.BurstLengthByte; } }); - auto run2 = sc_spawn([&dut, &setup](){ + auto run2 = sc_spawn([&dut, &state](){ unsigned int StartAddr{0x1020}; - for(int i = 0; i < setup.NumberOfIterations; ++i) { + for(int i = 0; i < state.NumberOfIterations; ++i) { SCCDEBUG("test") << "run1 executing transactions in iteration " << i; { // 1 - tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte, 0x8); + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, state.BurstLengthByte, 0x8); randomize(*trans); trans->set_command(tlm::TLM_READ_COMMAND); dut.intor_pe.transport(*trans, false); + state.sent_write_tx.emplace_back(trans); if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) SCCERR() << "Invalid response status" << trans->get_response_string(); } - StartAddr += setup.BurstLengthByte; + StartAddr += state.BurstLengthByte; { // 2 - tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, setup.BurstLengthByte, 0x8); + tlm::scc::tlm_gp_shared_ptr trans = prepare_trans(StartAddr, state.BurstLengthByte, 0x8); trans->set_command(tlm::TLM_WRITE_COMMAND); randomize(*trans); dut.intor_pe.transport(*trans, false); + state.sent_write_tx.emplace_back(trans); if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) SCCERR() << "Invalid response status" << trans->get_response_string(); } - StartAddr += setup.BurstLengthByte; + StartAddr += state.BurstLengthByte; } }); sc_start(1000 * dut.clk.period()); REQUIRE(run1.terminated()); REQUIRE(run2.terminated()); - REQUIRE(setup.resp_cnt==40); + REQUIRE(state.resp_cnt==40); + REQUIRE(state.sent_write_tx.size() == state.rcv_write_tx.size()); + for(auto i = 0; i -#include -#include -#include -using namespace scc; -namespace po = boost::program_options; - -namespace { -const size_t ERROR_IN_COMMAND_LINE = 1; -const size_t SUCCESS = 0; -const size_t ERROR_UNHANDLED_EXCEPTION = 2; -} // namespace - - -class top: public sc_core::sc_module { -public: - top(sc_core::sc_module_name const&){ - SC_HAS_PROCESS(top); - SC_THREAD(run); - } - ~top() override= default;; -private: - void run(){ - sem.wait(); - sem_t.wait(); - sem.set_capacity(4); - sem_t.set_capacity(4); - sem_t.post(); - sem.post(); - sc_core::sc_stop(); - } - scc::ordered_semaphore sem{"sem", 2}; - scc::ordered_semaphore_t<2> sem_t{"sem_t"}; -}; - - -int sc_main(int argc, char *argv[]) { - sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING ); - sc_core::sc_report_handler::set_actions(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, sc_core::SC_DO_NOTHING); - /////////////////////////////////////////////////////////////////////////// - // CLI argument parsing - /////////////////////////////////////////////////////////////////////////// - po::options_description desc("Options"); - // clang-format off - desc.add_options() - ("help,h", "Print help message") - ("debug,d", "set debug level") - ("trace,t", "trace SystemC signals"); - // clang-format on - po::variables_map vm; - try { - po::store(po::parse_command_line(argc, argv, desc), vm); // can throw - // --help option - if (vm.count("help")) { - std::cout << "JIT-ISS simulator for AVR" << std::endl << desc << std::endl; - return SUCCESS; - } - po::notify(vm); // throws on error, so do after help in case - // there are any problems - } catch (po::error &e) { - std::cerr << "ERROR: " << e.what() << std::endl << std::endl; - std::cerr << desc << std::endl; - return ERROR_IN_COMMAND_LINE; - } - /////////////////////////////////////////////////////////////////////////// - // configure logging - /////////////////////////////////////////////////////////////////////////// - scc::init_logging(vm.count("debug")?scc::log::DEBUG:scc::log::INFO); - /////////////////////////////////////////////////////////////////////////// - // instantiate top level - /////////////////////////////////////////////////////////////////////////// - top tb("tb"); - /////////////////////////////////////////////////////////////////////////// - // run simulation - /////////////////////////////////////////////////////////////////////////// - sc_start(sc_core::sc_time(1, sc_core::SC_MS)); - // todo: provide end-of-simulation macros - - if (!sc_core::sc_end_of_simulation_invoked()) { - SCCERR() << "simulation timed out"; - sc_core::sc_stop(); - } - auto errcnt = sc_core::sc_report_handler::get_count(sc_core::SC_ERROR); - auto warncnt = sc_core::sc_report_handler::get_count(sc_core::SC_WARNING); - SCCINFO() << "Finished, there were " << errcnt << " error" << (errcnt == 1 ? "" : "s") << " and " << warncnt << " warning" - << (warncnt == 1 ? "" : "s, 1 warning expected"); - return errcnt + (warncnt-1); -} diff --git a/tests/ordered_semaphore/test.cpp b/tests/ordered_semaphore/test.cpp new file mode 100644 index 0000000..9cccd2c --- /dev/null +++ b/tests/ordered_semaphore/test.cpp @@ -0,0 +1,32 @@ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include +#include +#include +#include +#include + +using namespace sc_core; + +class top: public sc_core::sc_module { +public: + scc::ordered_semaphore sem{"sem", 2}; + scc::ordered_semaphore_t<2> sem_t{"sem_t"}; +}; + +factory::add tb; + +TEST_CASE("simple ordered_semaphore test", "[SCC][ordered_semaphore]") { + + auto& dut = factory::get(); + auto run1 = sc_spawn([&dut](){ + dut.sem.wait(); + dut.sem_t.wait(); + dut.sem.set_capacity(4); + dut.sem_t.set_capacity(4); + dut.sem_t.post(); + dut.sem.post(); + }); + + sc_start(1_ns); + REQUIRE(run1.terminated()); +}