scc 2025.09
SystemC components library
cci_broker.cpp
1/*******************************************************************************
2 * Copyright 2022 MINRES Technologies GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17#include "cci_broker.h"
18#include "report.h"
19#include <string>
20#include <util/ities.h>
21namespace {}
22
23namespace scc {
24using namespace cci;
25
26cci_originator cci_broker::get_preset_value_origin(const std::string& parname) const { // TODO: check globs
27 const_cast<cci_broker*>(this)->insert_matching_preset_value(parname);
28 return consuming_broker::get_preset_value_origin(parname);
29}
30
31/*
32 * private function to determine if we send to the parent broker or not
33 */
34bool cci_broker::sendToParent(const std::string& parname) const {
35 return ((expose.find(parname) != expose.end()) && (!is_global_broker()));
36}
37
38/*
39 * public interface functions
40 */
41cci_broker::cci_broker(const std::string& name)
42: consuming_broker(name)
43, m_parent(get_parent_broker()) // local convenience function
44{
45 sc_assert(name.length() > 0 && "Name must not be empty");
46}
47
48cci_broker::~cci_broker() {}
49
50cci_originator cci_broker::get_value_origin(const std::string& parname) const {
51 if(sendToParent(parname)) {
52 return m_parent.get_value_origin(parname);
53 } else {
54 return consuming_broker::get_value_origin(parname);
55 }
56}
57
58void cci_broker::insert_matching_preset_value(const std::string& parname) {
59 bool match = false;
60 for(auto const& e : wildcard_presets) {
61 if(std::regex_match(parname, e.second.rr)) {
62 consuming_broker::set_preset_cci_value(parname, e.second.value, e.second.originator);
63 match = true;
64 break;
65 }
66 }
67 if(match)
68 for(auto const& e : wildcard_locks) {
69 if(std::regex_match(parname, e.second)) {
70 consuming_broker::lock_preset_value(parname);
71 }
72 }
73}
74
75bool cci_broker::has_preset_value(const std::string& parname) const {
76 if(sendToParent(parname)) {
77 return m_parent.has_preset_value(parname);
78 } else if(consuming_broker::has_preset_value(parname)) {
79 return true;
80 } else {
81 const_cast<cci_broker*>(this)->insert_matching_preset_value(parname);
82 return consuming_broker::has_preset_value(parname);
83 }
84}
85
86cci_value cci_broker::get_preset_cci_value(const std::string& parname) const {
87 if(sendToParent(parname)) {
88 return m_parent.get_preset_cci_value(parname);
89 } else if(consuming_broker::has_preset_value(parname)) {
90 return consuming_broker::get_preset_cci_value(parname);
91 } else {
92 const_cast<cci_broker*>(this)->insert_matching_preset_value(parname);
93 return consuming_broker::get_preset_cci_value(parname);
94 }
95}
96
97cci_value cci_broker::get_cci_value(const std::string& parname, const cci::cci_originator& originator) const {
98 if(sendToParent(parname)) {
99 return m_parent.get_cci_value(parname);
100 } else {
101 return consuming_broker::get_cci_value(parname);
102 }
103}
104
105void cci_broker::add_param(cci_param_if* par) {
106 if(sendToParent(par->name())) {
107 return m_parent.add_param(par);
108 } else {
109 return consuming_broker::add_param(par);
110 }
111}
112
113void cci_broker::remove_param(cci_param_if* par) {
114 if(sendToParent(par->name())) {
115 return m_parent.remove_param(par);
116 } else {
117 return consuming_broker::remove_param(par);
118 }
119}
120
121cci_param_untyped_handle cci_broker::get_param_handle(const std::string& parname, const cci_originator& originator) const {
122 if(sendToParent(parname)) {
123 return m_parent.get_param_handle(parname, originator);
124 }
125 cci_param_if* orig_param = get_orig_param(parname);
126 if(orig_param) {
127 return cci_param_untyped_handle(*orig_param, originator);
128 }
129 if(has_parent) {
130 return m_parent.get_param_handle(parname, originator);
131 }
132 return cci_param_untyped_handle(originator);
133}
134
135std::vector<cci_param_untyped_handle> cci_broker::get_param_handles(const cci_originator& originator) const {
136 if(has_parent) {
137 std::vector<cci_param_untyped_handle> p_param_handles = m_parent.get_param_handles();
138 std::vector<cci_param_untyped_handle> param_handles = consuming_broker::get_param_handles(originator);
139 param_handles.insert(param_handles.end(), p_param_handles.begin(), p_param_handles.end());
140 return param_handles;
141 } else {
142 return consuming_broker::get_param_handles(originator);
143 }
144}
145
146bool cci_broker::is_global_broker() const { return (!has_parent); }
147
148void cci_broker::set_preset_cci_value(const std::string& parname, const cci_value& value, const cci_originator& originator) {
149 if(sendToParent(parname)) {
150 return m_parent.set_preset_cci_value(parname, value, originator);
151 } else {
152 try {
153 if(parname.find_first_of("*?[") != std::string::npos) {
154 wildcard_presets.insert(std::pair<std::string, wildcard_entry>(
155 parname, wildcard_entry{std::regex(util::glob_to_regex(parname)), value, originator}));
156 } else if(parname[0] == '^') {
157 wildcard_presets.insert(
158 std::pair<std::string, wildcard_entry>(parname, wildcard_entry{std::regex(parname), value, originator}));
159 } else
160 consuming_broker::set_preset_cci_value(parname, value, originator);
161 } catch(std::regex_error& e) {
162 SCCERR() << "Invalid preset parameter name '" << parname << "', " << e.what();
163 }
164 }
165}
166
167void cci_broker::lock_preset_value(const std::string& parname) {
168 if(sendToParent(parname)) {
169 m_parent.lock_preset_value(parname);
170 } else {
171 try {
172 if(parname.find_first_of("*?[") != std::string::npos) {
173 wildcard_locks.insert(std::pair<std::string, std::regex>(parname, std::regex(util::glob_to_regex(parname))));
174 } else if(parname[0] == '^') {
175 wildcard_locks.insert(std::pair<std::string, std::regex>(parname, std::regex(parname)));
176 } else
177 consuming_broker::lock_preset_value(parname);
178 } catch(std::regex_error& e) {
179 SCCERR() << "Invalid preset parameter name '" << parname << "', " << e.what();
180 }
181 }
182}
183
184#if defined(CWR_SYSTEMC) || defined(MTI_SYSTEMC)
185static cci_broker broker("SCC Global Broker");
186#define STATIC_BROKER
187#endif
188bool init_cci(std::string name) {
189#ifndef STATIC_BROKER
190 thread_local cci_broker broker(name);
191#endif
192 thread_local bool registered{false};
193 if(!registered) {
194 cci::cci_register_broker(broker);
195 registered = true;
196 }
197 return registered;
198}
199} // namespace scc
void lock_preset_value(const std::string &parname) override
Lock a parameter's preset value.
void set_preset_cci_value(const std::string &parname, const cci::cci_value &cci_value, const cci::cci_originator &originator) override
Set a parameter's preset value.
SCC TLM utilities.
std::string glob_to_regex(std::string val)
Definition ities.h:457