scc  2022.4.0
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>
21 namespace {}
22 
23 namespace scc {
24 using namespace cci;
25 
26 cci_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  */
34 bool 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  */
41 cci_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 
48 cci_broker::~cci_broker() {}
49 
50 cci_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 
58 void 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 
75 bool 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 
86 cci_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 
97 cci_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 
105 void 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 
113 void 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 
121 cci_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 
135 std::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 
146 bool cci_broker::is_global_broker() const { return (!has_parent); }
147 
148 void 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 
167 void 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)
185 static cci_broker broker("SCC Global Broker");
186 #define STATIC_BROKER
187 #endif
188 bool 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
SCC SystemC utilities.
std::string glob_to_regex(std::string val)
Definition: ities.h:385