quic/qbox
Loading...
Searching...
No Matches
target-tester.h
1/*
2 * This file is part of libgsutils
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 * Author: GreenSocs 2022
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#ifndef GREENSOCS_GSUTILS_TESTS_TARGET_TESTER_H
10#define GREENSOCS_GSUTILS_TESTS_TARGET_TESTER_H
11
12#include <cstring>
13#include <functional>
14
15#include <gtest/gtest.h>
16
17#include <systemc>
18#include <tlm>
19#include <tlm_utils/simple_target_socket.h>
20#include <tlm_sockets_buswidth.h>
21
48class TargetTester : public sc_core::sc_module
49{
50public:
51 using TlmGenericPayload = tlm::tlm_generic_payload;
52 using TlmResponseStatus = tlm::tlm_response_status;
53 using TlmDmi = tlm::tlm_dmi;
54
55 using AccessCallbackFn = std::function<TlmResponseStatus(uint64_t addr, uint8_t* data, size_t len)>;
56 using DebugAccessCallbackFn = std::function<int(uint64_t addr, uint8_t* data, size_t len)>;
57 using GetDirectMemPtrCallbackFn = std::function<bool(uint64_t addr, TlmDmi&)>;
58
59private:
60 size_t m_mmio_size;
61
62 /* Only valid within a transaction callback */
63 TlmGenericPayload* m_cur_txn = nullptr;
64 sc_core::sc_time* m_cur_txn_delay = nullptr;
65
66 bool m_last_txn_valid = false;
67 TlmGenericPayload m_last_txn;
68
69 bool m_last_txn_delay_valid = false;
70 sc_core::sc_time m_last_txn_delay;
71
72 AccessCallbackFn m_read_cb;
73 AccessCallbackFn m_write_cb;
74
75 DebugAccessCallbackFn m_debug_read_cb;
76 DebugAccessCallbackFn m_debug_write_cb;
77
78 GetDirectMemPtrCallbackFn m_dmi_cb;
79
80 /* Factorized version of b_transport and transport_dbg */
81 template <class RET, RET DEFAULT_RET, RET ADDRESS_ERROR_RET, RET DEFAULT_CB_RET, class CB_FN>
82 RET generic_access(TlmGenericPayload& txn, const CB_FN& read_cb, const CB_FN& write_cb)
83 {
84 using namespace tlm;
85
87 uint8_t* ptr;
88 size_t len;
90
91 m_cur_txn = &txn;
92
93 if (txn.get_command() == TLM_IGNORE_COMMAND) {
94 goto out;
95 }
96
97 if (txn.get_address() + txn.get_data_length() >= m_mmio_size) {
99 goto out;
100 }
101
102 addr = txn.get_address();
103 ptr = txn.get_data_ptr();
104 len = txn.get_data_length();
105
106 switch (txn.get_command()) {
107 case TLM_READ_COMMAND:
108 if (m_read_cb) {
109 ret = read_cb(addr, ptr, len);
110 } else {
112 }
113 break;
114
116 if (m_write_cb) {
117 ret = write_cb(addr, ptr, len);
118 } else {
119 std::memset(ptr, 0, len);
121 }
122 break;
123
124 default:
125 /* TLM_IGNORE_COMMAND already handled above */
126 ADD_FAILURE();
127 }
128
129 out:
130 m_cur_txn = nullptr;
131
132 m_last_txn.deep_copy_from(txn);
133 m_last_txn_valid = true;
134
135 return ret;
136 }
137
138protected:
139 virtual void b_transport(TlmGenericPayload& txn, sc_core::sc_time& delay)
140 {
141 using namespace tlm;
142
143 TlmResponseStatus ret;
144
145 m_cur_txn_delay = &delay;
146 ret = generic_access<TlmResponseStatus, TLM_OK_RESPONSE, TLM_ADDRESS_ERROR_RESPONSE, TLM_OK_RESPONSE,
147 AccessCallbackFn>(txn, m_read_cb, m_write_cb);
148 m_cur_txn_delay = nullptr;
149
150 txn.set_response_status(ret);
151
152 m_last_txn_delay = delay;
153 m_last_txn_delay_valid = true;
154 }
155
156 virtual unsigned int transport_dbg(TlmGenericPayload& txn)
157 {
158 int ret = 0;
159
160 ret = generic_access<int, 0, 0, -1, DebugAccessCallbackFn>(txn, m_debug_read_cb, m_debug_write_cb);
161
162 if (ret == -1) {
163 ret = txn.get_data_length();
164 }
165
166 return ret;
167 }
168
169 virtual bool get_direct_mem_ptr(TlmGenericPayload& txn, TlmDmi& dmi_data)
170 {
172
173 m_last_txn.deep_copy_from(m_last_txn);
174
175 addr = txn.get_address();
176
177 if (m_dmi_cb) {
178 return m_dmi_cb(addr, dmi_data);
179 } else {
180 return false;
181 }
182 }
183
184public:
185 tlm_utils::simple_target_socket<TargetTester, DEFAULT_TLM_BUSWIDTH> socket;
186
193 TargetTester(const sc_core::sc_module_name& n, size_t mmio_size): sc_core::sc_module(n), m_mmio_size(mmio_size)
194 {
195 socket.register_b_transport(this, &TargetTester::b_transport);
196 socket.register_transport_dbg(this, &TargetTester::transport_dbg);
197 socket.register_get_direct_mem_ptr(this, &TargetTester::get_direct_mem_ptr);
198 }
199
200 virtual ~TargetTester() {}
201
205 void register_read_cb(AccessCallbackFn cb) { m_read_cb = cb; }
206
210 void register_write_cb(AccessCallbackFn cb) { m_write_cb = cb; }
211
215 void register_debug_read_cb(DebugAccessCallbackFn cb) { m_debug_read_cb = cb; }
216
220 void register_debug_write_cb(DebugAccessCallbackFn cb) { m_debug_write_cb = cb; }
221
225 void register_get_direct_mem_ptr_cb(GetDirectMemPtrCallbackFn cb) { m_dmi_cb = cb; }
226
237 bool last_txn_is_valid() const { return m_last_txn_valid; }
238
248 const TlmGenericPayload& get_last_txn()
249 {
250 EXPECT_TRUE(m_last_txn_valid);
251 m_last_txn_valid = false;
252
253 return m_last_txn;
254 }
255
265 const sc_core::sc_time& get_last_txn_delay()
266 {
267 EXPECT_TRUE(m_last_txn_delay_valid);
268 m_last_txn_delay_valid = false;
269
270 return m_last_txn_delay;
271 }
272
282 TlmGenericPayload& get_cur_txn()
283 {
284 EXPECT_TRUE(m_cur_txn != nullptr);
285 return *m_cur_txn;
286 }
287
297 sc_core::sc_time& get_cur_txn_delay()
298 {
299 EXPECT_TRUE(m_cur_txn_delay != nullptr);
300 return *m_cur_txn_delay;
301 }
302};
303
304#endif
Definition target.h:160
A TLM target to do testing on an initiator.
Definition target-tester.h:49
const TlmGenericPayload & get_last_txn()
Return a copy of the last transaction payload.
Definition target-tester.h:248
void register_debug_read_cb(DebugAccessCallbackFn cb)
Register callback called on transport_dbg read transaction.
Definition target-tester.h:215
void register_debug_write_cb(DebugAccessCallbackFn cb)
Register callback called on transport_dbg write transaction.
Definition target-tester.h:220
void register_read_cb(AccessCallbackFn cb)
Register callback called on b_tranport read transaction.
Definition target-tester.h:205
TlmGenericPayload & get_cur_txn()
Get the current transaction payload.
Definition target-tester.h:282
void register_write_cb(AccessCallbackFn cb)
Register callback called on b_tranport write transaction.
Definition target-tester.h:210
TargetTester(const sc_core::sc_module_name &n, size_t mmio_size)
Construct a TargetTester object with a name and an MMIO size.
Definition target-tester.h:193
void register_get_direct_mem_ptr_cb(GetDirectMemPtrCallbackFn cb)
Register a callback called on a get_direct_mem_ptr call.
Definition target-tester.h:225
const sc_core::sc_time & get_last_txn_delay()
Return a copy of the last transaction delay value.
Definition target-tester.h:265
sc_core::sc_time & get_cur_txn_delay()
Get the current transaction delay.
Definition target-tester.h:297
bool last_txn_is_valid() const
Return true if the copy of the last transaction is valid.
Definition target-tester.h:237