quic/qbox
Loading...
Searching...
No Matches
python_binder.h
1/*
2 * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _GREENSOCS_PYTHON_BINDER_DMI_H
8#define _GREENSOCS_PYTHON_BINDER_DMI_H
9
18#ifdef _WIN32
19#ifdef python_binder_EXPORTS
20#define PYTHON_BINDER_API __declspec(dllexport)
21#else
22#define PYTHON_BINDER_API __declspec(dllimport)
23#endif
24#else
25#define PYTHON_BINDER_API
26#endif
27
28#include <cci_configuration>
29#include <systemc>
30#include <tlm>
31#include <scp/report.h>
32#include <scp/helpers.h>
33#include <tlm_utils/simple_initiator_socket.h>
34#include <tlm_utils/simple_target_socket.h>
35#include <ports/initiator-signal-socket.h>
36#include <ports/target-signal-socket.h>
37#include <ports/biflow-socket.h>
38#include <tlm_sockets_buswidth.h>
39#include <libgssync.h>
40#include <uutils.h>
41#include <pybind11/pybind11.h>
42#include <tuple>
43#include <unordered_map>
44#include <thread>
45#include <future>
46#include <mutex>
47#include <condition_variable>
48#include <sstream>
49
50namespace gs {
51
52unsigned char* get_pybind11_buffer_info_ptr(const pybind11::buffer& bytes);
53
54std::string txn_command_str(const tlm::tlm_generic_payload& trans);
56{
57private:
58 tlm::tlm_generic_payload* txn;
59
60public:
61 generic_payload_data_buf(tlm::tlm_generic_payload* _txn): txn(_txn) {}
62 pybind11::buffer_info get_buffer()
63 {
64 return pybind11::buffer_info(txn->get_data_ptr(), sizeof(uint8_t),
65 pybind11::format_descriptor<uint8_t>::format(), 1,
66 { static_cast<ssize_t>(txn->get_data_length()) }, { sizeof(uint8_t) });
67 }
68};
69
71{
72private:
73 tlm::tlm_generic_payload* txn;
74
75public:
76 generic_payload_be_buf(tlm::tlm_generic_payload* _txn): txn(_txn) {}
77 pybind11::buffer_info get_buffer()
78 {
79 return pybind11::buffer_info(txn->get_byte_enable_ptr(), sizeof(uint8_t),
80 pybind11::format_descriptor<uint8_t>::format(), 1,
81 { static_cast<ssize_t>(txn->get_byte_enable_length()) }, { sizeof(uint8_t) });
82 }
83};
84
86{
87private:
88 tlm::tlm_generic_payload* txn;
89 bool txn_created;
90
91public:
92 tlm_generic_payload_wrapper(tlm::tlm_generic_payload* _txn): txn(_txn), txn_created(false) {}
93 tlm_generic_payload_wrapper(): txn_created(true) { txn = new tlm::tlm_generic_payload(); }
95 {
96 if (txn_created) delete txn;
97 }
98
99 tlm::tlm_generic_payload* get_payload() { return txn; }
100
101 bool is_read() const { return txn->is_read(); }
102 void set_read() { txn->set_read(); }
103 bool is_write() const { return txn->is_write(); }
104 void set_write() { txn->set_write(); }
105 tlm::tlm_command get_command() const { return txn->get_command(); }
106 void set_command(const tlm::tlm_command command) { txn->set_command(command); }
107 sc_dt::uint64 get_address() const { return txn->get_address(); }
108 void set_address(const sc_dt::uint64 address) { txn->set_address(address); }
109 void set_data(const pybind11::buffer& bytes)
110 {
111 unsigned char* data = get_pybind11_buffer_info_ptr(bytes);
112 std::memcpy(txn->get_data_ptr(), data, txn->get_data_length());
113 }
114 generic_payload_data_buf get_data() { return generic_payload_data_buf(txn); }
115 void set_data_ptr(const pybind11::buffer& bytes)
116 {
117 unsigned char* data = get_pybind11_buffer_info_ptr(bytes);
118 txn->set_data_ptr(data);
119 }
120 unsigned int get_data_length() const { return txn->get_data_length(); }
121 void set_data_length(const unsigned int length) { txn->set_data_length(length); }
122 bool is_response_ok() const { return txn->is_response_ok(); }
123 bool is_response_error() const { return txn->is_response_error(); }
124 tlm::tlm_response_status get_response_status() const { return txn->get_response_status(); }
125 void set_response_status(const tlm::tlm_response_status response_status)
126 {
127 txn->set_response_status(response_status);
128 }
129 std::string get_response_string() const { return txn->get_response_string(); };
130 unsigned int get_streaming_width() const { return txn->get_streaming_width(); }
131 void set_streaming_width(const unsigned int streaming_width) { txn->set_streaming_width(streaming_width); }
132 void set_byte_enable_ptr(const pybind11::buffer& bytes)
133 {
134 unsigned char* byte_enable = get_pybind11_buffer_info_ptr(bytes);
135 txn->set_data_ptr(byte_enable);
136 }
137 void set_byte_enable(const pybind11::buffer& bytes)
138 {
139 unsigned char* byte_enable = get_pybind11_buffer_info_ptr(bytes);
140 std::memcpy(txn->get_byte_enable_ptr(), byte_enable, txn->get_byte_enable_length());
141 }
142 generic_payload_be_buf get_byte_enable() { return generic_payload_be_buf(txn); }
143
144 unsigned int get_byte_enable_length() const { return txn->get_byte_enable_length(); }
145 void set_byte_enable_length(const unsigned int byte_enable_length)
146 {
147 txn->set_byte_enable_length(byte_enable_length);
148 }
149 std::string str()
150 {
151 std::stringstream ss;
152 ss << "txn type: " << txn->get_command() << " addr: 0x" << std::hex << txn->get_address()
153 << " data len: " << txn->get_data_length() << " response: " << txn->get_response_string();
154 return ss.str();
155 }
156};
157
159{
160private:
162
163public:
164 static void init();
165
167 void operator=(PyInterpreterManager const&) = delete;
168
170};
171
172template <unsigned int BUSWIDTH = DEFAULT_TLM_BUSWIDTH>
173class PYTHON_BINDER_API python_binder : public sc_core::sc_module, public sc_core::sc_stage_callback_if
174{
175 SCP_LOGGER();
177 using tlm_initiator_socket_t = tlm_utils::simple_initiator_socket_b<MOD, BUSWIDTH, tlm::tlm_base_protocol_types,
178 sc_core::SC_ZERO_OR_MORE_BOUND>;
179 using tlm_target_socket_t = tlm_utils::simple_target_socket_tagged_b<MOD, BUSWIDTH, tlm::tlm_base_protocol_types,
180 sc_core::SC_ZERO_OR_MORE_BOUND>;
181 using b_transport_info = std::tuple<tlm_generic_payload_wrapper, sc_core::sc_time,
182 std::shared_ptr<sc_core::sc_event>, std::shared_ptr<sc_core::sc_event>>;
183 using b_transport_th_info = std::tuple<int, tlm_generic_payload_wrapper, sc_core::sc_time, bool, std::string,
184 std::promise<void>>;
185
186public:
187 python_binder(const sc_core::sc_module_name& nm);
188
190
191private:
192 void init_binder();
193
194 void setup_biflow_socket(pybind11::object& _modules);
195
196 void do_b_transport(int id, pybind11::object& py_trans, pybind11::object& py_delay);
197
198 void b_transport(int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
199
200 void do_target_b_transport(int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay,
201 const std::string& tspt_name, std::unordered_map<int, b_transport_info>& cont,
202 bool is_id_used);
203
204 void bf_b_transport(tlm::tlm_generic_payload& txn, sc_core::sc_time& delay);
205
206 unsigned int transport_dbg(int id, tlm::tlm_generic_payload& trans);
207
208 bool get_direct_mem_ptr(int id, tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data);
209
210 void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end);
211
212 void exec_if_py_fn_exist(const char* fn_name);
213
214 void before_end_of_elaboration() override;
215
216 void end_of_elaboration() override;
217
218 void start_of_simulation() override;
219
220 void end_of_simulation() override;
221
222 void target_signal_cb(int id, bool value);
223
224 void exec_py_b_transport();
225
226 void exec_py_spawned_sc_thread();
227
228 void stage_callback(const sc_core::sc_stage& stage) override;
229
230 void method_thread();
231
232public:
233 cci::cci_param<std::string> p_py_mod_name;
234 cci::cci_param<std::string> p_py_mod_dir;
235 cci::cci_param<std::string> p_py_mod_args;
236 cci::cci_param<std::string> p_py_mod_current_mod_id_prefix;
237 cci::cci_param<uint32_t> p_tlm_initiator_ports_num;
238 cci::cci_param<uint32_t> p_tlm_target_ports_num;
239 cci::cci_param<uint32_t> p_initiator_signals_num;
240 cci::cci_param<uint32_t> p_target_signals_num;
241 cci::cci_param<uint32_t> p_bf_socket_num;
242 sc_core::sc_vector<tlm_initiator_socket_t> initiator_sockets;
243 sc_core::sc_vector<tlm_target_socket_t> target_sockets;
244 sc_core::sc_vector<InitiatorSignalSocket<bool>> initiator_signal_sockets;
245 sc_core::sc_vector<TargetSignalSocket<bool>> target_signal_sockets;
246 sc_core::sc_vector<gs::biflow_socket<python_binder<BUSWIDTH>>> bf_socket;
247
248private:
249 pybind11::module_ m_main_mod;
250 pybind11::module_ m_tlm_do_b_transport_mod;
251 pybind11::module_ m_biflow_socket_mod;
252 pybind11::module_ m_initiator_signal_socket_mod;
253 pybind11::module_ m_cpp_shared_vars_mod;
254 std::unordered_map<int, b_transport_info> m_btspt_cont;
255 std::unordered_map<int, b_transport_info> m_bftspt_cont;
256 std::unordered_map<int, std::pair<bool, std::shared_ptr<sc_core::sc_event>>> m_target_signals_cont;
257 std::unique_ptr<std::thread> m_btspt_method_thread;
258 b_transport_th_info m_btspt_info;
259 std::condition_variable m_btspt_cv;
260 std::mutex m_btspt_mutex;
261 bool m_btspt_ready;
262 bool m_btspt_thread_stop;
263};
264// Explicit template instantiation declarations (for consumers of the library)
265#if defined(_WIN32) && !defined(python_binder_EXPORTS)
266extern template class python_binder<32>;
267extern template class python_binder<64>;
268#endif
269
270} // namespace gs
271
272extern "C" void module_register();
273
274#endif
Definition target.h:160
Definition python_binder.h:159
Definition python_binder.h:71
Definition python_binder.h:56
Definition python_binder.h:174
Definition python_binder.h:86
Tool which reads a Lua configuration file and sets parameters.
Definition biflow.cc:10