Merge branch 'master' into verilog-ams

This commit is contained in:
Stephen Williams 2008-10-26 21:59:53 -07:00
commit 038b024e71
29 changed files with 245 additions and 3684 deletions

130
BUGS.txt
View File

@ -4,23 +4,24 @@ HOW TO REPORT BUGS
Before I can fix an error, I need to understand what the problem
is. Try to explain what is wrong and why you think it is wrong. Please
try to include sample code that demonstrates the problem. Include a
description of what ivl does that is wrong, and what you expect should
happen. And include the command line flags passed to the compiler to make
the error happen. (This is often overlooked, and sometimes important.)
description of what Icarus Verilog does that is wrong, and what you
expect should happen. And include the command line flags passed to the
compiler to make the error happen. (This is often overlooked, and
sometimes important.)
* The Compiler Doesn't Compile
If the Icarus Verilog don't compile, I need to know about the
If Icarus Verilog doesn't compile, I need to know about the
compilation tools you are using. Specifically, I need to know:
- Operating system and processor type,
- Compiler w/ version,
- Library version, and
- Versions of any libraries being linked, and
- anything else you think relevant.
Be aware that I do not have at my disposal a porting lab. I have the
alpha on my desk, and the Linux/Intel box with a logic analyzer and
'scope hanging off it.
workstation on my desk, a Mac laptop, and the Linux/Intel box with a
logic analyzer and 'scope hanging off it.
* The Compiler Crashes
@ -28,26 +29,26 @@ No compiler should crash, no matter what kind of garbage is fed to
it. If the compiler crashes, you definitely found a bug and I need to
know about it.
Ivl internally checks its state while it works, and if it detects
something wrong that it cannot recover from, it will abort
Icarus Verilog internally checks its state while it works, and if it
detects something wrong that it cannot recover from, it will abort
intentionally. The "assertion failure" message that the program
prints in the process of dying is very important. It tells me where in
the source the bad thing happened. Include that message in the bug
report.
If there are not assertion messages, I need to know that as well.
If there are no assertion messages, I need to know that as well.
I also need a complete test program that demonstrates the crash.
* It Doesn't Like My Perfectly Valid Program(tm)
I need to know what you think is right that ivl gets wrong. Does it
reject your "Perfectly Valid Program(tm)" or does it compile it but
give incorrect results? The latter is the most insidious as it doesn't
scream out to be fixed unless someone is watching closely. However, if
I get a sample program from you, and I can compile it, and I run it
and nuclear junk doesn't fall from the sky, I'm moving on to the next
problem.
I need to know what you think is right that Icarus Verilog gets
wrong. Does it reject your "Perfectly Valid Program(tm)" or does it
compile it but give incorrect results? The latter is the most
insidious as it doesn't scream out to be fixed unless someone is
watching closely. However, if I get a sample program from you, and I
can compile it, and I run it and nuclear junk doesn't fall from the
sky, I'm moving on to the next problem.
So, if your program doesn't compile, tell me so, tell me where the
error occurs, and include a complete Perfectly Valid Test Program(tm).
@ -57,24 +58,25 @@ know. What's on my disk is more recent then the latest snapshot.
If your program does compile, but generates incorrect output, I need
to know what it says and what you think it should say. From this I can
take your sample program and work on ivl until it gets the proper
results. For this to work, of course, I first need to know what is
wrong with the output. Spell it out, because I've been known to miss
the obvious. Compiler writers often get buried in the details of the
wrong problem.
take your sample program and work on Icarus Verilog until it gets the
proper results. For this to work, of course, I first need to know what
is wrong with the output. Spell it out, because I've been known to
miss the obvious. Compiler writers often get buried in the details of
the wrong problem.
* It Generates Incorrect Target Code (XNF, EDIF/LPM, etc.)
* It Generates Incorrect Target Code
As ivl adds target code generators, there will be cases where errors
in the output netlist format occur. This is a tough nut because I
might not have all the tools to test the target format you are
reporting problems with. However, if you clearly explain what is right
and wrong about the generated netlist, I will probably be able to fix
the problem. It may take a few iterations.
As Icarus Verilog adds target code generators, there will be cases
where errors in the output netlist format occur. This is a tough nut
because I might not have all the tools to test the target format you
are reporting problems with. However, if you clearly explain what is
right and wrong about the generated output, I will probably be able
to fix the problem. It may take a few iterations.
In this case, if possible include not only the sample Verilog program,
but the generated netlist file(s) and a clear indication of what went
wrong. If it is not clear to me, I will ask for clarification.
wrong or what is expected. If it is not clear to me, I will ask for
clarification.
* The Output is Correct, But Less Than Ideal
@ -91,13 +93,13 @@ demonstrates the problem. If the error occurs after elaboration,
please include a top level module in the program that is suitable for
the target format. If I have to write the module myself, I might not
write it in a way that tickles the bug. So please, send all the
Verilog source (after preprocessing) that I need to invoke the error.
Verilog source that I need to invoke the error.
Also, include the command line you use to invoke the compiler. For
example:
ivl foo.vl -o foo.cc -tvvm
ivl foo.vl -s starthere
iverilog -o foo.out -tvvp foo.v
iverilog foo.vl -s starthere
If the error occurs with the null target (``-tnull'') then a top level
module may not be needed as long as the ``-s <name>'' switch is
@ -108,15 +110,19 @@ invoke the error without any Verilog other than what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
make it all nice and legal.
make it all nice and legal. Please look at the existing tests in the
test suite <http://sourceforge.net/ivtest> for examples of good test
programs.
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
The URL <http://www.icarus.com/cgi-bin/ivl-bugs> is the main bug
tracking system. Once you believe you have found a bug, you may browse
the bugs database for existing bugs that may be related to yours. You
might find that your bug has already been fixed in a later release or
snapshot. If that's the case, then you are set.
The URL <http://sourceforge.net/tracker/?group_id=149850> is the main
bug tracking system. Once you believe you have found a bug, you may
browse the bugs database for existing bugs that may be related to
yours. You might find that your bug has already been fixed in a later
release or snapshot. If that's the case, then you are set. Also,
consider if you are reporting a bug or really asking for a new
feature, and use the appropriate tracker.
The bug database supports basic keyword searches, and you can
optionally limit your search to active bugs, or fixed bugs. You may
@ -125,8 +131,7 @@ broken. You may for example find a related bug that explains your
symptom.
The root page of the bug report database describes how to submit your
completed bug report. You may submit it via the web form, or via
e-mail.
completed bug report.
HOW TO SEND PATCHES
@ -134,21 +139,26 @@ Bug reports with patches are very welcome, especially if they are
formatted such that I can inspect them, decide that they are obviously
correct, and apply them without worry.
I prefer context diffs as emitted by diff from GNU diffutils. Human
beings can read such things, and they are resilient to changing
originals. A good set of flags to diff are ``diff -cNB''. With such
diffs, I can look at the changes you are offering and probably tell at
a glance that they are plausible. Then I can use patch(1) to apply
them. Or I can apply them by hand.
I prefer patches generated by the git source code tracking system. If
you are editing the source, you really should be using the latest
version from git. Please see the developer documentation for more
detailed instructions -- <http://iverilog.wikia.com/wiki/>.
However, if you send patches, *please* tell me what this patch is
supposed to accomplish, and if appropriate include a test program that
demonstrates the efficacy of the patch. (If I have no idea what the
patch is for, I will ask for clarification before applying it.)
When you make a patch, submit it to the "Patches" tracker at
<http://sourceforge.net/tracker/?group_id=149850>. Patches added to
the "Patches" tracker enter the developer workflow, are checked,
applied to the appropriate git branch, and are pushed. Then the
tracker item is closed.
If you send patches, *please* tell me what this patch is supposed to
accomplish, which branch you intended to be patched, and if
appropriate include a test program that demonstrates the efficacy of
the patch. (If I have no idea what the patch is for, I will ask for
clarification before applying it.)
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2003 Stephen Williams except
Icarus Verilog is Copyright (c) 1998-2008 Stephen Williams except
where otherwise noted. Minor patches are covered as derivative works
(or editorial comment or whatever the appropriate legal term is) and
folded into the rest of ivl. However, if a submission can reasonably
@ -158,19 +168,3 @@ then falls under the "otherwise noted" category.
I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
$Log: BUGS.txt,v $
Revision 1.5 2007/03/22 16:08:14 steve
Spelling fixes from Larry
Revision 1.4 2003/02/19 04:36:31 steve
Notes on hte bug database.
Revision 1.3 2003/01/30 16:23:07 steve
Spelling fixes.
Revision 1.2 1999/08/06 04:05:28 steve
Handle scope of parameters.

View File

@ -9,7 +9,7 @@
echo "Autoconf in root..."
autoconf -f
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub tgt-vhdl libveriuser cadpli
for dir in vpi vvp tgt-vvp tgt-fpga tgt-stub tgt-vhdl libveriuser cadpli
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf -f --include=.. )

View File

@ -1174,12 +1174,9 @@ void NetScope::dump(ostream&o) const
}
// Dump the signals,
if (signals_) {
NetNet*cur = signals_->sig_next_;
do {
cur->dump_net(o, 4);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; cur ++) {
cur->second->dump_net(o, 4);
}
// Dump specparams

149
developer-quick-start.txt Normal file
View File

@ -0,0 +1,149 @@
Developer Quick Start for Icarus Verilog
The documentation for getting, building and installing Icarus Verilog
is kept and maintained at the iverilog documentation wiki at
<http://iverilog.wikia.com>. See the Installation Guide for getting
the current source from the git repository (and how to use the git
repository) and see the Developer Guide for instructions on
participating in the Icarus Verilog development process. That
information will not be repeated here.
What this documentation *will* cover is the gross structure of the
Icarus Verilog core compiler source. This will help orient you to the
source code itself, so that you can find the global parts where you
can look for even better detail.
* Compiler Components
- The compiler driver (driver/)
This is the binary that is installed as "iverilog". This program takes
the command line arguments and assembles invocations of all the other
subcommands to perform the steps of compilation.
- The preprocessor (ivlpp/)
This implements the Verilog pre-processor. In Icarus Verilog, the
compiler directives `define, `include, `ifdef and etc. are implemented
in an external program. The ivlpp/ directory contains the source for
this program.
- The core compiler (this directory)
The "ivl" program is the core that does all the Verilog compiler
processing that is not handled elsewhere. This is the main core of the
Icarus Verilog compiler, not the runtime. See below for more details
on the core itself.
- The loadable code generators (tgt-*/)
This core compiler, after it is finished with parsing and semantic
analysis, uses loadable code generators to emit code for suppoted
targets. The tgt-*/ directories contains the source for the target
code generators that are bundled with Icarus Verilog. The tgt-vvp/
directory in particular contains the code generator for the vvp
runtime.
* Runtime Components
- The vvp runtime (vvp/)
This program implements the runtime environment for Icarus
Verilog. It implements the "vvp" command described in the user
documentation. See the vvp/ subdirectory for further developer
documentation.
- The system tasks implementations (vpi/)
The standard Verilog system tasks are implemented using VPI (PLI-2)
and the source is in this subdirectory.
- The PLI-1 compatibility library (libveriuser/)
The Icarus Verilog support for the deprecated PLI-1 is in this
subdirectory. The vvp runtime does not directly support the
PLI-1. Insead, the libveriuser library emulates it using the builtin
PLI-2 support.
- The Cadence PLI module compatibility module (cadpli/)
It is possible in some specialized situations to load and execute
PLI-1 code writen for Verilog-XL. This directory contains the source
for the module that provides the Cadence PLI interface.
* The Core Compiler
The "ivl" binary is the core compiler that does the heavy lifting of
compiling the Veriog source (including libraries) and generating the
output. This is the most complex component of the Icarus Verilog
compilation system.
The process in the abstract starts with the Verilog lexical analysis
and parsing to generate an internal "pform". The pform is then
translated by elaboration into the "netlist" form. The netlist is
processed by some functors (which include some optimizations and
optional synthesys) then is translated into the ivl_target internal
form. And finallly, the ivl_target form is passed via the ivl_target.h
API to the code generators.
- Lexical Analysis
Lexical analysis and parsing use the tools "flex", "gperf", and
"bison". The "flex" input file "lexor.lex" recognizes the tokens in
the input stream. This is called "lexical analysis". The lexical
analyzer also does some processing of compiler directives that are not
otherwise taken care of by the external preprocessor. The lexical
analyzer uses a table of keywords that is generated using the "gperf"
program and the input file "lexor_keywords.gperf". This table allows
the lexical analyzer to efficiently check input words with the rather
large set of potential keywords.
- Parsing
The parser input file "parse.y" is passed to the "bison" program to
generate the parser. The parser uses the functions in parse*.,
parse*.cc, pform*.h and pform*.cc to generate the pform from the
stream of input tokens. The pfrom is what compiler writers call a
"decorated parse tree".
The pform itself is described by the classes in the header files
"PScope.h", "Module.h", "PGenerate.h", "Statement.h", and
"PExpr.h". The implementations of the classes in those header files
are in the similarly named C++ files.
- Elaboration
Elaboration transforms the pform to the netlist form. Elaboration is
conceptually divided into several major steps: Scope elaboration,
parameter overrides and defparam propagation, signal elaboration, and
statement and expression elaboration.
The elaboration of scopes and parameter overrides and defparam
propagation are conceptually separate, but are in practice
intermingled. The elaboration of scopes scans the pform to find and
instantiate all the scopes of the design. New scopes are created by
instantiation of modules (starting with the root instances) by user
defined tasks and functions, named blocks, and generate schemes. The
elaborate_scope methods implement scope elaboration, and the
elab_scope.cc source file has the implementations of those
methods.
The elaborate.cc source file contains the initial calls to the
elaborate_scope for the root scopes to get the process started. In
particular, see the "elaborate" function near the bottom of the
elaborate.cc source file. The calls to Design::make_root_scope create
the initial root scopes, and the creation and enqueue of the
elaborate_root_scope_t work items primes the scope elaboration work
list.
Intermingled in the work list are defparms work items that call the
Design::run_defparams and Design::evaluate_parameters methods that
override and evaluate parameters. The override and evaluation of
parameters must be intermingled with the elaboration of scopes because
the exact values of parameters may impact the scopes created (imagine
generate schemes and instance arrays) and the created scopes in turn
create new parameters that need override and evaluation.

29
emit.cc
View File

@ -380,23 +380,20 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
if (signals_) {
NetNet*cur = signals_->sig_next_;
do {
tgt->signal(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; cur ++) {
tgt->signal(cur->second);
}
/* Run the signals again, but this time to connect the
delay paths. This is done as a second pass because
the paths reference other signals that may be later
in the list. We can do it here because delay paths are
always connected within the scope. */
cur = signals_->sig_next_;
do {
tgt->signal_paths(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
// Run the signals again, but this time to connect the
// delay paths. This is done as a second pass because
// the paths reference other signals that may be later
// in the list. We can do it here because delay paths are
// always connected within the scope.
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; cur ++) {
tgt->signal_paths(cur->second);
}
}

View File

@ -111,20 +111,12 @@ void NetScope::run_functor(Design*des, functor_t*fun)
// apply to signals. Each iteration, allow for the possibility
// that the current signal deletes itself.
if (signals_) {
unsigned count = 0;
NetNet*cur = signals_->sig_next_;
do {
count += 1;
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
cur = signals_->sig_next_;
for (unsigned idx = 0 ; idx < count ; idx += 1) {
NetNet*tmp = cur->sig_next_;
fun->signal(des, cur);
cur = tmp;
}
signals_map_iter_t cur = signals_map_.begin();
while (cur != signals_map_.end()) {
signals_map_iter_t tmp = cur;
cur ++;
fun->signal(des, tmp->second);
}
}

View File

@ -38,7 +38,6 @@
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
: type_(t), up_(up), sib_(0), sub_(0)
{
signals_ = 0;
events_ = 0;
lcounter_ = 0;
is_auto_ = false;
@ -360,30 +359,13 @@ NetEvent* NetScope::find_event(perm_string name)
void NetScope::add_signal(NetNet*net)
{
if (signals_ == 0) {
net->sig_next_ = net;
net->sig_prev_ = net;
} else {
net->sig_next_ = signals_->sig_next_;
net->sig_prev_ = signals_;
net->sig_next_->sig_prev_ = net;
net->sig_prev_->sig_next_ = net;
}
signals_ = net;
signals_map_[net->name()]=net;
}
void NetScope::rem_signal(NetNet*net)
{
assert(net->scope() == this);
if (signals_ == net)
signals_ = net->sig_prev_;
if (signals_ == net) {
signals_ = 0;
} else {
net->sig_prev_->sig_next_ = net->sig_next_;
net->sig_next_->sig_prev_ = net->sig_prev_;
}
signals_map_.erase(net->name());
}
/*
@ -393,16 +375,10 @@ void NetScope::rem_signal(NetNet*net)
*/
NetNet* NetScope::find_signal(perm_string key)
{
if (signals_ == 0)
if (signals_map_.find(key)!=signals_map_.end())
return signals_map_[key];
else
return 0;
NetNet*cur = signals_;
do {
if (cur->name() == key)
return cur;
cur = cur->sig_prev_;
} while (cur != signals_);
return 0;
}
/*

View File

@ -427,7 +427,7 @@ const Link& NetDelaySrc::condit_pin() const
}
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
: NetObj(s, n, 1), sig_next_(0), sig_prev_(0),
: NetObj(s, n, 1),
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
signed_(false), isint_(false), discipline_(0), msb_(npins-1), lsb_(0),
dimensions_(0),
@ -466,8 +466,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
NetNet::NetNet(NetScope*s, perm_string n, Type t,
long ms, long ls)
: NetObj(s, n, 1),
sig_next_(0), sig_prev_(0), type_(t),
: NetObj(s, n, 1), type_(t),
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
isint_(false), discipline_(0), msb_(ms), lsb_(ls), dimensions_(0), s0_(0), e0_(0),
local_flag_(false), eref_count_(0), lref_count_(0)
@ -514,7 +513,7 @@ static unsigned calculate_count(long s, long e)
NetNet::NetNet(NetScope*s, perm_string n, Type t,
long ms, long ls, long array_s, long array_e)
: NetObj(s, n, calculate_count(array_s, array_e)),
sig_next_(0), sig_prev_(0), type_(t), port_type_(NOT_A_PORT),
type_(t), port_type_(NOT_A_PORT),
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
discipline_(0), msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e),
local_flag_(false), eref_count_(0), lref_count_(0)

View File

@ -614,11 +614,6 @@ class NetNet : public NetObj {
virtual void dump_net(ostream&, unsigned) const;
private:
// The NetScope class uses this for listing signals.
friend class NetScope;
NetNet*sig_next_, *sig_prev_;
private:
Type type_;
PortType port_type_;
@ -861,7 +856,8 @@ class NetScope : public Attrib {
NetNet::Type default_nettype_;
NetEvent *events_;
NetNet *signals_;
typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
std::map <perm_string,NetNet*> signals_map_;
perm_string module_name_;
union {
NetTaskDef*task_;

View File

@ -2308,9 +2308,9 @@ generate_case_items
;
generate_case_item
: expression ':' { pform_generate_case_item(@1, $1); } generate_block
: expression ':' { pform_generate_case_item(@1, $1); } generate_block_opt
{ pform_endgenerate(); }
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block_opt
{ pform_endgenerate(); }
;

View File

@ -1,101 +0,0 @@
#
# 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.9 2007/02/06 05:07:32 steve Exp $"
#
#
SHELL = /bin/sh
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
P = vpi_bit.o vpi_callback.o \
vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \
vpi_priv.o vpi_scope.o vpi_signal.o vpi_simulation.o vpi_systask.o vpi_time.o \
vpi_mcd.o vpi_vlog_info.o
all: dep libvpip.a
check: all
Makefile: Makefile.in config.status
./config.status
libvpip.a: $P
ld -r -o vpip.o $P
rm -f $@
ar cvq $@ vpip.o
libvvm.a: $O
rm -f $@
ar cvq $@ $O
dep:
mkdir dep
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep
clean:
rm -rf *.o dep libvpip.a
distclean: clean
rm -f Makefile config.status config.log config.cache
install:: all installdirs \
$(libdir)/libvpip.a \
$(includedir)/vpi_priv.h
$(libdir)/libvpip.a: ./libvpip.a
$(INSTALL_DATA) ./libvpip.a $(libdir)/libvpip.a
$(includedir)/vpi_priv.h: $(srcdir)/vpi_priv.h
$(INSTALL_DATA) $(srcdir)/vpi_priv.h $(includedir)/vpi_priv.h
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(includedir) $(libdir)
uninstall::
rm -f $(libdir)/libvpip.a
rm -f $(includedir)/vpi_priv.h
-include $(patsubst %.o, dep/%.d, $O $P)

View File

@ -1,21 +0,0 @@
AC_INIT(Makefile.in)
AC_CANONICAL_HOST
AC_PROG_CC
AC_CHECK_TOOL(STRIP, strip, true)
AC_PROG_INSTALL
AC_EXEEXT
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# linker options when building a shared library
# AX_LD_SHAREDLIB_OPTS
AC_OUTPUT(Makefile)

View File

@ -1,40 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.1 2001/03/14 19:27:44 steve Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

View File

@ -1,166 +0,0 @@
/*
* Copyright (c) 2000 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_bit.c,v 1.2 2002/08/12 01:35:05 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdio.h>
/*
* A signal value is unambiguous if the top 4 bits and the bottom 4
* bits are identical. This means that the VSSSvsss bits of the 8bit
* value have V==v and SSS==sss.
*/
#define UNAMBIG(v) (! B_ISAMBIG(v))
# define STREN1(v) ( ((v)&0x80)? ((v)&0xf0) : (0x70 - ((v)&0xf0)) )
# define STREN0(v) ( ((v)&0x08)? ((v)&0x0f) : (0x07 - ((v)&0x0f)) )
vpip_bit_t vpip_pair_resolve(vpip_bit_t a, vpip_bit_t b)
{
vpip_bit_t res = a;
if (B_ISZ(b))
return a;
if (UNAMBIG(a) && UNAMBIG(b)) {
/* If both signals are unambiguous, simply choose
the stronger. If they have the same strength
but different values, then this becomes
ambiguous. */
if (a == b) {
/* values are equal. do nothing. */
} else if ((b&0x07) > (res&0x07)) {
/* New value is stronger. Take it. */
res = b;
} else if ((b&0x77) == (res&0x77)) {
/* Strengths are the same. Make value ambiguous. */
res = (res&0x70) | (b&0x07) | 0x80;
} else {
/* Must be res is the stronger one. */
}
} else if (UNAMBIG(res) || UNAMBIG(b)) {
/* If one of the signals is unambiguous, then it
will sweep up the weaker parts of the ambiguous
signal. The result may be ambiguous, or maybe not. */
vpip_bit_t tmp = 0;
if ((res&0x70) > (b&0x70))
tmp |= res&0xf0;
else
tmp |= b&0xf0;
if ((res&0x07) > (b&0x07))
tmp |= res&0x0f;
else
tmp |= b&0x0f;
res = tmp;
} else {
/* If both signals are ambiguous, then the result
has an even wider ambiguity. */
vpip_bit_t tmp = 0;
if (STREN1(b) > STREN1(res))
tmp |= b&0xf0;
else
tmp |= res&0xf0;
if (STREN0(b) < STREN0(res))
tmp |= b&0x0f;
else
tmp |= res&0x0f;
res = tmp;
}
/* Canonicalize the HiZ value. */
if ((res&0x77) == 0)
res = HiZ;
return res;
}
vpip_bit_t vpip_bits_resolve(const vpip_bit_t*bits, unsigned nbits)
{
unsigned idx;
vpip_bit_t res = bits[0];
idx = 1;
while ((idx < nbits) && B_ISZ(res)) {
res = bits[idx];
idx += 1;
}
for ( ; idx < nbits ; idx += 1)
res = vpip_pair_resolve(res, bits[idx]);
return res;
}
/*
* $Log: vpi_bit.c,v $
* Revision 1.2 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.5 2000/05/11 01:37:33 steve
* Calculate the X output value from drive0 and drive1
*
* Revision 1.4 2000/05/09 21:16:35 steve
* Give strengths to logic and bufz devices.
*
* Revision 1.3 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* Change vvm constants to use the driver_t to drive
* a constant value. This works better if there are
* multiple drivers on a signal.
*
* Revision 1.2 2000/03/22 05:16:38 steve
* Integrate drive resolution function.
*
* Revision 1.1 2000/03/22 04:26:40 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
*/

View File

@ -1,228 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_callback.c,v 1.2 2002/08/12 01:35:05 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdlib.h>
# include <assert.h>
static struct __vpirt vpip_callback_rt = {
vpiCallback,
0,
0,
0,
0,
0,
0
};
/*
* This function is called by the scheduler to execute an event of
* some sort. The parameter is a vpiHandle of the callback that is to
* be executed.
*/
static void vpip_call_callback(void*cp)
{
unsigned long now;
struct __vpiCallback*rfp = (struct __vpiCallback*)cp;
assert(rfp->base.vpi_type->type_code == vpiCallback);
switch (rfp->cb_data.time->type) {
case vpiSuppressTime:
case vpiScaledRealTime: /* XXXX not supported */
break;
case vpiSimTime:
now = ((struct __vpiTimeVar*)vpip_sim_time())->time;
rfp->cb_data.time->low = now;
rfp->cb_data.time->high = 0;
break;
}
rfp->cb_data.cb_rtn(&rfp->cb_data);
free(rfp);
}
/*
* This function is called by the product when it changes the value of
* a signal. It arranges for all the value chance callbacks to be
* called.
*/
void vpip_run_value_changes(struct __vpiSignal*sig)
{
struct __vpiCallback*cur;
while (sig->mfirst) {
cur = sig->mfirst;
sig->mfirst = cur->next;
if (sig->mfirst == 0)
sig->mlast = 0;
cur->next = 0;
cur->ev = vpip_sim_insert_event(0, cur, vpip_call_callback, 0);
}
}
/*
* Handle read-only synch events. This causes the callback to be
* scheduled for a moment at the end of the time period. This method
* handles scheduling with time delays.
*/
static void go_readonly_synch(struct __vpiCallback*rfp)
{
unsigned long tim;
assert(rfp->cb_data.time);
assert(rfp->cb_data.time->type == vpiSimTime);
assert(rfp->cb_data.time->high == 0);
tim = rfp->cb_data.time->low;
rfp->ev = vpip_sim_insert_event(tim, rfp, vpip_call_callback, 1);
}
/*
* To schedule a value change, attach the callback to the signal to me
* monitored. I'll be inserted as an event later.
*/
static void go_value_change(struct __vpiCallback*rfp)
{
struct __vpiSignal*sig = (struct __vpiSignal*)rfp->cb_data.obj;
assert((sig->base.vpi_type->type_code == vpiReg)
|| (sig->base.vpi_type->type_code == vpiNet));
/* If there are no monitor events, start the list. */
if (sig->mfirst == 0) {
rfp->sig = sig;
rfp->next = 0;
sig->mfirst = rfp;
sig->mlast = rfp;
return;
}
/* Put me at the end of the list. Remember that the monitor
points to the *last* item in the list. */
rfp->sig = sig;
rfp->next = 0;
sig->mlast->next = rfp;
}
/*
* Register callbacks. This supports a variety of callback reasons,
* mostly by dispatching them to a type specific handler.
*/
vpiHandle vpi_register_cb(p_cb_data data)
{
struct __vpiCallback*rfp = calloc(1, sizeof(struct __vpiCallback));
rfp->base.vpi_type = &vpip_callback_rt;
rfp->cb_data = *data;
switch (data->reason) {
case cbReadOnlySynch:
go_readonly_synch(rfp);
break;
case cbValueChange:
go_value_change(rfp);
break;
default:
assert(0);
}
return &(rfp->base);
}
int vpi_remove_cb(vpiHandle ref)
{
struct __vpiCallback*rfp = (struct __vpiCallback*)ref;
assert(ref->vpi_type->type_code == vpiCallback);
if (rfp->ev) {
/* callbacks attached to events are easy. */
vpip_sim_cancel_event(rfp->ev);
} else if (rfp->sig) {
/* callbacks to signals need to be removed from the
signal's list of monitor callbacks. */
struct __vpiSignal*sig = rfp->sig;
if (sig->mfirst == rfp) {
sig->mfirst = rfp->next;
if (sig->mfirst == 0)
sig->mlast = 0;
rfp->next = 0;
rfp->sig = 0;
} else {
struct __vpiCallback*cur = sig->mfirst;
while (cur->next != rfp) {
assert(cur->next);
cur = cur->next;
}
cur->next = rfp->next;
if (cur->next == 0)
sig->mlast = cur;
}
} else {
assert(0);
}
free(rfp);
return 0;
}
/*
* $Log: vpi_callback.c,v $
* Revision 1.2 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.8 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.7 2000/03/31 07:08:39 steve
* allow cancelling of cbValueChange events.
*
* Revision 1.6 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.5 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.4 1999/11/07 20:33:30 steve
* Add VCD output and related system tasks.
*
* Revision 1.3 1999/10/29 03:37:22 steve
* Support vpiValueChance callbacks.
*
* Revision 1.2 1999/10/28 04:47:57 steve
* Support delay in constSync callback.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,526 +0,0 @@
/*
* Copyright (c) 1999-2000 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_const.c,v 1.3 2002/08/12 01:35:05 steve Exp $"
#endif
# include "vpi_priv.h"
# include <assert.h>
# include <string.h>
# include <stdio.h>
static unsigned vpip_bits_to_dec_str(const vpip_bit_t*bits, unsigned nbits,
char*buf, unsigned nbuf, int signed_flag)
{
unsigned idx, len;
unsigned count_x = 0, count_z = 0;
unsigned long val = 0;
assert( nbits <= 8*sizeof(val) );
for (idx = 0 ; idx < nbits ; idx += 1) {
val *= 2;
if (B_ISZ(bits[nbits-idx-1]))
count_z += 1;
else if (B_ISX(bits[nbits-idx-1]))
count_x += 1;
else if (B_IS1(bits[nbits-idx-1]))
val += 1;
}
if (count_x == nbits) {
len = 1;
buf[0] = 'x';
buf[1] = 0;
} else if (count_x > 0) {
len = 1;
buf[0] = 'X';
buf[1] = 0;
} else if (count_z == nbits) {
len = 1;
buf[0] = 'z';
buf[1] = 0;
} else if (count_z > 0) {
len = 1;
buf[0] = 'Z';
buf[1] = 0;
} else {
if (signed_flag && B_IS1(bits[nbits-1])) {
long tmp = -1;
assert(sizeof(tmp) == sizeof(val));
tmp <<= nbits;
tmp |= val;
sprintf(buf, "%ld", tmp);
len = strlen(buf);
} else {
sprintf(buf, "%lu", val);
len = strlen(buf);
}
}
return len;
}
/*
* This function is used in a couple places to interpret a bit string
* as a value.
*/
void vpip_bits_get_value(const vpip_bit_t*bits, unsigned nbits,
s_vpi_value*vp, int signed_flag)
{
static char buff[1024];
static s_vpi_vecval vect[64];
char* cp = buff;
unsigned val;
unsigned idx;
int isx;
vp->value.str = buff;
switch (vp->format) {
case vpiObjTypeVal:
case vpiBinStrVal:
for (idx = 0 ; idx < nbits ; idx += 1) {
if (B_IS0(bits[nbits-idx-1]))
*cp++ = '0';
else if (B_IS1(bits[nbits-idx-1]))
*cp++ = '1';
else if (B_ISZ(bits[nbits-idx-1]))
*cp++ = 'z';
else
*cp++ = 'x';
}
vp->format = vpiBinStrVal;
*cp++ = 0;
break;
case vpiDecStrVal:
cp += vpip_bits_to_dec_str(bits, nbits, cp,
1024-(cp-buff), signed_flag);
break;
case vpiOctStrVal:
if (nbits%3) {
unsigned x = 0;
unsigned z = 0;
unsigned v = 0;
unsigned i;
for (i = 0 ; i < nbits%3 ; i += 1) {
v *= 2;
if (B_IS0(bits[nbits-i-1]))
;
else if (B_IS1(bits[nbits-i-1]))
v += 1;
else if (B_ISX(bits[nbits-i-1]))
x += 1;
else if (B_ISZ(bits[nbits-i-1]))
z += 1;
}
if (x == nbits%3)
*cp++ = 'x';
else if (x > 0)
*cp++ = 'X';
else if (z == nbits%3)
*cp++ = 'z';
else if (z > 0)
*cp++ = 'Z';
else
*cp++ = "01234567"[v];
}
for (idx = nbits%3 ; idx < nbits ; idx += 3) {
unsigned x = 0;
unsigned z = 0;
unsigned v = 0;
unsigned i;
for (i = idx ; i < idx+3 ; i += 1) {
v *= 2;
if (B_IS0(bits[nbits-i-1]))
;
else if (B_IS1(bits[nbits-i-1]))
v += 1;
else if (B_ISX(bits[nbits-i-1]))
x += 1;
else if (B_ISZ(bits[nbits-i-1]))
z += 1;
}
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];
}
*cp++ = 0;
break;
case vpiHexStrVal:
if (nbits%4) {
unsigned x = 0;
unsigned z = 0;
unsigned v = 0;
unsigned i;
for (i = 0 ; i < nbits%4 ; i += 1) {
v *= 2;
if (B_IS0(bits[nbits-i-1]))
;
else if (B_IS1(bits[nbits-i-1]))
v += 1;
else if (B_ISX(bits[nbits-i-1]))
x += 1;
else if (B_ISZ(bits[nbits-i-1]))
z += 1;
}
if (x == nbits%4)
*cp++ = 'x';
else if (x > 0)
*cp++ = 'X';
else if (z == nbits%4)
*cp++ = 'z';
else if (z > 0)
*cp++ = 'Z';
else
*cp++ = "0123456789abcdef"[v];
}
for (idx = nbits%4 ; idx < nbits ; idx += 4) {
unsigned x = 0;
unsigned z = 0;
unsigned v = 0;
unsigned i;
for (i = idx ; i < idx+4 ; i += 1) {
v *= 2;
if (B_IS0(bits[nbits-i-1]))
;
else if (B_IS1(bits[nbits-i-1]))
v += 1;
else if (B_ISX(bits[nbits-i-1]))
x += 1;
else if (B_ISZ(bits[nbits-i-1]))
z += 1;
}
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++ = "0123456789abcdef"[v];
}
*cp++ = 0;
break;
case vpiIntVal:
val = 0;
isx = 0;
for (idx = 0 ; idx < nbits ; idx += 1) {
val *= 2;
if (B_ISXZ(bits[nbits-idx-1]))
isx = 1;
else if (B_IS1(bits[nbits-idx-1]))
val += 1;
}
if(isx)
vp->value.integer = 0;
else
vp->value.integer = val;
break;
case vpiStringVal:
/* Turn the bits into an ASCII string, terminated by a
null. This is actually a bit tricky as nulls in the
bit array would terminate the C string. I therefore
translate them to ASCII ' ' characters. */
assert(nbits%8 == 0);
for (idx = nbits ; idx >= 8 ; idx -= 8) {
char tmp = 0;
unsigned bdx;
for (bdx = 8 ; bdx > 0 ; bdx -= 1) {
tmp <<= 1;
if (B_IS1(bits[idx-8+bdx-1]))
tmp |= 1;
}
*cp++ = tmp? tmp : ' ';
}
*cp++ = 0;
break;
case vpiVectorVal:
vp->value.vector = vect;
for (idx = 0 ; idx < nbits ; idx += 1) {
int major = idx/32;
int minor = idx%32;
vect[major].aval &= (1<<minor) - 1;
vect[major].bval &= (1<<minor) - 1;
if (B_IS1(bits[idx]) || B_ISX(bits[idx]))
vect[major].aval |= 1<<minor;
if (B_ISXZ(bits[idx]))
vect[major].bval |= 1<<minor;
}
break;
default:
*cp++ = '(';
*cp++ = '?';
*cp++ = ')';
*cp++ = 0;
vp->format = vpiStringVal;
break;
}
}
void vpip_bits_set_value(vpip_bit_t*bits, unsigned nbits, s_vpi_value*vp)
{
switch (vp->format) {
case vpiScalarVal:
switch (vp->value.scalar) {
case vpi0:
bits[0] = St0;
break;
case vpi1:
bits[0] = St1;
break;
case vpiX:
bits[0] = StX;
break;
case vpiZ:
bits[0] = HiZ;
break;
default:
assert(0);
}
break;
case vpiVectorVal: {
unsigned long aval = vp->value.vector->aval;
unsigned long bval = vp->value.vector->bval;
int idx;
for (idx = 0 ; idx < nbits ; idx += 1) {
int bit = (aval&1) | ((bval<<1)&2);
switch (bit) {
case 0:
bits[idx] = St0;
break;
case 1:
bits[idx] = St1;
break;
case 2:
bits[idx] = HiZ;
break;
case 3:
bits[idx] = StX;
break;
}
aval >>= 1;
bval >>= 1;
}
break;
}
case vpiIntVal: {
long val = vp->value.integer;
unsigned idx;
for (idx = 0 ; idx < nbits ; idx += 1) {
bits[idx] = (val&1)? St1 : St0;
val >>= 1;
}
break;
}
default:
assert(0);
}
}
static int string_get(int code, vpiHandle ref)
{
struct __vpiStringConst*rfp = (struct __vpiStringConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
switch (code) {
case vpiConstType:
return vpiStringConst;
default:
assert(0);
return 0;
}
}
static void string_value(vpiHandle ref, p_vpi_value vp)
{
struct __vpiStringConst*rfp = (struct __vpiStringConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
switch (vp->format) {
case vpiObjTypeVal:
case vpiStringVal:
vp->value.str = (char*)rfp->value;
vp->format = vpiStringVal;
break;
default:
vp->format = vpiSuppressVal;
break;
}
}
static int number_get(int code, vpiHandle ref)
{
struct __vpiNumberConst*rfp = (struct __vpiNumberConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
switch (code) {
case vpiConstType:
return vpiBinaryConst;
default:
assert(0);
return 0;
}
}
static void number_value(vpiHandle ref, p_vpi_value vp)
{
struct __vpiNumberConst*rfp = (struct __vpiNumberConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
vpip_bits_get_value(rfp->bits, rfp->nbits, vp, 0);
}
static const struct __vpirt vpip_string_rt = {
vpiConstant,
string_get,
0,
string_value,
0,
0,
0
};
static const struct __vpirt vpip_number_rt = {
vpiConstant,
number_get,
0,
number_value,
0,
0,
0
};
vpiHandle vpip_make_string_const(struct __vpiStringConst*ref, const char*val)
{
ref->base.vpi_type = &vpip_string_rt;
ref->value = val;
return &(ref->base);
}
vpiHandle vpip_make_number_const(struct __vpiNumberConst*ref,
const vpip_bit_t*bits,
unsigned nbits)
{
ref->base.vpi_type = &vpip_number_rt;
ref->bits = bits;
ref->nbits = nbits;
return &(ref->base);
}
/*
* $Log: vpi_const.c,v $
* Revision 1.3 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/04/24 15:47:37 steve
* Fix setting StX in vpip_bits_set_value.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.17 2001/01/07 18:22:15 steve
* Assert on length of bit vector.
*
* Revision 1.16 2001/01/06 22:22:17 steve
* Support signed decimal display of variables.
*
* Revision 1.15 2000/12/10 19:15:19 steve
* vpiStringVal handles leding nulls as blanks. (PR#62)
*
* Revision 1.14 2000/12/02 02:40:56 steve
* Support for %s in $display (PR#62)
*
* Revision 1.13 2000/09/23 16:34:47 steve
* Handle unknowns in decimal strings.
*
* Revision 1.12 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.11 2000/08/08 01:47:40 steve
* Add vpi_vlog_info support from Adrian
*
* Revision 1.10 2000/07/08 22:40:07 steve
* Allow set vpiIntVal on bitset type objects.
*
* Revision 1.9 2000/05/18 03:27:32 steve
* Support writing scalars and vectors to signals.
*
* Revision 1.8 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.7 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.6 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.5 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.4 1999/11/06 22:16:50 steve
* Get the $strobe task working.
*
* Revision 1.3 1999/11/06 16:52:16 steve
* complete value retrieval for number constants.
*
* Revision 1.2 1999/11/06 16:00:18 steve
* Put number constants into a static table.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,90 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_iter.c,v 1.2 2002/08/12 01:35:05 steve Exp $"
#endif
/*
* Find here the methods functions in support of iterator objects.
*/
# include "vpi_priv.h"
# include <stdlib.h>
# include <assert.h>
static const struct __vpirt vpip_iterator_rt = {
vpiIterator,
0,
0,
0,
0,
0,
0
};
vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args)
{
struct __vpiIterator*res = calloc(1, sizeof(struct __vpiIterator));
res->base.vpi_type = &vpip_iterator_rt;
res->args = args;
res->nargs = nargs;
res->next = 0;
return &(res->base);
}
/*
* The vpi_scan function only applies to iterators. It returns the
* next vpiHandle in the iterated list.
*/
vpiHandle vpi_scan(vpiHandle ref)
{
struct __vpiIterator*hp = (struct __vpiIterator*)ref;
assert(ref->vpi_type->type_code == vpiIterator);
if (hp->next == hp->nargs) {
vpi_free_object(ref);
return 0;
}
return hp->args[hp->next++];
}
/*
* $Log: vpi_iter.c,v $
* Revision 1.2 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.3 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,160 +0,0 @@
/*
* Copyright (c) 2000 Stephen G. Tell <steve@telltronics.org>
*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_mcd.c,v 1.7 2004/10/04 01:10:58 steve Exp $"
#endif
# include "vpi_priv.h"
# include <assert.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
struct mcd_entry {
FILE *fp;
char *filename;
};
static struct mcd_entry mcd_table[32];
/* Initialize mcd portion of vpi. Must be called before
* any vpi_mcd routines can be used.
*/
void vpi_mcd_init(void)
{
mcd_table[0].fp = stdout;
mcd_table[0].filename = "<stdout>";
mcd_table[1].fp = stderr;
mcd_table[1].filename = "<stderr>";
mcd_table[2].fp = 0; /* TODO: initialize this to log file */
mcd_table[2].filename = "<stdlog>";
}
/*
* close one or more channels. we silently refuse to close the preopened ones.
*/
unsigned int vpi_mcd_close(unsigned int mcd)
{
int i;
int rc;
rc = 0;
for(i = 3; i < 31; i++) {
if( ((mcd>>i) & 1) && mcd_table[i].filename) {
if(fclose(mcd_table[i].fp) != 0)
rc |= 1<<i;
free(mcd_table[i].filename);
mcd_table[i].fp = NULL;
mcd_table[i].filename = NULL;
} else {
rc |= 1<<i;
}
}
return rc;
}
char *vpi_mcd_name(unsigned int mcd)
{
int i;
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1)
return mcd_table[i].filename;
}
return NULL;
}
unsigned int vpi_mcd_open_x(char *name, char *mode)
{
int i;
for(i = 0; i < 31; i++) {
if(mcd_table[i].filename == NULL)
goto got_entry;
}
return 0; /* too many open mcd's */
got_entry:
mcd_table[i].fp = fopen(name, mode);
if(mcd_table[i].fp == NULL)
return 0;
mcd_table[i].filename = strdup(name);
return 1<<i;
}
unsigned int vpi_mcd_open(char *name)
{
return vpi_mcd_open_x(name, "w");
}
extern int vpi_mcd_vprintf(unsigned int mcd, const char*fmt, va_list ap)
{
int i;
int len;
int rc;
rc = len = 0;
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1) {
if(mcd_table[i].fp)
len = vfprintf(mcd_table[i].fp, fmt, ap);
else
rc = EOF;
}
}
if(rc)
return rc;
else
return len;
}
int vpi_mcd_fputc(unsigned int mcd, unsigned char x)
{
int i;
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1) {
return fputc(x, mcd_table[i].fp);
}
}
return 0;
}
int vpi_mcd_fgetc(unsigned int mcd)
{
int i;
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1) {
return fgetc(mcd_table[i].fp);
}
}
return 0;
}
/*
* $Log: vpi_mcd.c,v $
* Revision 1.7 2004/10/04 01:10:58 steve
* Clean up spurious trailing white space.
*
* Revision 1.6 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
*/

View File

@ -1,246 +0,0 @@
/*
* Copyright (c) 1999-2000 Picture Elements, Inc.
* Stephen Williams (steve@picturel.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. 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 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
* ---
* You should also have received a copy of the Picture Elements
* Binary Software License offer along with the source. This offer
* allows you to obtain the right to redistribute the software in
* binary (compiled) form. If you have not received it, contact
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_memory.c,v 1.4 2007/02/26 19:49:51 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdlib.h>
# include <assert.h>
static int memory_get(int code, vpiHandle ref)
{
struct __vpiMemory*rfp = (struct __vpiMemory*)ref;
assert(ref->vpi_type->type_code==vpiMemory);
switch (code) {
case vpiSize:
return rfp->size;
default:
return 0;
}
}
static const char* memory_get_str(int code, vpiHandle ref)
{
struct __vpiMemory*rfp = (struct __vpiMemory*)ref;
assert(ref->vpi_type->type_code==vpiMemory);
switch (code) {
case vpiFullName:
return (char*)rfp->name;
}
return 0;
}
static vpiHandle memory_iterate(int code, vpiHandle ref)
{
unsigned idx;
struct __vpiMemory*rfp = (struct __vpiMemory*)ref;
assert(ref->vpi_type->type_code==vpiMemory);
switch (code) {
case vpiMemoryWord:
if (rfp->args == 0) {
rfp->args = calloc(rfp->size, sizeof(vpiHandle));
for (idx = 0 ; idx < rfp->size ; idx += 1)
rfp->args[idx] = &rfp->words[idx].base;
}
return vpip_make_iterator(rfp->size, rfp->args);
default:
return 0;
}
}
static vpiHandle memory_index(vpiHandle ref, int index)
{
struct __vpiMemory*rfp = (struct __vpiMemory*)ref;
assert(ref->vpi_type->type_code==vpiMemory);
if (rfp->args == 0) {
unsigned idx;
rfp->args = calloc(rfp->size, sizeof(vpiHandle));
for (idx = 0 ; idx < rfp->size ; idx += 1)
rfp->args[idx] = &rfp->words[idx].base;
}
if (index > rfp->size) return 0;
if (index < 0) return 0;
return &(rfp->words[index].base);
}
static int memory_word_get(int code, vpiHandle ref)
{
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref;
assert(ref->vpi_type->type_code==vpiMemoryWord);
switch (code) {
case vpiSize:
return rfp->mem->width;
default:
return 0;
}
}
static vpiHandle memory_word_put(vpiHandle ref, p_vpi_value val,
p_vpi_time tim, int flags)
{
unsigned idx;
vpip_bit_t*base;
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref;
assert(ref->vpi_type->type_code==vpiMemoryWord);
base = rfp->mem->bits + rfp->index*rfp->mem->width;
assert(val->format == vpiVectorVal);
for (idx = 0 ; idx < rfp->mem->width ; idx += 1) {
p_vpi_vecval cur = val->value.vector + (idx/32);
int aval = cur->aval >> (idx%32);
int bval = cur->bval >> (idx%32);
if (bval & 1) {
if (aval & 1)
*base = StX;
else
*base = HiZ;
} else {
if (aval & 1)
*base = St1;
else
*base = St0;
}
base += 1;
}
return 0;
}
static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp)
{
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref;
assert(ref->vpi_type->type_code==vpiMemoryWord);
vpip_bits_get_value(rfp->mem->bits+rfp->index*rfp->mem->width,
rfp->mem->width, vp, 0);
}
static const struct __vpirt vpip_memory_rt = {
vpiMemory,
memory_get,
memory_get_str,
0,
0,
0,
memory_iterate,
memory_index
};
static const struct __vpirt vpip_memory_word_rt = {
vpiMemoryWord,
memory_word_get,
0,
memory_word_get_value,
memory_word_put,
0,
0,
0
};
vpiHandle vpip_make_memory(struct __vpiMemory*ref, const char*name,
unsigned wid, unsigned siz)
{
unsigned idx;
ref->base.vpi_type = &vpip_memory_rt;
ref->name = name;
ref->bits = calloc(wid*siz, sizeof(vpip_bit_t));
for (idx = 0 ; idx < wid*siz ; idx += 1)
ref->bits[idx] = StX;
ref->words = calloc(siz, sizeof(struct __vpiMemoryWord));
ref->args = 0;
ref->width = wid;
ref->size = siz;
for (idx = 0 ; idx < siz ; idx += 1) {
ref->words[idx].base.vpi_type = &vpip_memory_word_rt;
ref->words[idx].mem = ref;
ref->words[idx].index = idx;
}
return &(ref->base);
}
/*
* $Log: vpi_memory.c,v $
* Revision 1.4 2007/02/26 19:49:51 steve
* Spelling fixes (larry doolittle)
*
* Revision 1.3 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/10/26 02:29:10 steve
* const/non-const warnings. (Stephan Boettcher)
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.9 2001/01/06 22:22:17 steve
* Support signed decimal display of variables.
*
* Revision 1.8 2000/06/28 18:38:00 steve
* Initialize memories as they are create.
*
* Revision 1.7 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.6 2000/02/29 01:41:32 steve
* Fix warning and typo.
*
* Revision 1.5 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.4 2000/02/13 19:18:28 steve
* Accept memory words as parameter to $display.
*
* Revision 1.3 1999/12/15 04:15:17 steve
* Implement vpi_put_value for memory words.
*
* Revision 1.2 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.1 1999/11/10 02:52:24 steve
* Create the vpiMemory handle type.
*
*/

View File

@ -1,71 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_null.c,v 1.3 2004/10/04 01:10:58 steve Exp $"
#endif
# include "vpi_priv.h"
static const struct __vpirt vpip_null_rt = {
0,
0,
0,
0,
0,
0,
0
};
static struct __vpiNull vpip_null = {
{ &vpip_null_rt }
};
extern struct __vpiNull *vpip_get_null(void)
{
return &vpip_null;
}
/*
* $Log: vpi_null.c,v $
* Revision 1.3 2004/10/04 01:10:58 steve
* Clean up spurious trailing white space.
*
* Revision 1.2 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.4 2000/10/06 23:11:39 steve
* Replace data references with function calls. (Venkat)
*
* Revision 1.3 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,303 +0,0 @@
/*
* Copyright (c) 1999-2000 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_priv.c,v 1.5 2002/08/12 01:35:05 steve Exp $"
#endif
# include "vpi_priv.h"
# include <assert.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
/*
* Keep a list of vpi_systf_data structures. This list is searched
* forward whenever a function is invoked by name, and items are
* pushed in front of the list whenever they are registered. This
* allows entries to override older entries.
*/
struct systf_entry {
struct systf_entry* next;
s_vpi_systf_data systf_data;
};
static struct systf_entry*systf_func_list = 0;
static struct systf_entry*systf_task_list = 0;
/* This is the handle of the task currently being called. */
static struct __vpiSysTaskCall*vpip_cur_task;
void vpip_calltask(struct __vpiScope*scope, const char*fname,
unsigned nparms, vpiHandle*parms)
{
struct systf_entry*idx;
struct __vpiSysTaskCall cur_task;
cur_task.base.vpi_type = vpip_get_systask_rt();
cur_task.scope = scope;
cur_task.args = parms;
cur_task.nargs = nparms;
cur_task.res = 0;
cur_task.nres = 0;
vpip_cur_task = &cur_task;
/* Look for a systf function to invoke. */
for (idx = systf_task_list ; idx ; idx = idx->next)
if (strcmp(fname, idx->systf_data.tfname) == 0) {
cur_task.info = &idx->systf_data;
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. */
vpi_printf("Call %s\n", fname);
}
/*
* System functions are kept in the same sort of table as the system
* tasks, and we call them in a similar manner.
*/
void vpip_callfunc(const char*fname, unsigned nres, vpip_bit_t*res,
unsigned nparms, vpiHandle*parms)
{
struct systf_entry*idx;
struct __vpiSysTaskCall cur_task;
cur_task.base.vpi_type = vpip_get_sysfunc_rt();
cur_task.args = parms;
cur_task.nargs = nparms;
cur_task.res = res;
cur_task.nres = nres;
vpip_cur_task = &cur_task;
/* Look for a systf function to invoke. */
for (idx = systf_func_list ; idx ; idx = idx->next)
if (strcmp(fname, idx->systf_data.tfname) == 0) {
cur_task.info = &idx->systf_data;
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. */
vpi_printf("Call %s with width==%u\n", fname, nres);
}
int vpi_free_object(vpiHandle ref)
{
free(ref);
return 0;
}
static int vpip_get_global(int property)
{
switch (property) {
case vpiTimePrecision:
return vpip_get_simulation_obj()->time_precision;
default:
assert(0);
return -1;
}
}
int vpi_get(int property, vpiHandle ref)
{
if (property == vpiType)
return ref->vpi_type->type_code;
if (ref == 0)
return vpip_get_global(property);
if (ref->vpi_type->vpi_get_ == 0)
return -1;
return (ref->vpi_type->vpi_get_)(property, ref);
}
char* vpi_get_str(int property, vpiHandle ref)
{
if (ref->vpi_type->vpi_get_str_ == 0)
return 0;
return (char*)(ref->vpi_type->vpi_get_str_)(property, ref);
}
void vpi_get_time(vpiHandle obj, s_vpi_time*t)
{
s_vpi_value value;
vpiHandle tm = vpip_sim_time();
value.format = vpiTimeVal;
vpi_get_value(tm, &value);
memcpy(t, value.value.time, sizeof (*t));
}
void vpi_get_value(vpiHandle expr, s_vpi_value*vp)
{
if (expr->vpi_type->vpi_get_value_) {
(expr->vpi_type->vpi_get_value_)(expr, vp);
return;
}
vp->format = vpiSuppressVal;
}
vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
s_vpi_time*tp, int flags)
{
if (obj->vpi_type->vpi_put_value_)
return (obj->vpi_type->vpi_put_value_)(obj, vp, tp, flags);
else
return 0;
}
vpiHandle vpi_handle(int type, vpiHandle ref)
{
if (type == vpiSysTfCall) {
assert(ref == 0);
return &vpip_cur_task->base;
}
assert(ref->vpi_type->handle_);
return (ref->vpi_type->handle_)(type, ref);
}
/*
* This function asks the object to return an iterator for
* the specified reference. It is up to the iterate_ method to
* allocate a properly formed iterator.
*/
vpiHandle vpi_iterate(int type, vpiHandle ref)
{
assert(ref->vpi_type->iterate_);
return (ref->vpi_type->iterate_)(type, ref);
}
vpiHandle vpi_handle_by_index(vpiHandle ref, int idx)
{
assert(ref->vpi_type->index_);
return (ref->vpi_type->index_)(ref, idx);
}
extern void vpi_vprintf(const char*fmt, va_list ap)
{
vprintf(fmt, ap);
}
extern void vpi_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap,fmt);
vpi_vprintf(fmt,ap);
va_end(ap);
}
/*
* This function adds the information that the user supplies to a list
* that I keep.
*/
void vpi_register_systf(const struct t_vpi_systf_data*systf)
{
struct systf_entry*cur = calloc(1, sizeof(struct systf_entry));
cur->systf_data = *systf;
cur->systf_data.tfname = strdup(systf->tfname);
switch (systf->type) {
case vpiSysFunc:
cur->next = systf_func_list;
systf_func_list = cur;
break;
case vpiSysTask:
cur->next = systf_task_list;
systf_task_list = cur;
break;
default:
assert(0);
}
}
/*
* $Log: vpi_priv.c,v $
* Revision 1.5 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/10/26 02:29:10 steve
* const/non-const warnings. (Stephan Boettcher)
*
* Revision 1.3 2001/06/19 14:57:10 steve
* Get va_start arguments in right order.
*
* Revision 1.2 2001/06/12 03:53:10 steve
* Change the VPI call process so that loaded .vpi modules
* use a function table instead of implicit binding.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.11 2000/10/28 00:51:42 steve
* Add scope to threads in vvm, pass that scope
* to vpi sysTaskFunc objects, and add vpi calls
* to access that information.
*
* $display displays scope in %m (PR#1)
*
* Revision 1.10 2000/10/06 23:11:39 steve
* Replace data references with function calls. (Venkat)
*
* Revision 1.9 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.8 2000/07/26 03:53:12 steve
* Make simulation precision available to VPI.
*
* Revision 1.7 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.6 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.5 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.4 2000/02/13 19:18:28 steve
* Accept memory words as parameter to $display.
*
* Revision 1.3 2000/01/20 06:04:55 steve
* $dumpall checkpointing in VCD dump.
*
* Revision 1.2 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,542 +0,0 @@
#ifndef __vpi_priv_H
#define __vpi_priv_H
/*
* Copyright (c) 1999-2000 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_priv.h,v 1.4 2004/10/04 01:10:58 steve Exp $"
#endif
/*
* This header file describes the "back side" of the VPI
* interface. The product that offers the VPI interface uses types and
* methods declared here to manage the VPI structures and provide the
* needed behaviors.
*/
# include "vpi_user.h"
#ifdef __cplusplus
extern "C" {
#endif
struct __vpirt;
/*
* The simulation engine internally carries the strengths along with
* the bit values, and that includes ambiguous strengths. The complete
* bit value (including ambiguity) is encoded in 8 bits like so:
*
* VSSSvsss
*
* The V and v bits encode the bit logic values, and the SSS and sss
* bits encode the strength range. The logic values are like so:
*
* 0SSS0sss - Logic 0
* 1SSS1sss - Logic 1
* 1xxx0xxx - Logic X
* 00001000 - Logic Z
*
* 00000000 - Invalid/No signal
*
* So as you can see, logic values can be quickly compared by masking
* the strength bits.
*
* If the value is unambiguous, then the SSS and sss bits have the
* same value, and encode the strength of the driven value. If the
* value is logic X, then "unambiguous" in this context means the
* strength is well known, even though the logic value is
* not. However, it is treated as ambiguous by the resolver.
*
* If the strength is ambiguous, then the high 4 bits are always
* arithmetically larger then the low 4 bits. For logic 0 and logic 1
* values, this means that the SSS value is >= the sss value. For
* logic X values, the 'V' bit is set and SSS is the strength toward 1,
* and the 'v' bit is 0 and sss is the strength toward 0.
*/
typedef unsigned char vpip_bit_t;
# define Su1 0xff //supply1
# define St1 0xee //strong1
# define Pu1 0xdd //pull1
# define La1 0xcc //large1
# define We1 0xbb //weak1
# define Me1 0xaa //medium1
# define Sm1 0x99 //samll1
# define Su0 0x77 //supply0
# define St0 0x66 //strong0
# define Pu0 0x55 //pull0
# define La0 0x44 //large0
# define We0 0x33 //weak0
# define Me0 0x22 //medium0
# define Sm0 0x11 //small0
# define SuX 0xf7 //supplyx
# define StX 0xe6 //strongx
# define PuX 0xd5 //pullx
# define LaX 0xc4 //largex
# define WeX 0xb3 //weakx
# define MeX 0xa2 //mediumx
# define SmX 0x91 //smallx
# define HiZ 0x08 //highz
# define HiZ0 0x08 //highz
# define HiZ1 0x08 //highz
# define StH 0xe8 //strong 1 highz
# define StL 0x06 //highz strong0
/* Compare the logic values of two vpip_bit_t variables. This
is like the === operator of Verilog, it ignored strengths. */
# define B_EQ(l,r) (((l)&0x88) == ((r)&0x88))
/* Test and return true if the value has ambiguous
strength. The logic value may yet be knowable. */
# define B_ISAMBIG(v) (((v)&0x0f) != (((v)>>4)&0x0f))
/* Test whether the value is of the specified logic value. It
is possible for even ambiguous signals to have a known
logic value. */
# define B_IS0(v) (((v)&0x88) == 0x00)
# define B_IS1(v) (((v)&0x88) == 0x88)
# define B_ISX(v) (((v)&0x88) == 0x80)
# define B_ISZ(v) ((v) == HiZ)
# define B_ISXZ(v) (1 & (((v)>>7) ^ ((v)>>3)))
/* Take as input an array of bits, and return the resolved
value. The result accounts for the strengths involved. */
extern vpip_bit_t vpip_pair_resolve(vpip_bit_t a, vpip_bit_t b);
extern vpip_bit_t vpip_bits_resolve(const vpip_bit_t*bits, unsigned nbits);
extern void vpip_bits_get_value(const vpip_bit_t*bits, unsigned nbits,
s_vpi_value*vp, int signed_flag);
extern void vpip_bits_set_value(vpip_bit_t*bits, unsigned nbits,
s_vpi_value*vp);
/*
* This structure is the very base of a vpiHandle. Every handle
* structure starts with this structure, so that the library can
* internally pass the derived types as pointers to one of these.
*/
struct __vpiHandle {
const struct __vpirt *vpi_type;
};
/*
* Objects with this structure are used to represent a type of
* vpiHandle. A specific object becomes of this type by holding a
* pointer to an instance of this structure.
*/
struct __vpirt {
int type_code;
/* These methods extract information from the handle. */
int (*vpi_get_)(int, vpiHandle);
const char* (*vpi_get_str_)(int, vpiHandle);
void (*vpi_get_value_)(vpiHandle, p_vpi_value);
vpiHandle (*vpi_put_value_)(vpiHandle, p_vpi_value, p_vpi_time, int);
/* These methods follow references. */
vpiHandle (*handle_)(int, vpiHandle);
vpiHandle (*iterate_)(int, vpiHandle);
vpiHandle (*index_)(vpiHandle, int);
};
/*
* This is a private handle type that doesn't seem to be well defined
* by the VPI standard.
*/
struct __vpiCallback {
struct __vpiHandle base;
struct t_cb_data cb_data;
/* Set this value if I'm pending in the event queue. */
struct vpip_event*ev;
/* Set this value if I'm waiting for a value change on a signal*/
struct __vpiSignal*sig;
struct __vpiCallback*next;
};
/*
* The vpiHandle for an iterator has this structure. The definition of
* the methods lives in vpi_iter.c
*/
struct __vpiIterator {
struct __vpiHandle base;
vpiHandle *args;
unsigned nargs;
unsigned next;
};
/*
* Memory is an array of bits that is accessible in N-bit chunks, with
* N being the width of a word. The memory word handle just points
* back to the memory and uses an index to identify its position in
* the memory.
*/
struct __vpiMemory {
struct __vpiHandle base;
/* The signal has a name (this points to static memory.) */
const char*name;
vpip_bit_t*bits;
struct __vpiMemoryWord*words;
vpiHandle*args;
unsigned width;
unsigned size;
};
struct __vpiMemoryWord {
struct __vpiHandle base;
struct __vpiMemory*mem;
int index;
};
/*
* This type is occasionally useful. Really! And while we're at it,
* create a single instance of the null object. (This is all we need.)
*/
struct __vpiNull {
struct __vpiHandle base;
};
extern struct __vpiNull *vpip_get_null(void);
/*
* This type represents the handle to a Verilog scope. These include
* module instantiations and named begin-end blocks. The attach
* function is used to attach handles to the scope by the runtime
* initialization.
*/
struct __vpiScope {
struct __vpiHandle base;
/* The scope has a name. (this points to static memory.) */
const char*name;
/* Keep an array of internal scope items. */
struct __vpiHandle**intern;
unsigned nintern;
};
extern void vpip_attach_to_scope(struct __vpiScope*scope, vpiHandle obj);
/*
* This structure represents nets and registers. You can tell which by
* the type_code in the base. The bits member points to the actual
* array of bits that the environment provides. The bits must persist
* as long as this object persists.
*/
struct __vpiSignal {
struct __vpiHandle base;
/* The signal has a name (this points to static memory.) */
const char*name;
/* The signal has a value and dimension. */
vpip_bit_t*bits;
unsigned nbits;
unsigned signed_flag : 1;
/* monitors are added here. */
struct __vpiCallback*mfirst;
struct __vpiCallback*mlast;
};
extern const struct __vpirt *vpip_get_systask_rt(void);
extern const struct __vpirt *vpip_get_sysfunc_rt(void);
struct __vpiSysTaskCall {
struct __vpiHandle base;
struct __vpiScope*scope;
s_vpi_systf_data*info;
vpiHandle*args;
unsigned nargs;
vpip_bit_t*res;
unsigned nres;
const char*file;
unsigned lineno;
int subtype;
};
/*
* Represent a TimeVar variable. The actual time is stored in the
* "time" member for fast manipulation by various bits of the
* simulation engine. The time_obj member is used as persistent
* storage of the time value when get_value is used (on the opaque
* handle) to the get time.
*/
struct __vpiTimeVar {
struct __vpiHandle base;
const char*name;
unsigned long time;
struct t_vpi_time time_obj;
};
struct __vpiStringConst {
struct __vpiHandle base;
const char*value;
};
struct __vpiNumberConst {
struct __vpiHandle base;
const vpip_bit_t*bits;
unsigned nbits;
};
/*
* These are methods to initialize specific handle types. Except for
* vpip_make_iterator, all the vpi_make_* functions expect the caller
* to allocate the memory for the handle. The result is the vpiHandle
* of the constructed object.
*/
extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args);
extern vpiHandle vpip_make_net(struct __vpiSignal*ref, const char*name,
vpip_bit_t*bits, unsigned nbits,
int signed_flag);
extern vpiHandle vpip_make_scope(struct __vpiScope*ref,
int type_code,
const char*name);
extern vpiHandle vpip_make_string_const(struct __vpiStringConst*ref,
const char*val);
extern vpiHandle vpip_make_number_const(struct __vpiNumberConst*ref,
const vpip_bit_t*bits,
unsigned nbits);
extern vpiHandle vpip_make_memory(struct __vpiMemory*ref, const char*name,
unsigned width, unsigned size);
extern vpiHandle vpip_make_reg(struct __vpiSignal*ref, const char*name,
vpip_bit_t*bits, unsigned nbits,
int signed_flag);
extern vpiHandle vpip_make_time_var(struct __vpiTimeVar*ref,
const char*val);
/* Use this function to call a registered task. */
extern void vpip_calltask(struct __vpiScope*scope, const char*name,
unsigned nparms, vpiHandle*parms);
/*
* This calls a system function with a given name. The return value is
* taken by the res[] array.
*/
extern void vpip_callfunc(const char*name, unsigned nres, vpip_bit_t*res,
unsigned nparms, vpiHandle*parms);
extern void vpip_run_value_changes(struct __vpiSignal*sig);
/*
* The simulation object holds the current state of the
* simulation. There is a single global variable that is the
* simulation.
*/
struct vpip_simulation_cycle;
struct vpip_event;
struct vpip_simulation {
/* Current simulation time. */
struct __vpiTimeVar sim_time;
/* List of cbReadOnlySynch callbacks. */
struct __vpiCallback*read_sync_list;
/* List of simulation cycles, starting with the next time. */
struct vpip_simulation_cycle*sim;
int going_flag;
/* This is the precision of the simulation clock. It may be
used by the run time to scale time values. */
short time_precision;
};
extern struct vpip_simulation *vpip_get_simulation_obj(void);
extern void vpip_set_vlog_info(int argc, char**argv);
extern void vpip_init_simulation();
extern void vpip_time_scale(int precision);
extern void vpip_simulation_run();
extern void vpi_mcd_init(void);
/*
* Schedule an event to be run sometime in the future. The d parameter
* is the delay in simulation units before the event is processed. If
* the non-block flag is set, the event is scheduled to happen at the
* end of the time step.
*
* The return value from the insert method is a cookie that can be
* used to manipulate the event before it is executed.
*/
extern struct vpip_event* vpip_sim_insert_event(unsigned long d,
void*user_data,
void (*sim_fun)(void*),
int nonblock_flag);
extern void vpip_sim_cancel_event(struct vpip_event*cookie);
/*
* This function returns a handle to the vpiTimeVar that is th main
* simulation time clock.
*/
extern vpiHandle vpip_sim_time();
/*
* Return true if the going_flag is false.
*/
extern int vpip_finished();
#ifdef __cplusplus
}
#endif
/*
* $Log: vpi_priv.h,v $
* Revision 1.4 2004/10/04 01:10:58 steve
* Clean up spurious trailing white space.
*
* Revision 1.3 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/10/26 02:29:10 steve
* const/non-const warnings. (Stephan Boettcher)
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.31 2001/01/06 22:22:17 steve
* Support signed decimal display of variables.
*
* Revision 1.30 2000/11/11 01:52:09 steve
* change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1
* change set to correct behavior of bufif0 and bufif1
* (Tim Leight)
*
* Also includes fix for PR#27
*
* Revision 1.29 2000/10/28 00:51:42 steve
* Add scope to threads in vvm, pass that scope
* to vpi sysTaskFunc objects, and add vpi calls
* to access that information.
*
* $display displays scope in %m (PR#1)
*
* Revision 1.28 2000/10/06 23:11:39 steve
* Replace data references with function calls. (Venkat)
*
* Revision 1.27 2000/10/04 02:37:44 steve
* Use .def file instead of _dllexport.
*
* Revision 1.26 2000/10/03 16:15:35 steve
* Cleanup build of VPI modules under Cygwin. (Venkat)
*
* Revision 1.25 2000/09/30 03:20:48 steve
* Cygwin port changes from Venkat
*
* Revision 1.24 2000/09/08 17:08:10 steve
* initialize vlog info.
*
* Revision 1.23 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.22 2000/07/26 03:53:12 steve
* Make simulation precision available to VPI.
*
* Revision 1.21 2000/05/18 03:27:32 steve
* Support writing scalars and vectors to signals.
*
* Revision 1.20 2000/05/11 01:37:33 steve
* Calculate the X output value from drive0 and drive1
*
* Revision 1.19 2000/05/09 21:16:35 steve
* Give strengths to logic and bufz devices.
*
* Revision 1.18 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.17 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* Change vvm constants to use the driver_t to drive
* a constant value. This works better if there are
* multiple drivers on a signal.
*
* Revision 1.16 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.15 2000/04/22 04:20:20 steve
* Add support for force assignment.
*
* Revision 1.14 2000/03/31 07:08:39 steve
* allow cancelling of cbValueChange events.
*
* Revision 1.13 2000/03/25 05:02:24 steve
* signal bits are referenced at run time by the vpiSignal struct.
*
* Revision 1.12 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.11 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.10 2000/02/13 19:18:28 steve
* Accept memory words as parameter to $display.
*
* Revision 1.9 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.8 1999/11/28 00:56:08 steve
* Build up the lists in the scope of a module,
* and get $dumpvars to scan the scope for items.
*
* Revision 1.7 1999/11/27 19:07:58 steve
* Support the creation of scopes.
*
* Revision 1.6 1999/11/10 02:52:24 steve
* Create the vpiMemory handle type.
*
* Revision 1.5 1999/11/06 16:52:16 steve
* complete value retrieval for number constants.
*
* Revision 1.4 1999/11/06 16:00:18 steve
* Put number constants into a static table.
*
* Revision 1.3 1999/10/29 03:37:22 steve
* Support vpiValueChance callbacks.
*
* Revision 1.2 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
* Revision 1.1 1999/08/15 01:23:56 steve
* Convert vvm to implement system tasks with vpi.
*
*/
#endif

View File

@ -1,205 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_scope.c,v 1.3 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdlib.h>
# include <assert.h>
static const char* scope_get_str(int code, vpiHandle obj)
{
struct __vpiScope*ref = (struct __vpiScope*)obj;
assert((obj->vpi_type->type_code == vpiModule)
|| (obj->vpi_type->type_code == vpiNamedBegin)
|| (obj->vpi_type->type_code == vpiTask));
switch (code) {
case vpiFullName:
return ref->name;
default:
assert(0);
return 0;
}
}
static vpiHandle module_iter(int code, vpiHandle obj)
{
struct __vpiScope*ref = (struct __vpiScope*)obj;
assert((obj->vpi_type->type_code == vpiModule)
|| (obj->vpi_type->type_code == vpiNamedBegin)
|| (obj->vpi_type->type_code == vpiTask)
|| (obj->vpi_type->type_code == vpiFunction));
switch (code) {
case vpiInternalScope:
return vpip_make_iterator(ref->nintern, ref->intern);
}
return 0;
}
static const struct __vpirt vpip_module_rt = {
vpiModule,
0,
scope_get_str,
0,
0,
0,
module_iter
};
static const struct __vpirt vpip_task_rt = {
vpiTask,
0,
scope_get_str,
0,
0,
0,
module_iter
};
static const struct __vpirt vpip_function_rt = {
vpiFunction,
0,
scope_get_str,
0,
0,
0,
module_iter
};
static const struct __vpirt vpip_named_begin_rt = {
vpiNamedBegin,
0,
scope_get_str,
0,
0,
0,
module_iter
};
static const struct __vpirt vpip_named_fork_rt = {
vpiNamedFork,
0,
0,
0,
0,
0,
module_iter
};
vpiHandle vpip_make_scope(struct __vpiScope*ref, int type, const char*name)
{
ref->intern = 0;
ref->nintern = 0;
ref->name = name;
switch (type) {
case vpiModule:
ref->base.vpi_type = &vpip_module_rt;
break;
case vpiNamedBegin:
ref->base.vpi_type = &vpip_named_begin_rt;
break;
case vpiNamedFork:
ref->base.vpi_type = &vpip_named_fork_rt;
break;
case vpiTask:
ref->base.vpi_type = &vpip_task_rt;
break;
case vpiFunction:
ref->base.vpi_type = &vpip_function_rt;
break;
default:
assert(0);
}
return &ref->base;
}
void vpip_attach_to_scope(struct __vpiScope*ref, vpiHandle obj)
{
unsigned idx = ref->nintern++;
if (ref->intern == 0)
ref->intern = malloc(sizeof(vpiHandle));
else
ref->intern = realloc(ref->intern, sizeof(vpiHandle)*ref->nintern);
ref->intern[idx] = obj;
}
/*
* $Log: vpi_scope.c,v $
* Revision 1.3 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/10/21 23:37:49 steve
* Kill const-nonconst warning.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.11 2001/01/01 08:10:35 steve
* Handle function scopes in dumpvars scn (PR#95)
*
* Revision 1.10 2000/11/01 06:05:44 steve
* VCD scans tasks (PR#35)
*
* Revision 1.9 2000/10/29 17:10:02 steve
* task threads ned their scope initialized. (PR#32)
*
* Revision 1.8 2000/10/28 00:51:42 steve
* Add scope to threads in vvm, pass that scope
* to vpi sysTaskFunc objects, and add vpi calls
* to access that information.
*
* $display displays scope in %m (PR#1)
*
* Revision 1.7 2000/05/03 05:03:26 steve
* Support named for in VPI.
*
* Revision 1.6 2000/03/08 04:36:54 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.5 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.4 1999/12/15 18:21:20 steve
* Support named begin scope at run time.
*
* Revision 1.3 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.2 1999/11/28 00:56:08 steve
* Build up the lists in the scope of a module,
* and get $dumpvars to scan the scope for items.
*
* Revision 1.1 1999/11/27 19:07:58 steve
* Support the creation of scopes.
*
*/

View File

@ -1,179 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_signal.c,v 1.3 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vpi_priv.h"
# include <assert.h>
static int signal_get(int code, vpiHandle ref)
{
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
switch (code) {
case vpiSigned:
return rfp->signed_flag;
case vpiSize:
return rfp->nbits;
default:
return 0;
}
}
static const char* signal_get_str(int code, vpiHandle ref)
{
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
switch (code) {
case vpiFullName:
return (char*)rfp->name;
}
return 0;
}
static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
{
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
vpip_bits_get_value(rfp->bits, rfp->nbits, vp, rfp->signed_flag);
}
static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp,
p_vpi_time when, int flags)
{
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
vpip_bits_set_value(rfp->bits, rfp->nbits, vp);
return ref;
}
static const struct __vpirt vpip_net_rt = {
vpiNet,
signal_get,
signal_get_str,
signal_get_value,
signal_put_value,
0,
0
};
vpiHandle vpip_make_net(struct __vpiSignal*ref, const char*name,
vpip_bit_t*b, unsigned nb, int signed_flag)
{
ref->base.vpi_type = &vpip_net_rt;
ref->name = name;
ref->bits = b;
ref->nbits = nb;
ref->signed_flag = signed_flag? 1 : 0;
ref->mfirst = 0;
ref->mlast = 0;
return &(ref->base);
}
static const struct __vpirt vpip_reg_rt = {
vpiReg,
signal_get,
signal_get_str,
signal_get_value,
signal_put_value,
0,
0
};
vpiHandle vpip_make_reg(struct __vpiSignal*ref, const char*name,
vpip_bit_t*b, unsigned nb, int signed_flag)
{
ref->base.vpi_type = &vpip_reg_rt;
ref->name = name;
ref->bits = b;
ref->nbits = nb;
ref->signed_flag = signed_flag? 1 : 0;
ref->mfirst = 0;
ref->mlast = 0;
return &(ref->base);
}
/*
* $Log: vpi_signal.c,v $
* Revision 1.3 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/10/26 02:29:10 steve
* const/non-const warnings. (Stephan Boettcher)
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.12 2001/01/06 22:22:17 steve
* Support signed decimal display of variables.
*
* Revision 1.11 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.10 2000/05/18 03:27:32 steve
* Support writing scalars and vectors to signals.
*
* Revision 1.9 2000/03/31 07:08:39 steve
* allow cancelling of cbValueChange events.
*
* Revision 1.8 2000/03/25 05:02:25 steve
* signal bits are referenced at run time by the vpiSignal struct.
*
* Revision 1.7 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.5 1999/11/07 20:33:30 steve
* Add VCD output and related system tasks.
*
* Revision 1.4 1999/11/07 02:25:08 steve
* Add the $monitor implementation.
*
* Revision 1.3 1999/11/06 16:52:16 steve
* complete value retrieval for number constants.
*
* Revision 1.2 1999/10/29 03:37:22 steve
* Support vpiValueChance callbacks.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,243 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_simulation.c,v 1.3 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdlib.h>
# include <stdarg.h>
# include <assert.h>
struct vpip_event {
void*user_data;
void (*sim_fun)(void*);
struct vpip_event*next;
};
static struct vpip_simulation vpip_simulation_obj;
struct vpip_simulation *vpip_get_simulation_obj(void)
{
return &vpip_simulation_obj;
}
extern void vpi_sim_vcontrol(int func, va_list ap)
{
switch (func) {
case vpiFinish:
vpip_simulation_obj.going_flag = 0;
break;
}
}
/*
* The simulation event queue is a list of simulation cycles that in
* turn contain lists of simulation events. The simulation cycle
* represents the happening at some simulation time.
*/
struct vpip_simulation_cycle {
unsigned long delay;
struct vpip_simulation_cycle*next;
struct vpip_simulation_cycle*prev;
struct vpip_event*event_list;
struct vpip_event*event_last;
struct vpip_event*nonblock_list;
struct vpip_event*nonblock_last;
};
void vpip_init_simulation()
{
struct vpip_simulation_cycle*cur;
vpip_make_time_var(&vpip_simulation_obj.sim_time, "$time");
vpip_simulation_obj.read_sync_list = 0;
/* Allocate a header cell for the simulation event list. */
cur = calloc(1, sizeof(struct vpip_simulation_cycle));
cur->delay = 0;
cur->next = cur->prev = cur;
vpip_simulation_obj.sim = cur;
vpip_simulation_obj.time_precision = 0;
vpi_mcd_init();
}
void vpip_time_scale(int precision)
{
vpip_simulation_obj.time_precision = precision;
}
vpiHandle vpip_sim_time()
{
return &vpip_simulation_obj.sim_time.base;
}
struct vpip_event* vpip_sim_insert_event(unsigned long delay,
void*user_data,
void (*sim_fun)(void*),
int nonblock_flag)
{
struct vpip_event*event;
struct vpip_simulation_cycle*cur;
event = calloc(1, sizeof(struct vpip_event));
event->user_data = user_data;
event->sim_fun = sim_fun;
cur = vpip_simulation_obj.sim->next;
while ((cur != vpip_simulation_obj.sim) && (cur->delay < delay)) {
delay -= cur->delay;
cur = cur->next;
}
/* If there is no cycle cell for the specified time, create one. */
if ((cur == vpip_simulation_obj.sim) || (cur->delay > delay)) {
struct vpip_simulation_cycle*cell
= calloc(1,sizeof(struct vpip_simulation_cycle));
cell->delay = delay;
if (cur != vpip_simulation_obj.sim)
cur->delay -= delay;
cell->next = cur;
cell->prev = cur->prev;
cell->next->prev = cell;
cell->prev->next = cell;
cur = cell;
}
/* Put the event into the end of the cycle list. */
event->next = 0;
if (nonblock_flag) {
if (cur->nonblock_list == 0) {
cur->nonblock_list = cur->nonblock_last = event;
} else {
cur->nonblock_last->next = event;
cur->nonblock_last = event;
}
} else {
if (cur->event_list == 0) {
cur->event_list = cur->event_last = event;
} else {
cur->event_last->next = event;
cur->event_last = event;
}
}
return event;
}
void vpip_sim_cancel_event(struct vpip_event*ev)
{
assert(0);
}
int vpip_finished()
{
return ! vpip_simulation_obj.going_flag;
}
void vpip_simulation_run()
{
vpip_simulation_obj.sim_time.time = 0;
vpip_simulation_obj.going_flag = !0;
while (vpip_simulation_obj.going_flag) {
struct vpip_simulation_cycle*sim = vpip_simulation_obj.sim;
/* Step the time forward to the next time cycle. */
vpip_simulation_obj.sim_time.time += sim->delay;
sim->delay = 0;
while (vpip_simulation_obj.going_flag) {
struct vpip_event*active = sim->event_list;
sim->event_list = 0;
sim->event_last = 0;
if (active == 0) {
active = sim->nonblock_list;
sim->nonblock_list = 0;
sim->nonblock_last = 0;
}
if (active == 0)
break;
while (active && vpip_simulation_obj.going_flag) {
struct vpip_event*cur = active;
active = cur->next;
(cur->sim_fun)(cur->user_data);
free(cur);
}
}
if (! vpip_simulation_obj.going_flag)
break;
{ struct vpip_simulation_cycle*next = sim->next;
if (next == sim) {
vpip_simulation_obj.going_flag = 0;
break;
}
sim->next->prev = sim->prev;
sim->prev->next = sim->next;
free(sim);
vpip_simulation_obj.sim = next;
}
}
}
/*
* $Log: vpi_simulation.c,v $
* Revision 1.3 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/06/12 03:53:10 steve
* Change the VPI call process so that loaded .vpi modules
* use a function table instead of implicit binding.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.5 2000/10/06 23:11:39 steve
* Replace data references with function calls. (Venkat)
*
* Revision 1.4 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.3 2000/07/26 03:53:12 steve
* Make simulation precision available to VPI.
*
* Revision 1.2 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,175 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_systask.c,v 1.5 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdlib.h>
# include <assert.h>
static vpiHandle systask_handle(int type, vpiHandle ref)
{
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
assert((ref->vpi_type->type_code == vpiSysTaskCall)
|| (ref->vpi_type->type_code == vpiSysFuncCall));
switch (type) {
case vpiScope:
return &rfp->scope->base;
default:
assert(0);
return 0;
}
}
/*
* the iter function only supports getting an iterator of the
* arguments. This works equally well for tasks and functions.
*/
static vpiHandle systask_iter(int type, vpiHandle ref)
{
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
assert((ref->vpi_type->type_code == vpiSysTaskCall)
|| (ref->vpi_type->type_code == vpiSysFuncCall));
if (rfp->nargs == 0)
return 0;
return vpip_make_iterator(rfp->nargs, rfp->args);
}
static const struct __vpirt vpip_systask_rt = {
vpiSysTaskCall,
0,
0,
0,
0,
systask_handle,
systask_iter
};
const struct __vpirt *vpip_get_systask_rt(void)
{
return &vpip_systask_rt;
}
/*
* A value *can* be put to a vpiSysFuncCall object. This is how the
* return value is set. The value that is given should be converted to
* bits and set into the return value bit array.
*/
static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value val,
p_vpi_time t, int flag)
{
long tmp;
int idx;
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
assert(ref->vpi_type->type_code == vpiSysFuncCall);
/* There *must* be a return value array. */
assert(rfp->res);
assert(rfp->nres > 0);
/* XXXX For now, only support very specific formats. */
assert(val->format == vpiIntVal);
/* This fills the result bits with the signed value of the
integer. This automagically extends the sign bit by nature
of how the >> works in C. */
tmp = val->value.integer;
for (idx = 0 ; idx < rfp->nres ; idx += 1) {
rfp->res[idx] = (tmp&1) ? St1 : St0;
tmp >>= 1;
}
return 0;
}
static const struct __vpirt vpip_sysfunc_rt = {
vpiSysFuncCall,
0,
0,
0,
sysfunc_put_value,
0,
systask_iter
};
const struct __vpirt *vpip_get_sysfunc_rt(void)
{
return &vpip_sysfunc_rt;
}
/*
* $Log: vpi_systask.c,v $
* Revision 1.5 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/09/30 16:45:10 steve
* Fix some Cygwin DLL handling. (Venkat Iyer)
*
* Revision 1.3 2001/05/22 02:14:47 steve
* Update the mingw build to not require cygwin files.
*
* Revision 1.2 2001/05/20 15:09:40 steve
* Mingw32 support (Venkat Iyer)
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.9 2000/11/01 03:19:36 steve
* Add the general $time system function.
*
* Revision 1.8 2000/10/28 00:51:42 steve
* Add scope to threads in vvm, pass that scope
* to vpi sysTaskFunc objects, and add vpi calls
* to access that information.
*
* $display displays scope in %m (PR#1)
*
* Revision 1.7 2000/10/06 23:11:39 steve
* Replace data references with function calls. (Venkat)
*
* Revision 1.6 2000/09/30 03:20:48 steve
* Cygwin port changes from Venkat
*
* Revision 1.5 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.4 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.3 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,97 +0,0 @@
/*
* 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_time.c,v 1.2 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vpi_priv.h"
# include <assert.h>
# include <stdio.h>
/*
* IEEE-1364 VPI pretty much mandates the existence of this sort of
* thing. (Either this or a huge memory leak.) Sorry.
*/
static char buf_obj[128];
static void timevar_get_value(vpiHandle ref, s_vpi_value*vp)
{
struct __vpiTimeVar*rfp = (struct __vpiTimeVar*)ref;
assert(ref->vpi_type->type_code == vpiTimeVar);
switch (vp->format) {
case vpiObjTypeVal:
case vpiTimeVal:
rfp->time_obj.low = rfp->time;
vp->value.time = &rfp->time_obj;
vp->format = vpiTimeVal;
break;
case vpiDecStrVal:
sprintf(buf_obj, "%lu", rfp->time);
vp->value.str = buf_obj;
break;
default:
vp->format = vpiSuppressVal;
vp->value.str = 0;
break;
}
}
static const struct __vpirt vpip_time_var_rt = {
vpiTimeVar,
0,
0,
timevar_get_value,
0,
0,
0
};
vpiHandle vpip_make_time_var(struct __vpiTimeVar*ref, const char*val)
{
ref->base.vpi_type = &vpip_time_var_rt;
ref->name = val;
return &(ref->base);
}
/*
* $Log: vpi_time.c,v $
* Revision 1.2 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2001/03/14 19:27:44 steve
* Rearrange VPI support libraries.
*
* Revision 1.3 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/12/15 04:01:14 steve
* Add the VPI implementation of $readmemh.
*
* Revision 1.1 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
*/

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2000 Adrian Lewis (indproj@yahoo.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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_vlog_info.c,v 1.3 2002/08/12 01:35:06 steve Exp $"
#endif
#include <vpi_priv.h>
// STORAGE FOR COMMAND LINE ARGUMENTS
static int vpip_argc;
static char** vpip_argv;
// ROUTINE: vpi_get_vlog_info
//
// ARGUMENT: vlog_info_p
// Pointer to a structure containing simulation information.
//
// RETURNS:
// Boolean: true on success and false on failure.
//
// DESCRIPTION:
// Retrieve information about Verilog simulation execution.
int
vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p)
{
// AUTOMATICALLY UPDATING THE VERSION NUMBER WOULD BE A GOOD IDEA
static char* version = "$Name: $";
static char* product = "Icarus Verilog";
// CHECK THAT THE USER DIDN'T PASS A NULL POINTER
if (vlog_info_p != 0)
{
// FILL IN INFORMATION FIELDS
vlog_info_p->product = product;
vlog_info_p->version = version;
vlog_info_p->argc = vpip_argc;
vlog_info_p->argv = vpip_argv;
return 1==1;
}
else
return 1==0;
}
// ROUTINE: vpip_set_vlog_info
//
// ARGUMENTS: argc, argv
// Standard command line arguments.
//
// DESCRIPTION:
// Saves command line arguments to retrieval by vpi_get_vlog_info.
void
vpip_set_vlog_info(int argc, char** argv)
{
// SAVE COMMAND LINE ARGUMENTS IN STATIC VARIABLES
vpip_argc = argc;
vpip_argv = argv;
}
/*
* $Log: vpi_vlog_info.c,v $
* Revision 1.3 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:05 steve
* Add missing Log and Ident strings.
*
*/

View File

@ -1,55 +0,0 @@
EXPORTS
vpi_free_object
vpi_get
vpi_get_str
vpi_get_time
vpi_get_value
vpi_get_vlog_info
vpi_handle
vpi_handle_by_index
vpi_iterate
vpi_mcd_close
vpi_mcd_fgetc
vpi_mcd_fputc
vpi_mcd_init
vpi_mcd_name
vpi_mcd_open
vpi_mcd_open_x
vpi_mcd_printf
vpi_printf
vpi_put_value
vpi_register_cb
vpi_register_systf
vpi_remove_cb
vpi_scan
vpi_sim_control
vpip_attach_to_scope
vpip_bits_get_value
vpip_bits_resolve
vpip_bits_set_value
vpip_callfunc
vpip_calltask
vpip_finished
vpip_init_simulation
vpip_make_iterator
vpip_make_memory
vpip_make_net
vpip_make_number_const
vpip_make_reg
vpip_make_scope
vpip_make_string_const
vpip_make_time_var
vpip_get_null
vpip_pair_resolve
vpip_run_value_changes
vpip_set_vlog_info
vpip_sim_cancel_event
vpip_sim_insert_event
vpip_sim_time
vpip_get_simulation_obj
vpip_simulation_run
vpip_get_sysfunc_rt
vpip_get_systask_rt
vpip_time_scale