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:
Stefan Wallentowitz
2019-10-01 21:57:45 -04:00
committed by Wilson Snyder
parent 66209d1114
commit 045ff25f80
14 changed files with 634 additions and 50 deletions
+65 -5
View File
@@ -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));