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());
+}