mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Support vpiModule, bug1469.
Add very basic support for vpiModule. Basically it allows to traverse the module tree to find a variable etc. It does not support more than vpi_iterate and vpi_scan for vpiModule along basic operations like vpi_get_str on vpiModule. The support is added non-intrusively to non-VPI verilator runs. It essentially: - Tracks the creation of cell instances and keeps them alive until the emit phase. They are there converted to scopes if modules. - Emits empty (don't add anything during construction) VerilatedScopes for all inlined modules, only for those inlined modules that are on the hierarchical path to public variables. - Adds VerilatedHierarchy as abstraction to structure of the scopes. It is only created for VPI designs. It allows to traverse the hierarchy from the top (NULL). Signed-off-by: Stefan Wallentowitz <[email protected]> Signed-off-by: Wilson Snyder <[email protected]>
This commit is contained in:
committed by
Wilson Snyder
parent
66209d1114
commit
045ff25f80
@@ -24,17 +24,20 @@
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
|
||||
#define _VERILATED_VPI_CPP_
|
||||
|
||||
#if VM_SC
|
||||
# include "verilated_sc.h"
|
||||
#endif
|
||||
#include "verilated.h"
|
||||
#include "verilated_vpi.h"
|
||||
#include "verilated_imp.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
//======================================================================
|
||||
// Internal constants
|
||||
@@ -307,6 +310,45 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class VerilatedVpioModule : public VerilatedVpio {
|
||||
const VerilatedScope* m_modulep;
|
||||
const char* m_name;
|
||||
const char* m_fullname;
|
||||
public:
|
||||
explicit VerilatedVpioModule(const VerilatedScope* modulep)
|
||||
: m_modulep(modulep) {
|
||||
m_fullname = m_modulep->name();
|
||||
if (strncmp(m_fullname, "TOP.", 4) == 0) m_fullname += 4;
|
||||
m_name = m_modulep->identifier();
|
||||
}
|
||||
static inline VerilatedVpioModule* castp(vpiHandle h) {
|
||||
return dynamic_cast<VerilatedVpioModule*>((VerilatedVpio*)h); }
|
||||
virtual vluint32_t type() const { return vpiModule; }
|
||||
const VerilatedScope* modulep() const { return m_modulep; }
|
||||
virtual const char* name() const { return m_name; }
|
||||
virtual const char* fullname() const { return m_fullname; }
|
||||
};
|
||||
|
||||
class VerilatedVpioModuleIter : public VerilatedVpio {
|
||||
const std::vector<const VerilatedScope*> *m_vec;
|
||||
std::vector<const VerilatedScope*>::const_iterator m_it;
|
||||
public:
|
||||
explicit VerilatedVpioModuleIter(const std::vector<const VerilatedScope*>& vec) : m_vec(&vec) {
|
||||
m_it = m_vec->begin();
|
||||
}
|
||||
virtual ~VerilatedVpioModuleIter() {}
|
||||
static inline VerilatedVpioModuleIter* castp(vpiHandle h) {
|
||||
return dynamic_cast<VerilatedVpioModuleIter*>((VerilatedVpio*) h); }
|
||||
virtual vluint32_t type() const { return vpiIterator; }
|
||||
virtual vpiHandle dovpi_scan() {
|
||||
if (m_it == m_vec->end()) {
|
||||
return 0;
|
||||
}
|
||||
const VerilatedScope* modp = *m_it++;
|
||||
return (new VerilatedVpioModule(modp))->castVpiHandle();
|
||||
}
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
struct VerilatedVpiTimedCbsCmp {
|
||||
@@ -999,7 +1041,7 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
|
||||
if (VL_UNLIKELY(!namep)) return NULL;
|
||||
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_handle_by_name %s %p\n", namep, scope););
|
||||
VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope);
|
||||
const VerilatedVar* varp;
|
||||
const VerilatedVar* varp = NULL;
|
||||
const VerilatedScope* scopep;
|
||||
std::string scopeAndName = namep;
|
||||
if (voScopep) {
|
||||
@@ -1019,9 +1061,19 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
|
||||
baseNamep = dotp+1;
|
||||
scopename = std::string(namep, dotp-namep);
|
||||
}
|
||||
scopep = Verilated::scopeFind(scopename.c_str());
|
||||
if (!scopep) return NULL;
|
||||
varp = scopep->varFind(baseNamep);
|
||||
|
||||
if (scopename.find(".") == std::string::npos) {
|
||||
// This is a toplevel, hence search in our TOP ports first.
|
||||
scopep = Verilated::scopeFind("TOP");
|
||||
if (scopep) {
|
||||
varp = scopep->varFind(baseNamep);
|
||||
}
|
||||
}
|
||||
if (!varp) {
|
||||
scopep = Verilated::scopeFind(scopename.c_str());
|
||||
if (!scopep) return NULL;
|
||||
varp = scopep->varFind(baseNamep);
|
||||
}
|
||||
}
|
||||
if (!varp) return NULL;
|
||||
return (new VerilatedVpioVar(varp, scopep))->castVpiHandle();
|
||||
@@ -1133,6 +1185,14 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
|
||||
return ((new VerilatedVpioVarIter(vop->scopep()))
|
||||
->castVpiHandle());
|
||||
}
|
||||
case vpiModule: {
|
||||
VerilatedVpioModule* vop = VerilatedVpioModule::castp(object);
|
||||
const VerilatedHierarchyMap* map = VerilatedImp::hierarchyMap();
|
||||
const VerilatedScope *mod = vop ? vop->modulep() : NULL;
|
||||
VerilatedHierarchyMap::const_iterator it = map->find((VerilatedScope*) mod);
|
||||
if (it == map->end()) return 0;
|
||||
return ((new VerilatedVpioModuleIter(it->second))->castVpiHandle());
|
||||
}
|
||||
default:
|
||||
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned",
|
||||
VL_FUNC, VerilatedVpiError::strFromVpiObjType(type));
|
||||
|
||||
Reference in New Issue
Block a user