diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2023-11-01 18:41:44 +0100 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2023-11-01 18:41:44 +0100 |
commit | 291364e1b408d29236034854b7ed30f080e5b6c9 (patch) | |
tree | f55efb5954ea6374295f2e04d98041b766992660 /test/lt_bus.cc | |
parent | ccaae5eb310ae8aabd77f8fe53f181f4afe0365b (diff) | |
download | sysc-playground-291364e1b408d29236034854b7ed30f080e5b6c9.tar.gz sysc-playground-291364e1b408d29236034854b7ed30f080e5b6c9.zip |
lt_bus: add initial support for global bus locking
Diffstat (limited to 'test/lt_bus.cc')
-rw-r--r-- | test/lt_bus.cc | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/test/lt_bus.cc b/test/lt_bus.cc index ffbad9d..4f7fcf7 100644 --- a/test/lt_bus.cc +++ b/test/lt_bus.cc @@ -7,7 +7,6 @@ #include <tlm_utils/simple_target_socket.h> #include <sstream> -#include "gmock/gmock.h" using testing::_; @@ -28,11 +27,13 @@ struct [[nodiscard]] phantom { namespace tag { struct addr; struct len; +struct lock; } // namespace tag } // namespace detail using addr_t = detail::phantom<detail::tag::addr, sc_dt::uint64>; using len_t = detail::phantom<detail::tag::len, u32>; +using lock_t = detail::phantom<detail::tag::len, bool>; // -- TLM TARGET MOCK ---------------------------------------------------------- @@ -75,10 +76,15 @@ struct initiator : public sc_core::sc_module { MOCK_METHOD(void, invalidate_direct_mem_ptr, (sc_dt::uint64, sc_dt::uint64)); - bool transport(addr_t a, len_t l) { + bool transport(addr_t a, len_t l, lock_t lk = lock_t{false}) { tlm::tlm_generic_payload tx; setup_tx(tx, a, l); + // Set bus lock extension (will be owned by gp). + auto* bl = new bus_lock; + bl->is_lock = lk.cast(); + tx.set_extension(bl); + sc_core::sc_time t; p_sock->b_transport(tx, t); // Check bus restored correct original address. @@ -130,21 +136,14 @@ struct initiator : public sc_core::sc_module { static std::string tx_to_str(const tlm::tlm_generic_payload& tx) { std::ostringstream oss; // Only print values we are interested in in the tests. - oss << "tx.addr=0x" << std::hex << tx.get_address() << std::dec << ','; - oss << "tx.len=" << tx.get_data_length(); + oss << "tx.addr=0x" << std::hex << tx.get_address() << std::dec; + oss << ",tx.len=" << tx.get_data_length(); + if (const bus_lock* ext = tx.get_extension<bus_lock>()) { + oss << ",tx.is_lock=" << ext->is_lock; + } return oss.str(); }; -MATCHER_P(gp_addr, - /* arg0 */ arg_addr, - /* desc */ [](addr_t a) { - tlm::tlm_generic_payload tx; - tx.set_address(a.cast()); - return tx_to_str(tx); - }(arg_addr /* ign negation arg */)) { - return arg.get_address() == arg_addr.cast(); -} - // Custom generic payload (gp) address and length matcher. MATCHER_P2(gp_addr_len, /* arg0 */ arg_addr, @@ -159,6 +158,26 @@ MATCHER_P2(gp_addr_len, arg.get_data_length() == arg_len.cast(); } +// Custom generic payload (gp) address, length and lock matcher. +MATCHER_P3(gp_addr_len_lock, + /* arg0 */ arg_addr, + /* arg1 */ arg_len, + /* arg2 */ arg_lock, + /* desc */ [](addr_t a, len_t l, lock_t lk) { + tlm::tlm_generic_payload tx; + tx.set_address(a.cast()); + tx.set_data_length(l.cast()); + auto* ext = new bus_lock; + ext->is_lock = lk.cast(); + tx.set_extension(ext); + return tx_to_str(tx); + }(arg_addr, arg_len, arg_lock /* ign negation arg */)) { + const auto* ext = arg.template get_extension<bus_lock>(); + return arg.get_address() == arg_addr.cast() && + arg.get_data_length() == arg_len.cast() && ext && + ext->is_lock == arg_lock.cast(); +} + // Define operator<< for tlm generic payloads in the tlm namespace. Used // by gtest/gmock when printing payload objects. // It is not a good practice to add functions to non-owned namespaced but for @@ -335,3 +354,22 @@ TEST_F(bus_test, invalidate_dmi) { EXPECT_CALL(i2, invalidate_direct_mem_ptr(0xa80, 0xaff)); t2.inv_dmi(0x80, 0x101); } + +TEST_F(bus_test, fwd_lock) { + bus.attach_target(t1.p_sock, 0x400, 0x7ff); + + testing::InSequence seq; + + // Unlocked access. + EXPECT_CALL( + t1, + b_transport(gp_addr_len_lock(addr_t(0x0), len_t(1), lock_t(false)), _)); + ASSERT_TRUE(i1.transport(addr_t(0x400), len_t(1), lock_t(false))); + + // Locked access -> invalidates DMI pointer. + EXPECT_CALL(i1, invalidate_direct_mem_ptr(0x0, -1ull)); + EXPECT_CALL( + t1, + b_transport(gp_addr_len_lock(addr_t(0x100), len_t(1), lock_t(true)), _)); + ASSERT_TRUE(i1.transport(addr_t(0x500), len_t(1), lock_t(true))); +} |