From 4b3bbe0104940ac385a9946493afb174e3b35db4 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 25 May 2025 18:43:42 +0200 Subject: [PATCH] adds a test for scc::memory --- scc | 2 +- tests/CMakeLists.txt | 1 + tests/tlm_memory/CMakeLists.txt | 8 ++ tests/tlm_memory/memory_test.cpp | 137 +++++++++++++++++++++++++++++++ tests/tlm_memory/testbench.h | 42 ++++++++++ 5 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/tlm_memory/CMakeLists.txt create mode 100644 tests/tlm_memory/memory_test.cpp create mode 100644 tests/tlm_memory/testbench.h diff --git a/scc b/scc index 5824559..2ab9bcd 160000 --- a/scc +++ b/scc @@ -1 +1 @@ -Subproject commit 5824559e0d719ff8b259079c6b33ca0154f92ac9 +Subproject commit 2ab9bcda6911387ce53b480072fb345c1f5531cf diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cf8aa2f..8976ad1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(configuration) add_subdirectory(configurer) add_subdirectory(sc_fixed_tracing) add_subdirectory(cxs_tlm) +add_subdirectory(tlm_memory) add_subdirectory(sim_speed) if(FULL_TEST_SUITE) add_subdirectory(sim_performance) diff --git a/tests/tlm_memory/CMakeLists.txt b/tests/tlm_memory/CMakeLists.txt new file mode 100644 index 0000000..ec5fda1 --- /dev/null +++ b/tests/tlm_memory/CMakeLists.txt @@ -0,0 +1,8 @@ +project (tlm_memory) +add_executable(${PROJECT_NAME} + memory_test.cpp + ${test_util_SOURCE_DIR}/sc_main.cpp +) +target_link_libraries (${PROJECT_NAME} PUBLIC scc::components test_util) + +catch_discover_tests(${PROJECT_NAME}) diff --git a/tests/tlm_memory/memory_test.cpp b/tests/tlm_memory/memory_test.cpp new file mode 100644 index 0000000..f07c0cc --- /dev/null +++ b/tests/tlm_memory/memory_test.cpp @@ -0,0 +1,137 @@ + +#include "testbench.h" +#include +#include +#undef CHECK +#include +#include +#include +#include +#include + +using namespace sc_core; +namespace scc { +factory::add tb; + +template void prepare_trans(tlm::tlm_generic_payload& trans, tlm::tlm_command cmd, uint64_t addr, T val) { + unsigned len = cmd == tlm::TLM_IGNORE_COMMAND ? 0 : sizeof(val); + unsigned char* data = len ? new unsigned char[len] : nullptr; + if(cmd == tlm::TLM_WRITE_COMMAND) { + memcpy(data, &val, len); + trans.set_command(cmd); + } + if(cmd == tlm::TLM_READ_COMMAND) { + memset(data, 0, len); + trans.set_command(tlm::TLM_READ_COMMAND); + } + trans.set_address(addr); + trans.set_data_ptr(data); + trans.set_data_length(len); + trans.set_streaming_width(len); + trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); +} + +TEST_CASE("simple_read_write_with host memory map", "[memory][tlm-level]") { + auto& dut = factory::get(); + std::array ref_data; + auto val = 256; + for(auto& e : ref_data) + e = --val; + dut.rst.write(true); + sc_start(10 * dut.clk.read()); + dut.rst.write(false); + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + sc_core::sc_time t; + for(uint64_t addr = 0; addr < 1024; addr += sizeof(uint64_t)) { + prepare_trans(gp, tlm::TLM_WRITE_COMMAND, addr, 123456789ULL); + dut.isck->b_transport(gp, t); + delete gp.get_data_ptr(); + sc_start(dut.clk.read()); + } + } + { + tlm::tlm_generic_payload gp; + prepare_trans(gp, tlm::TLM_READ_COMMAND, 256, 0ULL); + sc_core::sc_time t; + dut.isck->b_transport(gp, t); + uint64_t res; + memcpy(&res, gp.get_data_ptr(), sizeof(uint64_t)); + REQUIRE(res == 123456789ULL); + delete gp.get_data_ptr(); + } + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + gp.set_command(tlm::TLM_IGNORE_COMMAND); + gp.set_address(256); + gp.set_data_ptr(nullptr); + gp.set_data_length(256); + gp.set_streaming_width(256); + gp.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + auto ext = new scc::host_mem_map_extension(ref_data.data()); + gp.set_extension(ext); + dut.isck->transport_dbg(gp); + } + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + prepare_trans(gp, tlm::TLM_READ_COMMAND, 256, 0ULL); + sc_core::sc_time t; + dut.isck->b_transport(gp, t); + uint64_t res; + memcpy(&res, gp.get_data_ptr(), sizeof(uint64_t)); + REQUIRE(res == 0xf8f9fafbfcfdfeffULL); + delete gp.get_data_ptr(); + } + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + prepare_trans(gp, tlm::TLM_READ_COMMAND, 384, 0ULL); + sc_core::sc_time t; + dut.isck->b_transport(gp, t); + uint64_t res; + memcpy(&res, gp.get_data_ptr(), sizeof(uint64_t)); + REQUIRE(res == 0x78797a7b7c7d7e7fULL); + delete gp.get_data_ptr(); + } + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + gp.set_command(tlm::TLM_IGNORE_COMMAND); + gp.set_address(256); + gp.set_data_ptr(nullptr); + gp.set_data_length(256); + gp.set_streaming_width(256); + gp.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + auto ext = new scc::host_mem_map_extension(nullptr); + gp.set_extension(ext); + dut.isck->transport_dbg(gp); + } + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + prepare_trans(gp, tlm::TLM_READ_COMMAND, 256, 0ULL); + sc_core::sc_time t; + dut.isck->b_transport(gp, t); + uint64_t res; + memcpy(&res, gp.get_data_ptr(), sizeof(uint64_t)); + REQUIRE(res == 123456789ULL); + delete gp.get_data_ptr(); + } + sc_start(dut.clk.read()); + { + tlm::tlm_generic_payload gp; + prepare_trans(gp, tlm::TLM_READ_COMMAND, 256, 0ULL); + sc_core::sc_time t; + dut.isck->b_transport(gp, t); + uint64_t res; + memcpy(&res, gp.get_data_ptr(), sizeof(uint64_t)); + REQUIRE(res == 123456789ULL); + delete gp.get_data_ptr(); + } + sc_start(dut.clk.read()); +} + +} // namespace scc diff --git a/tests/tlm_memory/testbench.h b/tests/tlm_memory/testbench.h new file mode 100644 index 0000000..4f0b721 --- /dev/null +++ b/tests/tlm_memory/testbench.h @@ -0,0 +1,42 @@ +#ifndef _TESTBENCH_H_ +#define _TESTBENCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace sc_core; +using namespace sc_dt; +using namespace std; +namespace scc { + +const char* sc_gen_unique_name(const char*, bool preserve_first); +struct testbench : public sc_core::sc_module { + + using transaction_type = tlm::tlm_base_protocol_types::tlm_payload_type; + using phase_type = tlm::tlm_base_protocol_types::tlm_phase_type; + + sc_core::sc_signal clk{"clk"}; + sc_core::sc_signal rst{"rst"}; + tlm::scc::initiator_mixin> isck{"isck"}; + scc::memory_tl<1_kB, scc::LT> mem{"mem"}; + + testbench() + : testbench(sc_core::sc_gen_unique_name("testbench", false)) {} + + testbench(sc_core::sc_module_name const& nm) + : sc_module(nm) { + isck(mem.target); + mem.clk_i(clk); + } + void start_of_simulation() { clk = 10_ns; } +}; +} // namespace scc +#endif // _TESTBENCH_H_