Extend VPI and build to for SIMetrix cosimulation
Added: basic vpiPort VPI Objects for vpiModulkes
vpiDirection, vpiPortIndex, vpiName, vpiSize attributes
Since ports do not exist as net-like entities (nets either side
module instance boundaries are in effect connect directly in
the language front-ends internal representation) the port information
is effectively just meta-data passed through t-dll interface and
output as a additional annotation of module scopes in vvp.
Added: vpiLocalParam attribute for vpiParameter VPI objects
Added: support build for 32-bit target on 64-bit host (--with-m32
option to configure.in and minor tweaks to Makefiles and systemc-vpi).
This commit is contained in:
parent
3354d83391
commit
9b3d20239a
|
|
@ -95,6 +95,7 @@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
|||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
CTARGETFLAGS = @CTARGETFLAGS@
|
||||
|
||||
# Source files in the libmisc directory
|
||||
M = LineInfo.o StringHeap.o
|
||||
|
|
@ -228,6 +229,7 @@ iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
|||
-e 's;@IVCXX@;$(CXX);' \
|
||||
-e 's;@IVCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;$(includedir);' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
|
|
|
|||
16
Module.cc
16
Module.cc
|
|
@ -90,6 +90,22 @@ unsigned Module::find_port(const char*name) const
|
|||
return ports.size();
|
||||
}
|
||||
|
||||
perm_string Module::get_port_name(unsigned idx) const
|
||||
{
|
||||
|
||||
assert(idx < ports.size());
|
||||
if (ports[idx] == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. */
|
||||
return perm_string::literal("");
|
||||
}
|
||||
return ports[idx]->name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
{
|
||||
|
|
|
|||
3
Module.h
3
Module.h
|
|
@ -136,6 +136,9 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
const vector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Return port name ("" for undeclared port)
|
||||
perm_string get_port_name(unsigned idx) const;
|
||||
|
||||
PGate* get_gate(perm_string name);
|
||||
|
||||
const list<PGate*>& get_gates() const;
|
||||
|
|
|
|||
2
PExpr.h
2
PExpr.h
|
|
@ -311,7 +311,7 @@ class PEIdent : public PExpr {
|
|||
|
||||
// Elaborate the PEIdent as a port to a module. This method
|
||||
// only applies to Ident expressions.
|
||||
NetNet* elaborate_port(Design*des, NetScope*sc) const;
|
||||
NetNet* elaborate_subport(Design*des, NetScope*sc) const;
|
||||
|
||||
verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
|
|
|
|||
28
configure.in
28
configure.in
|
|
@ -91,6 +91,20 @@ fi
|
|||
|
||||
AC_LANG(C++)
|
||||
|
||||
AC_ARG_WITH([m32], [AC_HELP_STRING([--with-m32], [Compile 32-bit on x86_64])],
|
||||
[ with_m32=yes ],[ with_m32=no ])
|
||||
|
||||
AS_IF( [test "x$with_m32" = xyes],
|
||||
[ AC_MSG_NOTICE([Compiling for 32-bit environment - needs gcc on x86_64])
|
||||
LDTARGETFLAGS="-m elf_i386"
|
||||
CTARGETFLAGS="-m32"
|
||||
],
|
||||
[])
|
||||
|
||||
CFLAGS="$CTARGETFLAGS $CFLAGS"
|
||||
CXXFLAGS="$CTARGETFLAGS $CXXFLAGS"
|
||||
LDFLAGS="$CTARGETFLAGS $LDFLAGS"
|
||||
|
||||
# Check that we are using either the GNU compilers or the Sun compilers
|
||||
# but not a mixture of the two (not currently supported).
|
||||
AC_CHECK_DECL(__SUNPRO_CC, using_sunpro_cc=1, using_sunpro_cc=0)
|
||||
|
|
@ -111,7 +125,11 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
iverilog_temp_cxxflags="$CXXFLAGS"
|
||||
CXXFLAGS="-DHAVE_DECL_BASENAME $CXXFLAGS"
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h inttypes.h libiberty.h iosfwd sys/wait.h)
|
||||
CXXFLAGS="$iverilog_temp_cxxflags"
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
|
|
@ -178,6 +196,11 @@ if test -z "$DLLIB" ; then
|
|||
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
AC_SUBST(LDRELOCFLAGS)
|
||||
|
||||
AC_SUBST(CTARGETFLAGS)
|
||||
AC_SUBST(LDTARGETFLAGS)
|
||||
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
|
|
@ -304,4 +327,9 @@ AC_MSG_RESULT(ok)
|
|||
|
||||
# XXX disable tgt-fpga for the moment
|
||||
|
||||
#
|
||||
# Ensure compiler target options go in...
|
||||
|
||||
|
||||
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile)
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
|
|||
* instantiation (PGModule::elaborate_mod_) to get NetNet objects for
|
||||
* the port.
|
||||
*/
|
||||
NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
||||
NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, scope->type() == NetScope::MODULE);
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
|
|
@ -748,7 +748,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
|||
/* If this is a part select of the entire signal (or no part
|
||||
select at all) then we're done. */
|
||||
if ((lidx == 0) && (midx == (long)sig->vector_width()-1)) {
|
||||
scope->add_module_port(sig);
|
||||
scope->add_module_port_net(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
|
@ -795,7 +795,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
|||
ps->set_line(*this);
|
||||
des->add_node(ps);
|
||||
|
||||
scope->add_module_port(sig);
|
||||
scope->add_module_port_net(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
|
|||
|
||||
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||
const LexicalScope::param_expr_t&cur,
|
||||
bool is_annotatable)
|
||||
bool is_annotatable,
|
||||
bool local_flag)
|
||||
{
|
||||
NetScope::range_t*range_list = 0;
|
||||
for (LexicalScope::range_t*range = cur.range ; range ; range = range->next) {
|
||||
|
|
@ -88,8 +89,9 @@ static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
|||
range_list = tmp;
|
||||
}
|
||||
|
||||
|
||||
scope->set_parameter(name, is_annotatable, cur.expr, cur.type, cur.msb,
|
||||
cur.lsb, cur.signed_flag, range_list, cur);
|
||||
cur.lsb, cur.signed_flag, local_flag, range_list, cur);
|
||||
}
|
||||
|
||||
static void collect_scope_parameters_(Design*des, NetScope*scope,
|
||||
|
|
@ -107,7 +109,7 @@ static void collect_scope_parameters_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false);
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +128,7 @@ static void collect_scope_localparams_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false);
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +147,7 @@ static void collect_scope_specparams_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, true);
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
54
elaborate.cc
54
elaborate.cc
|
|
@ -1250,6 +1250,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
get_name() << "..." << endl;
|
||||
for (unsigned inst = 0 ; inst < instance.size() ; inst += 1) {
|
||||
rmod->elaborate(des, instance[inst]);
|
||||
instance[inst]->set_num_ports( rmod->port_count() );
|
||||
}
|
||||
if (debug_elaborate) cerr << get_fileline() << ": debug: ...done." << endl;
|
||||
|
||||
|
|
@ -1329,7 +1330,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
unconnected_port = true;
|
||||
}
|
||||
|
||||
// Inside the module, the port is zero or more signals
|
||||
// Inside the module, the port connects zero or more signals
|
||||
// that were already elaborated. List all those signals
|
||||
// and the NetNet equivalents, for all the instances.
|
||||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
|
|
@ -1349,19 +1350,24 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// will be assembled in that order as well.
|
||||
NetScope*inst_scope = instance[instance.size()-inst-1];
|
||||
|
||||
unsigned int prt_vector_width = 0;
|
||||
PortType::Enum ptype = PortType::PIMPLICIT;
|
||||
// Scan the module sub-ports for this instance...
|
||||
for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) {
|
||||
unsigned lbase = inst * mport.size();
|
||||
PEIdent*pport = mport[ldx];
|
||||
assert(pport);
|
||||
prts[lbase + ldx]
|
||||
= pport->elaborate_port(des, inst_scope);
|
||||
if (prts[lbase + ldx] == 0)
|
||||
NetNet *netnet = pport->elaborate_subport(des, inst_scope);
|
||||
prts[lbase + ldx] = netnet;
|
||||
if (netnet == 0)
|
||||
continue;
|
||||
|
||||
assert(prts[lbase + ldx]);
|
||||
prts_vector_width += prts[lbase + ldx]->vector_width();
|
||||
assert(netnet);
|
||||
prts_vector_width += netnet->vector_width();
|
||||
prt_vector_width += netnet->vector_width();
|
||||
ptype = PortType::merged(netnet->port_type(), ptype);
|
||||
}
|
||||
inst_scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
|
||||
}
|
||||
|
||||
// If I find that the port is unconnected inside the
|
||||
|
|
@ -4512,6 +4518,7 @@ static void elaborate_tasks(Design*des, NetScope*scope,
|
|||
* When a module is instantiated, it creates the scope then uses this
|
||||
* method to elaborate the contents of the module.
|
||||
*/
|
||||
|
||||
bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool result_flag = true;
|
||||
|
|
@ -4976,10 +4983,22 @@ Design* elaborate(list<perm_string>roots)
|
|||
// creates all the NetNet and NetMemory objects for declared
|
||||
// objects.
|
||||
for (i = 0; i < root_elems.count(); i++) {
|
||||
|
||||
Module *rmod = root_elems[i]->mod;
|
||||
NetScope *scope = root_elems[i]->scope;
|
||||
scope->set_num_ports( rmod->port_count() );
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
|
||||
<< ": port elaboration root "
|
||||
<< rmod->port_count() << " ports" << endl;
|
||||
}
|
||||
|
||||
if (! rmod->elaborate_sig(des, scope)) {
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
|
||||
<< ": elaborate_sig failed!!!" << endl;
|
||||
}
|
||||
delete des;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4988,11 +5007,26 @@ Design* elaborate(list<perm_string>roots)
|
|||
// defined for the root modules. This code does that.
|
||||
for (unsigned idx = 0; idx < rmod->port_count(); idx += 1) {
|
||||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
unsigned int prt_vector_width = 0;
|
||||
PortType::Enum ptype = PortType::PIMPLICIT;
|
||||
for (unsigned pin = 0; pin < mport.size(); pin += 1) {
|
||||
// This really does more than we need and adds extra
|
||||
// stuff to the design that should be cleaned later.
|
||||
(void) mport[pin]->elaborate_port(des, scope);
|
||||
(void) mport[pin]->elaborate_subport(des, scope);
|
||||
NetNet *netnet = mport[pin]->elaborate_subport(des, scope);
|
||||
if( netnet != 0 )
|
||||
{
|
||||
// Elaboration may actually fail with erroneous input source
|
||||
prt_vector_width += netnet->vector_width();
|
||||
ptype = PortType::merged(netnet->port_type(), ptype);
|
||||
}
|
||||
}
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
|
||||
<< ": adding module port "
|
||||
<< rmod->get_port_name(idx) << endl;
|
||||
}
|
||||
scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5019,5 +5053,11 @@ Design* elaborate(list<perm_string>roots)
|
|||
des = 0;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: "
|
||||
<< " finishing with "
|
||||
<< des->find_root_scopes().size() << " root scopes " << endl;
|
||||
}
|
||||
|
||||
return des;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ SUFFIX=@SUFFIX@
|
|||
|
||||
# These are used for linking...
|
||||
LD=$CC
|
||||
LDFLAGS="@SHARED@ -L@LIBDIR@"
|
||||
LDFLAGS="@IVCTARGETFLAGS@ @SHARED@ -L@LIBDIR@"
|
||||
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
|
||||
|
||||
CCSRC=
|
||||
|
|
|
|||
16
ivl_target.h
16
ivl_target.h
|
|
@ -193,6 +193,7 @@ typedef struct ivl_parameter_s*ivl_parameter_t;
|
|||
typedef struct ivl_process_s *ivl_process_t;
|
||||
typedef struct ivl_scope_s *ivl_scope_t;
|
||||
typedef struct ivl_signal_s *ivl_signal_t;
|
||||
typedef struct ivl_port_info_s *ivl_port_info_t;
|
||||
typedef struct ivl_switch_s *ivl_switch_t;
|
||||
typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated));
|
||||
typedef struct ivl_statement_s*ivl_statement_t;
|
||||
|
|
@ -363,7 +364,7 @@ typedef enum ivl_scope_type_e {
|
|||
|
||||
/* Signals (ivl_signal_t) that are ports into the scope that contains
|
||||
them have a port type. Otherwise, they are port IVL_SIP_NONE. */
|
||||
typedef enum ivl_signal_port_e {
|
||||
typedef enum OUT {
|
||||
IVL_SIP_NONE = 0,
|
||||
IVL_SIP_INPUT = 1,
|
||||
IVL_SIP_OUTPUT= 2,
|
||||
|
|
@ -1568,6 +1569,10 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
|||
* Return the value of the parameter. This should be a simple
|
||||
* constant expression, an IVL_EX_STRING or IVL_EX_NUMBER.
|
||||
*
|
||||
* ivl_parameter_local
|
||||
* Return whether parameter was local (localparam, implicit genvar etc)
|
||||
* or not.
|
||||
*
|
||||
* ivl_parameter_file
|
||||
* ivl_parameter_lineno
|
||||
* Returns the file and line where this parameter is defined
|
||||
|
|
@ -1575,7 +1580,7 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
|||
extern const char* ivl_parameter_basename(ivl_parameter_t net);
|
||||
extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net);
|
||||
extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net);
|
||||
|
||||
extern int ivl_parameter_local(ivl_parameter_t net);
|
||||
extern const char* ivl_parameter_file(ivl_parameter_t net);
|
||||
extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
||||
|
||||
|
|
@ -1738,6 +1743,12 @@ extern const char* ivl_scope_basename(ivl_scope_t net);
|
|||
extern unsigned ivl_scope_params(ivl_scope_t net);
|
||||
extern ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx);
|
||||
extern ivl_scope_t ivl_scope_parent(ivl_scope_t net);
|
||||
|
||||
extern unsigned ivl_scope_mod_module_ports(ivl_scope_t net);
|
||||
extern const char *ivl_scope_mod_module_port_name(ivl_scope_t net, unsigned idx );
|
||||
extern ivl_signal_port_t ivl_scope_mod_module_port_type(ivl_scope_t net, unsigned idx );
|
||||
extern unsigned ivl_scope_mod_module_port_width(ivl_scope_t net, unsigned idx );
|
||||
|
||||
extern unsigned ivl_scope_ports(ivl_scope_t net);
|
||||
extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx);
|
||||
extern ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx);
|
||||
|
|
@ -1878,6 +1889,7 @@ extern int ivl_signal_msb(ivl_signal_t net) __attribute__((deprecated));
|
|||
extern int ivl_signal_lsb(ivl_signal_t net) __attribute__((deprecated));
|
||||
extern unsigned ivl_signal_width(ivl_signal_t net);
|
||||
extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net);
|
||||
extern int ivl_signal_module_port_index(ivl_signal_t net);
|
||||
extern int ivl_signal_signed(ivl_signal_t net);
|
||||
extern int ivl_signal_integer(ivl_signal_t net);
|
||||
extern int ivl_signal_local(ivl_signal_t net);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ else
|
|||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
LDRELOCFLAGS = @LDRELOCFLAGS@
|
||||
|
||||
LDTARGETFLAGS = @LDTARGETFLAGS@
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
|
||||
|
|
@ -87,7 +91,7 @@ stamp-config-h: $(srcdir)/config.h.in ../config.status
|
|||
config.h: stamp-config-h
|
||||
|
||||
libveriuser.o: $O
|
||||
$(LD) -r -o $@ $O
|
||||
$(LD) $(LDTARGETFLAGS) -r -o $@ $O
|
||||
|
||||
libveriuser.a: libveriuser.o
|
||||
rm -f $@
|
||||
|
|
|
|||
10
main.cc
10
main.cc
|
|
@ -784,7 +784,13 @@ int main(int argc, char*argv[])
|
|||
#if defined(TRAP_SIGINT_FOR_DEBUG)
|
||||
signal(SIGINT, &signals_handler);
|
||||
#endif
|
||||
|
||||
if( ::getenv("IVL_WAIT_FOR_DEBUGGER") != 0 ) {
|
||||
fprintf( stderr, "Waiting for debugger...\n");
|
||||
bool debugger_release = false;
|
||||
while( !debugger_release ) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
library_suff.push_back(strdup(".v"));
|
||||
|
||||
// Start the module list with the base system module.
|
||||
|
|
@ -839,6 +845,8 @@ int main(int argc, char*argv[])
|
|||
cout << COPYRIGHT << endl << endl;
|
||||
cout << NOTICE << endl;
|
||||
|
||||
cout << " FLAGS DLL " << flags["DLL"] << endl;
|
||||
|
||||
dll_target_obj.test_version(flags["DLL"]);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
51
net_scope.cc
51
net_scope.cc
|
|
@ -114,14 +114,10 @@ void NetScope::set_line(perm_string file, perm_string def_file,
|
|||
def_lineno_ = def_lineno;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the full-featured version of set_parameter. It is used for
|
||||
* adding parameter, localparam, and specparam declarations to the
|
||||
* parameter list.
|
||||
*/
|
||||
void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
||||
PExpr*val, ivl_variable_type_t type__,
|
||||
PExpr*msb, PExpr*lsb, bool signed_flag,
|
||||
bool local_flag,
|
||||
NetScope::range_t*range_list,
|
||||
const LineInfo&file_line)
|
||||
{
|
||||
|
|
@ -135,6 +131,7 @@ void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
|||
ref.msb = 0;
|
||||
ref.lsb = 0;
|
||||
ref.signed_flag = signed_flag;
|
||||
ref.local_flag = local_flag;
|
||||
ivl_assert(file_line, ref.range == 0);
|
||||
ref.range = range_list;
|
||||
ref.val = 0;
|
||||
|
|
@ -370,23 +367,51 @@ perm_string NetScope::module_name() const
|
|||
return module_name_;
|
||||
}
|
||||
|
||||
void NetScope::add_module_port(NetNet*port)
|
||||
void NetScope::set_num_ports(unsigned int num_ports)
|
||||
{
|
||||
assert(type_ == MODULE);
|
||||
ports_.push_back(port);
|
||||
assert(type_ == MODULE);
|
||||
assert( ports_.size() == 0 );
|
||||
ports_.resize( num_ports );
|
||||
}
|
||||
|
||||
unsigned NetScope::module_ports() const
|
||||
void NetScope::add_module_port_net(NetNet*subport)
|
||||
{
|
||||
assert(type_ == MODULE);
|
||||
return ports_.size();
|
||||
port_nets.push_back(subport);
|
||||
}
|
||||
|
||||
NetNet* NetScope::module_port(unsigned idx) const
|
||||
|
||||
void NetScope::add_module_port_info( unsigned idx, perm_string name, PortType::Enum ptype,
|
||||
unsigned long width )
|
||||
{
|
||||
assert(type_ == MODULE);
|
||||
assert(idx < ports_.size());
|
||||
return ports_[idx];
|
||||
PortInfo &info = ports_[idx];
|
||||
info.name = name;
|
||||
info.type = ptype;
|
||||
info.width = width;
|
||||
}
|
||||
|
||||
|
||||
unsigned NetScope::module_port_nets() const
|
||||
{
|
||||
assert(type_ == MODULE);
|
||||
return port_nets.size();
|
||||
}
|
||||
|
||||
|
||||
const std::vector<PortInfo> & NetScope::module_port_info() const
|
||||
{
|
||||
assert(type_ == MODULE);
|
||||
return ports_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NetNet* NetScope::module_port_net(unsigned idx) const
|
||||
{
|
||||
assert(type_ == MODULE);
|
||||
assert(idx < port_nets.size());
|
||||
return port_nets[idx];
|
||||
}
|
||||
|
||||
void NetScope::time_unit(int val)
|
||||
|
|
|
|||
28
netlist.cc
28
netlist.cc
|
|
@ -447,12 +447,27 @@ const Link& NetDelaySrc::condit_pin() const
|
|||
return pin(pin_count()-1);
|
||||
}
|
||||
|
||||
PortType::Enum PortType::merged( Enum lhs, Enum rhs )
|
||||
{
|
||||
if( lhs == NOT_A_PORT || rhs == NOT_A_PORT )
|
||||
return NOT_A_PORT;
|
||||
if( lhs == PIMPLICIT )
|
||||
return rhs;
|
||||
if( rhs == PIMPLICIT )
|
||||
return lhs;
|
||||
if( lhs == rhs ) {
|
||||
return lhs;
|
||||
}
|
||||
return PINOUT;
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
|
||||
signed_(false), isint_(false), is_scalar_(false), local_flag_(false),
|
||||
enumeration_(0), struct_type_(0), discipline_(0),
|
||||
eref_count_(0), lref_count_(0)
|
||||
eref_count_(0), lref_count_(0),
|
||||
port_index_(-1)
|
||||
{
|
||||
assert(s);
|
||||
assert(npins>0);
|
||||
|
|
@ -698,6 +713,17 @@ void NetNet::port_type(NetNet::PortType t)
|
|||
port_type_ = t;
|
||||
}
|
||||
|
||||
int NetNet::get_module_port_index() const
|
||||
{
|
||||
return port_index_;
|
||||
}
|
||||
|
||||
void NetNet::set_module_port_index(unsigned idx)
|
||||
{
|
||||
port_index_ = idx;
|
||||
assert( port_index_ >= 0 );
|
||||
}
|
||||
|
||||
ivl_variable_type_t NetNet::data_type() const
|
||||
{
|
||||
return data_type_;
|
||||
|
|
|
|||
61
netlist.h
61
netlist.h
|
|
@ -556,14 +556,42 @@ class NetDelaySrc : public NetObj {
|
|||
* anything and they are not a data sink, per se. The pins follow the
|
||||
* values on the nexus.
|
||||
*/
|
||||
class NetNet : public NetObj {
|
||||
|
||||
class PortType
|
||||
{
|
||||
public:
|
||||
enum Enum { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF };
|
||||
|
||||
/*
|
||||
* Merge Port types (used to construct a sane combined port-type
|
||||
* for module ports with complex defining expressions).
|
||||
*
|
||||
*/
|
||||
static Enum merged( Enum lhs, Enum rhs );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Information on actual ports (rather than port-connected signals) of
|
||||
* module.
|
||||
* N.b. must be POD as passed through a "C" interface in the t-dll-api.
|
||||
*/
|
||||
struct PortInfo
|
||||
{
|
||||
PortType::Enum type;
|
||||
unsigned long width;
|
||||
perm_string name;
|
||||
};
|
||||
|
||||
|
||||
class NetNet : public NetObj, public PortType {
|
||||
|
||||
public:
|
||||
enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1,
|
||||
SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG,
|
||||
UNRESOLVED_WIRE };
|
||||
|
||||
enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF };
|
||||
typedef PortType::Enum PortType;
|
||||
|
||||
public:
|
||||
// The width in this case is a shorthand for ms=width-1 and
|
||||
|
|
@ -592,6 +620,11 @@ class NetNet : public NetObj {
|
|||
PortType port_type() const;
|
||||
void port_type(PortType t);
|
||||
|
||||
// If this net net is a port (i.e. a *sub*port net of a module port)
|
||||
// its port index is number of the module it connects through
|
||||
int get_module_port_index() const; // -1 Not connected to port...
|
||||
void set_module_port_index(unsigned idx);
|
||||
|
||||
ivl_variable_type_t data_type() const;
|
||||
void data_type(ivl_variable_type_t t);
|
||||
|
||||
|
|
@ -713,6 +746,7 @@ class NetNet : public NetObj {
|
|||
std::vector<bool> lref_mask_;
|
||||
|
||||
vector<class NetDelaySrc*> delay_paths_;
|
||||
int port_index_;
|
||||
};
|
||||
|
||||
extern std::ostream&operator << (std::ostream&out, const std::list<netrange_t>&rlist);
|
||||
|
|
@ -747,6 +781,7 @@ class NetScope : public Attrib {
|
|||
void set_parameter(perm_string name, bool is_annotatable,
|
||||
PExpr*val, ivl_variable_type_t type,
|
||||
PExpr*msb, PExpr*lsb, bool signed_flag,
|
||||
bool local_flag,
|
||||
NetScope::range_t*range_list,
|
||||
const LineInfo&file_line);
|
||||
void set_parameter(perm_string name, NetExpr*val,
|
||||
|
|
@ -878,9 +913,18 @@ class NetScope : public Attrib {
|
|||
perm_string module_name() const;
|
||||
/* If the scope is a module then it may have ports that we need
|
||||
* to keep track of. */
|
||||
void add_module_port(NetNet*port);
|
||||
unsigned module_ports() const;
|
||||
NetNet*module_port(unsigned idx) const;
|
||||
|
||||
void set_num_ports(unsigned int num_ports);
|
||||
void add_module_port_net(NetNet*port);
|
||||
unsigned module_port_nets() const;
|
||||
NetNet*module_port_net(unsigned idx) const;
|
||||
|
||||
void add_module_port_info( unsigned idx,
|
||||
perm_string name, // May be "" for undeclared port
|
||||
PortType::Enum type,
|
||||
unsigned long width );
|
||||
|
||||
const std::vector<PortInfo> &module_port_info() const;
|
||||
|
||||
/* Scopes have their own time units and time precision. The
|
||||
unit and precision are given as power of 10, i.e., -3 is
|
||||
|
|
@ -951,6 +995,7 @@ class NetScope : public Attrib {
|
|||
param_expr_t() : msb_expr(0), lsb_expr(0), val_expr(0), val_scope(0),
|
||||
solving(false), is_annotatable(false),
|
||||
type(IVL_VT_NO_TYPE), signed_flag(false),
|
||||
local_flag(false),
|
||||
msb(0), lsb(0), range(0), val(0) { }
|
||||
// Source expressions
|
||||
PExpr*msb_expr;
|
||||
|
|
@ -965,6 +1010,7 @@ class NetScope : public Attrib {
|
|||
// Type information
|
||||
ivl_variable_type_t type;
|
||||
bool signed_flag;
|
||||
bool local_flag;
|
||||
NetExpr*msb;
|
||||
NetExpr*lsb;
|
||||
// range constraints
|
||||
|
|
@ -1018,7 +1064,10 @@ class NetScope : public Attrib {
|
|||
typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
|
||||
std::map <perm_string,NetNet*> signals_map_;
|
||||
perm_string module_name_;
|
||||
vector<NetNet*>ports_;
|
||||
vector<NetNet*> port_nets;
|
||||
|
||||
vector<PortInfo> ports_;
|
||||
|
||||
union {
|
||||
NetTaskDef*task_;
|
||||
NetFuncDef*func_;
|
||||
|
|
|
|||
46
t-dll-api.cc
46
t-dll-api.cc
|
|
@ -1681,6 +1681,13 @@ extern "C" const char* ivl_parameter_basename(ivl_parameter_t net)
|
|||
return net->basename;
|
||||
}
|
||||
|
||||
extern "C" int ivl_parameter_local(ivl_parameter_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->local;
|
||||
}
|
||||
|
||||
|
||||
extern "C" ivl_expr_t ivl_parameter_expr(ivl_parameter_t net)
|
||||
{
|
||||
assert(net);
|
||||
|
|
@ -1979,6 +1986,40 @@ extern "C" ivl_scope_t ivl_scope_parent(ivl_scope_t net)
|
|||
return net->parent;
|
||||
}
|
||||
|
||||
|
||||
extern "C" unsigned ivl_scope_mod_module_ports(ivl_scope_t net)
|
||||
{
|
||||
assert(net);
|
||||
assert (net->type_ == IVL_SCT_MODULE );
|
||||
return static_cast<unsigned>(net->module_ports_info.size());
|
||||
}
|
||||
|
||||
extern "C" const char *ivl_scope_mod_module_port_name(ivl_scope_t net, unsigned idx )
|
||||
{
|
||||
assert(net);
|
||||
assert (net->type_ == IVL_SCT_MODULE );
|
||||
assert( idx < net->module_ports_info.size());
|
||||
|
||||
return net->module_ports_info[idx].name;
|
||||
}
|
||||
|
||||
extern "C" ivl_signal_port_t ivl_scope_mod_module_port_type(ivl_scope_t net, unsigned idx )
|
||||
{
|
||||
switch( net->module_ports_info[idx].type )
|
||||
{
|
||||
case PortType::PINPUT : return IVL_SIP_INPUT;
|
||||
case PortType::POUTPUT : return IVL_SIP_OUTPUT;
|
||||
case PortType::PINOUT : return IVL_SIP_INOUT;
|
||||
default : return IVL_SIP_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_scope_mod_module_port_width(ivl_scope_t net, unsigned idx )
|
||||
{
|
||||
return net->module_ports_info[idx].width;
|
||||
}
|
||||
|
||||
|
||||
extern "C" unsigned ivl_scope_ports(ivl_scope_t net)
|
||||
{
|
||||
assert(net);
|
||||
|
|
@ -2198,6 +2239,11 @@ extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net)
|
|||
return net->port_;
|
||||
}
|
||||
|
||||
extern "C" int ivl_signal_module_port_index(ivl_signal_t net)
|
||||
{
|
||||
return net->module_port_index_;
|
||||
}
|
||||
|
||||
extern "C" int ivl_signal_local(ivl_signal_t net)
|
||||
{
|
||||
return net->local_;
|
||||
|
|
|
|||
14
t-dll.cc
14
t-dll.cc
|
|
@ -478,6 +478,7 @@ void dll_target::make_scope_parameters(ivl_scope_t scop, const NetScope*net)
|
|||
assert(idx < scop->nparam_);
|
||||
ivl_parameter_t cur_par = scop->param_ + idx;
|
||||
cur_par->basename = (*cur_pit).first;
|
||||
cur_par->local = cur_pit->second.local_flag;
|
||||
cur_par->scope = scop;
|
||||
FILE_NAME(cur_par, &((*cur_pit).second));
|
||||
|
||||
|
|
@ -550,13 +551,14 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s)
|
|||
root_->attr = fill_in_attributes(s);
|
||||
root_->is_auto = 0;
|
||||
root_->is_cell = s->is_cell();
|
||||
root_->ports = s->module_ports();
|
||||
root_->ports = s->module_port_nets();
|
||||
if (root_->ports > 0) {
|
||||
root_->u_.net = new NetNet*[root_->ports];
|
||||
for (unsigned idx = 0; idx < root_->ports; idx += 1) {
|
||||
root_->u_.net[idx] = s->module_port(idx);
|
||||
root_->u_.net[idx] = s->module_port_net(idx);
|
||||
}
|
||||
}
|
||||
root_->module_ports_info = s->module_port_info();
|
||||
|
||||
des__.nroots_++;
|
||||
if (des__.roots_)
|
||||
|
|
@ -2299,14 +2301,16 @@ void dll_target::scope(const NetScope*net)
|
|||
case NetScope::MODULE:
|
||||
scop->type_ = IVL_SCT_MODULE;
|
||||
scop->tname_ = net->module_name();
|
||||
scop->ports = net->module_ports();
|
||||
scop->ports = net->module_port_nets();
|
||||
if (scop->ports > 0) {
|
||||
scop->u_.net = new NetNet*[scop->ports];
|
||||
for (unsigned idx = 0; idx < scop->ports; idx += 1) {
|
||||
scop->u_.net[idx] = net->module_port(idx);
|
||||
scop->u_.net[idx] = net->module_port_net(idx);
|
||||
}
|
||||
}
|
||||
scop->module_ports_info = net->module_port_info();
|
||||
break;
|
||||
|
||||
case NetScope::TASK: {
|
||||
const NetTaskDef*def = net->task_def();
|
||||
if (def == 0) {
|
||||
|
|
@ -2425,6 +2429,8 @@ void dll_target::signal(const NetNet*net)
|
|||
break;
|
||||
}
|
||||
|
||||
obj->module_port_index_ = net->get_module_port_index();
|
||||
|
||||
switch (net->type()) {
|
||||
|
||||
case NetNet::REG:
|
||||
|
|
|
|||
7
t-dll.h
7
t-dll.h
|
|
@ -584,6 +584,7 @@ struct ivl_parameter_s {
|
|||
perm_string basename;
|
||||
ivl_scope_t scope;
|
||||
ivl_expr_t value;
|
||||
bool local;
|
||||
perm_string file;
|
||||
unsigned lineno;
|
||||
};
|
||||
|
|
@ -647,6 +648,10 @@ struct ivl_scope_s {
|
|||
|
||||
unsigned is_cell;
|
||||
|
||||
// Ports of Module scope (just introspection data for VPI) - actual connections
|
||||
// are nets defined in u_.net (may be > 1 per module port)
|
||||
std::vector<PortInfo> module_ports_info;
|
||||
|
||||
unsigned ports;
|
||||
union {
|
||||
ivl_signal_t*port;
|
||||
|
|
@ -672,6 +677,7 @@ struct ivl_scope_s {
|
|||
struct ivl_signal_s {
|
||||
ivl_signal_type_t type_;
|
||||
ivl_signal_port_t port_;
|
||||
int module_port_index_;
|
||||
ivl_variable_type_t data_type;
|
||||
ivl_discipline_t discipline;
|
||||
perm_string file;
|
||||
|
|
@ -709,6 +715,7 @@ struct ivl_signal_s {
|
|||
unsigned nattr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The ivl_statement_t represents any statement. The type of statement
|
||||
* is defined by the ivl_statement_type_t enumeration. Given the type,
|
||||
|
|
|
|||
|
|
@ -417,6 +417,36 @@ const char*draw_input_from_net(ivl_nexus_t nex)
|
|||
}
|
||||
|
||||
|
||||
/* Create flag string for port nature */
|
||||
|
||||
static const char *port_type_str( ivl_signal_port_t ptype )
|
||||
{
|
||||
switch( ptype )
|
||||
{
|
||||
case IVL_SIP_INPUT :
|
||||
return "INPUT";
|
||||
case IVL_SIP_OUTPUT :
|
||||
return "OUTPUT";
|
||||
case IVL_SIP_INOUT :
|
||||
return "INOUT";
|
||||
case IVL_SIP_NONE :
|
||||
default :
|
||||
return "NOT_PORT";
|
||||
}
|
||||
}
|
||||
/* Create flag string for et nature" port nature / localness */
|
||||
|
||||
static const char *port_nature_flag_str( ivl_signal_t sig )
|
||||
{
|
||||
return port_type_str( ivl_signal_port(sig) );
|
||||
}
|
||||
|
||||
|
||||
static const char *local_flag_str( ivl_signal_t sig )
|
||||
{
|
||||
return ivl_signal_local(sig)? "*" : "";
|
||||
}
|
||||
|
||||
/*
|
||||
* This function draws a reg/int/variable in the scope. This is a very
|
||||
* simple device to draw as there are no inputs to connect so no need
|
||||
|
|
@ -442,9 +472,9 @@ static void draw_reg_in_scope(ivl_signal_t sig)
|
|||
break;
|
||||
}
|
||||
|
||||
const char*datatype_flag = ivl_signal_integer(sig) ? "/i" :
|
||||
const char *datatype_flag = ivl_signal_integer(sig) ? "/i" :
|
||||
ivl_signal_signed(sig)? "/s" : "";
|
||||
const char*local_flag = ivl_signal_local(sig)? "*" : "";
|
||||
const char *local_flag = local_flag_str(sig);
|
||||
|
||||
switch (ivl_signal_data_type(sig)) {
|
||||
case IVL_VT_BOOL:
|
||||
|
|
@ -477,7 +507,7 @@ static void draw_reg_in_scope(ivl_signal_t sig)
|
|||
fprintf(vvp_out, "v%p_0 .var%s %s\"%s\", %d %d;%s\n",
|
||||
sig, datatype_flag, local_flag,
|
||||
vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb,
|
||||
ivl_signal_local(sig)? " Local signal" : "");
|
||||
ivl_signal_local(sig)? " Local signal" : "" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -506,7 +536,8 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
|||
}
|
||||
|
||||
const char*datatype_flag = ivl_signal_signed(sig)? "/s" : "";
|
||||
const char*local_flag = ivl_signal_local(sig)? "*" : "";
|
||||
const char *local_flag = local_flag_str(sig);
|
||||
|
||||
unsigned iword;
|
||||
|
||||
switch (ivl_signal_data_type(sig)) {
|
||||
|
|
@ -562,7 +593,7 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
|||
sig, iword, vec8, datatype_flag, sig,
|
||||
iword, msb, lsb, driver,
|
||||
nex_data->drivers_count,
|
||||
strength_aware_flag?", strength-aware":"");
|
||||
strength_aware_flag?", strength-aware":"" );
|
||||
|
||||
} else if (ivl_signal_local(sig) && ivl_scope_is_auto(ivl_signal_scope(sig))) {
|
||||
assert(word_count == 1);
|
||||
|
|
@ -578,13 +609,13 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
|||
/* If this is an isolated word, it uses its
|
||||
own name. */
|
||||
assert(word_count == 1);
|
||||
fprintf(vvp_out, "v%p_%u .net%s%s %s\"%s\", %d %d, %s;"
|
||||
" %u drivers%s\n",
|
||||
fprintf(vvp_out, "v%p_%u .net%s%s %s\"%s\", %d %d, %s; "
|
||||
" %u drivers %s\n",
|
||||
sig, iword, vec8, datatype_flag, local_flag,
|
||||
vvp_mangle_name(ivl_signal_basename(sig)),
|
||||
msb, lsb, driver,
|
||||
nex_data->drivers_count,
|
||||
strength_aware_flag?", strength-aware":"");
|
||||
strength_aware_flag?", strength-aware":"" );
|
||||
}
|
||||
nex_data->net = sig;
|
||||
nex_data->net_word = iword;
|
||||
|
|
@ -600,7 +631,7 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
|||
|
||||
if (word_count == ivl_signal_array_count(nex_data->net)) {
|
||||
if (iword == 0) {
|
||||
fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s\n",
|
||||
fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s \n",
|
||||
sig, vvp_mangle_name(ivl_signal_basename(sig)),
|
||||
nex_data->net,
|
||||
ivl_signal_basename(nex_data->net));
|
||||
|
|
@ -615,7 +646,7 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
|||
sig,
|
||||
vvp_mangle_name(ivl_signal_basename(sig)),
|
||||
swapped ? first : last,
|
||||
swapped ? last : first);
|
||||
swapped ? last : first );
|
||||
}
|
||||
|
||||
fprintf(vvp_out, "v%p_%u .alias%s v%p %u, %d %d, "
|
||||
|
|
@ -637,7 +668,7 @@ static void draw_net_in_scope(ivl_signal_t sig)
|
|||
if (strength_aware_flag)
|
||||
vec8 = "8";
|
||||
|
||||
fprintf(vvp_out, "v%p_%u .net%s%s %s\"%s\", %d %d, %s;"
|
||||
fprintf(vvp_out, "v%p_%u .net%s%s %s\"%s\", %d %d, %s; "
|
||||
" alias, %u drivers%s\n",
|
||||
sig, iword, vec8, datatype_flag, local_flag,
|
||||
vvp_mangle_name(ivl_signal_basename(sig)),
|
||||
|
|
@ -2075,6 +2106,20 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *vvp_port_info_type_str(ivl_signal_port_t ptype)
|
||||
{
|
||||
switch( ptype )
|
||||
{
|
||||
case IVL_SIP_INPUT : return "/INPUT";
|
||||
case IVL_SIP_OUTPUT : return "/OUTPUT";
|
||||
case IVL_SIP_INOUT : return "/INOUT";
|
||||
case IVL_SIP_NONE : return "/NODIR";
|
||||
default :
|
||||
abort(); // NO SUPPORT FOR ANYTHING ELSE YET...
|
||||
}
|
||||
}
|
||||
|
||||
int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||
{
|
||||
unsigned idx;
|
||||
|
|
@ -2109,20 +2154,36 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
fprintf(vvp_out, " .timescale %d %d;\n", ivl_scope_time_units(net),
|
||||
ivl_scope_time_precision(net));
|
||||
|
||||
if( ivl_scope_type(net) == IVL_SCT_MODULE ) {
|
||||
|
||||
// Port data for VPI: needed for vpiPorts property of vpiModule
|
||||
for( idx = 0; idx < ivl_scope_mod_module_ports(net); ++idx ) {
|
||||
const char *name = ivl_scope_mod_module_port_name(net,idx);
|
||||
ivl_signal_port_t ptype = ivl_scope_mod_module_port_type(net,idx);
|
||||
unsigned width = ivl_scope_mod_module_port_width(net,idx);
|
||||
if( name == 0 )
|
||||
name = "";
|
||||
fprintf( vvp_out, " .port_info %d %s %u \"%s\"\n",
|
||||
idx, vvp_port_info_type_str(ptype), width, name );
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < ivl_scope_params(net) ; idx += 1) {
|
||||
ivl_parameter_t par = ivl_scope_param(net, idx);
|
||||
ivl_expr_t pex = ivl_parameter_expr(par);
|
||||
switch (ivl_expr_type(pex)) {
|
||||
case IVL_EX_STRING:
|
||||
fprintf(vvp_out, "P_%p .param/str \"%s\" %d %d, \"%s\";\n",
|
||||
fprintf(vvp_out, "P_%p .param/str \"%s\" %d %d %d, \"%s\";\n",
|
||||
par, ivl_parameter_basename(par),
|
||||
ivl_parameter_local(par),
|
||||
ivl_file_table_index(ivl_parameter_file(par)),
|
||||
ivl_parameter_lineno(par),
|
||||
ivl_expr_string(pex));
|
||||
break;
|
||||
case IVL_EX_NUMBER:
|
||||
fprintf(vvp_out, "P_%p .param/l \"%s\" %d %d, %sC4<",
|
||||
fprintf(vvp_out, "P_%p .param/l \"%s\" %d %d %d, %sC4<",
|
||||
par, ivl_parameter_basename(par),
|
||||
ivl_parameter_local(par),
|
||||
ivl_file_table_index(ivl_parameter_file(par)),
|
||||
ivl_parameter_lineno(par),
|
||||
ivl_expr_signed(pex)? "+":"");
|
||||
|
|
@ -2136,8 +2197,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
break;
|
||||
case IVL_EX_REALNUM:
|
||||
{ char *res = draw_Cr_to_string(ivl_expr_dvalue(pex));
|
||||
fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; "
|
||||
fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d %d, %s; "
|
||||
"value=%#g\n", par, ivl_parameter_basename(par),
|
||||
ivl_parameter_local(par),
|
||||
ivl_file_table_index(ivl_parameter_file(par)),
|
||||
ivl_parameter_lineno(par), res,
|
||||
ivl_expr_dvalue(pex));
|
||||
|
|
|
|||
12
vpi_user.h
12
vpi_user.h
|
|
@ -43,6 +43,7 @@ EXTERN_C_START
|
|||
|
||||
# include <stdarg.h>
|
||||
# include <stdio.h>
|
||||
# include <stdarg.h>
|
||||
# include "_pli_types.h"
|
||||
|
||||
#define ICARUS_VPI_CONST
|
||||
|
|
@ -286,6 +287,7 @@ typedef struct t_vpi_delay {
|
|||
#define vpiParameter 41
|
||||
#define vpiPartSelect 42
|
||||
#define vpiPathTerm 43
|
||||
#define vpiPort 44
|
||||
#define vpiRealVar 47
|
||||
#define vpiReg 48
|
||||
#define vpiSysFuncCall 56
|
||||
|
|
@ -325,6 +327,14 @@ typedef struct t_vpi_delay {
|
|||
#define vpiTimePrecision 12
|
||||
#define vpiDefFile 15
|
||||
#define vpiDefLineNo 16
|
||||
|
||||
#define vpiDirection 20 /* direction of port: */
|
||||
# define vpiInput 1
|
||||
# define vpiOutput 2
|
||||
# define vpiInout 3
|
||||
# define vpiMixedIO 4 /* Not currently output */
|
||||
# define vpiNoDirection 5
|
||||
|
||||
#define vpiNetType 22
|
||||
# define vpiWire 1
|
||||
# define vpiWand 2
|
||||
|
|
@ -338,6 +348,7 @@ typedef struct t_vpi_delay {
|
|||
# define vpiSupply1 10
|
||||
# define vpiSupply0 11
|
||||
#define vpiArray 28
|
||||
#define vpiPortIndex 29
|
||||
#define vpiEdge 36
|
||||
# define vpiNoEdge 0x00 /* No edge */
|
||||
# define vpiEdge01 0x01 /* 0 --> 1 */
|
||||
|
|
@ -371,6 +382,7 @@ typedef struct t_vpi_delay {
|
|||
#define vpiAutomatic 50
|
||||
#define vpiConstantSelect 53
|
||||
#define vpiSigned 65
|
||||
#define vpiLocalParam 70
|
||||
/* IVL private properties, also see vvp/vpi_priv.h for other properties */
|
||||
#define _vpiNexusId 0x1000000
|
||||
/* used in vvp/vpi_priv.h 0x1000001 */
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
|
||||
# include "config.h"
|
||||
# include "delay.h"
|
||||
# include "arith.h"
|
||||
# include "compile.h"
|
||||
# include "logic.h"
|
||||
|
|
@ -28,6 +31,7 @@
|
|||
# include "vpi_priv.h"
|
||||
# include "parse_misc.h"
|
||||
# include "statistics.h"
|
||||
# include "schedule.h"
|
||||
# include <iostream>
|
||||
# include <list>
|
||||
# include <cstdlib>
|
||||
|
|
@ -610,7 +614,7 @@ static void compile_array_lookup(struct vvp_code_s*code, char*label)
|
|||
resolv_submit(res);
|
||||
}
|
||||
|
||||
static list<struct __vpiSysTaskCall*> scheduled_compiletf;
|
||||
static std::list<struct __vpiSysTaskCall*> scheduled_compiletf;
|
||||
|
||||
void compile_compiletf(struct __vpiSysTaskCall*obj)
|
||||
{
|
||||
|
|
@ -859,7 +863,7 @@ void input_connect(vvp_net_t*fdx, unsigned port, char*label)
|
|||
void inputs_connect(vvp_net_t*fdx, unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
if (argc > 4) {
|
||||
cerr << "XXXX argv[0] = " << argv[0].text << endl;
|
||||
std::cerr << "XXXX argv[0] = " << argv[0].text << std::endl;
|
||||
}
|
||||
assert(argc <= 4);
|
||||
|
||||
|
|
@ -1808,11 +1812,12 @@ void compile_thread(char*start_sym, char*flag)
|
|||
}
|
||||
|
||||
void compile_param_logic(char*label, char*name, char*value, bool signed_flag,
|
||||
bool local_flag,
|
||||
long file_idx, long lineno)
|
||||
{
|
||||
vvp_vector4_t value4 = c4string_to_vector4(value);
|
||||
vpiHandle obj = vpip_make_binary_param(name, value4, signed_flag,
|
||||
file_idx, lineno);
|
||||
local_flag, file_idx, lineno);
|
||||
compile_vpi_symbol(label, obj);
|
||||
vpip_attach_to_current_scope(obj);
|
||||
|
||||
|
|
@ -1821,10 +1826,11 @@ void compile_param_logic(char*label, char*name, char*value, bool signed_flag,
|
|||
}
|
||||
|
||||
void compile_param_string(char*label, char*name, char*value,
|
||||
bool local_flag,
|
||||
long file_idx, long lineno)
|
||||
{
|
||||
// name and value become owned bi vpip_make_string_param
|
||||
vpiHandle obj = vpip_make_string_param(name, value, file_idx, lineno);
|
||||
vpiHandle obj = vpip_make_string_param(name, value, local_flag, file_idx, lineno);
|
||||
compile_vpi_symbol(label, obj);
|
||||
vpip_attach_to_current_scope(obj);
|
||||
|
||||
|
|
@ -1832,10 +1838,11 @@ void compile_param_string(char*label, char*name, char*value,
|
|||
}
|
||||
|
||||
void compile_param_real(char*label, char*name, char*value,
|
||||
bool local_flag,
|
||||
long file_idx, long lineno)
|
||||
{
|
||||
double dvalue = crstring_to_double(value);
|
||||
vpiHandle obj = vpip_make_real_param(name, dvalue, file_idx, lineno);
|
||||
vpiHandle obj = vpip_make_real_param(name, dvalue, local_flag, file_idx, lineno);
|
||||
compile_vpi_symbol(label, obj);
|
||||
vpip_attach_to_current_scope(obj);
|
||||
|
||||
|
|
|
|||
|
|
@ -254,11 +254,13 @@ extern void compile_vpi_symbol(const char*label, vpiHandle obj);
|
|||
extern void compile_vpi_lookup(vpiHandle *objref, char*label);
|
||||
|
||||
extern void compile_param_string(char*label, char*name, char*value,
|
||||
bool local_flag,
|
||||
long file_idx, long lineno);
|
||||
extern void compile_param_logic(char*label, char*name, char*value,
|
||||
bool signed_flag,
|
||||
bool signed_flag, bool local_flag,
|
||||
long file_idx, long lineno);
|
||||
extern void compile_param_real(char*label, char*name, char*value,
|
||||
bool local_flag,
|
||||
long file_idx, long lineno);
|
||||
|
||||
/*
|
||||
|
|
@ -456,6 +458,17 @@ extern void compile_variable(char*label, char*name,
|
|||
extern void compile_var_real(char*label, char*name,
|
||||
int msb, int lsb);
|
||||
|
||||
/*
|
||||
* This function is used to create a scope port
|
||||
* Current ONLY module ports are supported and ports exist purely
|
||||
* as meta-data for VPI queries (i.e. there is NO corresponding net etc)
|
||||
* as elaboration internally eliminates port-nets by directly connecting
|
||||
* nets connected through module ports.
|
||||
*/
|
||||
|
||||
extern void compile_port_info( unsigned index, int vpi_port_type, unsigned width, const char *name );
|
||||
|
||||
|
||||
/*
|
||||
* The compile_net function is called to create a .net vector with a
|
||||
* given name.
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include <stddef.h>
|
||||
# include "vvp_net.h"
|
||||
# include "schedule.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ static char* strdupnew(char const *str)
|
|||
".part/v" { return K_PART_V; }
|
||||
".part/v.s" { return K_PART_V_S; }
|
||||
".port" { return K_PORT; }
|
||||
".port_info" { return K_PORT_INFO; }
|
||||
".reduce/and" { return K_REDUCE_AND; }
|
||||
".reduce/or" { return K_REDUCE_OR; }
|
||||
".reduce/xor" { return K_REDUCE_XOR; }
|
||||
|
|
@ -263,6 +264,12 @@ static char* strdupnew(char const *str)
|
|||
assert(yylval.text);
|
||||
return T_SYMBOL; }
|
||||
|
||||
"/INPUT" { return K_PORT_INPUT; }
|
||||
"/OUTPUT" { return K_PORT_OUTPUT; }
|
||||
"/INOUT" { return K_PORT_INOUT; }
|
||||
"/MIXED" { return K_PORT_MIXED; }
|
||||
"/NODIR" { return K_PORT_NODIR; }
|
||||
|
||||
/* Symbols are pretty much what is left. They are used to refer to
|
||||
labels so the rule must match a string that a label would match. */
|
||||
[.$_a-zA-Z\\]([.$_a-zA-Z\\0-9/]|(\\.))* {
|
||||
|
|
|
|||
10
vvp/main.cc
10
vvp/main.cc
|
|
@ -284,6 +284,16 @@ int main(int argc, char*argv[])
|
|||
vpip_module_path[0] = strdup(basepath);
|
||||
#endif
|
||||
|
||||
|
||||
if( ::getenv("VVP_WAIT_FOR_DEBUGGER") != 0 ) {
|
||||
fprintf( stderr, "Waiting for debugger...\n");
|
||||
bool debugger_release = false;
|
||||
while( !debugger_release ) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* For non-interactive runs we do not want to run the interactive
|
||||
* debugger, so make $stop just execute a $finish. */
|
||||
stop_is_finish = false;
|
||||
|
|
|
|||
35
vvp/parse.y
35
vvp/parse.y
|
|
@ -68,6 +68,8 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
vpiHandle vpi;
|
||||
|
||||
vvp_delay_t*cdelay;
|
||||
|
||||
int vpi_enum;
|
||||
};
|
||||
|
||||
%token K_A K_ALIAS K_ALIAS_R K_APV
|
||||
|
|
@ -84,7 +86,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
%token K_EXPORT K_EXTEND_S K_FUNCTOR K_IMPORT K_ISLAND K_MODPATH
|
||||
%token K_NET K_NET_S K_NET_R K_NET_2S K_NET_2U K_NET8 K_NET8_S
|
||||
%token K_PARAM_STR K_PARAM_L K_PARAM_REAL K_PART K_PART_PV
|
||||
%token K_PART_V K_PART_V_S K_PORT K_PV K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
|
||||
%token K_PART_V K_PART_V_S K_PORT K_PORT_INFO K_PV K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
|
||||
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
|
||||
%token K_RESOLV K_SCOPE K_SFUNC K_SFUNC_E K_SHIFTL K_SHIFTR K_SHIFTRS
|
||||
%token K_THREAD K_TIMESCALE K_TRAN K_TRANIF0 K_TRANIF1 K_TRANVP
|
||||
|
|
@ -95,6 +97,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
%token K_disable K_fork
|
||||
%token K_ivl_version K_ivl_delay_selection
|
||||
%token K_vpi_module K_vpi_time_precision K_file_names K_file_line
|
||||
%token K_PORT_INPUT K_PORT_OUTPUT K_PORT_INOUT K_PORT_MIXED K_PORT_NODIR
|
||||
|
||||
%token <text> T_INSTR
|
||||
%token <text> T_LABEL
|
||||
|
|
@ -104,6 +107,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
%token <vect> T_VECTOR
|
||||
|
||||
%type <flag> local_flag
|
||||
%type <vpi_enum> port_type
|
||||
%type <numb> signed_t_number
|
||||
%type <symb> symbol symbol_opt
|
||||
%type <symbv> symbols symbols_net
|
||||
|
|
@ -628,6 +632,7 @@ statement
|
|||
T_NUMBER T_NUMBER T_NUMBER ',' T_SYMBOL ';'
|
||||
{ compile_scope_decl($1, $3, $5, $6, $14, $7, $8, $10, $11, $12); }
|
||||
|
||||
|
||||
/* Legacy declaration that does not have `celldefine information. */
|
||||
|
||||
| T_LABEL K_SCOPE T_SYMBOL ',' T_STRING T_STRING T_NUMBER T_NUMBER ','
|
||||
|
|
@ -649,6 +654,10 @@ statement
|
|||
{ compile_scope_recall($2); }
|
||||
|
||||
|
||||
/* Port information for scopes... currently this is just meta-data for VPI queries */
|
||||
| K_PORT_INFO T_NUMBER port_type T_NUMBER T_STRING
|
||||
{ compile_port_info( $2 /* port_index */, $3, $4 /* width */, $5 /*&name */ ); }
|
||||
|
||||
| K_TIMESCALE T_NUMBER T_NUMBER';'
|
||||
{ compile_timescale($2, $3); }
|
||||
| K_TIMESCALE '-' T_NUMBER T_NUMBER';'
|
||||
|
|
@ -758,17 +767,17 @@ statement
|
|||
/* Parameter statements come in a few simple forms. The most basic
|
||||
is the string parameter. */
|
||||
|
||||
| T_LABEL K_PARAM_STR T_STRING T_NUMBER T_NUMBER',' T_STRING ';'
|
||||
{ compile_param_string($1, $3, $7, $4, $5); }
|
||||
| T_LABEL K_PARAM_STR T_STRING T_NUMBER T_NUMBER T_NUMBER',' T_STRING ';'
|
||||
{ compile_param_string($1, $3, $8, $4, $5, $6); }
|
||||
|
||||
| T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER',' T_SYMBOL ';'
|
||||
{ compile_param_logic($1, $3, $7, false, $4, $5); }
|
||||
| T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER T_NUMBER',' T_SYMBOL ';'
|
||||
{ compile_param_logic($1, $3, $8, false, $4, $5, $6); }
|
||||
|
||||
| T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER',' '+' T_SYMBOL ';'
|
||||
{ compile_param_logic($1, $3, $8, true, $4, $5); }
|
||||
| T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER T_NUMBER',' '+' T_SYMBOL ';'
|
||||
{ compile_param_logic($1, $3, $9, true, $4, $5, $6 ); }
|
||||
|
||||
| T_LABEL K_PARAM_REAL T_STRING T_NUMBER T_NUMBER',' T_SYMBOL ';'
|
||||
{ compile_param_real($1, $3, $7, $4, $5); }
|
||||
| T_LABEL K_PARAM_REAL T_STRING T_NUMBER T_NUMBER T_NUMBER',' T_SYMBOL ';'
|
||||
{ compile_param_real($1, $3, $8, $4, $5, $6); }
|
||||
|
||||
/* Islands */
|
||||
|
||||
|
|
@ -1049,6 +1058,14 @@ modpath_src_list
|
|||
| modpath_src_list ',' modpath_src
|
||||
;
|
||||
|
||||
port_type
|
||||
: K_PORT_INPUT { $$ = vpiInput; }
|
||||
| K_PORT_OUTPUT { $$ = vpiOutput; }
|
||||
| K_PORT_INOUT { $$ = vpiInout; }
|
||||
| K_PORT_MIXED { $$ = vpiMixedIO; }
|
||||
| K_PORT_NODIR { $$ = vpiNoDirection; }
|
||||
;
|
||||
|
||||
modpath_src
|
||||
: symbol '(' numbers ')' symbol
|
||||
{ compile_modpath_src(modpath_dst, 0, $1, $3, 0, $5, false); }
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ struct argv_s {
|
|||
char **syms;
|
||||
};
|
||||
|
||||
|
||||
extern void argv_init(struct argv_s*obj);
|
||||
extern void argv_add(struct argv_s*obj, vpiHandle);
|
||||
extern void argv_sym_add(struct argv_s*obj, char *);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ struct event_s {
|
|||
|
||||
void event_s::single_step_display(void)
|
||||
{
|
||||
cerr << "event_s: Step into event " << typeid(*this).name() << endl;
|
||||
std::cerr << "event_s: Step into event " << typeid(*this).name() << std::endl;
|
||||
}
|
||||
|
||||
struct event_time_s {
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ class __vpiStringParam : public __vpiStringConst {
|
|||
vpiHandle vpi_handle(int code);
|
||||
|
||||
struct __vpiScope* scope;
|
||||
bool local_flag;
|
||||
unsigned file_idx;
|
||||
unsigned lineno;
|
||||
private:
|
||||
|
|
@ -280,10 +281,16 @@ int __vpiStringParam::get_type_code(void) const
|
|||
|
||||
int __vpiStringParam::vpi_get(int code)
|
||||
{
|
||||
if (code == vpiLineNo)
|
||||
return lineno;
|
||||
switch (code) {
|
||||
case vpiLineNo :
|
||||
return lineno;
|
||||
|
||||
return __vpiStringConst::vpi_get(code);
|
||||
case vpiLocalParam :
|
||||
return local_flag;
|
||||
|
||||
default :
|
||||
return __vpiStringConst::vpi_get(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -312,10 +319,11 @@ vpiHandle __vpiStringParam::vpi_handle(int code)
|
|||
}
|
||||
|
||||
vpiHandle vpip_make_string_param(char*name, char*text,
|
||||
long file_idx, long lineno)
|
||||
bool local_flag, long file_idx, long lineno)
|
||||
{
|
||||
__vpiStringParam*obj = new __vpiStringParam(text, name);
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->local_flag = local_flag;
|
||||
obj->file_idx = (unsigned) file_idx;
|
||||
obj->lineno = (unsigned) lineno;
|
||||
|
||||
|
|
@ -449,6 +457,7 @@ struct __vpiBinaryParam : public __vpiBinaryConst {
|
|||
struct __vpiScope*scope;
|
||||
unsigned file_idx;
|
||||
unsigned lineno;
|
||||
bool local_flag;
|
||||
private:
|
||||
char*basename_;
|
||||
};
|
||||
|
|
@ -469,10 +478,16 @@ int __vpiBinaryParam::get_type_code(void) const
|
|||
|
||||
int __vpiBinaryParam::vpi_get(int code)
|
||||
{
|
||||
if (code == vpiLineNo)
|
||||
return lineno;
|
||||
switch (code) {
|
||||
case vpiLineNo :
|
||||
return lineno;
|
||||
|
||||
return __vpiBinaryConst::vpi_get(code);
|
||||
case vpiLocalParam :
|
||||
return local_flag;
|
||||
|
||||
default :
|
||||
return __vpiBinaryConst::vpi_get(code);
|
||||
}
|
||||
}
|
||||
|
||||
char*__vpiBinaryParam::vpi_get_str(int code)
|
||||
|
|
@ -500,13 +515,14 @@ vpiHandle __vpiBinaryParam::vpi_handle(int code)
|
|||
|
||||
|
||||
vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
|
||||
bool signed_flag,
|
||||
bool signed_flag, bool local_flag,
|
||||
long file_idx, long lineno)
|
||||
{
|
||||
struct __vpiBinaryParam*obj = new __vpiBinaryParam(bits, name);
|
||||
|
||||
obj->signed_flag = signed_flag? 1 : 0;
|
||||
obj->sized_flag = 0;
|
||||
obj->local_flag = local_flag;
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->file_idx = (unsigned) file_idx;
|
||||
obj->lineno = (unsigned) lineno;
|
||||
|
|
@ -662,6 +678,7 @@ struct __vpiRealParam : public __vpiRealConst {
|
|||
vpiHandle vpi_handle(int code);
|
||||
|
||||
struct __vpiScope* scope;
|
||||
bool local_flag;
|
||||
unsigned file_idx;
|
||||
unsigned lineno;
|
||||
private:
|
||||
|
|
@ -686,10 +703,16 @@ int __vpiRealParam::get_type_code(void) const
|
|||
|
||||
int __vpiRealParam::vpi_get(int code)
|
||||
{
|
||||
if (code == vpiLineNo)
|
||||
return lineno;
|
||||
switch (code) {
|
||||
case vpiLineNo :
|
||||
return lineno;
|
||||
|
||||
return __vpiRealConst::vpi_get(code);
|
||||
case vpiLocalParam :
|
||||
return local_flag;
|
||||
|
||||
default :
|
||||
return __vpiRealConst::vpi_get(code);
|
||||
}
|
||||
}
|
||||
|
||||
char* __vpiRealParam::vpi_get_str(int code)
|
||||
|
|
@ -716,11 +739,12 @@ vpiHandle __vpiRealParam::vpi_handle(int code)
|
|||
|
||||
|
||||
vpiHandle vpip_make_real_param(char*name, double value,
|
||||
long file_idx, long lineno)
|
||||
bool local_flag, long file_idx, long lineno)
|
||||
{
|
||||
struct __vpiRealParam*obj = new __vpiRealParam(value, name);
|
||||
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
obj->local_flag = local_flag;
|
||||
obj->file_idx = (unsigned) file_idx;
|
||||
obj->lineno = (unsigned) lineno;
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,10 @@ static const char* vpi_type_values(PLI_INT32 code)
|
|||
return "vpiNamedEvent";
|
||||
case vpiNamedFork:
|
||||
return "vpiNamedFork";
|
||||
case vpiPathTerm:
|
||||
return "vpiPathTerm";
|
||||
case vpiPort:
|
||||
return "vpiPort";
|
||||
case vpiNet:
|
||||
return "vpiNet";
|
||||
case vpiNetArray:
|
||||
|
|
@ -541,8 +545,7 @@ void vpi_set_vlog_info(int argc, char** argv)
|
|||
vpi_vlog_info.argv = argv;
|
||||
|
||||
static char trace_buf[1024];
|
||||
|
||||
if (const char*path = getenv("VPI_TRACE")) {
|
||||
if (const char*path = getenv("VPI_TRACE")) {
|
||||
if (!strcmp(path,"-"))
|
||||
vpi_trace = stdout;
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -200,6 +200,10 @@ struct __vpiScopedRealtime : public __vpiSystemTime {
|
|||
void vpi_get_value(p_vpi_value val);
|
||||
};
|
||||
|
||||
struct __vpiPortInfo : public __vpiHandle {
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Scopes are created by .scope statements in the source. These
|
||||
|
|
@ -536,7 +540,7 @@ extern struct __vpiSysTaskCall*vpip_cur_task;
|
|||
*/
|
||||
|
||||
vpiHandle vpip_make_string_const(char*text, bool persistent =true);
|
||||
vpiHandle vpip_make_string_param(char*name, char*value,
|
||||
vpiHandle vpip_make_string_param(char*name, char*value, bool local_flag,
|
||||
long file_idx, long lineno);
|
||||
|
||||
struct __vpiBinaryConst : public __vpiHandle {
|
||||
|
|
@ -554,7 +558,7 @@ struct __vpiBinaryConst : public __vpiHandle {
|
|||
|
||||
vpiHandle vpip_make_binary_const(unsigned wid, const char*bits);
|
||||
vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
|
||||
bool signed_flag,
|
||||
bool signed_flag, bool local_flag,
|
||||
long file_idx, long lineno);
|
||||
|
||||
struct __vpiDecConst : public __vpiHandle {
|
||||
|
|
@ -577,7 +581,7 @@ class __vpiRealConst : public __vpiHandle {
|
|||
};
|
||||
|
||||
vpiHandle vpip_make_real_const(double value);
|
||||
vpiHandle vpip_make_real_param(char*name, double value,
|
||||
vpiHandle vpip_make_real_param(char*name, double value, bool local_flag,
|
||||
long file_idx, long lineno);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
# include <cassert>
|
||||
# include "ivl_alloc.h"
|
||||
|
||||
|
||||
static vpiHandle *vpip_root_table_ptr = 0;
|
||||
static unsigned vpip_root_table_cnt = 0;
|
||||
|
||||
|
|
@ -525,3 +526,96 @@ unsigned vpip_add_item_to_context(automatic_hooks_s*item,
|
|||
/* Offset the context index by 2 to leave space for the list links. */
|
||||
return 2 + idx;
|
||||
}
|
||||
|
||||
|
||||
struct vpiPortInfo : public __vpiHandle {
|
||||
vpiPortInfo( __vpiScope *parent,
|
||||
unsigned index,
|
||||
int vpi_direction,
|
||||
unsigned width,
|
||||
const char *name );
|
||||
|
||||
|
||||
int get_type_code(void) const { return vpiPort; }
|
||||
|
||||
int vpi_get(int code);
|
||||
char* vpi_get_str(int code);
|
||||
vpiHandle vpi_handle(int code);
|
||||
|
||||
protected:
|
||||
__vpiScope *parent_;
|
||||
unsigned index_;
|
||||
int direction_;
|
||||
unsigned width_;
|
||||
const char *name_;
|
||||
};
|
||||
|
||||
vpiPortInfo::vpiPortInfo( __vpiScope *parent,
|
||||
unsigned index,
|
||||
int vpi_direction,
|
||||
unsigned width,
|
||||
const char *name ) :
|
||||
parent_(parent),
|
||||
index_(index),
|
||||
direction_(vpi_direction),
|
||||
width_(width),
|
||||
name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
int vpiPortInfo::vpi_get(int code)
|
||||
{
|
||||
switch( code ) {
|
||||
|
||||
case vpiDirection :
|
||||
return direction_;
|
||||
case vpiPortIndex :
|
||||
return index_;
|
||||
case vpiSize :
|
||||
return width_;
|
||||
default :
|
||||
return vpiUndefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
char *vpiPortInfo::vpi_get_str(int code)
|
||||
{
|
||||
switch( code ) {
|
||||
case vpiName :
|
||||
return simple_set_rbuf_str(name_);
|
||||
default :
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
vpiHandle vpiPortInfo::vpi_handle(int code)
|
||||
{
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiParent:
|
||||
case vpiScope:
|
||||
case vpiModule:
|
||||
return parent_;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Port info is meta-data to allow vpi queries of the port signature of modules for
|
||||
* code-generators etc. There are no actual nets corresponding to instances of module ports
|
||||
* as elaboration directly connects nets connected through module ports.
|
||||
*/
|
||||
void compile_port_info( unsigned index, int vpi_direction, unsigned width, const char *name )
|
||||
{
|
||||
vpiHandle obj = new vpiPortInfo( vpip_peek_current_scope(),
|
||||
index, vpi_direction, width, name );
|
||||
vpip_attach_to_current_scope(obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ void compile_variable(char*label, char*name,
|
|||
delete[] name;
|
||||
}
|
||||
|
||||
|
||||
vvp_net_t* create_constant_node(const char*val_str)
|
||||
{
|
||||
if (c4string_test(val_str)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue