17#ifndef _SCC_SC_VARIABLE_H_
18#define _SCC_SC_VARIABLE_H_
25#include <sysc/kernel/sc_event.h>
26#include <sysc/kernel/sc_simcontext.h>
27#include <sysc/tracing/sc_trace.h>
48struct sc_variable_b : sc_core::sc_object {
55 sc_variable_b(
const char* name)
56 : sc_core::sc_object(name) {}
58 sc_variable_b() =
delete;
59 sc_variable_b(sc_variable_b
const&) =
delete;
60 sc_variable_b(sc_variable_b&&) =
delete;
61 sc_variable_b& operator=(
const sc_variable_b& other) =
delete;
62 sc_variable_b& operator=(sc_variable_b&& other) =
delete;
70 const char*
kind()
const {
return "sc_variable"; }
77 virtual std::string
to_string()
const {
return ""; };
87template <
typename T>
struct sc_variable :
public sc_variable_b {
102 const T* operator->() {
return &value; }
111 : sc_variable_b(name.c_str())
128 std::stringstream ss;
136 T
get()
const {
return value; }
141 operator bool()
const {
return value; }
147 operator T()
const {
return value; }
232 T operator+=(
const T other) {
238 T operator-=(
const T other) {
244 T operator*=(
const T other) {
250 T operator/=(
const T other) {
256 T operator+(
const T other)
const {
return value - 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 this_type& other)
const {
return value + other.value; }
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; }
270 void trace(sc_core::sc_trace_file* tf)
const override {
271 if(
auto* obs =
dynamic_cast<observer*
>(tf))
272 hndl.push_back(observe(obs, value, name()));
274 sc_core::sc_trace(tf, value, name());
277 void trace(
observer* obs)
const override { hndl.push_back(observe(obs, value, name())); }
280 creator(T
const& default_val)
281 : default_val{default_val} {}
292 mutable std::vector<observer::notification_handle*> hndl;
296template <
typename T> T operator-(sc_variable<T>
const& a, sc_variable<T>
const& b) {
return a.get() - b.get(); }
299template <
typename T> T operator+(T
const& a,
sc_variable<T> const& b) {
return a + 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(); }
307template <>
struct sc_variable<bool> :
public sc_variable_b {
308 const bool&
operator*() {
return value; }
309 sc_variable(
const std::string& name,
const bool& value)
310 : sc_variable_b(name.c_str())
316 sc_variable& operator=(sc_variable<bool>&& other) =
delete;
317 virtual ~sc_variable() =
default;
319 std::stringstream ss;
323 bool get()
const {
return value; }
324 operator bool()
const {
return value; }
337 bool operator==(
bool other)
const {
return value == other; }
338 bool operator!=(
bool other)
const {
return value != other; }
339 void trace(sc_core::sc_trace_file* tf)
const override {
340 if(
auto* obs =
dynamic_cast<observer*
>(tf))
341 hndl.push_back(observe(obs, value, name()));
343 sc_core::sc_trace(tf, value, name());
345 void trace(observer* obs)
const override { hndl.push_back(observe(obs, value, name())); }
348 creator(
bool const& default_val)
349 : default_val{default_val} {}
350 sc_variable<bool>* operator()(
const char* n,
size_t i) {
return new sc_variable<bool>(n, default_val); }
358 mutable std::vector<observer::notification_handle*> hndl;
369template <
typename T>
struct sc_variable_vector {
371 sc_variable_vector(std::string
const& name,
size_t size)
373 , values(size,
nullptr)
376 sc_variable_vector(std::string
const& name,
size_t size, T
const& def_val)
378 , values(size,
nullptr) {
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)
384 , values(size,
nullptr)
385 , creator(creator) {}
387 size_t size() {
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 def_val) {
395 assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
398 for(
auto& e : values) {
399 std::stringstream ss;
400 ss << name <<
"(" << idx++ <<
")";
405 bool is_valid(
size_t idx)
const {
return values.size() > idx && values.at(idx) !=
nullptr; }
408 auto ret = values.at(idx);
410 if(sc_core::sc_get_curr_simcontext()->elaboration_done())
411 SCCFATAL(sc_core::sc_get_current_object()->name()) <<
"Trying to create a sc_variable vector entry in " << name
412 <<
" with index " << idx <<
" while elaboration finished is not allowed";
413 assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
415 std::stringstream ss;
416 ss << name <<
"(" << idx <<
")";
417 ret = values.at(idx) = creator(ss.str().c_str(), idx);
423 assert(values.at(idx) &&
"No initialized value in sc_variable_vector position");
424 return *values.at(idx);
426 ~sc_variable_vector() {
433 std::vector<sc_variable<T>*> values;
434 std::function<sc_variable<T>*(
char const*, size_t)> creator;
444template <
typename T>
struct sc_ref_variable :
public sc_variable_b {
464 , active_notification(active_notification) {}
466 virtual ~sc_ref_variable() =
default;
474 std::stringstream ss;
484 void trace(sc_core::sc_trace_file* tf)
const override {
485 if(active_notification)
486 if(
auto* obs =
dynamic_cast<observer*
>(tf)) {
487 hndl.push_back(observe(obs,
value, name()));
490 sc_core::sc_trace(tf,
value, name());
493 void trace(
observer* obs)
const override { hndl.push_back(observe(obs,
value, name())); }
495 void notify()
const {
501 const bool active_notification;
503 mutable std::vector<observer::notification_handle*> hndl;
505template <>
struct sc_ref_variable<sc_core::sc_event> :
public sc_variable_b {
506 const sc_core::sc_event& value;
507 const sc_core::sc_event&
operator*() {
return value; }
508 sc_ref_variable(
const std::string& name,
const sc_core::sc_event& value)
509 : sc_variable_b(name.c_str())
512 std::stringstream ss;
519 void trace(sc_core::sc_trace_file* tf)
const override { sc_core::sc_trace(tf,
value, name()); }
527template <
typename T>
struct sc_ref_variable_masked :
public sc_variable_b {
532 sc_ref_variable_masked(
const std::string& name,
const T& value,
int width)
533 : sc_variable_b(name.c_str())
535 , mask((1 << width) - 1) {}
537 virtual ~sc_ref_variable_masked() =
default;
540 std::stringstream ss;
541 ss << (value & mask);
547 void trace(sc_core::sc_trace_file* tf)
const override { sc_core::sc_trace(tf, value, name()); }
553template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_variable<T>&
object,
const char* name) {
object.trace(tf); }
554template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_variable<T>*
object,
const char* name) {
object->trace(tf); }
556template <
class T>
inline void sc_trace(sc_trace_file* tf, const ::scc::sc_ref_variable<T>&
object,
const char* name) {
object.trace(tf); }
557template <
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