Merge branch 'master' into verilog-ams
This commit is contained in:
commit
038b024e71
130
BUGS.txt
130
BUGS.txt
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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=.. )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
29
emit.cc
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
18
functor.cc
18
functor.cc
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
34
net_scope.cc
34
net_scope.cc
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
4
parse.y
4
parse.y
|
|
@ -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(); }
|
||||
;
|
||||
|
||||
|
|
|
|||
101
vpip/Makefile.in
101
vpip/Makefile.in
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
166
vpip/vpi_bit.c
166
vpip/vpi_bit.c
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
526
vpip/vpi_const.c
526
vpip/vpi_const.c
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
160
vpip/vpi_mcd.c
160
vpip/vpi_mcd.c
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
303
vpip/vpi_priv.c
303
vpip/vpi_priv.c
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
542
vpip/vpi_priv.h
542
vpip/vpi_priv.h
|
|
@ -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
|
||||
205
vpip/vpi_scope.c
205
vpip/vpi_scope.c
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue