64 sc_core::sc_module*
construct_module(std::string moduletype, sc_core::sc_module_name name, cci::cci_value_list args)
67 cci::cci_value
v = cci::cci_value::from_json(
"\"" + moduletype +
"\"");
69 register_module_from_dylib(name);
77 sc_core::sc_module* mod = (
m_fac)(name, args);
79 m_constructedModules.emplace_back(mod);
94 sc_core::sc_module*
construct_module(std::string moduletype, sc_core::sc_module_name name)
100 std::string get_parent_name(
const std::string&
module_name)
105 bool is_container_arg_mod_name(
const std::string& name)
107 if (!this->container_mod_arg)
return false;
121 cci::cci_value_list args;
122 for (
int i = 0; cci::cci_get_broker().has_preset_value(
modulename +
".args." + std::to_string(
i));
i++) {
125 gs::cci_clear_unused(m_broker,
modulename +
".args." + std::to_string(
i));
126 auto arg = cci::cci_get_broker().get_preset_cci_value(
modulename +
".args." + std::to_string(
i));
127 if (
arg.is_string() && std::string(
arg.get_string())[0] ==
'&') {
128 std::string parent = is_container_arg_mod_name(std::string(
arg.get_string()).erase(0, 1))
129 ? get_parent_name(std::string(this->container_mod_arg->name()))
131 if (std::string(
arg.get_string()).find(parent, 1) == std::string::npos)
132 arg.set_string(
"&" + parent +
"." + std::string(
arg.get_string()).erase(0, 1));
139 template <
typename I,
typename T>
140 bool try_bind(sc_core::sc_object*
i_obj, sc_core::sc_object*
t_obj)
142 auto i =
dynamic_cast<I*
>(
i_obj);
143 auto t =
dynamic_cast<T*
>(
t_obj);
147 (
"Binding initiator socket: {}({}) with the target socket: {}({})",
i_obj->name(),
typeid(
i).name(),
148 t_obj->name(),
typeid(
t).name());
156 (
"Binding initiator socket: {}({}) with the target socket: {}({})",
t_obj->name(),
typeid(
i).name(),
157 i_obj->name(),
typeid(
t).name());
180 gs::cci_clear_unused(m_broker,
targetname +
".0");
181 if (m_broker.get_preset_cci_value(
targetname +
".0").is_string()) {
183 std::string
src = m_broker.get_preset_cci_value(
targetname +
".0").get_string();
184 m_broker.set_preset_cci_value(
targetname +
".address", m_broker.get_preset_cci_value(
src +
".address"));
185 m_broker.set_preset_cci_value(
targetname +
".size", m_broker.get_preset_cci_value(
src +
".size"));
188 gs::cci_clear_unused(m_broker,
bindname);
189 if (!m_broker.get_preset_cci_value(
bindname).is_string()) {
192 std::string
initname = m_broker.get_preset_cci_value(
bindname).get_string();
194 if (
initname.at(0) !=
'&')
continue;
196 if (
initname.find(
';') != std::string::npos) {
212 template <
unsigned int BIND_BUSWIDTH>
215 if ((try_bind<tlm_utils::multi_init_base<BIND_BUSWIDTH>, tlm::tlm_base_target_socket<BIND_BUSWIDTH>>(
i_obj,
217 (try_bind<tlm_utils::multi_init_base<BIND_BUSWIDTH>, tlm_utils::multi_target_base<BIND_BUSWIDTH>>(
i_obj,
219 (try_bind<tlm::tlm_base_initiator_socket<BIND_BUSWIDTH>, tlm::tlm_base_target_socket<BIND_BUSWIDTH>>(
221 (try_bind<tlm::tlm_base_initiator_socket<BIND_BUSWIDTH>, tlm_utils::multi_target_base<BIND_BUSWIDTH>>(
223 (try_bind<tlm::tlm_base_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_fw_transport_if<>,
224 tlm::tlm_bw_transport_if<>, 1, sc_core::SC_ZERO_OR_MORE_BOUND>,
225 tlm_utils::multi_target_base<BIND_BUSWIDTH>>(
i_obj,
t_obj)) ||
227 (try_bind<tlm::tlm_base_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_fw_transport_if<>,
228 tlm::tlm_bw_transport_if<>, 1, sc_core::SC_ZERO_OR_MORE_BOUND>,
229 tlm::tlm_base_target_socket<BIND_BUSWIDTH>>(
i_obj,
t_obj)) ||
231 tlm::tlm_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1,
232 sc_core::SC_ONE_OR_MORE_BOUND>,
233 tlm::tlm_target_socket<BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND>>(
236 tlm_utils::multi_init_base<BIND_BUSWIDTH>,
237 tlm::tlm_target_socket<BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND>>(
240 tlm::tlm_base_initiator_socket<
BIND_BUSWIDTH, tlm::tlm_fw_transport_if<>, tlm::tlm_bw_transport_if<>, 1,
241 sc_core::SC_ZERO_OR_MORE_BOUND>,
242 tlm::tlm_target_socket<BIND_BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND>>(
244 (try_bind<sc_core::sc_port<sc_core::sc_signal_inout_if<bool>, 0, sc_core::SC_ZERO_OR_MORE_BOUND>,
265 std::list<std::string> PriorityConstruct(
void)
267 std::list<std::string> args;
268 std::set<std::string> done;
269 std::list<std::string>
todo;
270 std::string
module_name = std::string(sc_module::name());
274 while (
todo.size() > 0) {
278 std::string name = *
it;
281 if (
arg.is_string()) {
282 std::string
a =
arg.get_string();
284 if (done.count(
a.substr(
module_name.size() + 2)) == 0) {
295 args.push_back(name);
302 for (
auto t :
todo) {
303 SCP_WARN(()) <<
"Module name which is not constructable: " <<
t;
305 SCP_FATAL(()) <<
"Module Not constructable";
311 void register_module_from_dylib(sc_core::sc_module_name name)
315 if (m_broker.has_preset_value(std::string(sc_module::name()) +
"." + std::string(name) +
".moduletype")) {
317 .get_preset_cci_value(std::string(sc_module::name()) +
"." + std::string(name) +
322 if (m_broker.has_preset_value(std::string(sc_module::name()) +
"." + std::string(name) +
".dylib_path")) {
324 .get_preset_cci_value(std::string(sc_module::name()) +
"." + std::string(name) +
330 if (m_broker.has_preset_value(std::string(sc_module::name()) +
"." + std::string(name) +
".moduletype")) {
332 .get_preset_cci_value(std::string(sc_module::name()) +
"." + std::string(name) +
337 if (m_broker.has_preset_value(std::string(sc_module::name()) +
"." + std::string(name) +
".dylib_path")) {
339 .get_preset_cci_value(std::string(sc_module::name()) +
"." + std::string(name) +
345 std::cout <<
"libname =" <<
libname << std::endl;
348 SCP_FATAL(()) <<
"Impossible to load the library check the path in the lua file or if the library "
349 "exist in your system: "
354 if (!module_register) {
355 SCP_WARN(()) <<
"The method module_register has not been found in the class " << name;
360 void ModulesConstruct(
void)
362 for (
auto name : PriorityConstruct()) {
363 auto mod_type_name = std::string(sc_module::name()) +
"." + name +
".moduletype";
365 if (m_broker.has_preset_value(std::string(sc_module::name()) +
"." + name +
".dont_construct")) {
371 SCP_FATAL(()) <<
"The object " << std::string(sc_module::name()) +
"." + name
372 <<
" is not yet constructed";
381 << std::string(sc_module::name()) +
"." + name;
388 (
"Can't automatically handle argument list for module: " +
mod_type).
c_str());
391 m_allModules.push_back(
m);
396 SCP_WARN(()) <<
"The value of the parameter moduletype of the module " << name
397 <<
" is not a string";
403 for (
auto mod : m_allModules) {
408 using tlm_initiator_socket_type = tlm_utils::simple_initiator_socket_b<
409 ContainerBase, DEFAULT_TLM_BUSWIDTH, tlm::tlm_base_protocol_types, sc_core::SC_ZERO_OR_MORE_BOUND>;
410 using tlm_target_socket_type = tlm_utils::simple_target_socket_tagged_b<
411 ContainerBase, DEFAULT_TLM_BUSWIDTH, tlm::tlm_base_protocol_types, sc_core::SC_ZERO_OR_MORE_BOUND>;
414 bool m_defer_modules_construct;
415 std::list<sc_core::sc_module*> m_allModules;
416 std::list<std::shared_ptr<sc_core::sc_module>> m_constructedModules;
418 std::set<void*> m_dls;
421 cci::cci_broker_handle m_broker;
422 cci::cci_param<std::string> moduletype;
423 cci::cci_param<uint32_t> p_tlm_initiator_ports_num;
424 cci::cci_param<uint32_t> p_tlm_target_ports_num;
425 cci::cci_param<uint32_t> p_initiator_signals_num;
426 cci::cci_param<uint32_t> p_target_signals_num;
427 sc_core::sc_vector<tlm_initiator_socket_type> initiator_sockets;
428 sc_core::sc_vector<tlm_target_socket_type> target_sockets;
429 sc_core::sc_vector<InitiatorSignalSocket<bool>> initiator_signal_sockets;
430 sc_core::sc_vector<TargetSignalSocket<bool>> target_signal_sockets;
434 std::vector<cci::cci_param<gs::cci_constructor_vl>*> registered_mods;
435 sc_core::sc_object* container_mod_arg;
437 virtual ~ContainerBase()
439 m_constructedModules.reverse();
440 m_constructedModules.clear();
441 for (
auto l : m_dls) {
446 std::shared_ptr<sc_core::sc_module> find_module_by_name(
const std::string&
mod_name)
448 auto ret = std::find_if(m_constructedModules.begin(), m_constructedModules.end(),
449 [&](
auto mod) { return (mod && std::string(mod->name()) == mod_name); });
450 if (
ret == m_constructedModules.end()) {
456 template <
typename T>
460 auto ret = std::find_if(m_constructedModules.begin(), m_constructedModules.end(), [&](
auto mod) {
461 return (mod && m_broker.has_preset_value(std::string(mod->name()) +
"." + cci_param_name) &&
462 m_broker.get_preset_cci_value(std::string(mod->name()) +
"." + cci_param_name)
463 .template try_get<T>(ret_val) &&
464 (ret_val == cmp_value));
466 if (
ret == m_constructedModules.end()) {
482 , moduletype(
"moduletype",
"",
"Module type for the TLM container, must be \"Container\"")
483 , p_tlm_initiator_ports_num(
"tlm_initiator_ports_num", 0,
"number of tlm initiator ports")
484 , p_tlm_target_ports_num(
"tlm_target_ports_num", 0,
"number of tlm target ports")
485 , p_initiator_signals_num(
"initiator_signals_num", 0,
"number of initiator signals")
486 , p_target_signals_num(
"target_signals_num", 0,
"number of target signals")
487 , initiator_sockets(
"initiator_socket")
488 , target_sockets(
"target_socket")
489 , initiator_signal_sockets(
"initiator_signal_socket")
490 , target_signal_sockets(
"target_signal_socket")
491 , container_self_reset(
"container_self_reset")
495 SCP_DEBUG(()) <<
"ContainerBase Constructor";
497 initiator_sockets.init(p_tlm_initiator_ports_num.get_value(),
498 [
this](
const char*
n,
int i) { return new tlm_initiator_socket_type(n); });
499 target_sockets.init(p_tlm_target_ports_num.get_value(),
500 [
this](
const char*
n,
int i) { return new tlm_target_socket_type(n); });
501 initiator_signal_sockets.init(p_initiator_signals_num.get_value(),
502 [
this](
const char*
n,
int i) { return new InitiatorSignalSocket<bool>(n); });
503 target_signal_sockets.init(p_target_signals_num.get_value(),
504 [
this](
const char*
n,
int i) { return new TargetSignalSocket<bool>(n); });
506 for (
int i = 0;
i < p_tlm_target_ports_num.get_value();
i++) {
507 target_sockets[
i].register_b_transport(
this, &ContainerBase::b_transport,
i);
508 target_sockets[
i].register_transport_dbg(
this, &ContainerBase::transport_dbg,
i);
509 target_sockets[
i].register_get_direct_mem_ptr(
this, &ContainerBase::get_direct_mem_ptr,
i);
512 for (
int i = 0;
i < p_tlm_initiator_ports_num.get_value();
i++) {
513 initiator_sockets[
i].register_invalidate_direct_mem_ptr(
this, &ContainerBase::invalidate_direct_mem_ptr);
516 for (
int i = 0;
i < p_target_signals_num.get_value();
i++) {
517 target_signal_sockets[
i].register_value_changed_cb([&,
i](
bool value) {
518 if (m_local_pass) m_local_pass->fw_handle_signal(
i, value);
522 container_self_reset.register_value_changed_cb([
this](
bool value) { do_reset(value); });
524 auto mods = gs::ModuleFactory::GetAvailableModuleList();
526 while (
mods->size()) {
527 registered_mods.push_back((
mods->back())());
531 if (!m_defer_modules_construct) ModulesConstruct();
534 void fw_b_transport(
int id, tlm::tlm_generic_payload&
trans, sc_core::sc_time& delay)
override
536 SCP_DEBUG(()) <<
"calling b_transport on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
537 initiator_sockets[id]->b_transport(
trans, delay);
538 SCP_DEBUG(()) <<
"return from b_transport on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
541 unsigned int fw_transport_dbg(
int id, tlm::tlm_generic_payload&
trans)
override
543 SCP_DEBUG(()) <<
"calling transport_dbg on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
544 unsigned int ret = initiator_sockets[id]->transport_dbg(
trans);
545 SCP_DEBUG(()) <<
"return from transport_dbg on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
549 bool fw_get_direct_mem_ptr(
int id, tlm::tlm_generic_payload&
trans, tlm::tlm_dmi& dmi_data)
override
551 SCP_DEBUG(()) <<
"calling get_direct_mem_ptr on initiator_socket_" <<
id <<
" " << scp::scp_txn_tostring(
trans);
552 bool ret = initiator_sockets[id]->get_direct_mem_ptr(
trans, dmi_data);
553 SCP_DEBUG(()) <<
"return from get_direct_mem_ptr on initiator_socket_" <<
id <<
" "
554 <<
" RET: " << std::boolalpha <<
ret <<
" " << scp::scp_txn_tostring(
trans)
555 <<
" IS_READ_ALLOWED: " << std::boolalpha << dmi_data.is_read_allowed() <<
" "
556 <<
" IS_WRITE_ALLOWED: " << std::boolalpha << dmi_data.is_write_allowed();
560 void fw_invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
override
562 SCP_DEBUG(()) <<
" " << name() <<
" invalidate_direct_mem_ptr "
563 <<
" start address 0x" << std::hex << start <<
" end address 0x" << std::hex << end;
564 for (
int i = 0;
i < target_sockets.size();
i++) {
565 target_sockets[
i]->invalidate_direct_mem_ptr(start, end);
569 void fw_handle_signal(
int id,
bool value)
override
571 SCP_DEBUG(()) <<
"calling handle_signal on initiator_signal_socket_" <<
id <<
" value: " << std::boolalpha
573 initiator_signal_sockets[id]->write(value);
577 void b_transport(
int id, tlm::tlm_generic_payload&
trans, sc_core::sc_time& delay)
580 m_local_pass->fw_b_transport(
id,
trans, delay);
584 unsigned int transport_dbg(
int id, tlm::tlm_generic_payload&
trans)
587 return m_local_pass->fw_transport_dbg(
id,
trans);
592 bool get_direct_mem_ptr(
int id, tlm::tlm_generic_payload&
trans, tlm::tlm_dmi& dmi_data)
595 return m_local_pass->fw_get_direct_mem_ptr(
id,
trans, dmi_data);
600 void invalidate_direct_mem_ptr(sc_dt::uint64 start, sc_dt::uint64 end)
603 m_local_pass->fw_invalidate_direct_mem_ptr(start, end);
607 std::vector<std::string> parse_order_str(
const std::string&
reset_order)
609 std::vector<std::string>
ret;
621 std::sregex_token_iterator(), ret.begin());
627 sc_core::sc_object*
i_obj =
nullptr;
628 sc_core::sc_object*
t_obj =
nullptr;
659 virtual void do_reset(
bool value)