Convert vvm to implement system tasks with vpi.
This commit is contained in:
parent
f1825c54a7
commit
2d0e11283d
|
|
@ -18,7 +18,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.11 1999/08/07 20:05:51 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.12 1999/08/15 01:23:56 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
@ -46,11 +46,13 @@ CXXFLAGS = @CXXFLAGS@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
all: ivl
|
all: ivl
|
||||||
|
cd vpi ; make all
|
||||||
cd vvm ; make all
|
cd vvm ; make all
|
||||||
cd ivlpp ; make all
|
cd ivlpp ; make all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc
|
rm *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc
|
||||||
|
cd vpi ; make clean
|
||||||
cd vvm ; make clean
|
cd vvm ; make clean
|
||||||
cd ivlpp ; make clean
|
cd ivlpp ; make clean
|
||||||
|
|
||||||
|
|
@ -87,6 +89,7 @@ lexor.cc: lexor.lex
|
||||||
flex -PVL -s -olexor.cc lexor.lex
|
flex -PVL -s -olexor.cc lexor.lex
|
||||||
|
|
||||||
install: all installdirs $(bindir)/ivl
|
install: all installdirs $(bindir)/ivl
|
||||||
|
cd vpi ; make install
|
||||||
cd vvm ; make install
|
cd vvm ; make install
|
||||||
cd ivlpp ; make install
|
cd ivlpp ; make install
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ AC_PROG_CC
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
AC_OUTPUT(Makefile ivlpp/Makefile vvm/Makefile)
|
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile)
|
||||||
|
|
|
||||||
88
t-vvm.cc
88
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: t-vvm.cc,v 1.34 1999/08/02 00:19:16 steve Exp $"
|
#ident "$Id: t-vvm.cc,v 1.35 1999/08/15 01:23:56 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
@ -306,6 +306,14 @@ static string emit_proc_rval(ostream&os, unsigned indent, const NetExpr*expr)
|
||||||
return scan.result;
|
return scan.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The vvm_parm_rval class scans expressions for the purpose of making
|
||||||
|
* parameters for system tasks/functions. Thus, the generated code is
|
||||||
|
* geared towards making the handles needed to make the call.
|
||||||
|
*
|
||||||
|
* The result of any parm rval scan is a vpiHandle, or a string that
|
||||||
|
* automatically converts to a vpiHandle on assignment.
|
||||||
|
*/
|
||||||
class vvm_parm_rval : public expr_scan_t {
|
class vvm_parm_rval : public expr_scan_t {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -326,8 +334,11 @@ class vvm_parm_rval : public expr_scan_t {
|
||||||
void vvm_parm_rval::expr_const(const NetEConst*expr)
|
void vvm_parm_rval::expr_const(const NetEConst*expr)
|
||||||
{
|
{
|
||||||
if (expr->value().is_string()) {
|
if (expr->value().is_string()) {
|
||||||
result = "\"";
|
result = make_temp();
|
||||||
result = result + expr->value().as_string() + "\"";
|
os_ << " struct __vpiHandle " << result << ";" << endl;
|
||||||
|
os_ << " vvm_make_vpi_parm(&" << result << ", \""
|
||||||
|
<< expr->value().as_string() << "\");" << endl;
|
||||||
|
result = "&" + result;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -353,16 +364,19 @@ void vvm_parm_rval::expr_const(const NetEConst*expr)
|
||||||
os_ << ";" << endl;
|
os_ << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = tname;
|
result = make_temp();
|
||||||
|
os_ << " struct __vpiHandle " << result << ";" << endl;
|
||||||
|
os_ << " vvm_make_vpi_parm(&" << result << ", &" << tname
|
||||||
|
<< ");" << endl;
|
||||||
|
result = "&" + result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vvm_parm_rval::expr_ident(const NetEIdent*expr)
|
void vvm_parm_rval::expr_ident(const NetEIdent*expr)
|
||||||
{
|
{
|
||||||
if (expr->name() == "$time") {
|
if (expr->name() == "$time") {
|
||||||
string res = make_temp();
|
os_ << " system_time.val.time.low "
|
||||||
os_ << " vvm_calltf_parm " << res <<
|
"= sim_->get_sim_time();" << endl;
|
||||||
"(vvm_calltf_parm::TIME);" << endl;
|
result = string("&system_time");
|
||||||
result = res;
|
|
||||||
} else {
|
} else {
|
||||||
cerr << "Unhandled identifier: " << expr->name() << endl;
|
cerr << "Unhandled identifier: " << expr->name() << endl;
|
||||||
}
|
}
|
||||||
|
|
@ -370,12 +384,7 @@ void vvm_parm_rval::expr_ident(const NetEIdent*expr)
|
||||||
|
|
||||||
void vvm_parm_rval::expr_signal(const NetESignal*expr)
|
void vvm_parm_rval::expr_signal(const NetESignal*expr)
|
||||||
{
|
{
|
||||||
string res = make_temp();
|
string res = string("&") + mangle(expr->name()) + "_vpi";
|
||||||
os_ << " vvm_calltf_parm::SIG " << res << ";" << endl;
|
|
||||||
os_ << " " << res << ".bits = &" <<
|
|
||||||
mangle(expr->name()) << "_bits;" << endl;
|
|
||||||
os_ << " " << res << ".mon = &" <<
|
|
||||||
mangle(expr->name()) << ";" << endl;
|
|
||||||
result = res;
|
result = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,11 +402,16 @@ void target_vvm::start_design(ostream&os, const Design*mod)
|
||||||
os << "# include \"vvm_func.h\"" << endl;
|
os << "# include \"vvm_func.h\"" << endl;
|
||||||
os << "# include \"vvm_calltf.h\"" << endl;
|
os << "# include \"vvm_calltf.h\"" << endl;
|
||||||
os << "# include \"vvm_thread.h\"" << endl;
|
os << "# include \"vvm_thread.h\"" << endl;
|
||||||
|
os << "# include \"vpi_user.h\"" << endl;
|
||||||
|
os << "# include \"vpi_priv.h\"" << endl;
|
||||||
|
|
||||||
|
os << "static struct __vpiHandle system_time;" << endl;
|
||||||
process_counter = 0;
|
process_counter = 0;
|
||||||
|
|
||||||
init_code << "static void design_init(vvm_simulation&sim)" << endl;
|
init_code << "static void design_init(vvm_simulation&sim)" << endl;
|
||||||
init_code << "{" << endl;
|
init_code << "{" << endl;
|
||||||
|
init_code << " vvm_init_vpi_timevar(&system_time, \"$time\");"
|
||||||
|
<< endl;
|
||||||
start_code << "static void design_start(vvm_simulation&sim)" << endl;
|
start_code << "static void design_start(vvm_simulation&sim)" << endl;
|
||||||
start_code << "{" << endl;
|
start_code << "{" << endl;
|
||||||
}
|
}
|
||||||
|
|
@ -414,6 +428,7 @@ void target_vvm::end_design(ostream&os, const Design*mod)
|
||||||
os << start_code.str();
|
os << start_code.str();
|
||||||
|
|
||||||
os << "main()" << endl << "{" << endl;
|
os << "main()" << endl << "{" << endl;
|
||||||
|
os << " vvm_load_vpi_module(\"system.vpi\");" << endl;
|
||||||
os << " vvm_simulation sim;" << endl;
|
os << " vvm_simulation sim;" << endl;
|
||||||
os << " design_init(sim);" << endl;
|
os << " design_init(sim);" << endl;
|
||||||
os << " design_start(sim);" << endl;
|
os << " design_start(sim);" << endl;
|
||||||
|
|
@ -818,6 +833,14 @@ void target_vvm::net_esignal(ostream&os, const NetESignal*net)
|
||||||
os << "static vvm_signal_t<" << net->pin_count() << "> " <<
|
os << "static vvm_signal_t<" << net->pin_count() << "> " <<
|
||||||
mangle(net->name()) << "(\"" << net->name() << "\", &" <<
|
mangle(net->name()) << "(\"" << net->name() << "\", &" <<
|
||||||
mangle(net->name()) << "_bits);" << endl;
|
mangle(net->name()) << "_bits);" << endl;
|
||||||
|
|
||||||
|
os << "static struct __vpiHandle " << mangle(net->name()) <<
|
||||||
|
"_vpi;" << endl;
|
||||||
|
|
||||||
|
init_code << " vvm_init_vpi_handle(&" <<
|
||||||
|
mangle(net->name()) << "_vpi, &" << mangle(net->name()) <<
|
||||||
|
"_bits, &" << mangle(net->name()) << ");" << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1139,16 +1162,42 @@ void target_vvm::proc_repeat(ostream&os, const NetRepeat*net)
|
||||||
void target_vvm::proc_stask(ostream&os, const NetSTask*net)
|
void target_vvm::proc_stask(ostream&os, const NetSTask*net)
|
||||||
{
|
{
|
||||||
string ptmp = make_temp();
|
string ptmp = make_temp();
|
||||||
os << " struct vvm_calltf_parm " << ptmp << "[" <<
|
|
||||||
|
#if 0
|
||||||
|
os << " struct __vpiHandle " << ptmp << "[" <<
|
||||||
net->nparms() << "];" << endl;
|
net->nparms() << "];" << endl;
|
||||||
for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1)
|
for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1)
|
||||||
if (net->parm(idx)) {
|
if (net->parm(idx)) {
|
||||||
string val = emit_parm_rval(os, net->parm(idx));
|
string val = emit_parm_rval(os, net->parm(idx));
|
||||||
os << " " << ptmp << "[" << idx << "] = " <<
|
os << " vvm_make_vpi_parm(&" << ptmp << "["
|
||||||
val << ";" << endl;
|
<< idx << "], " << val << ");" << endl;
|
||||||
|
} else {
|
||||||
|
os << " vvm_make_vpi_parm(&" << ptmp << "["
|
||||||
|
<< idx << "]);" << endl;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
os << " vpiHandle " << ptmp << "[" << net->nparms() <<
|
||||||
|
"];" << endl;
|
||||||
|
for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1) {
|
||||||
|
string val;
|
||||||
|
if (net->parm(idx)) {
|
||||||
|
val = emit_parm_rval(os, net->parm(idx));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
val = make_temp();
|
||||||
|
os << " struct __vpiHandle " << val << ";" << endl;
|
||||||
|
os << " vvm_make_vpi_parm(&" << val << ");" << endl;
|
||||||
|
val = string("&") + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << " " << ptmp << "[" << idx << "] = " << val << ";"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os << " vvm_calltask(sim_, \"" << net->name() << "\", " <<
|
os << " vvm_calltask(sim_, \"" << net->name() << "\", " <<
|
||||||
net->nparms() << ", " << ptmp << ");" << endl;
|
net->nparms() << ", " << ptmp << ");" << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void target_vvm::proc_utask(ostream&os, const NetUTask*net)
|
void target_vvm::proc_utask(ostream&os, const NetUTask*net)
|
||||||
|
|
@ -1308,6 +1357,9 @@ extern const struct target tgt_vvm = {
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* $Log: t-vvm.cc,v $
|
* $Log: t-vvm.cc,v $
|
||||||
|
* Revision 1.35 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
* Revision 1.34 1999/08/02 00:19:16 steve
|
* Revision 1.34 1999/08/02 00:19:16 steve
|
||||||
* Get rid of excess set/init of NetESignal objects.
|
* Get rid of excess set/init of NetESignal objects.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
|
||||||
|
HOW IT WORKS
|
||||||
|
|
||||||
|
The VPI interface for Icarus Verilog works by creating from a
|
||||||
|
collection of PLI applications a single vpi module. The vpi module
|
||||||
|
includes compiled code for the applications linked together (with any
|
||||||
|
other libraries that the applications need) into a module with a
|
||||||
|
single exported symbol, the vlog_startup_routines array.
|
||||||
|
|
||||||
|
The product that wishes to invoke the module (normally at run time)
|
||||||
|
loads the module, locates the vlog_startup_routines table, and calls
|
||||||
|
all the startup routines contained in that table. It is possible for a
|
||||||
|
product to link with many modules. In that case, all the modules are
|
||||||
|
linked in and startup routines are called in order.
|
||||||
|
|
||||||
|
The product that uses vpi modules uses the environment variable
|
||||||
|
VPI_MODULE_PATH as a ':' separated list of directories. This is the
|
||||||
|
module search path. When a module is specified by name (using whatever
|
||||||
|
means the product supports) the module search path is scanned until
|
||||||
|
the module is located.
|
||||||
|
|
||||||
|
The special module name "system.vpi" is part of the core Icarus
|
||||||
|
Verilog distribution and includes implementations of the standard
|
||||||
|
system tasks/functions.
|
||||||
|
|
||||||
|
COMPILING A VPI MODULE (LINUX)
|
||||||
|
|
||||||
|
To compile a module, first compile down to object files all the PLI
|
||||||
|
applications that you wish to include in the module. Then, create a
|
||||||
|
small "C" source file that defines only the startup table like so:
|
||||||
|
|
||||||
|
extern void hello_register();
|
||||||
|
void (*vlog_startup_routines[])() = {
|
||||||
|
hello_register,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
Compile this table source down to its object file, as well. Finally,
|
||||||
|
link the application with the command:
|
||||||
|
|
||||||
|
cc -o foo.vpi -shared <all the .o files>
|
||||||
|
|
||||||
|
No VPI libraries need to be included because the product that loads
|
||||||
|
the module will supply all the standard vpi functions. If you use any
|
||||||
|
non-vpi library functions, you may need to include libraries to
|
||||||
|
support them.
|
||||||
|
|
||||||
|
The resulting foo.vpi file is the vpi module. Place it in a location
|
||||||
|
where the product to use it can locate it.
|
||||||
|
|
||||||
|
|
||||||
|
CAVEAT EMPTOR
|
||||||
|
|
||||||
|
Only the calltf function is supported. The compiletf and sizetf
|
||||||
|
functions are invoked at compile time, and the ivl compiler does not
|
||||||
|
yet support VPI.
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
Makefile
|
||||||
|
system.vpi
|
||||||
|
dep
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#
|
||||||
|
# This source code is free software; you can redistribute it
|
||||||
|
# and/or modify it in source code form under the terms of the GNU
|
||||||
|
# Library General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version. In order to redistribute the software in
|
||||||
|
# binary form, you will need a Picture Elements Binary Software
|
||||||
|
# License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public
|
||||||
|
# License along with this program; if not, write to the Free
|
||||||
|
# Software Foundation, Inc.,
|
||||||
|
# 59 Temple Place - Suite 330
|
||||||
|
# Boston, MA 02111-1307, USA
|
||||||
|
#
|
||||||
|
#ident "$Id: Makefile.in,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
VERSION = 0.0
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
|
||||||
|
VPATH = $(srcdir)
|
||||||
|
|
||||||
|
bindir = $(exec_prefix)/bin
|
||||||
|
libdir = $(exec_prefix)/lib
|
||||||
|
includedir = $(prefix)/include
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
CXX = @CXX@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
|
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
|
all: system.vpi
|
||||||
|
|
||||||
|
%.o dep/%.d: %.c
|
||||||
|
@[ -d dep ] || mkdir dep
|
||||||
|
$(CC) -Wall $(CPPFLAGS) -MD -c $< -o $*.o
|
||||||
|
mv $*.d dep
|
||||||
|
|
||||||
|
O = sys_table.o sys_display.o sys_finish.o
|
||||||
|
|
||||||
|
system.vpi: $O
|
||||||
|
$(CC) -shared -o $@ $O
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o dep/*.d
|
||||||
|
|
||||||
|
install: all installdirs $(libdir)/ivl/system.vpi \
|
||||||
|
$(includedir)/vpi_user.h \
|
||||||
|
$(includedir)/veriuser.h
|
||||||
|
|
||||||
|
$(libdir)/ivl/system.vpi: ./system.vpi
|
||||||
|
$(INSTALL_PROGRAM) ./system.vpi $(libdir)/ivl/system.vpi
|
||||||
|
|
||||||
|
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
|
||||||
|
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
|
||||||
|
|
||||||
|
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||||
|
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
|
||||||
|
|
||||||
|
|
||||||
|
installdirs: mkinstalldirs
|
||||||
|
$(srcdir)/mkinstalldirs $(includedir) $(bindir) $(libdir)/ivl
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f $(libdir)/ivl/system.vpi
|
||||||
|
rm -f $(includedir)/vpi_user.h
|
||||||
|
rm -f $(includedir)/veriuser.h
|
||||||
|
|
||||||
|
|
||||||
|
-include $(patsubst %.o, dep/%.d, $O)
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: sys_display.c,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# include "vpi_user.h"
|
||||||
|
# include <assert.h>
|
||||||
|
# include <string.h>
|
||||||
|
# include <ctype.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
|
||||||
|
static void format_binary(vpiHandle argv, int fsize)
|
||||||
|
{
|
||||||
|
s_vpi_value value;
|
||||||
|
vpiHandle item = vpi_scan(argv);
|
||||||
|
if (item == 0) return;
|
||||||
|
|
||||||
|
value.format = vpiBinStrVal;
|
||||||
|
vpi_get_value(item, &value);
|
||||||
|
vpi_printf("%s", value.value.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void format_decimal(vpiHandle argv, int fsize)
|
||||||
|
{
|
||||||
|
s_vpi_value value;
|
||||||
|
vpiHandle item = vpi_scan(argv);
|
||||||
|
if (item == 0) return;
|
||||||
|
|
||||||
|
value.format = vpiDecStrVal;
|
||||||
|
vpi_get_value(item, &value);
|
||||||
|
vpi_printf("%s", value.value.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void format_hex(vpiHandle argv, int fsize)
|
||||||
|
{
|
||||||
|
s_vpi_value value;
|
||||||
|
vpiHandle item = vpi_scan(argv);
|
||||||
|
if (item == 0) return;
|
||||||
|
|
||||||
|
value.format = vpiHexStrVal;
|
||||||
|
vpi_get_value(item, &value);
|
||||||
|
vpi_printf("%s", value.value.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void format_m(vpiHandle argv, int fsize)
|
||||||
|
{
|
||||||
|
vpiHandle item = vpi_scan(argv);
|
||||||
|
if (item == 0) return;
|
||||||
|
|
||||||
|
vpi_printf("%s", vpi_get_str(vpiFullName, item));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If $display discovers a string as a parameter, this function is
|
||||||
|
* called to process it as a format string. I need the argv handle as
|
||||||
|
* well so that I can look for arguments as I move forward through the
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
|
static void format(s_vpi_value*fmt, vpiHandle argv)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
char*cp = fmt->value.str;
|
||||||
|
assert(fmt->value.str);
|
||||||
|
|
||||||
|
while (*cp) {
|
||||||
|
size_t cnt = strcspn(cp, "%\\");
|
||||||
|
if (cnt > 0) {
|
||||||
|
if (cnt >= sizeof buf)
|
||||||
|
cnt = sizeof buf - 1;
|
||||||
|
strncpy(buf, cp, cnt);
|
||||||
|
buf[cnt] = 0;
|
||||||
|
vpi_printf("%s", buf);
|
||||||
|
cp += cnt;
|
||||||
|
|
||||||
|
} else if (*cp == '%') {
|
||||||
|
int fsize = -1;
|
||||||
|
|
||||||
|
cp += 1;
|
||||||
|
if (isdigit(*cp))
|
||||||
|
fsize = strtoul(cp, &cp, 10);
|
||||||
|
|
||||||
|
switch (*cp) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
format_binary(argv, fsize);
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
format_decimal(argv, fsize);
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
format_hex(argv, fsize);
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
format_m(argv, fsize);
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
vpi_printf("%%");
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpi_printf("%c", *cp);
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cp += 1;
|
||||||
|
switch (*cp) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
vpi_printf("\n");
|
||||||
|
cp += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpi_printf("%c", *cp);
|
||||||
|
cp += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sys_display_calltf(char *xx)
|
||||||
|
{
|
||||||
|
s_vpi_value value;
|
||||||
|
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
|
||||||
|
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
||||||
|
vpiHandle item;
|
||||||
|
|
||||||
|
for (item = vpi_scan(argv) ; item ; item = vpi_scan(argv)) {
|
||||||
|
|
||||||
|
switch (vpi_get(vpiType, item)) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
vpi_printf(" ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiConstant:
|
||||||
|
value.format = vpiObjTypeVal;
|
||||||
|
vpi_get_value(item, &value);
|
||||||
|
switch (value.format) {
|
||||||
|
case vpiStringVal:
|
||||||
|
format(&value, argv);
|
||||||
|
break;
|
||||||
|
case vpiSuppressVal:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpi_printf("?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiNet:
|
||||||
|
case vpiReg:
|
||||||
|
value.format = vpiBinStrVal;
|
||||||
|
vpi_get_value(item, &value);
|
||||||
|
vpi_printf("%s", value.value.str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiTimeVar:
|
||||||
|
value.format = vpiTimeVal;
|
||||||
|
vpi_get_value(item, &value);
|
||||||
|
vpi_printf("%u", value.value.time->low);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vpi_printf("?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vpi_printf("\n");
|
||||||
|
|
||||||
|
vpi_free_object(argv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_display_register()
|
||||||
|
{
|
||||||
|
s_vpi_systf_data tf_data;
|
||||||
|
|
||||||
|
tf_data.type = vpiSysTask;
|
||||||
|
tf_data.tfname = "$display";
|
||||||
|
tf_data.calltf = sys_display_calltf;
|
||||||
|
tf_data.compiletf = 0;
|
||||||
|
tf_data.sizetf = 0;
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: sys_display.c,v $
|
||||||
|
* Revision 1.1 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: sys_finish.c,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# include "vpi_user.h"
|
||||||
|
# include "veriuser.h"
|
||||||
|
|
||||||
|
static int sys_finish_calltf(char *xx)
|
||||||
|
{
|
||||||
|
tf_dofinish();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_finish_register()
|
||||||
|
{
|
||||||
|
s_vpi_systf_data tf_data;
|
||||||
|
|
||||||
|
tf_data.type = vpiSysTask;
|
||||||
|
tf_data.tfname = "$finish";
|
||||||
|
tf_data.calltf = sys_finish_calltf;
|
||||||
|
tf_data.compiletf = 0;
|
||||||
|
tf_data.sizetf = 0;
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: sys_finish.c,v $
|
||||||
|
* Revision 1.1 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: sys_table.c,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void sys_finish_register();
|
||||||
|
extern void sys_display_register();
|
||||||
|
|
||||||
|
void (*vlog_startup_routines[])() = {
|
||||||
|
sys_finish_register,
|
||||||
|
sys_display_register,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: sys_table.c,v $
|
||||||
|
* Revision 1.1 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef __veriuser_H
|
||||||
|
#define __veriuser_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: veriuser.h,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header file only exists as a stub, and to carry the function
|
||||||
|
* declaration for the tf_dofinish() function. I plan on removing both
|
||||||
|
* as soon as a VPI way of doing this appears.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void tf_dofinish();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: veriuser.h,v $
|
||||||
|
* Revision 1.1 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
#ifndef __vpi_user_H
|
||||||
|
#define __vpi_user_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: vpi_user.h,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct __vpiHandle *vpiHandle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This structure is created by the VPI application to provide hooks
|
||||||
|
* into the application that the compiler/simulator can access.
|
||||||
|
*/
|
||||||
|
typedef struct t_vpi_systf_data {
|
||||||
|
int type;
|
||||||
|
int subtype;
|
||||||
|
char *tfname;
|
||||||
|
int (*calltf)(char*);
|
||||||
|
int (*compiletf)(char*);
|
||||||
|
int (*sizetf)();
|
||||||
|
char *user_data;
|
||||||
|
} s_vpi_systf_data, *p_vpi_systf_data;
|
||||||
|
|
||||||
|
/* The type in the above structure can have one of the following
|
||||||
|
values: */
|
||||||
|
#define vpiSysTask 1
|
||||||
|
#define vpiSysFunc 2
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct t_vpi_time {
|
||||||
|
int type;
|
||||||
|
unsigned int high;
|
||||||
|
unsigned int low;
|
||||||
|
double real;
|
||||||
|
} s_vpi_time, *p_vpi_time;
|
||||||
|
|
||||||
|
#define vpiScaledRealTime 1
|
||||||
|
#define vpiSimTime 2
|
||||||
|
#define vpiSuppressTime 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This structure holds values that are passed back and forth between
|
||||||
|
* the simulator and the application.
|
||||||
|
*/
|
||||||
|
typedef struct t_vpi_value {
|
||||||
|
int format;
|
||||||
|
union {
|
||||||
|
char*str;
|
||||||
|
int scalar;
|
||||||
|
int integer;
|
||||||
|
double real;
|
||||||
|
struct t_vpi_time *time;
|
||||||
|
struct t_vpi_vecval *vector;
|
||||||
|
struct t_vpi_strengthval *strength;
|
||||||
|
char*misc;
|
||||||
|
} value;
|
||||||
|
} s_vpi_value, *p_vpi_value;
|
||||||
|
|
||||||
|
/* These are valid codes for the format of the t_vpi_value structure. */
|
||||||
|
#define vpiBinStrVal 1
|
||||||
|
#define vpiOctStrVal 2
|
||||||
|
#define vpiDecStrVal 3
|
||||||
|
#define vpiHexStrVal 4
|
||||||
|
#define vpiScalerVal 5
|
||||||
|
#define vpiIntVal 6
|
||||||
|
#define vpiReadVal 7
|
||||||
|
#define vpiStringVal 8
|
||||||
|
#define vpiVectorVal 9
|
||||||
|
#define vpiStrengthVal 10
|
||||||
|
#define vpiTimeVal 11
|
||||||
|
#define vpiObjTypeVal 12
|
||||||
|
#define vpiSuppressVal 13
|
||||||
|
|
||||||
|
|
||||||
|
/* OBJECT CODES */
|
||||||
|
#define vpiConstant 7
|
||||||
|
#define vpiNet 36
|
||||||
|
#define vpiReg 48
|
||||||
|
#define vpiSysTaskCall 57
|
||||||
|
#define vpiTimeVar 63
|
||||||
|
#define vpiSysTfCall 85
|
||||||
|
#define vpiArgument 89
|
||||||
|
|
||||||
|
|
||||||
|
/* PROPERTIES */
|
||||||
|
#define vpiType 1
|
||||||
|
#define vpiName 2
|
||||||
|
#define vpiFullName 3
|
||||||
|
#define vpiConstType 43
|
||||||
|
# define vpiDecConst 1
|
||||||
|
# define vpiRealConst 2
|
||||||
|
# define vpiBinaryConst 3
|
||||||
|
# define vpiOctConst 4
|
||||||
|
# define vpiHexConst 5
|
||||||
|
# define vpiStringConst 6
|
||||||
|
|
||||||
|
|
||||||
|
/* VPI FUNCTIONS */
|
||||||
|
extern void vpi_register_systf(const struct t_vpi_systf_data*ss);
|
||||||
|
extern void vpi_printf(const char*fmt, ...);
|
||||||
|
|
||||||
|
extern vpiHandle vpi_handle(int type, vpiHandle ref);
|
||||||
|
extern vpiHandle vpi_iterate(int type, vpiHandle ref);
|
||||||
|
extern vpiHandle vpi_scan(vpiHandle iter);
|
||||||
|
|
||||||
|
extern int vpi_get(int property, vpiHandle ref);
|
||||||
|
extern char* vpi_get_str(int property, vpiHandle ref);
|
||||||
|
extern void vpi_get_value(vpiHandle expr, p_vpi_value value);
|
||||||
|
|
||||||
|
extern int vpi_free_object(vpiHandle ref);
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the table of startup routines included in each module. */
|
||||||
|
extern void (*vlog_startup_routines[])();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: vpi_user.h,v $
|
||||||
|
* Revision 1.1 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
16
vvm.txt
16
vvm.txt
|
|
@ -16,6 +16,17 @@ So a sample command line to compile a Verilog file to C++ would be:
|
||||||
|
|
||||||
ivl -F nobufz -F sigfold -F propinit -t vvm -o foo.cc foo.vl
|
ivl -F nobufz -F sigfold -F propinit -t vvm -o foo.cc foo.vl
|
||||||
|
|
||||||
|
Once the program is compiled down to C++ code, it needs to be further
|
||||||
|
compiled and linked into an executable image. The command for doing
|
||||||
|
this is highly dependent on the system where you use Icarus
|
||||||
|
Verilog. For Linux, the compile command is typically:
|
||||||
|
|
||||||
|
c++ -o foo foo.cc -lvvm -ldl
|
||||||
|
|
||||||
|
On any system, the compiled program requires that the VPI_MODULE_PATH
|
||||||
|
be set to a ':' separated list of directories to search for vpi files,
|
||||||
|
the system.vpi file in particular. This is a run time requirement.
|
||||||
|
|
||||||
ATTRIBUTES
|
ATTRIBUTES
|
||||||
|
|
||||||
(none)
|
(none)
|
||||||
|
|
@ -99,8 +110,11 @@ bits are at:
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$Id: vvm.txt,v 1.1 1999/04/29 16:29:04 steve Exp $
|
$Id: vvm.txt,v 1.2 1999/08/15 01:23:56 steve Exp $
|
||||||
$Log: vvm.txt,v $
|
$Log: vvm.txt,v $
|
||||||
|
Revision 1.2 1999/08/15 01:23:56 steve
|
||||||
|
Convert vvm to implement system tasks with vpi.
|
||||||
|
|
||||||
Revision 1.1 1999/04/29 16:29:04 steve
|
Revision 1.1 1999/04/29 16:29:04 steve
|
||||||
Add vvm target documentation
|
Add vvm target documentation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.3 1999/05/09 01:24:59 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.4 1999/08/15 01:23:56 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
@ -36,7 +36,7 @@ libdir = $(exec_prefix)/lib
|
||||||
includedir = $(prefix)/include
|
includedir = $(prefix)/include
|
||||||
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CXX = @CXX@
|
CXX = @CXX@ -I../vpi
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
@ -52,9 +52,8 @@ all: libvvm.a
|
||||||
$(CXX) -Wall -fno-exceptions $(CXXFLAGS) -MD -c $< -o $*.o
|
$(CXX) -Wall -fno-exceptions $(CXXFLAGS) -MD -c $< -o $*.o
|
||||||
mv $*.d dep
|
mv $*.d dep
|
||||||
|
|
||||||
TF = display.o
|
|
||||||
O = vvm_bit.o vvm_calltf.o vvm_event.o vvm_monitor.o vvm_pevent.o \
|
O = vvm_bit.o vvm_calltf.o vvm_event.o vvm_monitor.o vvm_pevent.o \
|
||||||
vvm_simulation.o vvm_thread.o $(TF)
|
vvm_simulation.o vvm_thread.o
|
||||||
|
|
||||||
libvvm.a: $O
|
libvvm.a: $O
|
||||||
rm -f $@
|
rm -f $@
|
||||||
|
|
|
||||||
264
vvm/display.cc
264
vvm/display.cc
|
|
@ -1,264 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
|
|
||||||
*
|
|
||||||
* This source code is free software; you can redistribute it
|
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
|
||||||
* General Public License as published by the Free Software
|
|
||||||
* Foundation; either version 2 of the License, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
*/
|
|
||||||
#if !defined(WINNT)
|
|
||||||
#ident "$Id: display.cc,v 1.5 1999/05/31 15:46:36 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "vvm.h"
|
|
||||||
# include "vvm_calltf.h"
|
|
||||||
# include <iostream>
|
|
||||||
|
|
||||||
static void format_hex(vvm_simulation*sim, ostream&os,
|
|
||||||
class vvm_calltf_parm*parm)
|
|
||||||
{
|
|
||||||
switch (parm->type()) {
|
|
||||||
case vvm_calltf_parm::TIME:
|
|
||||||
os << sim->get_sim_time();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::NONE:
|
|
||||||
os << "z";
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::ULONG:
|
|
||||||
os << ((parm->as_ulong()&1) ? "0" : "1");
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::STRING:
|
|
||||||
os << parm->as_string();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::BITS:
|
|
||||||
unsigned c = 0;
|
|
||||||
for (unsigned idx = parm->as_bits()->get_width()
|
|
||||||
; idx > 0 ; idx -= 1)
|
|
||||||
c = (c << 1) | parm->as_bits()->get_bit(idx-1);
|
|
||||||
cout.form("%x",c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void format_bit(vvm_simulation*sim, ostream&os,
|
|
||||||
class vvm_calltf_parm*parm)
|
|
||||||
{
|
|
||||||
switch (parm->type()) {
|
|
||||||
case vvm_calltf_parm::TIME:
|
|
||||||
os << (sim->get_sim_time()&1);
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::NONE:
|
|
||||||
os << "z";
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::ULONG:
|
|
||||||
os << ((parm->as_ulong()&1) ? "0" : "1");
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::STRING:
|
|
||||||
os << parm->as_string();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::BITS:
|
|
||||||
for (unsigned idx = parm->as_bits()->get_width()
|
|
||||||
; idx > 0 ; idx -= 1)
|
|
||||||
os << parm->as_bits()->get_bit(idx-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_dec(vvm_simulation*sim, ostream&os,
|
|
||||||
class vvm_calltf_parm*parm)
|
|
||||||
{
|
|
||||||
switch (parm->type()) {
|
|
||||||
case vvm_calltf_parm::TIME:
|
|
||||||
os << sim->get_sim_time();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::NONE:
|
|
||||||
os << "0";
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::ULONG:
|
|
||||||
os << parm->as_ulong();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::STRING:
|
|
||||||
os << parm->as_string();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::BITS: {
|
|
||||||
unsigned long val = 0;
|
|
||||||
unsigned long mask = 1;
|
|
||||||
const vvm_bits_t*bstr = parm->as_bits();
|
|
||||||
for (unsigned idx = 0 ; idx < bstr->get_width() ; idx += 1) {
|
|
||||||
if (bstr->get_bit(idx) == V1) val |= mask;
|
|
||||||
mask <<= 1;
|
|
||||||
}
|
|
||||||
os << val;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void format_name(ostream&os, class vvm_calltf_parm*parm)
|
|
||||||
{
|
|
||||||
switch (parm->type()) {
|
|
||||||
case vvm_calltf_parm::TIME:
|
|
||||||
os << "$time";
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::NONE:
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::ULONG:
|
|
||||||
os << parm->as_ulong();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::STRING:
|
|
||||||
os << "\"" << parm->as_string() << "\"";
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::BITS:
|
|
||||||
os << parm->sig_name();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned format(vvm_simulation*sim, const string&str,
|
|
||||||
unsigned nparms,
|
|
||||||
class vvm_calltf_parm*parms)
|
|
||||||
{
|
|
||||||
char prev = 0;
|
|
||||||
unsigned next_parm = 0;
|
|
||||||
unsigned idx = 0;
|
|
||||||
while (idx < str.length()) {
|
|
||||||
if (prev == '%') {
|
|
||||||
switch (str[idx]) {
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
format_bit(sim, cout, parms+next_parm);
|
|
||||||
next_parm += 1;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
case 'h':
|
|
||||||
case 'H':
|
|
||||||
format_hex(sim, cout, parms+next_parm);
|
|
||||||
next_parm += 1;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
format_dec(sim, cout, parms+next_parm);
|
|
||||||
next_parm += 1;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
case 'M':
|
|
||||||
format_name(cout, parms+next_parm);
|
|
||||||
next_parm += 1;
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
cout << str[idx];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (str[idx] != '%')
|
|
||||||
cout << str[idx];
|
|
||||||
else
|
|
||||||
prev = '%';
|
|
||||||
}
|
|
||||||
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return next_parm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sdisplay(vvm_simulation*sim, const string&name,
|
|
||||||
unsigned nparms, class vvm_calltf_parm*parms)
|
|
||||||
{
|
|
||||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1)
|
|
||||||
switch (parms[idx].type()) {
|
|
||||||
case vvm_calltf_parm::NONE:
|
|
||||||
cout << " ";
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::TIME:
|
|
||||||
cout << sim->get_sim_time();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::ULONG:
|
|
||||||
cout << parms[idx].as_ulong();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::STRING:
|
|
||||||
idx += format(sim, parms[idx].as_string(),
|
|
||||||
nparms-idx-1, parms+idx+1);
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::BITS:
|
|
||||||
cout << *parms[idx].as_bits();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
class monitor_event : public vvm_event {
|
|
||||||
public:
|
|
||||||
monitor_event(vvm_simulation*sim,
|
|
||||||
unsigned nparms, class vvm_calltf_parm*parms)
|
|
||||||
{ sim_ = sim;
|
|
||||||
nparms_ = nparms;
|
|
||||||
parms_ = new vvm_calltf_parm[nparms];
|
|
||||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
|
||||||
parms_[idx] = parms[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
~monitor_event() { delete[]parms_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
vvm_simulation*sim_;
|
|
||||||
unsigned nparms_;
|
|
||||||
vvm_calltf_parm*parms_;
|
|
||||||
void event_function();
|
|
||||||
};
|
|
||||||
|
|
||||||
void monitor_event::event_function()
|
|
||||||
{
|
|
||||||
Sdisplay(sim_, "$display", nparms_, parms_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static monitor_event*mon = 0;
|
|
||||||
|
|
||||||
void Smonitor(vvm_simulation*sim, const string&name,
|
|
||||||
unsigned nparms, class vvm_calltf_parm*parms)
|
|
||||||
{
|
|
||||||
if (mon) delete mon;
|
|
||||||
mon = new monitor_event(sim, nparms, parms);
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
|
|
||||||
if (parms[idx].type() != vvm_calltf_parm::BITS)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
parms[idx].as_mon()->enable(mon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: display.cc,v $
|
|
||||||
* Revision 1.5 1999/05/31 15:46:36 steve
|
|
||||||
* Handle time in more places.
|
|
||||||
*
|
|
||||||
* Revision 1.4 1999/05/12 04:02:17 steve
|
|
||||||
* Add %x support contributed by Steve Wilson.
|
|
||||||
*
|
|
||||||
* Revision 1.3 1999/01/01 01:44:40 steve
|
|
||||||
* Proberly print vectors in binary.
|
|
||||||
*
|
|
||||||
* Revision 1.2 1998/11/10 00:48:31 steve
|
|
||||||
* Add support it vvm target for level-sensitive
|
|
||||||
* triggers (i.e. the Verilog wait).
|
|
||||||
* Fix display of $time is format strings.
|
|
||||||
*
|
|
||||||
* Revision 1.1 1998/11/09 23:44:10 steve
|
|
||||||
* Add vvm library.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
#ifndef __vpi_priv_H
|
||||||
|
#define __vpi_priv_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#if !defined(WINNT)
|
||||||
|
#ident "$Id: vpi_priv.h,v 1.1 1999/08/15 01:23:56 steve Exp $"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the most basic type in the vpi implementation. A handle can
|
||||||
|
* exist to refer to most any of the supported vpi objects. The
|
||||||
|
* interpretation of the parts depends in general on the type of the
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
struct __vpiHandle {
|
||||||
|
int type;
|
||||||
|
int subtype;
|
||||||
|
|
||||||
|
/* These are property values. */
|
||||||
|
char*full_name;
|
||||||
|
|
||||||
|
/* This pointer is used for to-one references. */
|
||||||
|
struct __vpiHandle*referent;
|
||||||
|
|
||||||
|
/* This pointer table is used for to-many refrences to
|
||||||
|
arguments, and is used by the vpiArgument iterator. */
|
||||||
|
struct __vpiHandle**arguments;
|
||||||
|
unsigned narguments;
|
||||||
|
|
||||||
|
/* These methods support the various vpi_get() functions. */
|
||||||
|
int (*get_)(int property, vpiHandle ref);
|
||||||
|
char* (*get_str_)(int property, vpiHandle ref);
|
||||||
|
|
||||||
|
/* This method is used to get a value. */
|
||||||
|
void (*get_value_)(struct __vpiHandle*expr, s_vpi_value*vp);
|
||||||
|
|
||||||
|
/* This is a value union, that reflect state or the value of a
|
||||||
|
handle. */
|
||||||
|
union {
|
||||||
|
unsigned unum;
|
||||||
|
struct vvm_bits_t*bits;
|
||||||
|
struct t_vpi_time time;
|
||||||
|
} val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* TYPE MEANINGS:
|
||||||
|
*
|
||||||
|
* vpiArgument
|
||||||
|
* This type of handle contains a single referent, the item that has
|
||||||
|
* many arguments. It is an iterator.
|
||||||
|
*
|
||||||
|
* vpiConstant
|
||||||
|
* Constant values, such as strings and numbers, are this type.
|
||||||
|
*
|
||||||
|
* vpiSysTaskCall
|
||||||
|
* This handle type represents a call to a system task. It has a
|
||||||
|
* to-many reference to argument expressions, and a to-one reference
|
||||||
|
* to a vpiUserSystf object.
|
||||||
|
*
|
||||||
|
* vpiTimeVar
|
||||||
|
* This type is a special kind of variable, that holds a time. The
|
||||||
|
* time value is a more complex structure then a single number. The
|
||||||
|
* type really seems to exist to implement the $time system variable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log: vpi_priv.h,v $
|
||||||
|
* Revision 1.1 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
13
vvm/vvm.h
13
vvm/vvm.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvm.h,v 1.9 1999/06/21 01:02:34 steve Exp $"
|
#ident "$Id: vvm.h,v 1.10 1999/08/15 01:23:56 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <vector>
|
# include <vector>
|
||||||
|
|
@ -235,17 +235,17 @@ class vvm_simulation {
|
||||||
*/
|
*/
|
||||||
class vvm_monitor_t {
|
class vvm_monitor_t {
|
||||||
public:
|
public:
|
||||||
vvm_monitor_t(const string&);
|
vvm_monitor_t(const char*);
|
||||||
|
|
||||||
void trigger(vvm_simulation*sim)
|
void trigger(vvm_simulation*sim)
|
||||||
{ if (event_) sim->monitor_event(event_); }
|
{ if (event_) sim->monitor_event(event_); }
|
||||||
|
|
||||||
const string& name() const { return name_; }
|
const char* name() const { return name_; }
|
||||||
|
|
||||||
void enable(vvm_event*e) { event_ = e; }
|
void enable(vvm_event*e) { event_ = e; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string name_;
|
const char* name_;
|
||||||
vvm_event*event_;
|
vvm_event*event_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
|
|
@ -257,7 +257,7 @@ class vvm_monitor_t {
|
||||||
template <unsigned WIDTH> class vvm_signal_t : public vvm_monitor_t {
|
template <unsigned WIDTH> class vvm_signal_t : public vvm_monitor_t {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vvm_signal_t(const string&n, vvm_bitset_t<WIDTH>*b)
|
vvm_signal_t(const char*n, vvm_bitset_t<WIDTH>*b)
|
||||||
: vvm_monitor_t(n), bits_(b)
|
: vvm_monitor_t(n), bits_(b)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -280,6 +280,9 @@ template <unsigned WIDTH> class vvm_signal_t : public vvm_monitor_t {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvm.h,v $
|
* $Log: vvm.h,v $
|
||||||
|
* Revision 1.10 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
* Revision 1.9 1999/06/21 01:02:34 steve
|
* Revision 1.9 1999/06/21 01:02:34 steve
|
||||||
* Add init to vvm_signal_t.
|
* Add init to vvm_signal_t.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -17,153 +17,461 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvm_calltf.cc,v 1.2 1999/05/31 15:46:36 steve Exp $"
|
#ident "$Id: vvm_calltf.cc,v 1.3 1999/08/15 01:23:56 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvm_calltf.h"
|
# include "vvm_calltf.h"
|
||||||
|
# include <vpi_user.h>
|
||||||
|
# include "vpi_priv.h"
|
||||||
# include <new>
|
# include <new>
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <stdarg.h>
|
||||||
|
# include <malloc.h>
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <dlfcn.h>
|
||||||
|
|
||||||
vvm_calltf_parm::vvm_calltf_parm()
|
# define MAX_PATHLEN 1024
|
||||||
: type_(NONE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
vvm_calltf_parm::vvm_calltf_parm(TYPE t)
|
/* This simulation pointer is used by vpi functions to get back to the
|
||||||
: type_(t)
|
simulation. */
|
||||||
{
|
static vvm_simulation*vpi_sim;
|
||||||
assert((t == NONE) || (t == TIME));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vvm_calltf_parm::release_()
|
static vpiHandle vvm_vpi_cur_task;
|
||||||
{
|
|
||||||
switch (type_) {
|
|
||||||
case NONE:
|
|
||||||
case TIME:
|
|
||||||
case ULONG:
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
((string*)string_)->string::~string();
|
|
||||||
break;
|
|
||||||
case BITS:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
type_ = NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
vvm_calltf_parm& vvm_calltf_parm::operator= (unsigned long val)
|
/*
|
||||||
{
|
* Keep a list of vpi_systf_data structures. This list is searched
|
||||||
release_();
|
* forward whenever a function is invoked by name, and items are
|
||||||
type_ = ULONG;
|
* pushed in front of the list whenever they are registered. This
|
||||||
ulong_ = val;
|
* allows entries to override older entries.
|
||||||
return *this;
|
*/
|
||||||
}
|
struct systf_entry {
|
||||||
|
struct systf_entry* next;
|
||||||
vvm_calltf_parm& vvm_calltf_parm::operator= (const string&val)
|
s_vpi_systf_data systf_data;
|
||||||
{
|
|
||||||
release_();
|
|
||||||
type_ = STRING;
|
|
||||||
new (string_) string (val);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
vvm_calltf_parm& vvm_calltf_parm::operator= (const vvm_calltf_parm::SIG&val)
|
|
||||||
{
|
|
||||||
release_();
|
|
||||||
type_ = BITS;
|
|
||||||
bits_ = val;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
vvm_calltf_parm& vvm_calltf_parm::operator= (const vvm_calltf_parm&that)
|
|
||||||
{
|
|
||||||
if (this == &that)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
release_();
|
|
||||||
switch (that.type_) {
|
|
||||||
case NONE:
|
|
||||||
case TIME:
|
|
||||||
type_ = that.type_;
|
|
||||||
break;
|
|
||||||
case ULONG:
|
|
||||||
type_ = ULONG;
|
|
||||||
ulong_ = that.ulong_;
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
type_ = STRING;
|
|
||||||
new (string_) string (that.as_string());
|
|
||||||
break;
|
|
||||||
case BITS:
|
|
||||||
type_ = BITS;
|
|
||||||
bits_ = that.bits_;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
vvm_calltf_parm::~vvm_calltf_parm()
|
|
||||||
{
|
|
||||||
release_();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void Sdisplay(vvm_simulation*sim, const string&name,
|
|
||||||
unsigned nparms, class vvm_calltf_parm*parms);
|
|
||||||
extern void Smonitor(vvm_simulation*sim, const string&name,
|
|
||||||
unsigned nparms, class vvm_calltf_parm*parms);
|
|
||||||
|
|
||||||
static void Sfinish(vvm_simulation*sim, const string&,
|
|
||||||
unsigned, class vvm_calltf_parm*)
|
|
||||||
{
|
|
||||||
sim->s_finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
const string name;
|
|
||||||
void (*func)(vvm_simulation*, const string&,
|
|
||||||
unsigned, class vvm_calltf_parm*);
|
|
||||||
} sys_table[] = {
|
|
||||||
{ "$display", &Sdisplay },
|
|
||||||
{ "$finish", &Sfinish },
|
|
||||||
{ "$monitor", &Smonitor },
|
|
||||||
{ "", 0 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void vvm_calltask(vvm_simulation*sim, const string&fname,
|
static struct systf_entry*systf_list = 0;
|
||||||
unsigned nparms, class vvm_calltf_parm*parms)
|
|
||||||
|
extern "C" void vpi_register_systf(const struct t_vpi_systf_data*systf)
|
||||||
{
|
{
|
||||||
|
struct systf_entry*cur = new struct systf_entry;
|
||||||
|
cur->systf_data = *systf;
|
||||||
|
cur->systf_data.tfname = strdup(systf->tfname);
|
||||||
|
cur->next = systf_list;
|
||||||
|
systf_list = cur;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; sys_table[idx].func ; idx += 1)
|
extern "C" void vpi_printf(const char*fmt, ...)
|
||||||
if (fname == sys_table[idx].name) {
|
{
|
||||||
sys_table[idx].func(sim, fname, nparms, parms);
|
va_list ap;
|
||||||
return;
|
va_start(ap, fmt);
|
||||||
}
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
cout << "Call " << fname << "(";
|
extern "C" void tf_dofinish()
|
||||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
|
{
|
||||||
if (idx > 0) cout << ", ";
|
vpi_sim->s_finish();
|
||||||
switch (parms[idx].type()) {
|
}
|
||||||
case vvm_calltf_parm::NONE:
|
|
||||||
break;
|
extern "C" vpiHandle vpi_handle(int type, vpiHandle ref)
|
||||||
case vvm_calltf_parm::ULONG:
|
{
|
||||||
cout << parms[idx].as_ulong();
|
switch (type) {
|
||||||
break;
|
case vpiSysTfCall:
|
||||||
case vvm_calltf_parm::STRING:
|
return vvm_vpi_cur_task;
|
||||||
cout << "\"" << parms[idx].as_string() << "\"";
|
|
||||||
break;
|
default:
|
||||||
case vvm_calltf_parm::BITS:
|
return 0;
|
||||||
cout << *parms[idx].as_bits();
|
|
||||||
break;
|
|
||||||
case vvm_calltf_parm::TIME:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cout << ")" << endl;
|
}
|
||||||
|
|
||||||
|
extern "C" vpiHandle vpi_iterate(int type, vpiHandle ref)
|
||||||
|
{
|
||||||
|
vpiHandle res = (vpiHandle)calloc(1, sizeof (struct __vpiHandle));
|
||||||
|
res->type = type;
|
||||||
|
res->referent = ref;
|
||||||
|
res->val.unum = 0;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" vpiHandle vpi_scan(vpiHandle ref)
|
||||||
|
{
|
||||||
|
assert(ref->type == vpiArgument);
|
||||||
|
if (ref->val.unum >= ref->referent->narguments)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ref->referent->arguments[ref->val.unum++];
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int vpi_get(int property, vpiHandle ref)
|
||||||
|
{
|
||||||
|
if (property == vpiType)
|
||||||
|
return ref->type;
|
||||||
|
|
||||||
|
if (ref->get_ == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (ref->get_)(property, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" char* vpi_get_str(int property, vpiHandle ref)
|
||||||
|
{
|
||||||
|
if (property == vpiFullName)
|
||||||
|
return ref->full_name;
|
||||||
|
|
||||||
|
if (ref->get_str_ == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (ref->get_str_)(property, ref);
|
||||||
|
|
||||||
|
switch (property) {
|
||||||
|
case vpiName:
|
||||||
|
return ref->full_name;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void vpi_get_value(vpiHandle expr, s_vpi_value*vp)
|
||||||
|
{
|
||||||
|
if (expr->get_value_) {
|
||||||
|
expr->get_value_(expr, vp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vp->format = vpiSuppressVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int vpi_free_object(vpiHandle ref)
|
||||||
|
{
|
||||||
|
free(ref);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is a get_value_ method of a vpiHandle, that supports
|
||||||
|
* reading bits as a string.
|
||||||
|
*/
|
||||||
|
static void get_value_bits(vpiHandle ref, s_vpi_value*vp)
|
||||||
|
{
|
||||||
|
static char buff[1024];
|
||||||
|
char*cp;
|
||||||
|
unsigned width, bytes;
|
||||||
|
unsigned val;
|
||||||
|
assert(ref->val.bits);
|
||||||
|
width = ref->val.bits->get_width();
|
||||||
|
cp = buff;
|
||||||
|
|
||||||
|
switch (vp->format) {
|
||||||
|
case vpiObjTypeVal:
|
||||||
|
case vpiBinStrVal:
|
||||||
|
for (unsigned idx = 0 ; idx < width ; idx += 1)
|
||||||
|
switch (ref->val.bits->get_bit(width-idx-1)) {
|
||||||
|
case V0:
|
||||||
|
*cp++ = '0';
|
||||||
|
break;
|
||||||
|
case V1:
|
||||||
|
*cp++ = '1';
|
||||||
|
break;
|
||||||
|
case Vx:
|
||||||
|
*cp++ = 'x';
|
||||||
|
break;
|
||||||
|
case Vz:
|
||||||
|
*cp++ = 'z';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vp->format = vpiBinStrVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiDecStrVal:
|
||||||
|
val = 0;
|
||||||
|
for (unsigned idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
val *= 2;
|
||||||
|
switch (ref->val.bits->get_bit(width-idx-1)) {
|
||||||
|
case V0:
|
||||||
|
case Vx:
|
||||||
|
case Vz:
|
||||||
|
break;
|
||||||
|
case V1:
|
||||||
|
val += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sprintf(cp, "%u", val);
|
||||||
|
cp += strlen(cp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiOctStrVal:
|
||||||
|
bytes = width%3;
|
||||||
|
if (bytes) {
|
||||||
|
*cp++ = '?';
|
||||||
|
}
|
||||||
|
for (unsigned idx = bytes ; idx < width ; idx += 3) {
|
||||||
|
unsigned x = 0;
|
||||||
|
unsigned z = 0;
|
||||||
|
unsigned v = 0;
|
||||||
|
for (unsigned i = idx ; i < idx+3 ; i += 1) {
|
||||||
|
v *= 2;
|
||||||
|
switch (ref->val.bits->get_bit(width-idx-i-1)) {
|
||||||
|
case V0:
|
||||||
|
break;
|
||||||
|
case V1:
|
||||||
|
v += 1;
|
||||||
|
break;
|
||||||
|
case Vx:
|
||||||
|
x += 1;
|
||||||
|
break;
|
||||||
|
case Vz:
|
||||||
|
z += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x == 3)
|
||||||
|
*cp++ = 'x';
|
||||||
|
else if (x > 0)
|
||||||
|
*cp++ = 'X';
|
||||||
|
else if (z == 3)
|
||||||
|
*cp++ = 'z';
|
||||||
|
else if (z > 0)
|
||||||
|
*cp++ = 'Z';
|
||||||
|
else
|
||||||
|
*cp++ = "01234567"[v];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiHexStrVal:
|
||||||
|
bytes = width%4;
|
||||||
|
if (bytes) {
|
||||||
|
*cp++ = '?';
|
||||||
|
}
|
||||||
|
for (unsigned idx = bytes ; idx < width ; idx += 4) {
|
||||||
|
unsigned x = 0;
|
||||||
|
unsigned z = 0;
|
||||||
|
unsigned v = 0;
|
||||||
|
for (unsigned i = idx ; i < idx+4 ; i += 1) {
|
||||||
|
v *= 2;
|
||||||
|
switch (ref->val.bits->get_bit(width-idx-i-1)) {
|
||||||
|
case V0:
|
||||||
|
break;
|
||||||
|
case V1:
|
||||||
|
v += 1;
|
||||||
|
break;
|
||||||
|
case Vx:
|
||||||
|
x += 1;
|
||||||
|
break;
|
||||||
|
case Vz:
|
||||||
|
z += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x == 4)
|
||||||
|
*cp++ = 'x';
|
||||||
|
else if (x > 0)
|
||||||
|
*cp++ = 'X';
|
||||||
|
else if (z == 4)
|
||||||
|
*cp++ = 'z';
|
||||||
|
else if (z > 0)
|
||||||
|
*cp++ = 'Z';
|
||||||
|
else
|
||||||
|
*cp++ = "01234567abcdef"[v];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*cp++ = '(';
|
||||||
|
*cp++ = '?';
|
||||||
|
*cp++ = ')';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cp++ = 0;
|
||||||
|
vp->value.str = buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_value_strconst(vpiHandle ref, s_vpi_value*vp)
|
||||||
|
{
|
||||||
|
switch (vp->format) {
|
||||||
|
case vpiObjTypeVal:
|
||||||
|
case vpiStringVal:
|
||||||
|
vp->value.str = ref->full_name;
|
||||||
|
vp->format = vpiStringVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vp->format = vpiSuppressVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_value_timevar(vpiHandle ref, s_vpi_value*vp)
|
||||||
|
{
|
||||||
|
static char buf[128];
|
||||||
|
switch (vp->format) {
|
||||||
|
case vpiObjTypeVal:
|
||||||
|
case vpiTimeVal:
|
||||||
|
vp->value.time = &ref->val.time;
|
||||||
|
vp->format = vpiTimeVal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case vpiDecStrVal:
|
||||||
|
sprintf(buf, "%u", ref->val.time.low);
|
||||||
|
vp->value.str = buf;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vp->format = vpiSuppressVal;
|
||||||
|
vp->value.str = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The load_vpi_module function attempts to locate and load the named
|
||||||
|
* vpi module and call the included startup routines. This is invoked
|
||||||
|
* by the generated C++ code to load all the modules that the
|
||||||
|
* simulation requires.
|
||||||
|
*
|
||||||
|
* If there is a '/' character in the name, or there is no
|
||||||
|
* VPI_MODULE_PATH, the the name is usd as is. No path is searched for
|
||||||
|
* the module.
|
||||||
|
*
|
||||||
|
* If there is a VPI_MODULE_PATH and there is no '/' in the name, the
|
||||||
|
* VPI_MODULE_PATH is taken as a ':' separated list of directory
|
||||||
|
* names. Each directory is searched for a module with the right name
|
||||||
|
* that will link in. The current working directory is not implicitly
|
||||||
|
* tried. If you wish '.' be in th search path, include it.
|
||||||
|
*/
|
||||||
|
typedef void (*vlog_startup_routines_t)(void);
|
||||||
|
|
||||||
|
void vvm_load_vpi_module(const char*name)
|
||||||
|
{
|
||||||
|
void*mod = 0;
|
||||||
|
const char*path = getenv("VPI_MODULE_PATH");
|
||||||
|
|
||||||
|
if ((path == 0) || (strchr(name, '/'))) {
|
||||||
|
mod = dlopen(name, RTLD_NOW);
|
||||||
|
if (mod == 0) {
|
||||||
|
cerr << name << ": " << dlerror() << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const char*cur = path;
|
||||||
|
const char*ep;
|
||||||
|
for (cur = path ; cur ; cur = ep? ep+1 : 0) {
|
||||||
|
char dest[MAX_PATHLEN+1];
|
||||||
|
|
||||||
|
ep = strchr(cur, ':');
|
||||||
|
size_t n = ep? ep-cur : strlen(cur);
|
||||||
|
if ((n + strlen(name) + 2) > sizeof dest)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
strncpy(dest, cur, n);
|
||||||
|
dest[n] = '/';
|
||||||
|
dest[n+1] = 0;
|
||||||
|
strcat(dest, name);
|
||||||
|
|
||||||
|
mod = dlopen(dest, RTLD_NOW);
|
||||||
|
if (mod) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mod == 0) {
|
||||||
|
cerr << dlerror() << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*table = dlsym(mod, "vlog_startup_routines");
|
||||||
|
vlog_startup_routines_t*routines = (vlog_startup_routines_t*)table;
|
||||||
|
if (routines == 0) {
|
||||||
|
cerr << name << ": Unable to locate the vlog_startup_routines"
|
||||||
|
" table." << endl;
|
||||||
|
dlclose(mod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; routines[idx] ; idx += 1)
|
||||||
|
(routines[idx])();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvm_make_vpi_parm(vpiHandle ref, const char*val)
|
||||||
|
{
|
||||||
|
memset(ref, 0, sizeof*ref);
|
||||||
|
ref->type = vpiConstant;
|
||||||
|
ref->subtype = vpiStringConst;
|
||||||
|
ref->full_name = const_cast<char*>(val);
|
||||||
|
ref->get_value_ = &get_value_strconst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvm_make_vpi_parm(vpiHandle ref, vvm_bits_t*val)
|
||||||
|
{
|
||||||
|
memset(ref, 0, sizeof*ref);
|
||||||
|
ref->type = vpiConstant;
|
||||||
|
ref->subtype = vpiBinaryConst;
|
||||||
|
ref->full_name = "";
|
||||||
|
ref->val.bits = val;
|
||||||
|
ref->get_value_ = &get_value_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvm_init_vpi_handle(vpiHandle ref, vvm_bits_t*bits, vvm_monitor_t*mon)
|
||||||
|
{
|
||||||
|
memset(ref, 0, sizeof*ref);
|
||||||
|
ref->type = vpiReg;
|
||||||
|
ref->full_name = const_cast<char*>(mon->name());
|
||||||
|
ref->val.bits = bits;
|
||||||
|
ref->get_value_ = &get_value_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvm_init_vpi_timevar(vpiHandle ref, const char*name)
|
||||||
|
{
|
||||||
|
memset(ref, 0, sizeof*ref);
|
||||||
|
ref->type = vpiTimeVar;
|
||||||
|
ref->full_name = const_cast<char*>(name);
|
||||||
|
ref->get_value_ = &get_value_timevar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvm_make_vpi_parm(vpiHandle ref)
|
||||||
|
{
|
||||||
|
memset(ref, 0, sizeof*ref);
|
||||||
|
ref->type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvm_calltask(vvm_simulation*sim, const string&fname,
|
||||||
|
unsigned nparms, vpiHandle*parms)
|
||||||
|
{
|
||||||
|
vpi_sim = sim;
|
||||||
|
|
||||||
|
struct __vpiHandle cur_task;
|
||||||
|
cur_task.type = vpiSysTaskCall;
|
||||||
|
cur_task.full_name = 0;
|
||||||
|
cur_task.referent = 0;
|
||||||
|
cur_task.arguments = parms;
|
||||||
|
cur_task.narguments = nparms;
|
||||||
|
|
||||||
|
vvm_vpi_cur_task = &cur_task;
|
||||||
|
|
||||||
|
/* Look for a systf function to invoke. */
|
||||||
|
for (systf_entry*idx = systf_list ; idx ; idx = idx->next)
|
||||||
|
if (fname == idx->systf_data.tfname) {
|
||||||
|
cur_task.full_name = idx->systf_data.tfname;
|
||||||
|
idx->systf_data.calltf(idx->systf_data.user_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Finally, if nothing is found then something is not
|
||||||
|
right. Print out the function name all the parameters
|
||||||
|
passed, so that someone can deal with it. */
|
||||||
|
cout << "Call " << fname << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvm_calltf.cc,v $
|
* $Log: vvm_calltf.cc,v $
|
||||||
|
* Revision 1.3 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
* Revision 1.2 1999/05/31 15:46:36 steve
|
* Revision 1.2 1999/05/31 15:46:36 steve
|
||||||
* Handle time in more places.
|
* Handle time in more places.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,69 +19,51 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvm_calltf.h,v 1.1 1998/11/09 23:44:11 steve Exp $"
|
#ident "$Id: vvm_calltf.h,v 1.2 1999/08/15 01:23:56 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvm.h"
|
# include "vvm.h"
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
|
typedef struct __vpiHandle*vpiHandle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function loads a vpi module by name.
|
||||||
|
*/
|
||||||
|
extern void vvm_load_vpi_module(const char*path);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The vvm_init_vpi_handle functions initialize statis VPI handles
|
||||||
|
* that may be used many places within the program.
|
||||||
|
*/
|
||||||
|
extern void vvm_init_vpi_handle(vpiHandle, vvm_bits_t*, vvm_monitor_t*);
|
||||||
|
extern void vvm_init_vpi_timevar(vpiHandle, const char*name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The vvm_make_vpi_parm functions initialize the vpiHandles to
|
||||||
|
* represent objects suitable for use as vvm_calltask parameters.
|
||||||
|
*/
|
||||||
|
extern void vvm_make_vpi_parm(vpiHandle ref, const char*val);
|
||||||
|
extern void vvm_make_vpi_parm(vpiHandle ref, vvm_bits_t*val);
|
||||||
|
extern void vvm_make_vpi_parm(vpiHandle ref);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The vvm environment supports external calls to C++ by
|
* The vvm environment supports external calls to C++ by
|
||||||
* vvm_calltask. The code generator generates calls to vvm_calltask
|
* vvm_calltask. The code generator generates calls to vvm_calltask
|
||||||
* that corresponds to the system call in the Verilog source. The
|
* that corresponds to the system call in the Verilog source. The
|
||||||
* vvm_calltask in turn locates the function (by name) and calls the
|
* vvm_calltask in turn locates the vpi implementation (by name) and
|
||||||
* C++ code that implements the task.
|
* calls the VPI that implements the task.
|
||||||
*
|
|
||||||
* The parameters of the task are implemented as an array of
|
|
||||||
* vvm_calltf_parm objects. Each object represents a paramter from the
|
|
||||||
* source.
|
|
||||||
*/
|
*/
|
||||||
class vvm_calltf_parm {
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum TYPE { NONE, ULONG, STRING, BITS, TIME };
|
|
||||||
|
|
||||||
vvm_calltf_parm();
|
|
||||||
explicit vvm_calltf_parm(TYPE);
|
|
||||||
vvm_calltf_parm(const vvm_calltf_parm&);
|
|
||||||
~vvm_calltf_parm();
|
|
||||||
|
|
||||||
TYPE type() const { return type_; }
|
|
||||||
|
|
||||||
struct SIG {
|
|
||||||
vvm_bits_t*bits;
|
|
||||||
vvm_monitor_t*mon;
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned long as_ulong() const { return ulong_; }
|
|
||||||
string as_string() const { return *(string*)string_; }
|
|
||||||
vvm_bits_t* as_bits() const { return bits_.bits; }
|
|
||||||
vvm_monitor_t* as_mon() const { return bits_.mon; }
|
|
||||||
|
|
||||||
const string& sig_name() const { return bits_.mon->name(); }
|
|
||||||
|
|
||||||
vvm_calltf_parm& operator= (unsigned long);
|
|
||||||
vvm_calltf_parm& operator= (const string&);
|
|
||||||
vvm_calltf_parm& operator= (const SIG&);
|
|
||||||
vvm_calltf_parm& operator= (const vvm_calltf_parm&);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TYPE type_;
|
|
||||||
|
|
||||||
union {
|
|
||||||
unsigned long ulong_;
|
|
||||||
char string_[sizeof(string)];
|
|
||||||
SIG bits_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void release_();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void vvm_calltask(vvm_simulation*sim, const string&name,
|
extern void vvm_calltask(vvm_simulation*sim, const string&name,
|
||||||
unsigned nparms, class vvm_calltf_parm*parms);
|
unsigned nparms, vpiHandle*parms);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvm_calltf.h,v $
|
* $Log: vvm_calltf.h,v $
|
||||||
|
* Revision 1.2 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
* Revision 1.1 1998/11/09 23:44:11 steve
|
* Revision 1.1 1998/11/09 23:44:11 steve
|
||||||
* Add vvm library.
|
* Add vvm library.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvm_monitor.cc,v 1.1 1998/11/09 23:44:11 steve Exp $"
|
#ident "$Id: vvm_monitor.cc,v 1.2 1999/08/15 01:23:56 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvm.h"
|
# include "vvm.h"
|
||||||
|
|
||||||
|
|
||||||
vvm_monitor_t::vvm_monitor_t(const string&n)
|
vvm_monitor_t::vvm_monitor_t(const char*n)
|
||||||
: name_(n)
|
: name_(n)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -31,6 +31,9 @@ vvm_monitor_t::vvm_monitor_t(const string&n)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvm_monitor.cc,v $
|
* $Log: vvm_monitor.cc,v $
|
||||||
|
* Revision 1.2 1999/08/15 01:23:56 steve
|
||||||
|
* Convert vvm to implement system tasks with vpi.
|
||||||
|
*
|
||||||
* Revision 1.1 1998/11/09 23:44:11 steve
|
* Revision 1.1 1998/11/09 23:44:11 steve
|
||||||
* Add vvm library.
|
* Add vvm library.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue