reworkes test infrastructure and tests

This commit is contained in:
Eyck Jentzsch 2022-10-02 11:39:06 +02:00
parent 6516244afe
commit aa58ec0fa7
9 changed files with 121 additions and 154 deletions

View File

@ -40,14 +40,22 @@
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="SystemC-Components-Test.null.276784792" name="SystemC-Components-Test"/> <project id="SystemC-Components-Test.null.276784792" name="SystemC-Components-Test"/>
</storageModule> </storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2"> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default"> <configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/> <resource resourceType="PROJECT" workspacePath="/SystemC-Components-Test"/>
</configuration> </configuration>
<configuration configurationName="Debug"/>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605;cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612;cmake4eclipse.mbs.toolchain.tool.dummy.326050058;cmake4eclipse.mbs.inputType.cpp.459033018">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cmake4eclipse.mbs.toolchain.cmake.134761605;cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612;cmake4eclipse.mbs.toolchain.tool.dummy.326050058;cmake4eclipse.mbs.inputType.c.1524512146">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject> </cproject>

View File

@ -61,13 +61,14 @@ endif()
endif() endif()
conan_check() 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 GENERATORS cmake_find_package
OPTIONS fmt:header_only=True OPTIONS fmt:header_only=True
) )
conan_install() conan_install()
find_package(ZLIB) find_package(ZLIB)
find_package(lz4)
# This line finds the boost lib and headers. # 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. 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) find_package(Boost COMPONENTS program_options filesystem system thread REQUIRED)

View File

@ -2,3 +2,4 @@ project (test_util)
add_library(${PROJECT_NAME} factory.cpp) add_library(${PROJECT_NAME} factory.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries (${PROJECT_NAME} PUBLIC scc Catch2::Catch2)

View File

@ -7,19 +7,25 @@
#include "factory.h" #include "factory.h"
#include <catch2/catch_session.hpp> #include <catch2/catch_session.hpp>
#include "../axi4_pin_level/testbench.h" #include <scc/report.h>
#include <scc/trace.h>
#include <scc/tracer.h>
#include <util/ities.h>
using namespace scc; using namespace scc;
int sc_main(int argc, char* argv[]) { using namespace sc_core;
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);
factory::add<testbench> 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(); factory::get_instance().create();
int result = Catch::Session().run( argc, argv ); int result = Catch::Session().run( argc, argv );
factory::get_instance().destroy(); 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); return result + sc_report_handler::get_count(SC_ERROR) + sc_report_handler::get_count(SC_WARNING);
} }

View File

@ -1,9 +1,9 @@
project (axi4_pin_level) project (axi4_pin_level)
add_executable(${PROJECT_NAME} add_executable(${PROJECT_NAME}
sc_main.cpp
narrow_burst_test.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}) add_test(NAME narrow_burst COMMAND ${PROJECT_NAME})

View File

@ -1,12 +1,31 @@
#define SC_INCLUDE_DYNAMIC_PROCESSES #define SC_INCLUDE_DYNAMIC_PROCESSES
#include "../axi4_pin_level/testbench.h" #include "testbench.h"
#include <factory.h> #include <factory.h>
#include <tlm/scc/tlm_gp_shared.h>
#include <catch2/catch_all.hpp> #include <catch2/catch_all.hpp>
using namespace sc_core; using namespace sc_core;
factory::add<testbench> 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<a.get_data_length(); ++i)
ret &= a.get_data_ptr()[i] == b.get_data_ptr()[i];
if(a.get_byte_enable_ptr() && b.get_byte_enable_ptr()) {
ret &= a.get_byte_enable_length() == b.get_byte_enable_length();
for(auto i=0u; i<a.get_byte_enable_length(); ++i)
ret &= a.get_byte_enable_ptr()[i] == b.get_byte_enable_ptr()[i];
}
ret &= a.get_command() == b.get_command();
if(!ret) SCCWARN()<<"Comparison failed: "<<a<<" and "<<b;
return ret;
}
template<typename bus_cfg> template<typename bus_cfg>
tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, size_t len, unsigned id_offs = 0, tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, size_t len, unsigned id_offs = 0,
unsigned addr_offs = 0) { unsigned addr_offs = 0) {
@ -40,22 +59,26 @@ inline void randomize(tlm::tlm_generic_payload& gp) {
req_cnt++; req_cnt++;
} }
TEST_CASE("AXI", "[axi]") { TEST_CASE("pin level narrow burst", "[AXI][pin-level]") {
struct { struct {
unsigned int ResetCycles{10}; unsigned int ResetCycles{10};
unsigned int BurstLengthByte{16}; unsigned int BurstLengthByte{16};
unsigned int NumberOfIterations{10}; unsigned int NumberOfIterations{10};
std::vector<tlm::scc::tlm_gp_shared_ptr> sent_read_tx, sent_write_tx;
std::vector<tlm::scc::tlm_gp_shared_ptr> rcv_read_tx, rcv_write_tx;
unsigned resp_cnt{0}; unsigned resp_cnt{0};
} setup; } state;
auto& dut = factory::get<testbench>(); auto& dut = factory::get<testbench>();
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(); auto addr = trans.get_address();
uint8_t const* src = reinterpret_cast<uint8_t const*>(&addr); uint8_t const* src = reinterpret_cast<uint8_t const*>(&addr);
for(size_t i = 0; i < trans.get_data_length(); ++i) { 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; return 0;
}); });
@ -64,56 +87,66 @@ TEST_CASE("AXI", "[axi]") {
dut.rst.write(true); dut.rst.write(true);
sc_start(3*dut.clk.period()); sc_start(3*dut.clk.period());
auto run1 = sc_spawn([&dut, &setup](){ auto run1 = sc_spawn([&dut, &state](){
unsigned int StartAddr{0x20}; 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; SCCDEBUG("test") << "run0 executing transactions in iteration " << i;
{ // 1 { // 1
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, setup.BurstLengthByte); tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, state.BurstLengthByte);
randomize(*trans); randomize(*trans);
trans->set_command(tlm::TLM_READ_COMMAND); trans->set_command(tlm::TLM_READ_COMMAND);
dut.intor_pe.transport(*trans, false); dut.intor_pe.transport(*trans, false);
state.sent_read_tx.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR() << "Invalid response status" << trans->get_response_string(); SCCERR() << "Invalid response status" << trans->get_response_string();
} }
StartAddr += setup.BurstLengthByte; StartAddr += state.BurstLengthByte;
{ // 2 { // 2
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, setup.BurstLengthByte); tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, state.BurstLengthByte);
trans->set_command(tlm::TLM_WRITE_COMMAND); trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans); randomize(*trans);
dut.intor_pe.transport(*trans, false); dut.intor_pe.transport(*trans, false);
state.sent_read_tx.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR() << "Invalid response status" << trans->get_response_string(); 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}; 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; SCCDEBUG("test") << "run1 executing transactions in iteration " << i;
{ // 1 { // 1
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, setup.BurstLengthByte, 0x8); tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, state.BurstLengthByte, 0x8);
randomize(*trans); randomize(*trans);
trans->set_command(tlm::TLM_READ_COMMAND); trans->set_command(tlm::TLM_READ_COMMAND);
dut.intor_pe.transport(*trans, false); dut.intor_pe.transport(*trans, false);
state.sent_write_tx.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR() << "Invalid response status" << trans->get_response_string(); SCCERR() << "Invalid response status" << trans->get_response_string();
} }
StartAddr += setup.BurstLengthByte; StartAddr += state.BurstLengthByte;
{ // 2 { // 2
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, setup.BurstLengthByte, 0x8); tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, state.BurstLengthByte, 0x8);
trans->set_command(tlm::TLM_WRITE_COMMAND); trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans); randomize(*trans);
dut.intor_pe.transport(*trans, false); dut.intor_pe.transport(*trans, false);
state.sent_write_tx.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR() << "Invalid response status" << trans->get_response_string(); SCCERR() << "Invalid response status" << trans->get_response_string();
} }
StartAddr += setup.BurstLengthByte; StartAddr += state.BurstLengthByte;
} }
}); });
sc_start(1000 * dut.clk.period()); sc_start(1000 * dut.clk.period());
REQUIRE(run1.terminated()); REQUIRE(run1.terminated());
REQUIRE(run2.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<state.sent_write_tx.size(); ++i)
CHECK(*state.sent_write_tx[i] == *state.rcv_write_tx[i]);
REQUIRE(state.sent_read_tx.size() == state.rcv_read_tx.size());
for(auto i = 0; i<state.sent_write_tx.size(); ++i)
CHECK(*state.sent_read_tx[i] == *state.rcv_read_tx[i]);
} }

View File

@ -1,13 +1,9 @@
cmake_minimum_required(VERSION 3.12) project (ordered_semaphore)
find_package(Boost COMPONENTS program_options REQUIRED)
add_executable (ordered_sem
sc_main.cpp
)
target_link_libraries (ordered_sem LINK_PUBLIC scc)
if(TARGET Boost::program_options)
target_link_libraries(ordered_sem PUBLIC Boost::program_options)
else()
target_link_libraries(ordered_sem LINK_PUBLIC ${BOOST_program_options_LIBRARY})
endif()
add_test(NAME ordered_sem_test COMMAND ordered_sem) add_executable(${PROJECT_NAME}
test.cpp
${test_util_SOURCE_DIR}/sc_main.cpp
)
target_link_libraries (${PROJECT_NAME} PUBLIC test_util)
add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME})

View File

@ -1,110 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2017 eyck@minres.com
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
////////////////////////////////////////////////////////////////////////////////
/*
* sc_main.cpp
*
* Created on: 17.09.2017
* Author: eyck@minres.com
*/
#include <scc/report.h>
#include <scc/tracer.h>
#include <boost/program_options.hpp>
#include <scc/ordered_semaphore.h>
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);
}

View File

@ -0,0 +1,32 @@
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include <scc/ordered_semaphore.h>
#include <scc/utilities.h>
#include <factory.h>
#include <catch2/catch_all.hpp>
#include <systemc>
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<top> tb;
TEST_CASE("simple ordered_semaphore test", "[SCC][ordered_semaphore]") {
auto& dut = factory::get<top>();
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());
}