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