63 sc_core::sc_module*
construct_module(std::string moduletype, sc_core::sc_module_name name, cci::cci_value_list args)
66 cci::cci_value
v = cci::cci_value::from_json(
"\"" + moduletype +
"\"");
68 register_module_from_dylib(name);
76 sc_core::sc_module* mod = (
m_fac)(name, args);
78 m_constructedModules.emplace_back(mod);
93 sc_core::sc_module*
construct_module(std::string moduletype, sc_core::sc_module_name name)
99 std::string get_parent_name(
const std::string&
module_name)
104 bool is_container_arg_mod_name(
const std::string& name)
106 if (!this->container_mod_arg)
return false;
120 cci::cci_value_list args;
121 for (
int i = 0; cci::cci_get_broker().has_preset_value(
modulename +
".args." + std::to_string(
i));
i++) {
124 gs::cci_clear_unused(m_broker,
modulename +
".args." + std::to_string(
i));
125 auto arg = cci::cci_get_broker().get_preset_cci_value(
modulename +
".args." + std::to_string(
i));
126 if (
arg.is_string() && std::string(
arg.get_string())[0] ==
'&') {
127 std::string parent = is_container_arg_mod_name(std::string(
arg.get_string()).erase(0, 1))
128 ? get_parent_name(std::string(this->container_mod_arg->name()))
130 if (std::string(
arg.get_string()).find(parent, 1) == std::string::npos)
131 arg.set_string(
"&" + parent +
"." + std::string(
arg.get_string()).erase(0, 1));
138 template <
typename I,
typename T>
139 bool try_bind(sc_core::sc_object*
i_obj, sc_core::sc_object*
t_obj)
141 auto i =
dynamic_cast<I*
>(
i_obj);
142 auto t =
dynamic_cast<T*
>(
t_obj);
146 (
"Binding initiator socket: {}({}) with the target socket: {}({})",
i_obj->name(),
typeid(
i).name(),
147 t_obj->name(),
typeid(
t).name());
155 (
"Binding initiator socket: {}({}) with the target socket: {}({})",
t_obj->name(),
typeid(
i).name(),
156 i_obj->name(),
typeid(
t).name());
179 gs::cci_clear_unused(m_broker,
targetname +
".0");
180 if (m_broker.get_preset_cci_value(
targetname +
".0").is_string()) {
182 std::string
src = m_broker.get_preset_cci_value(
targetname +
".0").get_string();
183 m_broker.set_preset_cci_value(
targetname +
".address", m_broker.get_preset_cci_value(
src +
".address"));
184 m_broker.set_preset_cci_value(
targetname +
".size", m_broker.get_preset_cci_value(
src +
".size"));
187 gs::cci_clear_unused(m_broker,
bindname);
188 if (!m_broker.get_preset_cci_value(
bindname).is_string()) {
191 std::string
initname = m_broker.get_preset_cci_value(
bindname).get_string();
193 if (
initname.at(0) !=
'&')
continue;
195 if (
initname.find(
';') != std::string::npos) {
211 template <
unsigned int BIND_BUSWIDTH>
214 if ((try_bind<tlm_utils::multi_init_base<BIND_BUSWIDTH>, tlm::tlm_base_target_socket<BIND_BUSWIDTH>>(
i_obj,
216 (try_bind<tlm_utils::multi_init_base<BIND_BUSWIDTH>, tlm_utils::multi_target_base<BIND_BUSWIDTH>>(
i_obj,
218 (try_bind<tlm::tlm_base_initiator_socket<BIND_BUSWIDTH>, tlm::tlm_base_target_socket<BIND_BUSWIDTH>>(
220 (try_bind<tlm::tlm_base_initiator_socket<BIND_BUSWIDTH>, tlm_utils::multi_target_base<BIND_BUSWIDTH>>(
222 (try_bind<tlm::tlm_base_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_fw_transport_if<>,
223 tlm::tlm_bw_transport_if<>, 1, sc_core::SC_ZERO_OR_MORE_BOUND>,
224 tlm_utils::multi_target_base<BIND_BUSWIDTH>>(
i_obj,
t_obj)) ||
226 (try_bind<tlm::tlm_base_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_fw_transport_if<>,
227 tlm::tlm_bw_transport_if<>, 1, sc_core::SC_ZERO_OR_MORE_BOUND>,
228 tlm::tlm_base_target_socket<BIND_BUSWIDTH>>(
i_obj,
t_obj)) ||
230 tlm::tlm_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1,
231 sc_core::SC_ONE_OR_MORE_BOUND>,
232 tlm::tlm_target_socket<BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND>>(
235 tlm_utils::multi_init_base<BIND_BUSWIDTH>,
236 tlm::tlm_target_socket<BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND>>(
239 tlm::tlm_base_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_fw_transport_if<>, tlm::tlm_bw_transport_if<>, 1,
240 sc_core::SC_ZERO_OR_MORE_BOUND>,
241 tlm::tlm_target_socket<BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND>>(
243 (try_bind<sc_core::sc_port<sc_core::sc_signal_inout_if<bool>, 0, sc_core::SC_ZERO_OR_MORE_BOUND>,
264 std::list<std::string> PriorityConstruct(
void)
266 std::list<std::string> args;
267 std::set<std::string> done;
268 std::list<std::string>
todo;
269 std::string
module_name = std::string(sc_module::name());
273 while (
todo.size() > 0) {
277 std::string name = *
it;
280 if (
arg.is_string()) {
281 std::string
a =
arg.get_string();
283 if (done.count(
a.substr(
module_name.size() + 2)) == 0) {
294 args.push_back(name);
301 for (
auto t :
todo) {
302 SCP_WARN(()) <<
"Module name which is not constructable: " <<
t;
304 SCP_FATAL(()) <<
"Module Not constructable";
310 void register_module_from_dylib(sc_core::sc_module_name name)
313 std::vector<std::string>
lib_types = {
".moduletype",
".dylib_path" };
316 const std::string
base_name = std::string(sc_module::name()) +
"." + std::string(name) + type;
317 if (m_broker.has_preset_value(
base_name)) {
318 libname = std::string(m_broker.get_preset_cci_value(
base_name).get_string()) +
"." +
319 std::string(m_library_loader.get_lib_ext());
323 qemu::LibraryLoaderIface::LibraryIfacePtr
libraryHandle = m_library_loader.load_library(
libname);
326 "Impossible to load the library {}, check the path in the lua file or if the library "
327 "exist in your system. Error: {}",
328 libname, m_library_loader.get_last_error());
333 void (*module_register)() =
nullptr;
335 SCP_INFO(()) <<
"Found module_register in the library " << name;
336 module_register =
reinterpret_cast<void (*)()
>(
libraryHandle->get_symbol(
"module_register"));
339 SCP_WARN(()) <<
"The method module_register has not been found in the library " <<
libname;
343 void ModulesConstruct(
void)
345 for (
auto name : PriorityConstruct()) {
346 auto mod_type_name = std::string(sc_module::name()) +
"." + name +
".moduletype";
348 if (m_broker.has_preset_value(std::string(sc_module::name()) +
"." + name +
".dont_construct")) {
354 SCP_FATAL(()) <<
"The object " << std::string(sc_module::name()) +
"." + name
355 <<
" is not yet constructed";
364 << std::string(sc_module::name()) +
"." + name;
371 (
"Can't automatically handle argument list for module: " +
mod_type).
c_str());
374 m_allModules.push_back(
m);
379 SCP_WARN(()) <<
"The value of the parameter moduletype of the module " << name
380 <<
" is not a string";
386 for (
auto mod : m_allModules) {
391 using tlm_initiator_socket_type = tlm_utils::simple_initiator_socket_b<
392 ContainerBase, DEFAULT_TLM_BUSWIDTH, tlm::tlm_base_protocol_types, sc_core::SC_ZERO_OR_MORE_BOUND>;
393 using tlm_target_socket_type = tlm_utils::simple_target_socket_tagged_b<
394 ContainerBase, DEFAULT_TLM_BUSWIDTH, tlm::tlm_base_protocol_types, sc_core::SC_ZERO_OR_MORE_BOUND>;
397 bool m_defer_modules_construct;
398 std::list<sc_core::sc_module*> m_allModules;
399 std::list<std::shared_ptr<sc_core::sc_module>> m_constructedModules;
401 std::set<qemu::LibraryLoaderIface::LibraryIfacePtr> m_dls;
405 cci::cci_broker_handle m_broker;
406 cci::cci_param<std::string> moduletype;
407 cci::cci_param<uint32_t> p_tlm_initiator_ports_num;
408 cci::cci_param<uint32_t> p_tlm_target_ports_num;
409 cci::cci_param<uint32_t> p_initiator_signals_num;
410 cci::cci_param<uint32_t> p_target_signals_num;
411 sc_core::sc_vector<tlm_initiator_socket_type> initiator_sockets;
412 sc_core::sc_vector<tlm_target_socket_type> target_sockets;
413 sc_core::sc_vector<InitiatorSignalSocket<bool>> initiator_signal_sockets;
414 sc_core::sc_vector<TargetSignalSocket<bool>> target_signal_sockets;
418 std::vector<cci::cci_param<gs::cci_constructor_vl>*> registered_mods;
419 sc_core::sc_object* container_mod_arg;
421 virtual ~ContainerBase()
423 m_constructedModules.reverse();
424 m_constructedModules.clear();
427 std::shared_ptr<sc_core::sc_module> find_module_by_name(
const std::string&
mod_name)
429 auto ret = std::find_if(m_constructedModules.begin(), m_constructedModules.end(),
430 [&](
auto mod) { return (mod && std::string(mod->name()) == mod_name); });
431 if (
ret == m_constructedModules.end()) {
437 template <
typename T>
441 auto ret = std::find_if(m_constructedModules.begin(), m_constructedModules.end(), [&](
auto mod) {
442 return (mod && m_broker.has_preset_value(std::string(mod->name()) +
"." + cci_param_name) &&
443 m_broker.get_preset_cci_value(std::string(mod->name()) +
"." + cci_param_name)
444 .template try_get<T>(ret_val) &&
445 (ret_val == cmp_value));
447 if (
ret == m_constructedModules.end()) {
463 , moduletype(
"moduletype",
"",
"Module type for the TLM container, must be \"Container\"")
464 , p_tlm_initiator_ports_num(
"tlm_initiator_ports_num", 0,
"number of tlm initiator ports")
465 , p_tlm_target_ports_num(
"tlm_target_ports_num", 0,
"number of tlm target ports")
466 , p_initiator_signals_num(
"initiator_signals_num", 0,
"number of initiator signals")
467 , p_target_signals_num(
"target_signals_num", 0,
"number of target signals")
468 , initiator_sockets(
"initiator_socket")
469 , target_sockets(
"target_socket")
470 , initiator_signal_sockets(
"initiator_signal_socket")
471 , target_signal_sockets(
"target_signal_socket")
472 , container_self_reset(
"container_self_reset")
476 SCP_DEBUG(()) <<
"ContainerBase Constructor";
478 initiator_sockets.init(p_tlm_initiator_ports_num.get_value(),
479 [
this](
const char*
n,
int i) { return new tlm_initiator_socket_type(n); });
480 target_sockets.init(p_tlm_target_ports_num.get_value(),
481 [
this](
const char*
n,
int i) { return new tlm_target_socket_type(n); });
482 initiator_signal_sockets.init(p_initiator_signals_num.get_value(),
483 [
this](
const char*
n,
int i) { return new InitiatorSignalSocket<bool>(n); });
484 target_signal_sockets.init(p_target_signals_num.get_value(),
485 [
this](
const char*
n,
int i) { return new TargetSignalSocket<bool>(n); });
487 for (
int i = 0;
i < p_tlm_target_ports_num.get_value();
i++) {
488 target_sockets[
i].register_b_transport(
this, &ContainerBase::b_transport,
i);
489 target_sockets[
i].register_transport_dbg(
this, &ContainerBase::transport_dbg,
i);
490 target_sockets[
i].register_get_direct_mem_ptr(
this, &ContainerBase::get_direct_mem_ptr,
i);
493 for (
int i = 0;
i < p_tlm_initiator_ports_num.get_value();
i++) {
494 initiator_sockets[
i].register_invalidate_direct_mem_ptr(
this, &ContainerBase::invalidate_direct_mem_ptr);
497 for (
int i = 0;
i < p_target_signals_num.get_value();
i++) {
498 target_signal_sockets[
i].register_value_changed_cb([&,
i](
bool value) {
499 if (m_local_pass) m_local_pass->fw_handle_signal(
i, value);
503 container_self_reset.register_value_changed_cb([
this](
bool value) { do_reset(value); });
505 auto mods = gs::ModuleFactory::GetAvailableModuleList();
507 while (
mods->size()) {
508 registered_mods.push_back((
mods->back())());
512 if (!m_defer_modules_construct) ModulesConstruct();
515 void fw_b_transport(
int id, tlm::tlm_generic_payload&
trans, sc_core::sc_time& delay)
override
517 SCP_DEBUG(()) <<
"calling b_transport on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
518 initiator_sockets[id]->b_transport(
trans, delay);
519 SCP_DEBUG(()) <<
"return from b_transport on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
522 unsigned int fw_transport_dbg(
int id, tlm::tlm_generic_payload&
trans)
override
524 SCP_DEBUG(()) <<
"calling transport_dbg on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
525 unsigned int ret = initiator_sockets[id]->transport_dbg(
trans);
526 SCP_DEBUG(()) <<
"return from transport_dbg on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
530 bool fw_get_direct_mem_ptr(
int id, tlm::tlm_generic_payload&
trans, tlm::tlm_dmi& dmi_data)
override
532 SCP_DEBUG(()) <<
"calling get_direct_mem_ptr on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
533 bool ret = initiator_sockets[id]->get_direct_mem_ptr(
trans, dmi_data);
534 SCP_DEBUG(()) <<
"return from get_direct_mem_ptr on initiator_socket_" <<
id <<
" "
535 <<
" RET: " << std::boolalpha <<
ret <<
" " << scp::scp_txn_tostring(
trans)
536 <<
" IS_READ_ALLOWED: " << std::boolalpha << dmi_data.is_read_allowed() <<
" "
537 <<
" IS_WRITE_ALLOWED: " << std::boolalpha << dmi_data.is_write_allowed();
541 void fw_invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
override
543 SCP_DEBUG(()) <<
" " << name() <<
" invalidate_direct_mem_ptr "
544 <<
" start address 0x" << std::hex << start <<
" end address 0x" << std::hex << end;
545 for (
int i = 0;
i < target_sockets.size();
i++) {
546 target_sockets[
i]->invalidate_direct_mem_ptr(start, end);
550 void fw_handle_signal(
int id,
bool value)
override
552 SCP_DEBUG(()) <<
"calling handle_signal on initiator_signal_socket_" <<
id <<
" value: " << std::boolalpha
554 initiator_signal_sockets[id]->write(value);
558 void b_transport(
int id, tlm::tlm_generic_payload&
trans, sc_core::sc_time& delay)
561 m_local_pass->fw_b_transport(
id,
trans, delay);
565 unsigned int transport_dbg(
int id, tlm::tlm_generic_payload&
trans)
568 return m_local_pass->fw_transport_dbg(
id,
trans);
573 bool get_direct_mem_ptr(
int id, tlm::tlm_generic_payload&
trans, tlm::tlm_dmi& dmi_data)
576 return m_local_pass->fw_get_direct_mem_ptr(
id,
trans, dmi_data);
581 void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
584 m_local_pass->fw_invalidate_direct_mem_ptr(start, end);
588 std::vector<std::string> parse_order_str(
const std::string&
reset_order)
590 std::vector<std::string>
ret;
602 std::sregex_token_iterator(), ret.begin());
608 sc_core::sc_object*
i_obj =
nullptr;
609 sc_core::sc_object*
t_obj =
nullptr;
640 virtual void do_reset(
bool value)