#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); } template void do_dmi_access(T& isck, uint64_t address, uint64_t expected_size) { tlm::tlm_generic_payload gp; tlm::tlm_dmi dmi; gp.set_address(address); auto res = isck->get_direct_mem_ptr(gp, dmi); REQUIRE(res == true); REQUIRE(dmi.get_start_address() == address); REQUIRE(dmi.get_end_address() == (address + expected_size - 1)); REQUIRE(dmi.is_read_write_allowed()); } TEST_CASE("dmi_access", "[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()); do_dmi_access(dut.isck0, 0, 1_kB); do_dmi_access(dut.isck0, 1_kB, 1_kB); do_dmi_access(dut.isck0, 16_MB, 16_MB); do_dmi_access(dut.isck0, 32_MB, 16_MB); do_dmi_access(dut.isck0, 48_MB, 4_MB); do_dmi_access(dut.isck0, 64_MB, 16_MB); do_dmi_access(dut.isck0, 80_MB, 4_MB); do_dmi_access(dut.isck1, 0 - 1_MB, 1_kB); do_dmi_access(dut.isck1, 1_kB - 1_MB, 1_kB); do_dmi_access(dut.isck1, 16_MB - 1_MB, 16_MB); do_dmi_access(dut.isck1, 32_MB - 1_MB, 16_MB); do_dmi_access(dut.isck1, 48_MB - 1_MB, 4_MB); sc_start(dut.clk.read()); } } // namespace scc