Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/components/scc/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,11 @@ bool router<BUSWIDTH, TARGET_SOCKET_TYPE>::get_direct_mem_ptr(int i, tlm::tlm_ge
trans.set_address(address - offset);
bool status = initiator[idx]->get_direct_mem_ptr(trans, dmi_data);
// make sure end address does not exceed size
auto remap_end = (tranges[idx].remap ? 0 : tranges[idx].base) + tranges[idx].size;
if(tranges[idx].size && dmi_data.get_end_address() >= remap_end)
auto const remap_base = tranges[idx].remap ? 0 : tranges[idx].base;
auto const remap_size = tranges[idx].size;
auto const remap_end = remap_base + remap_size;
auto const remap_end_overflow = remap_end < remap_base;
if(remap_size && !remap_end_overflow && dmi_data.get_end_address() >= remap_end)
dmi_data.set_end_address(remap_end - 1);
// Calculate DMI address of target in system address space
dmi_data.set_start_address(dmi_data.get_start_address() - ibases[i] + offset);
Expand Down
13 changes: 13 additions & 0 deletions tests/memory_subsys/memory_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ TEST_CASE("scattered_access", "[memory][tlm-level]") {
f(kPageSize - 2);
}

TEST_CASE("dmi_high_range_wrap_regression", "[memory][tlm-level]") {
auto& dut = factory::get<testbench>();
tlm::tlm_generic_payload gp;
tlm::tlm_dmi dmi;

gp.set_address(testbench::high_range_base);
auto res = dut.isck0->get_direct_mem_ptr(gp, dmi);

REQUIRE(res == true);
REQUIRE(dmi.get_start_address() == testbench::high_range_base);
REQUIRE(dmi.get_end_address() == testbench::high_range_base + dmi_probe_target::window_size - 1);
}

TEST_CASE("page_boundary_check", "[memory][tlm-level]") {
auto& dut = factory::get<testbench>();
constexpr uint64_t kPageSize = dut.mem3.getPageSize();
Expand Down
35 changes: 34 additions & 1 deletion tests/memory_subsys/testbench.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#ifndef _TESTBENCH_H_
#define _TESTBENCH_H_

#include <array>
#include <cxs/cxs_tlm.h>
#include <limits>
#include <scc/cci_util.h>
#include <scc/configurer.h>
#include <scc/memory.h>
Expand All @@ -19,22 +21,51 @@ using namespace std;
namespace scc {

const char* sc_gen_unique_name(const char*, bool preserve_first);
struct dmi_probe_target : public sc_core::sc_module {
static constexpr auto window_size = uint64_t{64};
tlm::scc::target_mixin<tlm::tlm_target_socket<scc::LT>> target{"target"};
std::array<uint8_t, window_size> storage{};

dmi_probe_target()
: dmi_probe_target(sc_core::sc_gen_unique_name("dmi_probe_target", false)) {}

explicit dmi_probe_target(sc_core::sc_module_name const& nm)
: sc_module(nm) {
target.register_b_transport([](tlm::tlm_generic_payload& gp, sc_core::sc_time&) { gp.set_response_status(tlm::TLM_OK_RESPONSE); });
target.register_get_direct_mem_ptr([this](tlm::tlm_generic_payload& gp, tlm::tlm_dmi& dmi_data) -> bool {
auto const start = gp.get_address();
dmi_data.set_start_address(start);
dmi_data.set_end_address(start + window_size - 1);
dmi_data.set_dmi_ptr(storage.data());
dmi_data.set_granted_access(tlm::tlm_dmi::DMI_ACCESS_READ_WRITE);
dmi_data.set_read_latency(sc_core::SC_ZERO_TIME);
dmi_data.set_write_latency(sc_core::SC_ZERO_TIME);
return true;
});
}
};

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;

static constexpr uint64_t high_range_size = 4_kB;
static constexpr uint64_t high_range_base = std::numeric_limits<uint64_t>::max() - (high_range_size - 1);

sc_core::sc_signal<sc_core::sc_time> clk{"clk"};
sc_core::sc_signal<bool> rst{"rst"};
tlm::scc::initiator_mixin<tlm::tlm_initiator_socket<scc::LT>> isck0{"isck0"};
tlm::scc::initiator_mixin<tlm::tlm_initiator_socket<scc::LT>> isck1{"isck1"};
scc::router<scc::LT> router{"router", 6, 2};

scc::router<scc::LT> router{"router", 7, 2};
scc::memory_tl<1_kB, scc::LT> mem0{"mem0"};
scc::memory_tl<1_kB, scc::LT> mem1{"mem1"};
scc::memory_tl<18_MB, scc::LT> mem2{"mem2"};
scc::memory_tl<24_MB, scc::LT> mem3{"mem3"};
scc::memory_tl<88_MB, scc::LT> mem4{"mem4"};
scc::memory<4_GB> mem5{"mem5"};
dmi_probe_target dmi_probe{"dmi_probe"};

testbench()
: testbench(sc_core::sc_gen_unique_name("testbench", false)) {}
Expand All @@ -51,6 +82,8 @@ struct testbench : public sc_core::sc_module {
router.bind_target(mem4.target, 4, 64_MB, 20_MB, false);
router.initiator[5].bind(mem5.target);
router.set_default_target(5);

router.bind_target(dmi_probe.target, 6, high_range_base, high_range_size, false);
mem0.clk_i(clk);
mem1.clk_i(clk);
mem2.clk_i(clk);
Expand Down
Loading