Skip to content

Commit

Permalink
Merge branch 'origin/feature/scc_broker' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
eyck committed Nov 11, 2022
2 parents eb20c0f + fe02a80 commit b1b9ad0
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 26 deletions.
1 change: 1 addition & 0 deletions src/sysc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ set(LIB_SOURCES
tlm/scc/scv/tlm_recorder.cpp
tlm/scc/pe/parallel_pe.cpp
scc/hierarchy_dumper.cpp
scc/cci_broker.cpp
)

if(ZLIB_FOUND)
Expand Down
108 changes: 108 additions & 0 deletions src/sysc/scc/cci_broker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*******************************************************************************
* Copyright 2022 MINRES Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include <string>
#ifdef HAS_CCI
#include "cci_broker.h"
#include <util/ities.h>
namespace {
bool glob_match(std::string const& s, std::string const& p) {
const char* cp = nullptr;
const char* mp = nullptr;
const char* string = s.c_str();
const char* pat = p.c_str();
while((*string) && (*pat != '*')) {
if((*pat != *string) && (*pat != '?'))
return false;

pat++;
string++;
}
while(*string) {
if(*pat == '*') {
if(!*++pat)
return true;

mp = pat;
cp = string + 1;
} else if((*pat == *string) || (*pat == '?')) {
pat++;
string++;
} else {
pat = mp;
string = cp++;
}
}
while(*pat == '*')
pat++;
return *pat == 0;
}

std::string glob_to_regex(std::string val){
util::trim(val);
const char* expression = "(\\*)|(\\?)|([[:blank:]])|(\\.|\\+|\\^|\\$|\\[|\\]|\\(|\\)|\\{|\\}|\\\\)";
const char* format = "(?1\\\\w+)(?2\\.)(?3\\\\s*)(?4\\\\$&)";
std::ostringstream oss;
oss << "^.*";
std::ostream_iterator<char, char> oi(oss);
std::regex re;
re.assign(expression);
std::regex_replace(oi, val.begin(), val.end(), re, format, std::regex_constants::match_default | std::regex_constants::format_default);
oss << ".*" << std::ends;
return oss.str();
}
}
namespace scc {
using namespace cci;

void cci_broker::set_preset_cci_value(
const std::string &parname,
const cci_value & value,
const cci_originator& originator) {
super::set_preset_cci_value(parname, value, originator);
}

cci_originator cci_broker::get_preset_value_origin(const std::string &parname) const { //TODO: check globs
return super::get_preset_value_origin(parname);
}

cci_value cci_broker::get_preset_cci_value(const std::string &parname) const { //TODO: check globs
return super::get_preset_cci_value(parname);
}

void cci_broker::lock_preset_value(const std::string &parname) {
super::lock_preset_value(parname);
}

cci_value cci_broker::get_cci_value(const std::string &parname, const cci_originator &originator) const {
return consuming_broker::get_cci_value(parname, originator);
}

bool cci_broker::has_preset_value(const std::string &parname) const { //TODO: check globs
return super::has_preset_value(parname);
}

void init_cci(std::string name) {
thread_local cci_broker broker(name);
cci::cci_register_broker(broker);
}
}
#else
namespace scc {
void init_cci(std::string name) {
}
}
#endif
53 changes: 53 additions & 0 deletions src/sysc/scc/cci_broker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright 2022 MINRES Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#ifndef _SYSC_SCC_CCI_BROKER_H_
#define _SYSC_SCC_CCI_BROKER_H_

#include <string>
#include <unordered_map>
#include <unordered_set>
#include <regex>
#include <vector>
#include <cci_utils/broker.h>

namespace scc {
class cci_broker: public cci_utils::broker {
using super = cci_utils::broker;
public:
explicit cci_broker(const std::string& name): cci_utils::broker(name) { }

~cci_broker() = default;

void set_preset_cci_value(
const std::string &parname,
const cci::cci_value & value,
const cci::cci_originator& originator) override;

cci::cci_originator get_preset_value_origin(const std::string &parname) const override;

cci::cci_value get_preset_cci_value(const std::string &parname) const override ;

void lock_preset_value(const std::string &parname) override;

cci::cci_value get_cci_value(const std::string &parname, const cci::cci_originator &originator = cci::cci_originator()) const override;

bool has_preset_value(const std::string &parname) const override;
protected:
std::unordered_map<std::string, std::regex> wildcard_presets;
};
}
#endif // _SYSC_SCC_CCI_BROKER_H_
64 changes: 41 additions & 23 deletions src/sysc/scc/configurer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ inline auto get_sc_objects(sc_core::sc_object* obj = nullptr) -> const std::vect
}

#define FDECL(TYPE, FUNC) \
inline void writeValue(writer_type& writer, std::string const& key, TYPE value) { \
writer.Key(key.c_str()); \
writer.FUNC(value); \
inline void writeValue(writer_type& writer, std::string const& key, TYPE value) { \
writer.Key(key.c_str()); \
writer.FUNC(value); \
}
FDECL(int, Int)
FDECL(unsigned int, Uint)
Expand Down Expand Up @@ -164,13 +164,13 @@ struct config_dumper {
};

#define CHECK_N_ASSIGN(TYPE, ATTR, VAL) \
{ \
auto* a = dynamic_cast<sc_core::sc_attribute<TYPE>*>(ATTR); \
if(a != nullptr) { \
a->value = VAL; \
return; \
} \
}
{ \
auto* a = dynamic_cast<sc_core::sc_attribute<TYPE>*>(ATTR); \
if(a != nullptr) { \
a->value = VAL; \
return; \
} \
}

void try_set_value(sc_core::sc_attr_base* attr_base, Value const& hier_val) {
CHECK_N_ASSIGN(int, attr_base, hier_val.Get<int>());
Expand Down Expand Up @@ -304,15 +304,24 @@ void check_config_hierarchical(configurer::broker_t const& broker, Value const&
auto* obj = sc_core::sc_find_object(objname.c_str());
if(!obj || !obj->get_attribute(attrname.c_str())) {
#ifdef HAS_CCI
auto param_handle = broker.get_param_handle(hier_name);
if(!param_handle.is_valid() && attrname != SCC_LOG_LEVEL_PARAM_NAME)
if(!broker.get_param_handle(hier_name).is_valid() && attrname != SCC_LOG_LEVEL_PARAM_NAME)
#endif
throw std::invalid_argument(hier_name);
}
}
}
}
}

bool cci_name_ignore(std::pair<std::string, cci::cci_value> const& preset_value) {
std::string ending(SCC_LOG_LEVEL_PARAM_NAME);
auto& name = preset_value.first;
if (name.length() >= ending.length()) {
return (0 == name.compare(name.length() - ending.length(), ending.length(), ending));
} else {
return false;
}
}
} // namespace

struct configurer::ConfigHolder {
Expand Down Expand Up @@ -403,25 +412,34 @@ void configurer::set_configuration_value(sc_core::sc_attr_base* attr_base, sc_co
try_set_value(attr_base, val);
}
}

void configurer::config_check() {
try {
if(root)
if(root) {
check_config_hierarchical(cci_broker, root->document, "");
}
#ifdef HAS_CCI
cci_broker.ignore_unconsumed_preset_values(&cci_name_ignore);
auto res = cci_broker.get_unconsumed_preset_values();
if(res.size()) {
std::ostringstream oss;
for(auto& val:res)
oss<<"\t - "<<val.first<<"\n";
if(res.size()==1) {
SCCWARN("scc::configurer")<<"There is " << res.size() << " unused CCI preset value:\n"
<< oss.str() << "Please check your setup!";
} else {
SCCWARN("scc::configurer")<<"There are " << res.size() << " unused CCI preset values:\n"
<< oss.str() << "Please check your setup!";
}
}
#endif
} catch(std::domain_error& e) {
SCCFATAL(this->name()) << "Illegal hierarchy name: '" << e.what() << "'";
SCCFATAL("scc::configurer") << "Illegal hierarchy name: '" << e.what() << "'";
} catch(std::invalid_argument& e) {
SCCFATAL(this->name()) << "Illegal parameter name: '" << e.what() << "'";
SCCFATAL("scc::configurer") << "Illegal parameter name: '" << e.what() << "'";
}
}

void init_cci(std::string name) {
#ifdef HAS_CCI
thread_local cci_utils::broker broker(name);
cci::cci_register_broker(&broker);
#endif
}

void configurer::start_of_simulation() {
if(config_phases & START_OF_SIMULATION) configure();
config_check();
Expand Down
7 changes: 4 additions & 3 deletions src/sysc/scc/configurer.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ class configurer : public sc_core::sc_module {
using broker_t = void*;
#endif
enum {
BEFORE_END_OF_ELABORATION=1, END_OF_ELABORATION=2, START_OF_SIMULATION=4
NEVER=0, BEFORE_END_OF_ELABORATION=1, END_OF_ELABORATION=2, START_OF_SIMULATION=4
};
/**
* create a configurer using an input file
* @param filename
* @param filename the input file to read containing the values to apply
* @param sc_attr_config_phases defines when to apply the values to sc_attribute instances
*/
configurer(const std::string& filename, unsigned config_phases = BEFORE_END_OF_ELABORATION);
configurer(const std::string& filename, unsigned sc_attr_config_phases = BEFORE_END_OF_ELABORATION);

configurer() = delete;

Expand Down

0 comments on commit b1b9ad0

Please sign in to comment.