17#ifndef _SCC_SC_VARIABLE_H_
18#define _SCC_SC_VARIABLE_H_
26#include <sysc/kernel/sc_event.h>
27#include <sysc/kernel/sc_simcontext.h>
28#include <sysc/tracing/sc_trace.h>
49struct sc_variable_b : sc_core::sc_object {
56 sc_variable_b(
const char* name)
57 : sc_core::sc_object(name) {}
59 sc_variable_b() =
delete;
60 sc_variable_b(sc_variable_b
const&) =
delete;
61 sc_variable_b(sc_variable_b&&) =
delete;
62 sc_variable_b& operator=(
const sc_variable_b& other) =
delete;
63 sc_variable_b& operator=(sc_variable_b&& other) =
delete;
71 const char*
kind()
const {
return "sc_variable"; }
78 virtual std::string
to_string()
const {
return ""; };
88template <
typename T>
struct sc_variable :
public sc_variable_b {
103 const T* operator->() {
return &value; }
112 : sc_variable_b(name.c_str())
129 std::stringstream ss;
137 T
get()
const {
return value; }
142 operator bool()
const {
return value; }
148 operator T()
const {
return value; }
233 T operator+=(
const T other) {
239 T operator-=(
const T other) {
245 T operator*=(
const T other) {
251 T operator/=(
const T other) {
257 T operator+(
const T other)
const {
return value + other; }
258 T operator-(
const T other)
const {
return value - other; }
259 T
operator*(
const T other)
const {
return value * other; }
260 T operator/(
const T other)
const {
return value / other; }
261 T operator+(
const this_type& other)
const {
return value + other.value; }
262 T operator-(
const this_type& other)
const {
return value - other.value; }
263 T
operator*(
const this_type& other)
const {
return value * other.value; }
264 T operator/(
const this_type& other)
const {
return value / other.value; }
271 void trace(sc_core::sc_trace_file* tf)
const override {
272 if(
auto* obs =
dynamic_cast<observer*
>(tf))
273 hndl.push_back(observe(obs, value, name()));
275 sc_core::sc_trace(tf, value, name());
278 void trace(
observer* obs)
const override { hndl.push_back(observe(obs, value, name())); }
281 creator(T
const& default_val)
282 : default_val{default_val} {}
293 mutable std::vector<observer::notification_handle*> hndl;
297template <
typename T> T operator-(sc_variable<T>
const& a, sc_variable<T>
const& b) {
return a.get() - b.get(); }
300template <
typename T> T operator+(T
const& a,
sc_variable<T> const& b) {
return a + b.get(); }
301template <
typename T> T operator-(T
const& a,
sc_variable<T> const& b) {
return a - b.get(); }
302template <
typename T> T operator*(T
const& a,
sc_variable<T> const& b) {
return a * b.get(); }
303template <
typename T> T operator/(T
const& a,
sc_variable<T> const& b) {
return a / b.get(); }
308template <>
struct sc_variable<bool> :
public sc_variable_b {
309 const bool&
operator*() {
return value; }
310 sc_variable(
const std::string& name,
const bool& value)
311 : sc_variable_b(name.c_str())
317 sc_variable& operator=(sc_variable<bool>&& other) =
delete;
318 virtual ~sc_variable() =
default;
320 std::stringstream ss;
324 bool get()
const {
return value; }
325 operator bool()
const {
return value; }
338 bool operator==(
bool other)
const {
return value == other; }
339 bool operator!=(
bool other)
const {
return value != other; }
340 void trace(sc_core::sc_trace_file* tf)
const override {
341 if(
auto* obs =
dynamic_cast<observer*
>(tf))
342 hndl.push_back(observe(obs, value, name()));
344 sc_core::sc_trace(tf, value, name());
346 void trace(observer* obs)
const override { hndl.push_back(observe(obs, value, name())); }
349 creator(
bool const& default_val)
350 : default_val{default_val} {}
351 sc_variable<bool>* operator()(
const char* n,
size_t i) {
return new sc_variable<bool>(n, default_val); }
359 mutable std::vector<observer::notification_handle*> hndl;
370template <
typename T>
struct sc_variable_vector {
372 sc_variable_vector(std::string
const& name,
size_t size)
377 sc_variable_vector(std::string
const& name,
size_t size, T
const& def_val)
379 resize(size, def_val);
382 sc_variable_vector(std::string
const& name,
size_t size, std::function<
sc_variable<T>*(
char const*,
size_t)> creator)
385 , creator(std::move(creator)) {}
387 size_t size()
const {
return values.size(); }
389 void resize(
size_t sz) {
390 assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
394 void resize(
size_t sz, T
const& def_val) {
395 assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
396 auto old_size = values.size();
399 for(
size_t i = old_size; i < sz; ++i) {
400 std::stringstream ss;
401 ss << name <<
"(" << i <<
")";
402 values[i] = scc::make_unique<sc_variable<T>>(ss.str().c_str(), def_val);
406 bool is_valid(
size_t idx)
const {
return values.size() > idx && values.at(idx) !=
nullptr; }
409 auto& ret = values.at(idx);
411 if(sc_core::sc_get_curr_simcontext()->elaboration_done())
412 SCCFATAL(sc_core::sc_get_current_object()->name()) <<
"Trying to create a sc_variable vector entry in " << name
413 <<
" with index " << idx <<
" while elaboration finished is not allowed";
414 assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
416 std::stringstream ss;
417 ss << name <<
"(" << idx <<
")";
418 ret.reset(creator(ss.str().c_str(), idx));
424 assert(values.at(idx) &&
"No initialized value in sc_variable_vector position");
425 return *values.at(idx);
430 std::vector<std::unique_ptr<sc_variable<T>>> values;
431 std::function<sc_variable<T>*(
char const*, size_t)> creator;
441template <
typename T>
struct sc_ref_variable :
public sc_variable_b {
461 , active_notification(active_notification) {}
463 virtual ~sc_ref_variable() =
default;
471 std::stringstream ss;
481 void trace(sc_core::sc_trace_file* tf)
const override {
482 if(active_notification)
483 if(
auto* obs =
dynamic_cast<observer*
>(tf)) {
484 hndl.push_back(observe(obs,
value, name()));
487 sc_core::sc_trace(tf,
value, name());
490 void trace(
observer* obs)
const override { hndl.push_back(observe(obs,
value, name())); }
492 void notify()
const {
498 const bool active_notification;
500 mutable std::vector<observer::notification_handle*> hndl;
502template <>
struct sc_ref_variable<sc_core::sc_event> :
public sc_variable_b {
503 const sc_core::sc_event& value;
504 const sc_core::sc_event&
operator*() {
return value; }
505 sc_ref_variable(
const std::string& name,
const sc_core::sc_event& value)
506 : sc_variable_b(name.c_str())
509 std::stringstream ss;
516 void trace(sc_core::sc_trace_file* tf)
const override { sc_core::sc_trace(tf,
value, name()); }
524template <
typename T>
struct sc_ref_variable_masked :
public sc_variable_b {
529 sc_ref_variable_masked(
const std::string& name,
const T& value,
int width)
530 : sc_variable_b(name.c_str())
532 , mask((1 << width) - 1) {}
534 virtual ~sc_ref_variable_masked() =
default;
537 std::stringstream ss;
538 ss << (value & mask);
544 void trace(sc_core::sc_trace_file* tf)
const override { sc_core::sc_trace(tf, value, name()); }
550template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_variable<T>&
object,
const char* name) {
object.trace(tf); }
551template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_variable<T>*
object,
const char* name) {
object->trace(tf); }
553template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_ref_variable<T>&
object,
const char* name) {
object.trace(tf); }
554template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_ref_variable<T>*
object,
const char* name) {
object->trace(tf); }
SCC SystemC tracing utilities.
The interface defining an observer.
std::string to_string() const override
retrieve the textual representation of the value
std::string to_string() const override
retrieve the textual representation of the value
the sc_ref_variable for a particular plain data type. This marks an existing C++ variable as discover...
const T & value
the wrapped value
std::string to_string() const override
create a textual representation of the wrapped value
void trace(sc_core::sc_trace_file *tf) const override
register the value with the SystemC trace implementation
const T & operator*()
get a reference to the wrapped value
std::string to_string() const override
retrieve the textual representation of the value
virtual std::string to_string() const
retrieve the textual representation of the value
const char * kind() const
get the kind of this sc_object
void trace(sc_core::sc_trace_file *tf) const override
register the value with the SystemC trace implementation
bool operator==(T other) const
bool operator<=(T other) const
T operator++(int)
overloaded postfix ++ operator
bool operator!=(T other) const
bool operator<(T other) const
std::string to_string() const override
create a textual representation of the wrapped value
const T & operator*()
get a reference to the wrapped value
bool operator>=(T other) const
sc_variable(const std::string &name, const T &value)
constructor taking a name and a reference of the variable to be wrapped
bool operator>(T other) const
sc_variable & operator++()
overloaded prefix ++ operator
sc_variable & operator--()
overloaded prefix – operator
T get() const
value getter
T operator--(int)
overloaded postfix – operator