quic/qbox
Loading...
Searching...
No Matches
cciutils.h
1/*
2 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 * Author: GreenSocs 2022
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#ifndef CCIUTILS_H
9#define CCIUTILS_H
10
11#include <scp/report.h>
12#include <iostream>
13#include <list>
14#include <regex>
15#include <unordered_set>
16
17#include "luafile_tool.h"
18#include <cci_configuration>
19#define SC_INCLUDE_DYNAMIC_PROCESSES
20#include <systemc>
21#include <tlm>
22#include <tuple>
23
24/*********************
25 * CCI Convenience
26 *********************/
27
28namespace gs {
29using namespace cci;
30
37template <typename, typename... U>
38class cci_function; // undefined
39template <typename T, typename... U>
40class cci_function<T(U...)> : public std::function<T(U...)>
41{
42 using std::function<T(U...)>::function;
43
44public:
45 // add operater== as required by CCI
46 bool operator==(const cci_function& rhs) const
47 {
48 assert(false);
49 return false;
50 }
51};
52
58class cci_constructor_vl : public std::function<sc_core::sc_module*(sc_core::sc_module_name, cci::cci_value_list)>
59{
60 using std::function<sc_core::sc_module*(sc_core::sc_module_name, cci::cci_value_list)>::function;
61
62 /* local 'apply' helper */
63 template <typename _T, typename... U, size_t... I>
64 _T* new_t(sc_core::sc_module_name name, std::tuple<U...> tuple, std::index_sequence<I...>)
65 {
66 (void)tuple; // mark tupal as used for older compilers.
67 return new _T(name, std::get<I>(tuple)...);
68 }
69
70public:
76 template <typename T, typename... U>
78 {
79 public:
80 const char* type;
81 FactoryMaker<T, U...>(const char* _t): type(_t) {}
82 };
83
84 const char* type; // maintain a string representation of the type.
85
93 template <typename _T, typename... U>
95 : std::function<sc_core::sc_module*(sc_core::sc_module_name name, cci::cci_value_list v)>(
96 [&](sc_core::sc_module_name name, cci::cci_value_list v) -> sc_core::sc_module* {
97 if (sizeof...(U) != v.size()) {
98 SC_REPORT_ERROR("GS CCI UTILS",
99 ("Wrong number of CCI arguments for module " + std::string(name)).c_str());
100 }
101 int n = 0;
102 try {
103 std::tuple<U...> tuple = { v[n++].get<U>()... };
104 auto is = std::make_index_sequence<sizeof...(U)>{};
105 return new_t<_T, U...>(name, tuple, is);
106 } catch (...) {
107 SC_REPORT_ERROR("GS CCI UTILS",
108 ("CCI argument types dont match for module " + std::string(name)).c_str());
109 }
110 return nullptr;
111 })
112 {
113 type = fm.type;
114 }
115
116 // add operater== as required by CCI
117 bool operator==(const cci_constructor_vl& rhs) const
118 {
119 SCP_FATAL("cciutils.operator") << "Operator required by CCI";
120 return false;
121 }
122};
123
131sc_core::sc_object* find_sc_obj(sc_core::sc_object* m, std::string name, bool test = false);
132
139template <typename T>
140std::vector<T*> find_sc_objects(sc_core::sc_object* m = nullptr)
141{
142 std::vector<T*> res;
143 if (m) {
144 T* o = dynamic_cast<T*>(m);
145 if (o) res.push_back(o);
146 }
147 std::vector<sc_core::sc_object*> children;
148 if (m) {
149 children = m->get_child_objects();
150 } else {
151 children = sc_core::sc_get_top_level_objects();
152 }
153 for (auto o : children) {
154 auto c = find_sc_objects<T>(o);
155 res.insert(res.end(), std::make_move_iterator(c.begin()), std::make_move_iterator(c.end()));
156 }
157 return res;
158}
159
166std::string sc_cci_leaf_name(std::string name);
167
175std::list<std::string> sc_cci_children(sc_core::sc_module_name name);
176
186std::list<std::string> sc_cci_list_items(sc_core::sc_module_name module_name, std::string list_name);
187
188std::string get_parent_name(sc_core::sc_module_name n);
189
190cci::cci_value cci_get(cci::cci_broker_handle broker, std::string name);
191
192template <typename T>
193T cci_get(cci::cci_broker_handle broker, std::string name)
194{
195 T ret{};
196 cci_value v = cci_get(broker, name);
197
198 if (!v.template try_get<T>(ret)) {
199 SCP_ERR("cciutils.cci_get") << "Unable to get parameter " << name << "\nIs your config file up-to-date?";
200 }
201 return ret;
202}
203
204template <typename T>
205T cci_get_d(cci::cci_broker_handle broker, std::string name, T default_val)
206{
207 T ret{};
208 cci_value v = cci_get(broker, name);
209
210 if (!v.template try_get<T>(ret)) {
211 return default_val;
212 }
213 return ret;
214}
215
216template <typename T>
217bool cci_get(cci::cci_broker_handle broker, std::string name, T& param)
218{
219 return cci_get(broker, name).try_get<T>(param);
220}
221
222class HelpSingleton : public sc_core::sc_module
223{
224public:
225 static HelpSingleton* GetInstance();
226 std::set<std::string> m_unused;
227 std::set<std::string> m_used;
228 std::set<std::string> m_capture;
229
230 void start_of_simulation()
231 {
232 if (!m_unused.empty()) {
233 SCP_WARN("Param check") << "";
234 SCP_WARN("Param check") << "Unused Parameters:";
235 SCP_WARN("Param check") << "===================================";
236 for (auto p : m_unused) {
237 SCP_WARN("Param check") << "Params: Unused parameter : " << p;
238 }
239 }
240 }
241
242 std::vector<std::tuple<std::string, std::string, std::string>> get_used_parameters(cci::cci_broker_handle broker,
243 std::string path = "",
244 bool print_params = true)
245 {
246 std::vector<std::tuple<std::string, std::string, std::string>> ret; // tuple<param_name, param_val, param_desc>
247 bool found_match = false;
248 for (auto v : m_used) {
249 if (v.rfind(path, 0) == 0) {
250 cci::cci_value c = cci_get(broker, v);
251 if (c.to_json() == "null") {
252 if (print_params) std::cout << "Configurable Parameters: " << v << " the value is not set";
253 } else {
254 if (print_params) std::cout << "Configurable Parameters: " << v << " the value is: " << c.to_json();
255 }
256 auto h = broker.get_param_handle(v);
257 std::string param_desc = "null";
258 if (h.is_valid()) {
259 param_desc = h.get_description();
260 if (print_params) std::cout << " (" << param_desc << ")";
261 }
262 if (print_params) std::cout << std::endl;
263 found_match = true;
264 ret.push_back(std::make_tuple(v, c.to_json(), param_desc));
265 }
266 }
267 if (!path.empty() && !found_match) {
268 SCP_FATAL("cciutils") << "No parameter matching '" << path << "'.";
269 }
270 return ret;
271 }
272
273 void set_unused(const std::string& parname, const cci_originator& originator)
274 {
275 if (m_capture.find(originator.name()) != m_capture.end()) m_unused.insert(parname);
276 }
277
278 void capture_originator(std::string name) { m_capture.insert(name); }
279
280 void clear_unused(const std::string& parname)
281 {
282 m_used.insert(parname);
283 auto iter = m_unused.find(parname);
284 if (iter != m_unused.end()) {
285 m_unused.erase(iter);
286 }
287 }
288
289private:
291 static HelpSingleton* pHelpSingleton;
292};
293
300class ConfigurableBroker : public cci_utils::consuming_broker
301{
302private:
303 std::set<std::string> m_unignored; // before conf_file
304
305public:
306 // a set of perameters that should be exposed up the broker stack
307 HelpSingleton* m_help_helper;
308 std::set<std::string> hide;
309 friend class PrivateConfigurableBroker;
310
311protected:
312 std::string m_orig_name;
313 cci_originator m_originator;
314 bool has_parent;
315 cci_broker_if& m_parent;
317
318 std::unordered_set<std::string> m_initialized;
319 std::function<void(std::string)> m_uninitialized_cb;
320
322
323 // convenience function for constructor
324 cci_broker_if& get_parent_broker()
325 {
326 if (sc_core::sc_get_current_object()) {
327 has_parent = true;
329 } else {
330 // We ARE the global broker
331 has_parent = false;
332 return *this;
333 }
334 }
335 std::string hierarchical_name()
336 {
337 if (!sc_core::sc_get_current_object()) {
338 return std::string("");
339 } else {
340 return cci_originator().name();
341 }
342 }
343 cci_originator get_cci_originator(const char* n)
344 {
345 if (!sc_core::sc_get_current_object()) {
346 return cci_originator(n);
347 } else {
348 return cci_originator();
349 }
350 }
351 inline bool is_log_param(const std::string& parname) const
352 {
355 int p_len = parname.length();
359 } else {
360 return false;
361 }
362 }
367 virtual bool sendToParent(const std::string& parname) const
368 {
369 if (m_uninitialized_cb && (!is_log_param(parname))) {
370 while (1) {
371 auto pos = std::string::npos;
372 pos = parname.find_last_of('.', pos);
373 if (pos == std::string::npos) break;
374 auto parent = parname.substr(0, pos);
375 if (m_initialized.count(parent) != 0) break;
376 const_cast<ConfigurableBroker*>(this)->m_initialized.insert(parent);
377 m_uninitialized_cb(parent);
378 }
379 }
380 return ((hide.find(parname) == hide.end()) && (!is_global_broker()));
381 }
382
388 void initialize_params(const std::initializer_list<cci_name_value_pair>& list)
389 {
390 using namespace cci;
391
392 for (auto& p : list) {
393 hide.insert(relname(p.first));
394 if (!p.second.is_null()) {
395 set_preset_cci_value(relname(p.first), p.second, m_originator);
396 }
397 }
398 }
399
400 void alias_params(const std::initializer_list<std::pair<std::string, std::string>>& list)
401 {
402 // handle aliases
403 for (auto& p : list) {
404 std::string aliasname = relname(p.second);
405 set_preset_cci_value(relname(p.first), get_preset_cci_value(aliasname), m_originator);
406 alias_param(relname(p.first), aliasname);
407 }
408 }
415 void untyped_post_write_callback(const cci::cci_param_write_event<>& ev, cci::cci_param_handle synced_handle)
416 {
417 synced_handle.set_cci_value(ev.new_value);
418 }
428 void sync_values(cci::cci_param_handle _param_handle_1, cci::cci_param_handle _param_handle_2)
429 {
430 // In order to synchronize even the default values of the owner modules,
431 // use cci_base_param of one parameter as reference, write the same value
432 // to the other pararmeter's cci_base_param using JSON
433 _param_handle_1.set_cci_value(_param_handle_2.get_cci_value());
434
435 post_write_cb_vec.push_back(_param_handle_1.register_post_write_callback(
436 sc_bind(&ConfigurableBroker::untyped_post_write_callback, this, sc_unnamed::_1, _param_handle_2)));
437
438 post_write_cb_vec.push_back(_param_handle_2.register_post_write_callback(
439 sc_bind(&ConfigurableBroker::untyped_post_write_callback, this, sc_unnamed::_1, _param_handle_1)));
440 }
441
442 std::vector<cci::cci_callback_untyped_handle> post_write_cb_vec;
443
445 std::vector<std::pair<std::string, std::string>> alias_list;
446
447 void alias_param(std::string a, std::string b)
448 {
449 alias_list.push_back(std::make_pair(a, b));
450 if (register_cb == cci_param_create_callback_handle()) {
451 register_cb = register_create_callback(
452 sc_bind(&ConfigurableBroker::alias_param_callback, this, sc_unnamed::_1), m_originator);
453 }
454 alias_param_callback(cci::cci_param_handle());
455 }
456
457 void alias_param_callback(const cci_param_untyped_handle& ph)
458 {
459 alias_list.erase(std::remove_if(alias_list.begin(), alias_list.end(),
460 [&](auto a) {
461 cci_param_untyped_handle h_a = get_param_handle(a.first, m_originator);
462 if (h_a.is_valid() && h_a.get_mutable_type() == cci::CCI_IMMUTABLE_PARAM) {
463 return true;
464 }
465 cci_param_untyped_handle h_b = get_param_handle(a.second, m_originator);
466 if (h_b.is_valid() && !h_a.is_valid()) {
467 set_preset_cci_value(a.first, h_b.get_cci_value(), m_originator);
468 return false; // maybe it'll be mutable when it arrives?
469 }
470 if (h_a.is_valid() && h_b.is_valid()) {
472 return true;
473 }
474 return false;
475 }),
476 alias_list.end());
477
478 if (alias_list.size() == 0) {
479 unregister_create_callback(register_cb, m_originator);
480 }
481 }
482
483public:
484 /*
485 * public interface functions
486 */
487
488 std::vector<cci_name_value_pair> get_consumed_preset_values() const
489 {
490 std::vector<cci_name_value_pair> consumed_preset_cci_values;
491 std::map<std::string, cci_value>::const_iterator iter;
492 std::vector<cci_preset_value_predicate>::const_iterator pred;
493
494 for (iter = m_unused_value_registry.begin(); iter != m_unused_value_registry.end(); ++iter) {
496 ++pred) {
497 const cci_preset_value_predicate& p = *pred; // get the actual predicate
498 if (p(std::make_pair(iter->first, iter->second))) {
499 break;
500 }
501 }
503 consumed_preset_cci_values.push_back(std::make_pair(iter->first, iter->second));
504 }
505 }
507 }
508
516#define BROKERNAME "gs::ConfigurableBroker"
517 ConfigurableBroker(const std::string& name = BROKERNAME,
518 std::function<void(std::string)> uninitialized_cb = nullptr)
519 : consuming_broker(hierarchical_name() + "." + name)
520 , m_help_helper(HelpSingleton::GetInstance())
521 , m_orig_name(hierarchical_name())
522 , m_originator(get_cci_originator(name.c_str()))
523 , m_parent(get_parent_broker()) // local convenience function
524 , m_child_ref(NULL)
525 , m_uninitialized_cb(uninitialized_cb)
526
527 {
528 if (has_parent) {
529 m_child_ref = new cci_param<ConfigurableBroker*>((name + ".childbroker").c_str(), (this), "");
530 }
531
533 }
534
541 ConfigurableBroker(std::initializer_list<cci_name_value_pair> list,
542 std::initializer_list<std::pair<std::string, std::string>> alias_list = {},
543 std::function<void(std::string)> uninitialized_cb = nullptr)
545 {
546 initialize_params(list);
547 alias_params(alias_list);
548 }
549
550 std::string relname(const std::string& n) const
551 {
552 return (m_orig_name.empty()) ? n : m_orig_name + std::string(".") + n;
553 }
554
555 ~ConfigurableBroker()
556 {
557 if (m_child_ref) {
558 delete m_child_ref;
559 }
560 }
561
562 void set_uninitialized_cb(std::function<void(std::string)> uninitialized_cb)
563 {
564 m_uninitialized_cb = uninitialized_cb;
565 }
566 void clear_uninitialized_cb() { m_uninitialized_cb = nullptr; }
567
568 cci_originator get_value_origin(const std::string& parname) const override
569 {
570 if (sendToParent(parname)) {
571 return m_parent.get_value_origin(parname);
572 } else {
573 return consuming_broker::get_value_origin(parname);
574 }
575 }
576
577 /* NB missing from upstream CCI 'broker' see
578 * https://github.com/OSCI-WG/cci/issues/258 */
579 bool has_preset_value(const std::string& parname) const override
580 {
581 if (sendToParent(parname)) {
582 return m_parent.has_preset_value(parname);
583 } else {
584 return consuming_broker::has_preset_value(parname);
585 }
586 }
587
588 cci_value get_preset_cci_value(const std::string& parname) const override
589 {
590 if (sendToParent(parname)) {
591 return m_parent.get_preset_cci_value(parname);
592 } else {
593 return consuming_broker::get_preset_cci_value(parname);
594 }
595 }
596
597 void lock_preset_value(const std::string& parname) override
598 {
599 if (sendToParent(parname)) {
600 return m_parent.lock_preset_value(parname);
601 } else {
602 return consuming_broker::lock_preset_value(parname);
603 }
604 }
605
606 cci_value get_cci_value(const std::string& parname,
607 const cci::cci_originator& originator = cci::cci_originator()) const override
608 {
609 if (sendToParent(parname)) {
610 return m_parent.get_cci_value(parname, originator);
611 } else {
612 return consuming_broker::get_cci_value(parname, originator);
613 }
614 }
615
616 void add_param(cci_param_if* par) override
617 {
618 m_help_helper->clear_unused(par->name());
619 if (sendToParent(par->name())) {
620 return m_parent.add_param(par);
621 } else {
622 auto iter = m_unignored.find(par->name());
623 if (iter != m_unignored.end()) {
624 m_unignored.erase(iter);
625 }
626 return consuming_broker::add_param(par);
627 }
628 }
629
630 void remove_param(cci_param_if* par) override
631 {
632 if (sendToParent(par->name())) {
633 return m_parent.remove_param(par);
634 } else {
635 m_unignored.insert(par->name());
636 return consuming_broker::remove_param(par);
637 }
638 }
639
640 // Upstream consuming broker fails to pass get_unconsumed_preset_value to parent
641 std::vector<cci_name_value_pair> get_unconsumed_preset_values() const override
642 {
643 std::vector<cci_name_value_pair> r;
644 for (auto u : m_unignored) {
645 auto p = get_preset_cci_value(u);
646 r.push_back(std::make_pair(u, p));
647 }
648 if (has_parent) {
649 std::vector<cci_name_value_pair> p = m_parent.get_unconsumed_preset_values();
650 r.insert(r.end(), p.begin(), p.end());
651 }
652 return r;
653 }
654
655 // Upstream consuming broker fails to pass ignore_unconsumed_preset_values
656 void ignore_unconsumed_preset_values(const cci_preset_value_predicate& pred) override
657 {
658 if (has_parent) {
659 m_parent.ignore_unconsumed_preset_values(pred);
660 }
661 for (auto u = m_unignored.begin(); u != m_unignored.end();) {
662 if (pred(make_pair(*u, cci_value(0)))) {
663 m_help_helper->clear_unused(*u);
664 u = m_unignored.erase(u);
665 } else {
666 ++u;
667 }
668 }
669 }
670
671 cci_preset_value_range get_unconsumed_preset_values(const cci_preset_value_predicate& pred) const override
672 {
673 return cci_preset_value_range(pred, ConfigurableBroker::get_unconsumed_preset_values());
674 }
675
676 // Functions below here require an orriginator to be passed to the local
677 // method variant.
678
679 void set_preset_cci_value(const std::string& parname, const cci_value& cci_value,
680 const cci_originator& originator) override
681 {
682 m_help_helper->set_unused(parname, originator);
683 if (sendToParent(parname)) {
684 return m_parent.set_preset_cci_value(parname, cci_value, originator);
685 } else {
686 m_unignored.insert(parname);
687 return consuming_broker::set_preset_cci_value(parname, cci_value, originator);
688 }
689 }
690
691 cci_param_untyped_handle get_param_handle(const std::string& parname,
692 const cci_originator& originator) const override
693 {
694 if (sendToParent(parname)) {
695 return m_parent.get_param_handle(parname, originator);
696 }
698 if (orig_param) {
700 }
701 if (has_parent) {
702 return m_parent.get_param_handle(parname, originator);
703 }
705 }
706
707 std::vector<cci_param_untyped_handle> get_param_handles(const cci_originator& originator) const override
708 {
709 if (has_parent) {
710 std::vector<cci_param_untyped_handle> p_param_handles = m_parent.get_param_handles();
711 std::vector<cci_param_untyped_handle> param_handles = consuming_broker::get_param_handles(originator);
712 // this is likely to be more efficient the other way round, but it keeps
713 // things consistent and means the local (more useful) params will be at
714 // the head of the list.
715 param_handles.insert(param_handles.end(), p_param_handles.begin(), p_param_handles.end());
716 return param_handles;
717 } else {
718 return consuming_broker::get_param_handles(originator);
719 }
720 }
721
722 bool is_global_broker() const override { return (!has_parent); }
723}; // namespace gs
724
726{
727 std::string m_name;
728 unsigned m_name_length;
729 std::set<std::string> parent;
730 bool sendToParent(const std::string& parname) const override
731 {
732 if (m_uninitialized_cb) {
733 auto pos = parname.find_last_of('.');
734 if (pos != std::string::npos) {
735 auto p = parname.substr(0, pos);
736 if (m_uninitialized_cb && m_initialized.count(p) == 0) {
737 const_cast<PrivateConfigurableBroker*>(this)->m_initialized.insert(p);
738 m_uninitialized_cb(p);
739 }
740 }
741 }
742
743 if (parent.count(parname) > 0) {
744 return true;
745 }
746 if (parname.substr(0, m_name_length) == m_name) {
747 return false;
748 } else {
749 return true;
750 }
751 }
752
753public:
755 {
756 m_name = hierarchical_name();
757 m_name_length = m_name.length();
758
759 auto uncon = m_parent.get_unconsumed_preset_values(
760 [&](const std::pair<std::string, cci_value>& iv) { return iv.first.find(m_name + ".") == 0; });
761 for (auto p : uncon) {
762 parent.insert(p.first);
763 }
764 }
765
766 virtual std::vector<cci_name_value_pair> get_unconsumed_preset_values() const override
767 {
768 std::vector<cci_name_value_pair> r;
769 for (auto u : m_unignored) {
770 auto p = get_preset_cci_value(u);
771 r.push_back(std::make_pair(u, p));
772 }
773 return r;
774 }
775 cci_preset_value_range get_unconsumed_preset_values(const cci_preset_value_predicate& pred) const override
776 {
777 return cci_preset_value_range(pred, PrivateConfigurableBroker::get_unconsumed_preset_values());
778 }
779};
780
781void cci_clear_unused(cci::cci_broker_handle broker, std::string name);
782
783template <typename T>
784std::vector<T> cci_get_vector(cci::cci_broker_handle broker, const std::string base)
785{
786 std::vector<T> ret;
787 for (std::string s : sc_cci_children(base.c_str())) {
788 if (std::count_if(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c); })) {
789 ret.push_back(cci_get<T>(broker, base + "." + s));
790 }
791 }
792 return ret;
793}
794
795} // namespace gs
796
801template <>
802struct cci::cci_value_converter<sc_core::sc_object*> {
803 typedef sc_core::sc_object* type;
804 static bool pack(cci::cci_value::reference dst, type const& src)
805 {
806 dst.set_string(src->name());
807 return true;
808 }
809 static bool unpack(type& dst, cci::cci_value::const_reference src)
810 {
811 if (!src.is_string()) {
812 return false;
813 }
814 std::string name;
815 if (!src.try_get(name)) {
816 return false;
817 }
818 sc_assert(name[0] == '&');
819 dst = gs::find_sc_obj(nullptr, name.substr(1));
820 return true;
821 }
822};
823
829template <typename T, typename... U>
830struct cci::cci_value_converter<gs::cci_function<T(U...)>> {
831 typedef gs::cci_function<T(U...)> type;
832 static bool pack(cci::cci_value::reference dst, type const& src)
833 {
834 // unimplemented
835 return false;
836 }
837 static bool unpack(type& dst, cci::cci_value::const_reference src)
838 {
839 // unimplemented
840 return false;
841 }
842};
843
844template <>
845struct cci::cci_value_converter<gs::ConfigurableBroker*> {
847 static bool pack(cci_value::reference dst, type const& src)
848 {
849 dst.set_string(src->name());
850 return true;
851 }
852 static bool unpack(type& dst, cci_value::const_reference src) { return false; }
853};
854
855#endif // CCIUTILS_H
Definition target.h:160
Configurable Broker class, inherits from the 'standard' cci_utils broker, but adds 1/ The ability to ...
Definition cciutils.h:301
ConfigurableBroker(std::initializer_list< cci_name_value_pair > list, std::initializer_list< std::pair< std::string, std::string > > alias_list={}, std::function< void(std::string)> uninitialized_cb=nullptr)
Construct a new Configurable Broker object from list. When constructed with a list of initialised par...
Definition cciutils.h:541
void initialize_params(const std::initializer_list< cci_name_value_pair > &list)
Expose all params that have not been configured.
Definition cciutils.h:388
std::vector< cci::cci_callback_untyped_handle > post_write_cb_vec
Callback Adaptor Objects.
Definition cciutils.h:442
virtual bool sendToParent(const std::string &parname) const
private function to determine if we send to the parent broker or not
Definition cciutils.h:367
void sync_values(cci::cci_param_handle _param_handle_1, cci::cci_param_handle _param_handle_2)
Function for synchronizing the values of cci_parameter of OWNER modules via the PARAM_VALUE_SYNC.
Definition cciutils.h:428
Definition cciutils.h:223
Definition cciutils.h:726
The FactoryMaker carries the type infomation into the constructor functor.
Definition cciutils.h:78
sc_module constructor container for CCI This uses the CCI Function container, and the FactoryMaker in...
Definition cciutils.h:59
cci_constructor_vl(FactoryMaker< _T, U... > fm)
Construct a new cci constructor vl object The FactoryMaker carries the type info into this constructo...
Definition cciutils.h:94
Definition cciutils.h:41
Basic function container for CCI Packing and unpacking are not supported.
Definition cciutils.h:38
Tool which reads a Lua configuration file and sets parameters.
Definition biflow.cc:10
std::list< std::string > sc_cci_children(sc_core::sc_module_name name)
return a list of 'unconsumed' children from the given module name, can be used inside or outside the ...
Definition cciutils.cc:63
std::vector< T * > find_sc_objects(sc_core::sc_object *m=nullptr)
Helper function to find a sc_objects of a given type.
Definition cciutils.h:140
std::string sc_cci_leaf_name(std::string name)
return the leaf name of the given systemc hierarchical name
Definition cciutils.cc:54
sc_core::sc_object * find_sc_obj(sc_core::sc_object *m, std::string name, bool test=false)
Helper function to find a sc_object by fully qualified name throws SC_ERROR if nothing found.
Definition cciutils.cc:18
std::list< std::string > sc_cci_list_items(sc_core::sc_module_name module_name, std::string list_name)
return a list of 'unconsumed' items in the module matching the base name given, plus '_' and a numeri...
Definition cciutils.cc:90