Skip to content

Commit

Permalink
Rework hierarchy guards for systemc 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Mar 14, 2024
1 parent 3360740 commit 8b165a2
Show file tree
Hide file tree
Showing 29 changed files with 92 additions and 113 deletions.
14 changes: 1 addition & 13 deletions include/vcml/core/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

namespace vcml {

class module : public sc_module
class module : public sc_module, public hierarchy_element
{
private:
std::map<string, command_base*> m_commands;
Expand All @@ -45,9 +45,6 @@ class module : public sc_module
VCML_KIND(module);
virtual const char* version() const;

void hierarchy_push();
void hierarchy_pop();

sc_object* find_child(const string& name) const;

virtual void session_suspend();
Expand Down Expand Up @@ -84,15 +81,6 @@ class module : public sc_module
bool is_local_process(sc_process_b* proc = current_process()) const;
};

inline void module::hierarchy_push() {
vcml::hierarchy_push(this);
}

inline void module::hierarchy_pop() {
sc_module* top = vcml::hierarchy_pop();
VCML_ERROR_ON(top != this, "broken hierarchy");
}

inline sc_object* module::find_child(const string& name) const {
return vcml::find_child(*this, name);
}
Expand Down
33 changes: 24 additions & 9 deletions include/vcml/core/systemc.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ using sc_core::sc_module;

using sc_core::sc_vector;

void hierarchy_push(sc_module* mod);
sc_module* hierarchy_pop();
sc_module* hierarchy_top();

template <typename MODULE = sc_core::sc_object>
Expand All @@ -169,25 +167,42 @@ bool is_child(const sc_object* obj, const sc_object* parent);

sc_object* find_child(const sc_object& parent, const string& name);

#if SYSTEMC_VERSION >= SYSTEMC_VERSION_3_0_0
using hierarchy_guard = sc_core::sc_hierarchy_scope;
#else
class hierarchy_guard
{
private:
sc_module* m_owner;

public:
hierarchy_guard(sc_module* owner):
m_owner(owner ? owner : hierarchy_top()) {
hierarchy_push(m_owner);
}

hierarchy_guard(sc_object* obj):
hierarchy_guard(hierarchy_search<sc_module>(obj)) {}
m_owner(hierarchy_search<sc_module>(obj)) {
m_owner->simcontext()->hierarchy_push(m_owner);
}

~hierarchy_guard() {
sc_module* top = hierarchy_pop();
auto top = m_owner->simcontext()->hierarchy_pop();
VCML_ERROR_ON(top != m_owner, "SystemC hierarchy corrupted");
}
};
#endif

class hierarchy_element
{
public:
hierarchy_element() = default;
virtual ~hierarchy_element() = default;

#if SYSTEMC_VERSION < SYSTEMC_VERSION_3_0_0
protected:
virtual hierarchy_guard get_hierarchy_scope() {
sc_object* obj = dynamic_cast<sc_object*>(this);
VCML_ERROR_ON(!obj, "unable to create a hierarchy scope");
return hierarchy_guard(obj);
}
#endif
};

using sc_core::sc_spawn;
using sc_core::sc_spawn_options;
Expand Down
2 changes: 1 addition & 1 deletion include/vcml/models/pci/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class device : public peripheral, public pci_target

template <typename T>
reg<T>* capability::new_cap_reg(const string& regnm, T val, vcml_access rw) {
hierarchy_guard guard(dev);
auto guard = dev->get_hierarchy_scope();
string nm = mkstr("%s_%s", name.c_str(), regnm.c_str());
reg<T>* r = new reg<T>(PCI_AS_CFG, nm, dev->curr_cap_off, val);
if (is_write_allowed(rw))
Expand Down
8 changes: 5 additions & 3 deletions include/vcml/protocols/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

namespace vcml {

class base_socket
class base_socket : public hierarchy_element
{
private:
sc_object* m_port;
Expand All @@ -39,6 +39,7 @@ class base_socket

base_socket() = delete;
base_socket(sc_object* port, address_space space):
hierarchy_element(),
m_port(port),
as(space),
trace_all(port, "trace", false),
Expand Down Expand Up @@ -123,7 +124,7 @@ struct supports_tracing<T, std::void_t<decltype(std::declval<T>().trace_all)>>
: std::true_type {};

template <typename SOCKET>
class socket_array : public sc_object
class socket_array : public sc_object, public hierarchy_element
{
public:
typedef unordered_map<size_t, SOCKET*> map_type;
Expand All @@ -144,6 +145,7 @@ class socket_array : public sc_object

socket_array(const char* nm):
sc_object(nm),
hierarchy_element(),
m_next(0),
m_max(SIZE_MAX),
m_space(VCML_AS_DEFAULT),
Expand Down Expand Up @@ -187,7 +189,7 @@ class socket_array : public sc_object
if (idx >= m_max)
VCML_ERROR("socket index out of bounds: %s[%zu]", name(), idx);

hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();
string nm = mkstr("%s[%zu]", basename(), idx);
socket = new SOCKET(nm.c_str(), m_space);
if constexpr (supports_tracing<SOCKET>::value) {
Expand Down
14 changes: 8 additions & 6 deletions include/vcml/protocols/tlm_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,44 @@

namespace vcml {

class tlm_base_initiator_socket : public tlm::tlm_initiator_socket<>
class tlm_base_initiator_socket : public tlm::tlm_initiator_socket<>,
public hierarchy_element
{
private:
tlm_target_stub* m_stub;

public:
tlm_base_initiator_socket(const char* nm,
address_space as = VCML_AS_DEFAULT):
tlm::tlm_initiator_socket<>(nm), m_stub() {}
tlm::tlm_initiator_socket<>(nm), hierarchy_element(), m_stub() {}
virtual ~tlm_base_initiator_socket() { delete m_stub; }
VCML_KIND(tlm_base_initiator_socket);

bool is_stubbed() const { return m_stub != nullptr; }
void stub(tlm_response_status r = TLM_ADDRESS_ERROR_RESPONSE) {
VCML_ERROR_ON(m_stub, "socket %s already stubbed", name());
hierarchy_guard guard(get_parent_object());
auto guard = get_hierarchy_scope();
m_stub = new tlm_target_stub(strcat(basename(), "_stub").c_str(), r);
tlm::tlm_initiator_socket<>::bind(m_stub->in);
}
};

class tlm_base_target_socket : public tlm::tlm_target_socket<>
class tlm_base_target_socket : public tlm::tlm_target_socket<>,
public hierarchy_element
{
private:
tlm_initiator_stub* m_stub;

public:
tlm_base_target_socket(const char* nm, address_space as = VCML_AS_DEFAULT):
tlm::tlm_target_socket<>(nm), m_stub() {}
tlm::tlm_target_socket<>(nm), hierarchy_element(), m_stub() {}
virtual ~tlm_base_target_socket() { delete m_stub; }
VCML_KIND(tlm_base_target_socket);

bool is_stubbed() const { return m_stub != nullptr; }
void stub() {
VCML_ERROR_ON(m_stub, "socket %s already stubbed", name());
hierarchy_guard guard(get_parent_object());
auto guard = get_hierarchy_scope();
m_stub = new tlm_initiator_stub(strcat(basename(), "_stub").c_str());
m_stub->out.bind(*this);
}
Expand Down
18 changes: 10 additions & 8 deletions include/vcml/protocols/tlm_sockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
namespace vcml {

class tlm_initiator_socket
: public simple_initiator_socket<tlm_initiator_socket>
: public simple_initiator_socket<tlm_initiator_socket>,
public hierarchy_element
{
private:
tlm_generic_payload m_tx;
Expand Down Expand Up @@ -198,7 +199,7 @@ inline void tlm_initiator_socket::bind(
VCML_ERROR_ON(m_adapter, "socket %s already bound", name());
string nm = strcat(basename(), "_adapter");

hierarchy_guard guard(m_parent);
auto guard = get_hierarchy_scope();
adapter_type* adapter = new adapter_type(nm.c_str());
base_type::bind(adapter->in);
adapter->out.bind(socket);
Expand All @@ -218,7 +219,7 @@ inline void tlm_initiator_socket::bind(
VCML_ERROR_ON(m_adapter, "socket %s already bound", name());
string nm = strcat(basename(), "_adapter");

hierarchy_guard guard(m_parent);
auto guard = get_hierarchy_scope();
adapter_type* adapter = new adapter_type(nm.c_str());
base_type::bind(adapter->in);
adapter->out.bind(socket);
Expand All @@ -231,7 +232,8 @@ inline void tlm_initiator_socket::bind<32>(
base_type::bind(other);
}

class tlm_target_socket : public simple_target_socket<tlm_target_socket>
class tlm_target_socket : public simple_target_socket<tlm_target_socket>,
public hierarchy_element
{
private:
int m_curr;
Expand Down Expand Up @@ -307,7 +309,7 @@ class tlm_target_socket : public simple_target_socket<tlm_target_socket>

inline void tlm_target_socket::wait_free() {
if (!m_free_ev) {
hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();
m_free_ev = new sc_event(mkstr("%s_free", basename()).c_str());
}

Expand Down Expand Up @@ -347,7 +349,7 @@ inline void tlm_target_socket::bind(
VCML_ERROR_ON(m_adapter, "socket %s already bound", name());
const string nm = strcat(basename(), "_adapter");

hierarchy_guard guard(m_parent);
auto guard = get_hierarchy_scope();
adapter_type* adapter = new adapter_type(nm.c_str());
socket.bind(adapter->in);
adapter->out.bind(*this);
Expand All @@ -367,7 +369,7 @@ inline void tlm_target_socket::bind(
VCML_ERROR_ON(m_adapter, "socket %s already bound", name());
const string nm = strcat(basename(), "_adapter");

hierarchy_guard guard(m_parent);
auto guard = get_hierarchy_scope();
adapter_type* adapter = new adapter_type(nm.c_str());
socket.bind(adapter->in);
adapter->out.bind(*this);
Expand All @@ -387,7 +389,7 @@ inline tlm::tlm_target_socket<WIDTH>& tlm_target_socket::adapt() {
VCML_ERROR_ON(m_adapter && !adapter, "socket %s already bound", name());
if (adapter == nullptr) {
const string nm = strcat(basename(), "_adapter");
hierarchy_guard guard(m_parent);
auto guard = get_hierarchy_scope();
adapter = new adapter_type(nm.c_str());
adapter->out.bind(*this);
m_adapter = adapter;
Expand Down
17 changes: 0 additions & 17 deletions patches/systemc-3.0.0_pub_rev_20231129-01-hierarchy-guard.patch

This file was deleted.

1 change: 1 addition & 0 deletions src/vcml/core/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ bool module::cmd_version(const vector<string>& args, ostream& os) {
// clang-format off
module::module(const sc_module_name& nm):
sc_module(nm),
hierarchy_element(),
m_commands(),
trace_all("trace", false),
trace_errors("trace_errors", false),
Expand Down
16 changes: 0 additions & 16 deletions src/vcml/core/systemc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,6 @@ sc_attr_base* find_attribute(const string& name) {

const sc_time SC_MAX_TIME = time_from_value(~0ull);

void hierarchy_push(sc_module* mod) {
sc_simcontext* simc = sc_get_curr_simcontext();
VCML_ERROR_ON(!simc, "no simulation context");
simc->hierarchy_push(mod);
}

sc_module* hierarchy_pop() {
sc_simcontext* simc = sc_get_curr_simcontext();
VCML_ERROR_ON(!simc, "no simulation context");
#if SYSTEMC_VERSION < SYSTEMC_VERSION_3_0_0
return simc->hierarchy_pop();
#else
return dynamic_cast<sc_module*>(simc->hierarchy_pop());
#endif
}

sc_module* hierarchy_top() {
sc_simcontext* simc = sc_get_curr_simcontext();
VCML_ERROR_ON(!simc, "no simulation context");
Expand Down
1 change: 1 addition & 0 deletions src/vcml/models/can/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ void bridge::detach(backend* b) {
}

size_t bridge::create_backend(const string& type) {
auto guard = get_hierarchy_scope();
m_dynamic_backends[m_next_id] = backend::create(this, type);
return m_next_id++;
}
Expand Down
1 change: 1 addition & 0 deletions src/vcml/models/ethernet/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ void bridge::detach(backend* b) {
}

size_t bridge::create_backend(const string& type) {
auto guard = get_hierarchy_scope();
m_dynamic_backends[m_next_id] = backend::create(this, type);
return m_next_id++;
}
Expand Down
6 changes: 3 additions & 3 deletions src/vcml/models/pci/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,21 +324,21 @@ void device::pci_declare_bar(int barno, u64 size, u32 type) {
}

void device::pci_declare_pm_cap(u16 pm_caps) {
hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();
VCML_ERROR_ON(m_pm, "pci_cap_pm already declared");
m_pm = new cap_pm("pci_cap_pm", pm_caps);
}

void device::pci_declare_msi_cap(u16 msi_ctrl) {
hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();
VCML_ERROR_ON(m_msi, "pci_cap_msi already declared");
m_msi = new cap_msi("pci_cap_msi", msi_ctrl);
SC_HAS_PROCESS(device);
SC_THREAD(msi_process);
}

void device::pci_declare_msix_cap(u32 bar, size_t nvec, u32 offset) {
hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();
VCML_ERROR_ON(m_msix, "pci_cap_msix already declared");
m_msix = new cap_msix("pci_cap_msix", bar, nvec, offset);
SC_HAS_PROCESS(device);
Expand Down
2 changes: 1 addition & 1 deletion src/vcml/models/serial/terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void terminal::notify(backend* b) {
}

size_t terminal::create_backend(const string& type) {
hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();
m_backends[m_next_id] = backend::create(this, type);
return m_next_id++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/vcml/models/virtio/mmio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void mmio::enable_virtqueue(u32 vqid) {
return out.lookup_dmi_ptr(addr, len, acs);
};

hierarchy_guard guard(this);
auto guard = get_hierarchy_scope();

virtqueue* q;
if (has_feature(VIRTIO_F_RING_PACKED))
Expand Down
Loading

0 comments on commit 8b165a2

Please sign in to comment.