mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 06:16:47 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84de8f2b93 | ||
|
|
08dac488c1 | ||
|
|
f2cff31b6e | ||
|
|
7c3f5c9fae | ||
|
|
aa16e82102 | ||
|
|
ddd3566d50 | ||
|
|
ec82af0c74 | ||
|
|
78bb3d6f09 | ||
|
|
54dab22042 | ||
|
|
9756cb6382 | ||
|
|
9fa0f95003 | ||
|
|
a624021a2e | ||
|
|
928df5caf7 | ||
|
|
5796524f06 | ||
|
|
b761a105b3 | ||
|
|
364ffc9024 | ||
|
|
712080f7e0 | ||
|
|
b906f4c0a1 | ||
|
|
d48bb4d744 | ||
|
|
d67ad166cd | ||
|
|
4e286ea86b | ||
|
|
a9be4e009f | ||
|
|
2f05d4b227 | ||
|
|
0b68639f7d | ||
|
|
5f09e01a44 | ||
|
|
6a98764b3b | ||
|
|
853c1f4387 | ||
|
|
b99c5aa394 | ||
|
|
349be0f169 | ||
|
|
4f28f6a770 | ||
|
|
fcf64c0c38 | ||
|
|
da8d59757e | ||
|
|
a02cfe0f1b | ||
|
|
f3255121a2 | ||
|
|
608555ce7e | ||
|
|
ec8b6e126e | ||
|
|
a697157257 | ||
|
|
ec070ee65b | ||
|
|
02f5ccd5d9 | ||
|
|
361d4f2147 | ||
|
|
c09a148cd9 | ||
|
|
b274dada85 | ||
|
|
c6a937e2e7 | ||
|
|
5840368f2d | ||
|
|
dee52dd2d0 | ||
|
|
a0e3b3386d | ||
|
|
6535b48c1c | ||
|
|
4d3611c5f1 | ||
|
|
77c4c88a4c | ||
|
|
4291866b9f | ||
|
|
8aef782411 | ||
|
|
0aa033ddf3 | ||
|
|
edba542c7a | ||
|
|
0e5289b022 | ||
|
|
6be3be0f16 | ||
|
|
03d188fc52 | ||
|
|
6e1e658922 | ||
|
|
a87575a76e | ||
|
|
336624c7b9 | ||
|
|
71660fbaa5 | ||
|
|
dd79885f6d | ||
|
|
51ffeb7c06 | ||
|
|
912749342c | ||
|
|
4bb91c4f98 | ||
|
|
400580179f | ||
|
|
c9d6b5431d | ||
|
|
51db00fb44 | ||
|
|
e20acfc9f9 | ||
|
|
a3fe753826 | ||
|
|
03aebd7525 | ||
|
|
fd5c0cfa28 | ||
|
|
357a0ff23e | ||
|
|
1a22f37d92 | ||
|
|
a5890b914f | ||
|
|
b397b10104 | ||
|
|
5de8e0555c | ||
|
|
91b01cd67e | ||
|
|
9c6b17c887 | ||
|
|
000d187c94 | ||
|
|
989e9d4d94 | ||
|
|
40ef704cc3 | ||
|
|
7c9fe0c173 | ||
|
|
dddbeb957a | ||
|
|
fd0cb30a4d | ||
|
|
125c631091 | ||
|
|
443dc7853f | ||
|
|
a5400d7212 | ||
|
|
da09d4c6e6 | ||
|
|
ace6b0a767 | ||
|
|
7d494fd3d5 | ||
|
|
cd1524e6ca | ||
|
|
a0526cdd32 | ||
|
|
4dd5f97a96 | ||
|
|
1ca6fe5519 | ||
|
|
6b2c604124 |
@@ -17,13 +17,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: HName.cc,v 1.1 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: HName.cc,v 1.3 2002/01/05 04:36:06 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "HName.h"
|
||||
# include <iostream>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
@@ -249,6 +253,12 @@ ostream& operator<< (ostream&out, const hname_t&that)
|
||||
|
||||
/*
|
||||
* $Log: HName.cc,v $
|
||||
* Revision 1.3 2002/01/05 04:36:06 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.2 2001/12/18 04:52:45 steve
|
||||
* Include config.h for namespace declaration.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+16
-11
@@ -16,12 +16,16 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.109 2001/12/06 02:55:24 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.114 2002/02/03 07:05:36 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.5
|
||||
# This version string is only used in the version message printed
|
||||
# by the compiler. It reflects the assigned version number for the
|
||||
# product as a whole. Most components also print the CVS Name: token
|
||||
# in order to get a more automatic version stamp as well.
|
||||
VERSION = 0.6
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -46,6 +50,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
STRIP = @STRIP@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
@@ -66,7 +72,7 @@ all: ivl@EXEEXT@ libvpi.a
|
||||
cd vvm ; $(MAKE) all
|
||||
cd vpi ; $(MAKE) all
|
||||
cd ivlpp ; $(MAKE) all
|
||||
cd driver ; $(MAKE) all
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) all
|
||||
cd tgt-verilog ; $(MAKE) all
|
||||
cd tgt-stub ; $(MAKE) all
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
|
||||
@@ -83,9 +89,8 @@ endif
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
driver/iverilog -Ccheck.conf -ocheck -tvvm-check -B./ivlpp examples/hello.vl
|
||||
$(CXX) -o check $(rdynamic) -fno-exceptions -I$(srcdir) -I$(srcdir)/vvm -I$(srcdir)/vpip -Lvvm -Lvpip check.cc -lvvm -lvpip $(dllib)
|
||||
./check | grep 'Hello, World'
|
||||
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
|
||||
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
||||
clean:
|
||||
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a
|
||||
@@ -116,8 +121,8 @@ elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
|
||||
elab_sig.o emit.o eval.o eval_rconst.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o mangle.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \
|
||||
net_scope.o net_udp.o pad_to_width.o \
|
||||
net_design.o net_event.o net_expr.o net_force.o net_link.o net_modulo.o \
|
||||
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
@@ -170,14 +175,14 @@ lexor.o: lexor.cc parse.h
|
||||
parse.o: parse.cc
|
||||
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h || mv parse.hh parse.h
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
flex -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
lexor_keyword.o: lexor_keyword.cc
|
||||
|
||||
|
||||
+13
-4
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.cc,v 1.7 2001/11/22 06:20:59 steve Exp $"
|
||||
#ident "$Id: PDelays.cc,v 1.8 2001/12/29 20:19:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -30,14 +30,17 @@
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delay_[idx] = 0;
|
||||
}
|
||||
|
||||
PDelays::~PDelays()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delete delay_[idx];
|
||||
if (delete_flag_) {
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delete delay_[idx];
|
||||
}
|
||||
}
|
||||
|
||||
void PDelays::set_delay(PExpr*del)
|
||||
@@ -45,15 +48,18 @@ void PDelays::set_delay(PExpr*del)
|
||||
assert(del);
|
||||
assert(delay_[0] == 0);
|
||||
delay_[0] = del;
|
||||
delete_flag_ = true;
|
||||
}
|
||||
|
||||
|
||||
void PDelays::set_delays(const svector<PExpr*>*del)
|
||||
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||
{
|
||||
assert(del);
|
||||
assert(del->count() <= 3);
|
||||
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
|
||||
delay_[idx] = (*del)[idx];
|
||||
|
||||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
static unsigned long calculate_val(Design*des, const NetScope*scope,
|
||||
@@ -125,6 +131,9 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
|
||||
/*
|
||||
* $Log: PDelays.cc,v $
|
||||
* Revision 1.8 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.7 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.h,v 1.4 2001/11/22 06:20:59 steve Exp $"
|
||||
#ident "$Id: PDelays.h,v 1.5 2001/12/29 20:19:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
@@ -45,8 +45,11 @@ class PDelays {
|
||||
PDelays();
|
||||
~PDelays();
|
||||
|
||||
/* Set the delay expressions. If the delete_flag is true, then
|
||||
this object takes ownership of the expressions, and will
|
||||
delete it in the destructor. */
|
||||
void set_delay(PExpr*);
|
||||
void set_delays(const svector<PExpr*>*del);
|
||||
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
|
||||
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
@@ -57,6 +60,7 @@ class PDelays {
|
||||
|
||||
private:
|
||||
PExpr* delay_[3];
|
||||
bool delete_flag_;
|
||||
|
||||
private: // not implemented
|
||||
PDelays(const PDelays&);
|
||||
@@ -67,6 +71,9 @@ ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* Revision 1.5 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.4 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.cc,v 1.28 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: PExpr.cc,v 1.29 2001/12/30 21:32:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -46,18 +46,6 @@ bool PExpr::is_constant(Module*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
Link::strength_t,
|
||||
Link::strength_t) const
|
||||
{
|
||||
cerr << get_line() << ": error: Unable to elaborate `"
|
||||
<< *this << "' as gates." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": error: expression not valid in assign l-value: "
|
||||
@@ -216,13 +204,14 @@ bool PENumber::is_constant(Module*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
PEString::PEString(const string&s)
|
||||
PEString::PEString(char*s)
|
||||
: text_(s)
|
||||
{
|
||||
}
|
||||
|
||||
PEString::~PEString()
|
||||
{
|
||||
delete[]text_;
|
||||
}
|
||||
|
||||
string PEString::value() const
|
||||
@@ -267,6 +256,9 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.29 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.28 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.53 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.54 2001/12/30 21:32:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -285,21 +285,35 @@ class PENumber : public PExpr {
|
||||
verinum*const value_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This represents a string constant in an expression.
|
||||
*
|
||||
* The s parameter to the PEString constructor is a C string that this
|
||||
* class instance will take for its own. The caller should not delete
|
||||
* the string, the destructor will do it.
|
||||
*/
|
||||
class PEString : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEString(const string&s);
|
||||
explicit PEString(char*s);
|
||||
~PEString();
|
||||
|
||||
string value() const;
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private:
|
||||
const string text_;
|
||||
char*text_;
|
||||
};
|
||||
|
||||
class PEUnary : public PExpr {
|
||||
@@ -449,6 +463,9 @@ class PECallFunction : public PExpr {
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.54 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.53 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.cc,v 1.7 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: PWire.cc,v 1.8 2002/01/26 05:28:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -39,14 +39,7 @@ NetNet::Type PWire::get_wire_type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
#if 0
|
||||
string PWire::name() const
|
||||
{
|
||||
string name = hname_[0];
|
||||
for (unsigned idx = 1 ; hname_[idx] ; idx += 1)
|
||||
name = name + "." + hname_[idx];
|
||||
}
|
||||
#endif
|
||||
|
||||
const hname_t& PWire::path() const
|
||||
{
|
||||
return hname_;
|
||||
@@ -127,6 +120,9 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.8 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.7 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+21
-15
@@ -13,13 +13,13 @@ home page at <http://www.icarus.com/eda/verilog>.
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
tools. These back-end tools currently include a simulator written in
|
||||
C++ called VVM, another faster simulator called VVP and an XNF (Xilinx
|
||||
Netlist Format) generator. See "vvm.txt" and "xnf.txt" for further
|
||||
details on these back-end processors. In the future, backends are
|
||||
expected for EDIF/LPM, structural Verilog, VHDL, etc.
|
||||
C++ called VVM, another faster simulator called VVP, an XNF (Xilinx
|
||||
Netlist Format) generator and an EDIF fpga netlist generator. In the
|
||||
future, backends are expected for EDIF/LPM, structural Verilog, VHDL,
|
||||
etc.
|
||||
|
||||
For instructions on how to run Icarus Verilog, see the ``iverilog''
|
||||
man page.
|
||||
For instructions on how to run Icarus Verilog,
|
||||
see the ``iverilog'' man page.
|
||||
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
@@ -30,6 +30,8 @@ system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
If you are building for Windows, see the mingw.txt file.
|
||||
|
||||
2.1 Compile Time Prerequisites
|
||||
|
||||
You need the following software to compile Icarus Verilog from source
|
||||
@@ -73,7 +75,7 @@ configure script that modify its behavior:
|
||||
|
||||
--without-ipal
|
||||
This turns off support for Icarus PAL, whether ipal
|
||||
libaries are installed or not.
|
||||
libraries are installed or not.
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
@@ -81,8 +83,9 @@ configure script that modify its behavior:
|
||||
/usr/local/share/ivl, etc.
|
||||
|
||||
I recommend that if you are configuring for precompiled
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
common to use --prefix=/opt.
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
common to use --prefix=/opt. You can configure for a non-root
|
||||
install with --prefix=$HOME.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
@@ -91,7 +94,7 @@ To run a simple test before installation, execute
|
||||
make check
|
||||
|
||||
The commands printed by this run might help you in running Icarus
|
||||
Verilog on your own verilog sources before the package is installed
|
||||
Verilog on your own Verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
2.4 Installation
|
||||
@@ -127,7 +130,7 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
|
||||
|
||||
3.2 Parse
|
||||
|
||||
The verilog compiler starts by parsing the verilog source file. The
|
||||
The Verilog compiler starts by parsing the Verilog source file. The
|
||||
output of the parse in a list of Module objects in PFORM. The pform
|
||||
(see pform.h) is mostly a direct reflection of the compilation
|
||||
step. There may be dangling references, and it is not yet clear which
|
||||
@@ -186,7 +189,7 @@ some useful transformations would be,
|
||||
|
||||
- eliminate null effect circuitry,
|
||||
- combinational reduction
|
||||
- Constant propagation
|
||||
- constant propagation
|
||||
|
||||
The actual functions performed are specified on the ivl command line by
|
||||
the -F flags (See below).
|
||||
@@ -206,7 +209,7 @@ command line.
|
||||
|
||||
3.6 ATTRIBUTES
|
||||
|
||||
The parser accepts as an extension to Verilog the $attribute module
|
||||
The parser accepts, as an extension to Verilog, the $attribute module
|
||||
item. The syntax of the $attribute item is:
|
||||
|
||||
$attribute (<identifier>, <key>, <value>);
|
||||
@@ -275,7 +278,7 @@ Usage: ivl <options>... file
|
||||
|
||||
This list can also be set with -fVPI_MODULE_LIST=<list> which
|
||||
sets the list completely. Then, -m after this will append
|
||||
module names to the list sp specified. The default list
|
||||
module names to the list specified. The default list
|
||||
includes "system".
|
||||
|
||||
-N <file>
|
||||
@@ -374,7 +377,7 @@ by the compiler. See the iverilog(1) man page.
|
||||
|
||||
Icarus Verilog is in development - as such it still only supports a
|
||||
(growing) subset of Verilog. Below is a description of some of the
|
||||
currently unsupported verilog features. This list is not exhaustive,
|
||||
currently unsupported Verilog features. This list is not exhaustive,
|
||||
and does not account for errors in the compiler. See the Icarus
|
||||
Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
@@ -404,6 +407,8 @@ constructs.
|
||||
|
||||
- trireg is not supported. tri0 and tri1 are supported.
|
||||
|
||||
- force to nets are not supported. Force to variables, and
|
||||
assign/deassign, are supported.
|
||||
|
||||
6.0 CREDITS
|
||||
|
||||
@@ -429,6 +434,7 @@ Verilog guidance, and especially testing from many people, including
|
||||
Stuart Sutherland <[email protected]>
|
||||
Stephen Tell <[email protected]>
|
||||
Stefan Theide <[email protected]>
|
||||
Tom Verbeure
|
||||
Steve Wilson <[email protected]>
|
||||
|
||||
and others. Testers in particular include a larger community of people
|
||||
|
||||
@@ -14,3 +14,6 @@ do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd $dir ; autoconf )
|
||||
done
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
|
||||
@@ -4,3 +4,6 @@
|
||||
|
||||
[-tvvm-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
|
||||
|
||||
[-tvvp-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o -- -
|
||||
|
||||
@@ -14,6 +14,22 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
if test "$LEX" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable flex found. ***"
|
||||
echo " Please install the 'flex' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(YACC,bison,none)
|
||||
if test "$YACC" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable bison found. ***"
|
||||
echo " Please install the 'bison' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cprop.cc,v 1.30 2001/10/28 01:14:53 steve Exp $"
|
||||
#ident "$Id: cprop.cc,v 1.32 2002/02/03 00:06:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -217,7 +217,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
with a simple XOR gate. */
|
||||
if (top == 1) {
|
||||
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
|
||||
NetLogic::XOR);
|
||||
NetLogic::XNOR);
|
||||
connect(tmp->pin(0), obj->pin_AEB());
|
||||
connect(tmp->pin(1), obj->pin_DataA(0));
|
||||
connect(tmp->pin(2), obj->pin_DataB(0));
|
||||
@@ -583,7 +583,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
unsigned idx = 1;
|
||||
|
||||
/* Eliminate all the 0 inputs. They have no effect
|
||||
on the output of an XOR gate. */
|
||||
on the output of an XOR gate. The eliminate works
|
||||
by unlinking the current input and relinking the
|
||||
last input to this position. It's like bubbling
|
||||
all the 0 inputs to the end. */
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
idx += 1;
|
||||
@@ -651,7 +654,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
|
||||
/* If all the inputs were eliminated, then replace
|
||||
the gate with a constant 0 and I am done. */
|
||||
the gate with a constant value and I am done. */
|
||||
if (top == 1) {
|
||||
verinum::V out = obj->type()==NetLogic::XNOR
|
||||
? verinum::V1
|
||||
@@ -887,7 +890,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
return;
|
||||
|
||||
// Look for signals that have NetESignal nodes attached to
|
||||
// them. If I find any, this this constant is used by a
|
||||
// them. If I find any, then this constant is used by a
|
||||
// behavioral expression somewhere.
|
||||
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
|
||||
Nexus*nex = obj->pin(idx).nexus();
|
||||
@@ -920,7 +923,6 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Done. Delete me.
|
||||
delete obj;
|
||||
}
|
||||
@@ -942,6 +944,12 @@ void cprop(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.32 2002/02/03 00:06:28 steve
|
||||
* Comments about xor evaluation.
|
||||
*
|
||||
* Revision 1.31 2001/12/31 01:56:08 steve
|
||||
* Get sense of 1-bit == operator right.
|
||||
*
|
||||
* Revision 1.30 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
|
||||
+6
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: design_dump.cc,v 1.120 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.121 2001/12/31 00:03:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -884,6 +884,8 @@ void NetESFunc::dump(ostream&o) const
|
||||
|
||||
void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
if (has_sign())
|
||||
o << "+";
|
||||
o << name() << "[" << msi_<<":"<<lsi_ << "]";
|
||||
}
|
||||
|
||||
@@ -970,6 +972,9 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.121 2001/12/31 00:03:05 steve
|
||||
* Include s indicator in dump of signed numbers.
|
||||
*
|
||||
* Revision 1.120 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+3
-3
@@ -18,12 +18,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.10 2001/11/17 17:57:58 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.11 2002/02/03 07:05:36 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.6
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -46,7 +46,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
|
||||
+2
-1
@@ -18,11 +18,12 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cfparse.y,v 1.5 2001/12/08 04:13:07 steve Exp $"
|
||||
#ident "$Id: cfparse.y,v 1.6 2002/01/02 02:39:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include <ctype.h>
|
||||
|
||||
/*
|
||||
|
||||
+18
-1
@@ -20,12 +20,29 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: cfparse_misc.h,v 1.2 2001/11/12 18:47:32 steve Exp $"
|
||||
#ident "$Id: cfparse_misc.h,v 1.3 2002/01/02 02:39:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The vlltype supports the passing of detailed source file location
|
||||
* information between the lexical analyzer and the parser. Defining
|
||||
* YYLTYPE compels the lexor to use this type and not something other.
|
||||
*/
|
||||
struct cfltype {
|
||||
unsigned first_line;
|
||||
unsigned first_column;
|
||||
unsigned last_line;
|
||||
unsigned last_column;
|
||||
const char*text;
|
||||
};
|
||||
# define YYLTYPE struct cfltype
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.3 2002/01/02 02:39:34 steve
|
||||
* Use my own cfltype to defend against bison 1.30.
|
||||
*
|
||||
* Revision 1.2 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
|
||||
+7
-3
@@ -1,10 +1,10 @@
|
||||
.TH iverilog 1 "$Date: 2001/12/08 04:13:07 $" Version "$Date: 2001/12/08 04:13:07 $"
|
||||
.TH iverilog 1 "$Date: 2002/02/03 07:05:37 $" Version "$Date: 2002/02/03 07:05:37 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-ESVv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule]
|
||||
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
|
||||
@@ -111,7 +111,11 @@ Use this switch to specify the target output format. See the
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
information from the various components.
|
||||
information from the various components, as well as the version of the
|
||||
product as a whole.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
.TP 8
|
||||
.B -W\fIclass\fP
|
||||
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
|
||||
|
||||
+20
-3
@@ -16,12 +16,13 @@
|
||||
* 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: main.c,v 1.31 2001/11/21 02:20:34 steve Exp $"
|
||||
#ident "$Id: main.c,v 1.32 2002/02/03 07:05:37 steve Exp $"
|
||||
|
||||
# include "config.h"
|
||||
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESv] [-B base] [-C path] [-c cmdfile]\n"
|
||||
"Usage: iverilog [-ESvV] [-B base] [-C path] [-c cmdfile]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
@@ -347,6 +348,7 @@ int main(int argc, char **argv)
|
||||
char*cmd;
|
||||
unsigned ncmd;
|
||||
int e_flag = 0;
|
||||
int version_flag = 0;
|
||||
int opt, idx;
|
||||
char*cp;
|
||||
|
||||
@@ -392,7 +394,7 @@ int main(int argc, char **argv)
|
||||
source_file = fopen(source_path, "w");
|
||||
assert(source_file);
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:y:")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vVW:y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
@@ -493,6 +495,9 @@ int main(int argc, char **argv)
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
case 'V':
|
||||
version_flag = 1;
|
||||
break;
|
||||
case 'W':
|
||||
process_warning_switch(optarg);
|
||||
break;
|
||||
@@ -508,6 +513,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION "\n");
|
||||
printf("Copyright 1998-2002 Stephen Williams\n");
|
||||
printf("$Name: $\n");
|
||||
|
||||
if (version_flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command_filename) {
|
||||
int rc;
|
||||
|
||||
@@ -624,6 +638,9 @@ int main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.32 2002/02/03 07:05:37 steve
|
||||
* Support print of version number.
|
||||
*
|
||||
* Revision 1.31 2001/11/21 02:20:34 steve
|
||||
* Pass list of file to ivlpp via temporary file.
|
||||
*
|
||||
|
||||
+12
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: dup_expr.cc,v 1.6 2001/11/19 01:54:14 steve Exp $"
|
||||
#ident "$Id: dup_expr.cc,v 1.7 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -31,6 +31,12 @@ NetEScope* NetEScope::dup_expr() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetESelect* NetESelect::dup_expr() const
|
||||
{
|
||||
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
|
||||
expr_width());
|
||||
}
|
||||
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
|
||||
@@ -68,6 +74,11 @@ NetEUnary* NetEUnary::dup_expr() const
|
||||
|
||||
/*
|
||||
* $Log: dup_expr.cc,v $
|
||||
* Revision 1.7 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.6 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
|
||||
+65
-3
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_expr.cc,v 1.46 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: elab_expr.cc,v 1.50 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -162,10 +162,32 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
*/
|
||||
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
{
|
||||
|
||||
/* Catch the special case that the system function is the
|
||||
$signed function. This function is special, in that it does
|
||||
not lead to executable code but takes the single parameter
|
||||
and makes it into a signed expression. No bits are changed,
|
||||
it just changes the interpretation. */
|
||||
if (strcmp(path_.peek_name(0), "$signed") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $signed() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope);
|
||||
sub->cast_signed(true);
|
||||
return sub;
|
||||
}
|
||||
|
||||
unsigned wid = 32;
|
||||
|
||||
if (strcmp(path_.peek_name(0), "$time") == 0)
|
||||
wid = 64;
|
||||
if (strcmp(path_.peek_name(0), "$stime") == 0)
|
||||
wid = 32;
|
||||
|
||||
|
||||
/* How many parameters are there? The Verilog language allows
|
||||
@@ -369,10 +391,19 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return new NetEConst(verinum(val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate an identifier in an expression. The identifier can be a
|
||||
* parameter name, a signal name or a memory name. It can also be a
|
||||
* scope name (Return a NetEScope) but only certain callers can use
|
||||
* scope names. However, we still support it here.
|
||||
*
|
||||
* Function names are not handled here, they are detected by the
|
||||
* parser and are elaborated by PECallFunction.
|
||||
*
|
||||
* The signal name may be escaped, but that affects nothing here.
|
||||
*/
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(path_.peek_name(0)[0] != '$');
|
||||
|
||||
assert(scope);
|
||||
|
||||
// If the identifier name is a parameter name, then return
|
||||
@@ -384,6 +415,23 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
else
|
||||
tmp = new NetEParam(des, scope, path_);
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
cerr << get_line() << ": error: part select of "
|
||||
<< "parameter " << path_ << " in " << scope->name()
|
||||
<< " is illegal." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else if (msb_) {
|
||||
/* Handle the case where a parameter has a bit
|
||||
select attached to it. Generate a NetESelect
|
||||
object to select the bit as desired. */
|
||||
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
|
||||
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
|
||||
tmp->set_line(*this);
|
||||
tmp = stmp;
|
||||
}
|
||||
|
||||
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
@@ -642,6 +690,20 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.50 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.49 2002/01/11 05:25:45 steve
|
||||
* The stime system function is 32bits.
|
||||
*
|
||||
* Revision 1.48 2001/12/31 00:08:14 steve
|
||||
* Support $signed cast of expressions.
|
||||
*
|
||||
* Revision 1.47 2001/12/29 20:41:30 steve
|
||||
* Allow escaped $ in identifiers.
|
||||
*
|
||||
* Revision 1.46 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+118
-12
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_net.cc,v 1.82 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: elab_net.cc,v 1.86 2002/01/23 05:23:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,6 +29,18 @@
|
||||
|
||||
# include <iostream>
|
||||
|
||||
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
Link::strength_t,
|
||||
Link::strength_t) const
|
||||
{
|
||||
cerr << get_line() << ": error: Unable to elaborate `"
|
||||
<< *this << "' as gates." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborating binary operations generally involves elaborating the
|
||||
* left and right expressions, then making an output wire and
|
||||
@@ -642,9 +654,12 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope,
|
||||
NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
if (rsig == 0) return 0;
|
||||
|
||||
unsigned rwidth = lsig->pin_count();
|
||||
if (rsig->pin_count() > rwidth)
|
||||
rwidth = rsig->pin_count();
|
||||
unsigned rwidth = lwidth;
|
||||
if (rwidth == 0) {
|
||||
rwidth = lsig->pin_count();
|
||||
if (rsig->pin_count() > rwidth)
|
||||
rwidth = rsig->pin_count();
|
||||
}
|
||||
NetModulo*mod = new NetModulo(scope, scope->local_hsymbol(), rwidth,
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
@@ -771,12 +786,45 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const
|
||||
{
|
||||
verinum*lnum = left_->eval_const(des, scope);
|
||||
verinum*rnum = right_->eval_const(des, scope);
|
||||
|
||||
/* Detect and handle the special case that both the operands
|
||||
of the multiply are constant expressions. Evalulate the
|
||||
value and make this a simple constant. */
|
||||
if (lnum && rnum) {
|
||||
verinum prod = *lnum * *rnum;
|
||||
if (lwidth == 0)
|
||||
lwidth = prod.len();
|
||||
|
||||
verinum res (verinum::V0, lwidth);
|
||||
for (unsigned idx = 0
|
||||
; idx < prod.len() && idx < lwidth
|
||||
; idx += 1) {
|
||||
res.set(idx, prod.get(idx));
|
||||
}
|
||||
|
||||
NetConst*odev = new NetConst(scope, scope->local_hsymbol(), res);
|
||||
NetNet*osig = new NetNet(scope, scope->local_hsymbol(),
|
||||
NetNet::IMPLICIT, lwidth);
|
||||
for (unsigned idx = 0 ; idx < lwidth ; idx += 1)
|
||||
connect(odev->pin(idx), osig->pin(idx));
|
||||
|
||||
des->add_node(odev);
|
||||
osig->local_flag(true);
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0);
|
||||
if (lsig == 0) return 0;
|
||||
NetNet*rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0);
|
||||
if (rsig == 0) return 0;
|
||||
|
||||
unsigned rwidth = lwidth;
|
||||
if (rwidth == 0) {
|
||||
rwidth = lsig->pin_count() + rsig->pin_count();
|
||||
}
|
||||
|
||||
NetMult*mult = new NetMult(scope, scope->local_hsymbol(), rwidth,
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
@@ -1232,14 +1280,11 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fine, create an implicit wire as an l-value. */
|
||||
sig = new NetNet(scope, path+"."+path_.peek_name(0),
|
||||
NetNet::IMPLICIT, 1);
|
||||
|
||||
if (warn_implicit)
|
||||
cerr << get_line() << ": warning: implicit "
|
||||
" definition of wire " << path << "." <<
|
||||
path_.peek_name(0) << "." << endl;
|
||||
cerr << get_line() << ": error: Net " << path_
|
||||
<< " is not defined in this context." << endl;
|
||||
cerr << get_line() << ": : Do you mean this? wire "
|
||||
<< path_ << " = <expr>;" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(sig);
|
||||
@@ -1539,6 +1584,55 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
|
||||
return net;
|
||||
}
|
||||
|
||||
/*
|
||||
* A string is a NetEConst node that is made of the ASCII bits of the
|
||||
* string instead of the bits of a number. In fact, a string is just
|
||||
* another numeric notation.
|
||||
*/
|
||||
NetNet* PEString::elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const
|
||||
{
|
||||
unsigned strbits = strlen(text_) * 8;
|
||||
NetNet*net;
|
||||
|
||||
/* If we are constrained by a l-value size, then just make a
|
||||
number constant with the correct size and set as many bits
|
||||
in that constant as make sense. Pad excess with zeros. */
|
||||
if (lwidth > 0) {
|
||||
net = new NetNet(scope, scope->local_hsymbol(),
|
||||
NetNet::IMPLICIT, lwidth);
|
||||
|
||||
} else {
|
||||
net = new NetNet(scope, scope->local_hsymbol(),
|
||||
NetNet::IMPLICIT, strbits);
|
||||
}
|
||||
net->local_flag(true);
|
||||
|
||||
/* Make a verinum that is filled with the 0 pad. */
|
||||
verinum num(verinum::V0, net->pin_count());
|
||||
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < num.len() && idx < strbits; idx += 1) {
|
||||
char byte = text_[strbits/8 - 1 - idx/8];
|
||||
char mask = 1<<(idx%8);
|
||||
num.set(idx, (byte & mask)? verinum::V1 : verinum::V0);
|
||||
}
|
||||
|
||||
NetConst*tmp = new NetConst(scope, scope->local_hsymbol(), num);
|
||||
for (idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
||||
tmp->pin(idx).drive0(drive0);
|
||||
tmp->pin(idx).drive1(drive1);
|
||||
connect(net->pin(idx), tmp->pin(idx));
|
||||
}
|
||||
|
||||
des->add_node(tmp);
|
||||
return net;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the ternary operator in a netlist by creating a LPM_MUX
|
||||
@@ -1880,6 +1974,18 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||
|
||||
/*
|
||||
* $Log: elab_net.cc,v $
|
||||
* Revision 1.86 2002/01/23 05:23:17 steve
|
||||
* No implicit declaration in assign l-values.
|
||||
*
|
||||
* Revision 1.85 2002/01/03 04:19:01 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.84 2001/12/31 04:23:59 steve
|
||||
* Elaborate multiply nets with constant operands ad NetConst.
|
||||
*
|
||||
* Revision 1.83 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.82 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+12
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_pexpr.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: elab_pexpr.cc,v 1.13 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -152,6 +152,12 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msb_ || lsb_ || idx_) {
|
||||
cerr << get_line() << ": error: Cannot bit/part select "
|
||||
"bits of parameters." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
|
||||
assert(res);
|
||||
delete name;
|
||||
@@ -218,6 +224,11 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.13 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+19
-8
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_scope.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: elab_scope.cc,v 1.13 2001/12/30 04:47:57 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -256,8 +256,10 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
|
||||
// Look for module parameter replacements. This map receives
|
||||
// those replacements.
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
// passed. It is built up by the ordered overrices or named
|
||||
// overrides.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
@@ -271,12 +273,18 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<string>::const_iterator cur = mod->param_names.begin();
|
||||
for (unsigned idx = 0
|
||||
; idx < overrides_->count()
|
||||
; idx += 1, cur++) {
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
}
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
if (idx >= overrides_->count())
|
||||
break;
|
||||
if (cur == mod->param_names.end())
|
||||
break;
|
||||
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
|
||||
idx += 1;
|
||||
cur ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
@@ -459,6 +467,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* Revision 1.13 2001/12/30 04:47:57 steve
|
||||
* Properly handle empty target in positionla parameter override.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+42
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_sig.cc,v 1.18 2001/12/03 04:47:14 steve Exp $"
|
||||
#ident "$Id: elab_sig.cc,v 1.20 2002/01/26 05:28:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -237,6 +237,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
string fname = scope->basename();
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
/* Make sure the function has at least one input port. If it
|
||||
fails this test, print an error message. Keep going so we
|
||||
can find more errors. */
|
||||
if (ports_ == 0) {
|
||||
cerr << get_line() << ": error: Function " << fname
|
||||
<< " has no ports." << endl;
|
||||
cerr << get_line() << ": : Functions must have"
|
||||
<< " at least one input port." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
|
||||
/* Get the reg for the return value. I know the name of the
|
||||
@@ -379,6 +390,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
if (msb_.count()) {
|
||||
svector<long>mnum (msb_.count());
|
||||
svector<long>lnum (msb_.count());
|
||||
/* There may be places where the signal is declared as a
|
||||
scaler. Count those here, for consistency check
|
||||
later. */
|
||||
unsigned count_scalars = 0;
|
||||
|
||||
/* There may be multiple declarations of ranges, because
|
||||
the symbol may have its range declared in i.e. input
|
||||
@@ -387,6 +402,14 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
|
||||
|
||||
if (msb_[idx] == 0) {
|
||||
count_scalars += 1;
|
||||
assert(lsb_[idx] == 0);
|
||||
mnum[idx] = 0;
|
||||
lnum[idx] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
NetEConst*tmp;
|
||||
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
|
||||
|
||||
@@ -417,6 +440,18 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
}
|
||||
|
||||
/* Check that the declarations were all scalar or all
|
||||
vector. It is an error to mix them. Use the
|
||||
count_scalars to know. */
|
||||
if ((count_scalars > 0) && (count_scalars != msb_.count())) {
|
||||
cerr << get_line() << ": error: Signal ``" << hname_
|
||||
<< "'' declared both as a vector and a scalar."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure all the values for msb and lsb match by
|
||||
value. If not, report an error. */
|
||||
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
|
||||
@@ -484,6 +519,12 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.20 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.19 2002/01/23 03:35:17 steve
|
||||
* Detect incorrect function ports.
|
||||
*
|
||||
* Revision 1.18 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+30
-4
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elaborate.cc,v 1.236 2001/12/06 05:04:49 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.240 2002/01/23 05:56:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -669,11 +669,11 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
||||
unsigned long rise_time = 0, fall_time = 0, decay_time = 0;
|
||||
if (overrides_) {
|
||||
PDelays tmp_del;
|
||||
tmp_del.set_delays(overrides_);
|
||||
tmp_del.set_delays(overrides_, false);
|
||||
tmp_del.eval_delays(des, scope, rise_time, fall_time, decay_time);
|
||||
delete overrides_;
|
||||
}
|
||||
|
||||
|
||||
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
|
||||
net->set_attributes(udp->attributes);
|
||||
net->rise_time(rise_time);
|
||||
@@ -1200,6 +1200,10 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||
NetCase*res = new NetCase(type_, expr, icount);
|
||||
res->set_line(*this);
|
||||
|
||||
/* Iterate over all the case items (guard/statement pairs)
|
||||
elaborating them. If the guard has no expression, then this
|
||||
is a "default" cause. Otherwise, the guard has one or more
|
||||
expressions, and each guard is a case. */
|
||||
unsigned inum = 0;
|
||||
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
|
||||
|
||||
@@ -1227,6 +1231,16 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||
assert(cur->expr[e]);
|
||||
gu = cur->expr[e]->elaborate_expr(des, scope);
|
||||
|
||||
/* Try to evaluate the guard expression down to a
|
||||
simple constant. */
|
||||
if (! dynamic_cast<NetEConst*>(gu)) {
|
||||
NetExpr*tmp = gu->eval_tree();
|
||||
if (tmp != 0) {
|
||||
delete gu;
|
||||
gu = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur->stat)
|
||||
st = cur->stat->elaborate(des, scope);
|
||||
|
||||
@@ -1520,7 +1534,7 @@ NetDeassign* PDeassign::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
NetNet*lval = lval_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
NetNet*lval = lval_->elaborate_anet(des, scope);
|
||||
if (lval == 0)
|
||||
return 0;
|
||||
|
||||
@@ -2394,6 +2408,18 @@ Design* elaborate(list<const char*>roots)
|
||||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.240 2002/01/23 05:56:22 steve
|
||||
* elaborate deassign lval as done for assign.
|
||||
*
|
||||
* Revision 1.239 2002/01/19 20:09:56 steve
|
||||
* Evaluate case guards, if possible.
|
||||
*
|
||||
* Revision 1.238 2001/12/31 00:39:20 steve
|
||||
* Remove test print
|
||||
*
|
||||
* Revision 1.237 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.236 2001/12/06 05:04:49 steve
|
||||
* Forgot to evaluate UDP delays.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.63 2001/10/19 21:53:24 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.65 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -186,8 +186,7 @@ bool NetCAssign::emit_proc(struct target_t*tgt) const
|
||||
|
||||
bool NetCondit::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_condit(this);
|
||||
return true;
|
||||
return tgt->proc_condit(this);
|
||||
}
|
||||
|
||||
bool NetDeassign::emit_proc(struct target_t*tgt) const
|
||||
@@ -263,16 +262,20 @@ void NetBlock::emit_recurse(struct target_t*tgt) const
|
||||
} while (cur != last_);
|
||||
}
|
||||
|
||||
void NetCondit::emit_recurse_if(struct target_t*tgt) const
|
||||
bool NetCondit::emit_recurse_if(struct target_t*tgt) const
|
||||
{
|
||||
if (if_)
|
||||
if_->emit_proc(tgt);
|
||||
return if_->emit_proc(tgt);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetCondit::emit_recurse_else(struct target_t*tgt) const
|
||||
bool NetCondit::emit_recurse_else(struct target_t*tgt) const
|
||||
{
|
||||
if (else_)
|
||||
else_->emit_proc(tgt);
|
||||
return else_->emit_proc(tgt);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetEvProbe::emit_node(struct target_t*tgt) const
|
||||
@@ -431,6 +434,11 @@ void NetEScope::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_scope(this);
|
||||
}
|
||||
|
||||
void NetESelect::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_select(this);
|
||||
}
|
||||
|
||||
void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_sfunc(this);
|
||||
@@ -474,6 +482,14 @@ bool emit(const Design*des, const char*type)
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.65 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.64 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.63 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval.cc,v 1.24 2001/12/03 04:47:15 steve Exp $"
|
||||
#ident "$Id: eval.cc,v 1.26 2001/12/29 22:10:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -46,46 +46,56 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
|
||||
switch (op_) {
|
||||
case '+': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv+rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv+rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '-': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv-rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv-rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '*': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv * rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv * rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '/': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv / rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv / rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv % rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv % rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
case 'l': { // left shift (<<)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
res = new verinum(verinum::V0, l->len());
|
||||
@@ -96,6 +106,17 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r': { // right shift (>>)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
res = new verinum(verinum::V0, l->len());
|
||||
if (rv < res->len()) {
|
||||
unsigned cnt = res->len() - rv;
|
||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||
res->set(idx, l->get(idx+rv));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
delete l;
|
||||
@@ -196,6 +217,12 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.26 2001/12/29 22:10:10 steve
|
||||
* constant eval of arithmetic with x and z.
|
||||
*
|
||||
* Revision 1.25 2001/12/29 00:43:55 steve
|
||||
* Evaluate constant right shifts.
|
||||
*
|
||||
* Revision 1.24 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+72
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval_tree.cc,v 1.30 2001/12/03 04:47:15 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.33 2002/02/01 05:09:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -758,6 +758,50 @@ NetEConst* NetEConcat::eval_tree()
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are limits to our ability to evaluate a memory reference
|
||||
* expression, because the content of a memory is never
|
||||
* constant. However, the index expression may be precalculated, and
|
||||
* there are certain index values that do give us constant results.
|
||||
*/
|
||||
NetExpr* NetEMemory::eval_tree()
|
||||
{
|
||||
/* Attempt to evaluate the index expression to a constant, if
|
||||
it is not already. */
|
||||
if (idx_ && !dynamic_cast<NetEConst*>(idx_)) {
|
||||
NetExpr* tmp = idx_->eval_tree();
|
||||
if (tmp) {
|
||||
delete idx_;
|
||||
idx_ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst*itmp = dynamic_cast<NetEConst*>(idx_);
|
||||
if (itmp == 0)
|
||||
return 0;
|
||||
|
||||
verinum ival = itmp->value();
|
||||
|
||||
/* If the index expression has any x or z bits, then we know
|
||||
already that the expression result is a constant x. */
|
||||
if (! ival.is_defined()) {
|
||||
verinum xres (verinum::Vx, mem_->width(), false);
|
||||
NetEConst*res = new NetEConst(xres);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* If the index expression is outside the range of the memory,
|
||||
then the result is a constant x. */
|
||||
unsigned norm_idx = mem_->index_to_address(ival.as_long());
|
||||
if (norm_idx >= mem_->count()) {
|
||||
verinum xres (verinum::Vx, mem_->width(), false);
|
||||
NetEConst*res = new NetEConst(xres);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr* NetEParam::eval_tree()
|
||||
{
|
||||
if (des_ == 0)
|
||||
@@ -911,6 +955,24 @@ NetEConst* NetEUnary::eval_tree()
|
||||
|
||||
switch (op_) {
|
||||
|
||||
case '+':
|
||||
/* Unary + is a no-op. */
|
||||
return new NetEConst(val);
|
||||
|
||||
case '-': {
|
||||
if (val.is_defined()) {
|
||||
|
||||
verinum tmp (verinum::V0, val.len());
|
||||
tmp.has_sign(val.has_sign());
|
||||
val = tmp - val;
|
||||
|
||||
} else {
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
val.set(idx, verinum::Vx);
|
||||
}
|
||||
|
||||
return new NetEConst(val);
|
||||
}
|
||||
|
||||
case '~': {
|
||||
/* Bitwise not is even simpler then logical
|
||||
@@ -1002,6 +1064,15 @@ NetEConst* NetEUReduce::eval_tree()
|
||||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.33 2002/02/01 05:09:14 steve
|
||||
* Propagate sign in unary minus.
|
||||
*
|
||||
* Revision 1.32 2002/01/22 01:40:04 steve
|
||||
* Precalculate constant results of memory index expressions.
|
||||
*
|
||||
* Revision 1.31 2001/12/30 00:39:25 steve
|
||||
* Evaluate constant unary minus.
|
||||
*
|
||||
* Revision 1.30 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+33
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: expr_synth.cc,v 1.29 2001/11/29 01:58:18 steve Exp $"
|
||||
#ident "$Id: expr_synth.cc,v 1.31 2001/12/30 17:06:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -467,6 +467,26 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
NetLogic::AND);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::OR);
|
||||
break;
|
||||
|
||||
case '^':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::XOR);
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::NAND);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::XNOR);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Unable to synthesize " << *this << "." << endl;
|
||||
@@ -481,7 +501,12 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Synthesize a ?: operator an a NetMux device. Connect the condition
|
||||
* expression to the select input, then connect the true and false
|
||||
* expressions to the B and A inputs. This way, when the select input
|
||||
* is one, the B input, which is the true expression, is selected.
|
||||
*/
|
||||
NetNet* NetETernary::synthesize(Design *des)
|
||||
{
|
||||
NetNet*csig = cond_->synthesize(des);
|
||||
@@ -562,6 +587,12 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: expr_synth.cc,v $
|
||||
* Revision 1.31 2001/12/30 17:06:52 steve
|
||||
* Synthesize reduction logic.
|
||||
*
|
||||
* Revision 1.30 2001/12/18 05:34:02 steve
|
||||
* Comments about MUX synthesis.
|
||||
*
|
||||
* Revision 1.29 2001/11/29 01:58:18 steve
|
||||
* Handle part selects in l-values of DFF devices.
|
||||
*
|
||||
|
||||
+25
-1
@@ -318,8 +318,32 @@ the right length, and will therefore flag instances u5 and u6 as
|
||||
errors. The IEEE1364 standard should be more specific one way or the
|
||||
other.
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.8 2001/08/01 05:17:31 steve Exp $
|
||||
* UNKNOWN VALUES IN L-VALUE BIT SELECTS
|
||||
|
||||
Consider this example:
|
||||
|
||||
reg [7:0] vec;
|
||||
wire [4:0] idx = <expr>;
|
||||
[...]
|
||||
vec[idx] = 1;
|
||||
|
||||
So long as the value of idx is a valid bit select address, the
|
||||
behavior of this assignment is obvious. However, there is no explicit
|
||||
word in the standard as to what happens if the value is out of
|
||||
range. The standard clearly states the value of an expression when the
|
||||
bit-select or part select is out of range (the value is x) but does
|
||||
not address the behavior when the expression is an l-value.
|
||||
|
||||
Icarus Verilog will take the position that bit select expressions in
|
||||
the l-value will select oblivion if it is out of range. That is, if
|
||||
idx has a value that is not a valid bit select of vec, then the
|
||||
assignment will have no effect.
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.9 2002/01/26 02:08:07 steve Exp $
|
||||
$Log: ieee1364-notes.txt,v $
|
||||
Revision 1.9 2002/01/26 02:08:07 steve
|
||||
Handle x in l-value of set/x
|
||||
|
||||
Revision 1.8 2001/08/01 05:17:31 steve
|
||||
Accept empty port lists to module instantiation.
|
||||
|
||||
|
||||
+15
-2
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_target.h,v 1.89 2001/12/06 03:11:00 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.92 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -164,6 +164,7 @@ typedef enum ivl_expr_type_e {
|
||||
IVL_EX_MEMORY,
|
||||
IVL_EX_NUMBER,
|
||||
IVL_EX_SCOPE,
|
||||
IVL_EX_SELECT,
|
||||
IVL_EX_SFUNC,
|
||||
IVL_EX_SIGNAL,
|
||||
IVL_EX_STRING,
|
||||
@@ -210,6 +211,7 @@ typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_CMP_NE = 11,
|
||||
IVL_LPM_DIVIDE = 12,
|
||||
IVL_LPM_FF = 3,
|
||||
IVL_LPM_MOD = 13,
|
||||
IVL_LPM_MULT = 4,
|
||||
IVL_LPM_MUX = 5,
|
||||
IVL_LPM_SHIFTL = 6,
|
||||
@@ -258,7 +260,6 @@ typedef enum ivl_signal_type_e {
|
||||
IVL_SIT_TRIAND,
|
||||
IVL_SIT_TRIOR,
|
||||
IVL_SIT_WAND,
|
||||
IVL_SIT_WIRE,
|
||||
IVL_SIT_WOR
|
||||
} ivl_signal_type_t;
|
||||
|
||||
@@ -977,6 +978,18 @@ _END_DECL
|
||||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.92 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.91 2002/01/03 04:19:01 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.90 2001/12/15 02:13:17 steve
|
||||
* The IVL_SIT_WIRE type does not exist, it is a
|
||||
* synonym for IVL_SIT_TRI.
|
||||
*
|
||||
* Revision 1.89 2001/12/06 03:11:00 steve
|
||||
* Add ivl_logic_delay function to ivl_target.
|
||||
*
|
||||
|
||||
+3
-2
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.28 2001/11/29 02:26:25 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.29 2002/01/06 04:51:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -525,7 +525,8 @@ static void do_include()
|
||||
}
|
||||
|
||||
if (standby->file == 0) {
|
||||
perror(standby->path);
|
||||
fprintf(stderr, "%s:%u: Include file %s not found\n",
|
||||
istack->path, istack->lineno, standby->path);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -19,9 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.2 2000/08/20 17:49:05 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.3 2002/01/24 03:57:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
static void yyerror(const char*msg);
|
||||
%}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.67 2001/12/03 04:47:15 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.68 2001/12/29 19:00:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -193,7 +193,7 @@ W [ \t\b\f\r]+
|
||||
}
|
||||
|
||||
|
||||
\\[^ \t\b\f\r]+ {
|
||||
\\[^ \t\b\f\r\n]+ {
|
||||
yylval.text = strdup(yytext+1);
|
||||
return IDENTIFIER; }
|
||||
|
||||
|
||||
+10
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_event.cc,v 1.16 2001/10/28 01:14:53 steve Exp $"
|
||||
#ident "$Id: net_event.cc,v 1.17 2002/02/02 06:13:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -171,7 +171,12 @@ NetEvent* NetEvent::find_similar_event()
|
||||
if (tmp->edge() != cur->edge())
|
||||
continue;
|
||||
|
||||
table[ncand++].ev = tmp->event();
|
||||
/* Don't include myself in the list of candidates. */
|
||||
NetEvent*etmp = tmp->event();
|
||||
if (etmp == this)
|
||||
continue;
|
||||
|
||||
table[ncand++].ev = etmp;
|
||||
assert(ncand <= max_cand);
|
||||
}
|
||||
|
||||
@@ -451,6 +456,9 @@ NetProc* NetEvWait::statement()
|
||||
|
||||
/*
|
||||
* $Log: net_event.cc,v $
|
||||
* Revision 1.17 2002/02/02 06:13:38 steve
|
||||
* event find_similar should not find self.
|
||||
*
|
||||
* Revision 1.16 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: net_expr.cc,v 1.2 2002/01/29 22:36:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "netlist.h"
|
||||
|
||||
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
|
||||
: expr_(exp), base_(base)
|
||||
{
|
||||
expr_width(wid);
|
||||
}
|
||||
|
||||
NetESelect::~NetESelect()
|
||||
{
|
||||
delete expr_;
|
||||
delete base_;
|
||||
}
|
||||
|
||||
const NetExpr*NetESelect::sub_expr() const
|
||||
{
|
||||
return expr_;
|
||||
}
|
||||
|
||||
const NetExpr*NetESelect::select() const
|
||||
{
|
||||
return base_;
|
||||
}
|
||||
|
||||
bool NetESelect::has_width() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetESelect::set_width(unsigned w)
|
||||
{
|
||||
if (expr_width() == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_expr.cc,v $
|
||||
* Revision 1.2 2002/01/29 22:36:31 steve
|
||||
* include config.h to eliminate warnings.
|
||||
*
|
||||
* Revision 1.1 2002/01/28 01:39:45 steve
|
||||
* Add ne_expr.cc
|
||||
*
|
||||
*/
|
||||
|
||||
+7
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_force.cc,v 1.6 2001/11/14 03:28:49 steve Exp $"
|
||||
#ident "$Id: net_force.cc,v 1.7 2002/01/19 19:02:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -89,6 +89,8 @@ const NetNet*NetDeassign::lval() const
|
||||
NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
|
||||
: NetNode(s, n, l->pin_count()), lval_(l)
|
||||
{
|
||||
lval_->incr_eref();
|
||||
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("I", idx);
|
||||
@@ -97,6 +99,7 @@ NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
|
||||
|
||||
NetForce::~NetForce()
|
||||
{
|
||||
lval_->decr_eref();
|
||||
}
|
||||
|
||||
const Link& NetForce::lval_pin(unsigned idx) const
|
||||
@@ -127,6 +130,9 @@ const NetNet*NetRelease::lval() const
|
||||
|
||||
/*
|
||||
* $Log: net_force.cc,v $
|
||||
* Revision 1.7 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.6 2001/11/14 03:28:49 steve
|
||||
* DLL target support for force and release.
|
||||
*
|
||||
|
||||
+38
-13
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.cc,v 1.178 2001/12/03 04:47:15 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.181 2002/02/01 05:09:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -1789,7 +1789,7 @@ const NetScope* NetUTask::task() const
|
||||
}
|
||||
|
||||
NetExpr::NetExpr(unsigned w)
|
||||
: width_(w)
|
||||
: width_(w), signed_flag_(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1799,7 +1799,12 @@ NetExpr::~NetExpr()
|
||||
|
||||
bool NetExpr::has_sign() const
|
||||
{
|
||||
return false;
|
||||
return signed_flag_;
|
||||
}
|
||||
|
||||
void NetExpr::cast_signed(bool flag)
|
||||
{
|
||||
signed_flag_ = flag;
|
||||
}
|
||||
|
||||
bool NetExpr::has_width() const
|
||||
@@ -2046,6 +2051,7 @@ NetEConcat* NetEConcat::dup_expr() const
|
||||
NetEConst::NetEConst(const verinum&val)
|
||||
: NetExpr(val.len()), value_(val)
|
||||
{
|
||||
cast_signed(value_.has_sign());
|
||||
}
|
||||
|
||||
NetEConst::~NetEConst()
|
||||
@@ -2057,11 +2063,6 @@ const verinum& NetEConst::value() const
|
||||
return value_;
|
||||
}
|
||||
|
||||
bool NetEConst::has_sign() const
|
||||
{
|
||||
return value_.has_sign();
|
||||
}
|
||||
|
||||
bool NetEConst::has_width() const
|
||||
{
|
||||
return value_.has_len();
|
||||
@@ -2083,6 +2084,16 @@ NetEMemory::~NetEMemory()
|
||||
{
|
||||
}
|
||||
|
||||
const string& NetEMemory::name() const
|
||||
{
|
||||
return mem_->name();
|
||||
}
|
||||
|
||||
const NetExpr* NetEMemory::index() const
|
||||
{
|
||||
return idx_;
|
||||
}
|
||||
|
||||
NetMemory::NetMemory(NetScope*sc, const string&n, long w, long s, long e)
|
||||
: name_(n), width_(w), idxh_(s), idxl_(e), ram_list_(0), scope_(sc)
|
||||
{
|
||||
@@ -2214,6 +2225,7 @@ NetESignal::NetESignal(NetNet*n)
|
||||
lsi_ = 0;
|
||||
net_->incr_eref();
|
||||
set_line(*n);
|
||||
cast_signed(net_->get_signed());
|
||||
}
|
||||
|
||||
NetESignal::NetESignal(NetNet*n, unsigned m, unsigned l)
|
||||
@@ -2224,6 +2236,7 @@ NetESignal::NetESignal(NetNet*n, unsigned m, unsigned l)
|
||||
lsi_ = l;
|
||||
net_->incr_eref();
|
||||
set_line(*n);
|
||||
cast_signed(net_->get_signed());
|
||||
}
|
||||
|
||||
NetESignal::~NetESignal()
|
||||
@@ -2236,11 +2249,6 @@ string NetESignal::name() const
|
||||
return net_->name();
|
||||
}
|
||||
|
||||
bool NetESignal::has_sign() const
|
||||
{
|
||||
return net_->get_signed();
|
||||
}
|
||||
|
||||
unsigned NetESignal::bit_count() const
|
||||
{
|
||||
return msi_ - lsi_ + 1;
|
||||
@@ -2331,6 +2339,14 @@ NetEUnary::NetEUnary(char op, NetExpr*ex)
|
||||
expr_width(1);
|
||||
break;
|
||||
}
|
||||
switch (op_) {
|
||||
case '-':
|
||||
case '+':
|
||||
cast_signed(ex->has_sign());
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
NetEUnary::~NetEUnary()
|
||||
@@ -2407,6 +2423,15 @@ const NetProc*NetTaskDef::proc() const
|
||||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.181 2002/02/01 05:09:14 steve
|
||||
* Propagate sign in unary minus.
|
||||
*
|
||||
* Revision 1.180 2002/01/22 01:40:04 steve
|
||||
* Precalculate constant results of memory index expressions.
|
||||
*
|
||||
* Revision 1.179 2001/12/31 00:08:14 steve
|
||||
* Support $signed cast of expressions.
|
||||
*
|
||||
* Revision 1.178 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __netlist_H
|
||||
#define __netlist_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2002 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
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.h,v 1.227 2001/12/03 04:47:15 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.231 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -847,7 +847,8 @@ class NetExpr : public LineInfo {
|
||||
|
||||
// This method returns true if the expression is
|
||||
// signed. Unsigned expressions return false.
|
||||
virtual bool has_sign() const;
|
||||
bool has_sign() const;
|
||||
void cast_signed(bool flag);
|
||||
|
||||
// This returns true if the expression has a definite
|
||||
// width. This is generally true, but in some cases the
|
||||
@@ -880,6 +881,7 @@ class NetExpr : public LineInfo {
|
||||
|
||||
private:
|
||||
unsigned width_;
|
||||
bool signed_flag_;
|
||||
|
||||
private: // not implemented
|
||||
NetExpr(const NetExpr&);
|
||||
@@ -901,7 +903,6 @@ class NetEConst : public NetExpr {
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
|
||||
virtual bool has_sign() const;
|
||||
virtual bool has_width() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
@@ -1454,8 +1455,8 @@ class NetCondit : public NetProc {
|
||||
// Replace the condition expression.
|
||||
void set_expr(NetExpr*ex);
|
||||
|
||||
void emit_recurse_if(struct target_t*) const;
|
||||
void emit_recurse_else(struct target_t*) const;
|
||||
bool emit_recurse_if(struct target_t*) const;
|
||||
bool emit_recurse_else(struct target_t*) const;
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
@@ -2307,6 +2308,32 @@ class NetEParam : public NetExpr {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This expression node supports bit/part selects from general
|
||||
* expressions. The sub-expression is self-sized, and has bits
|
||||
* selected from it. The base is the expression that identifies the
|
||||
* lsb of the expression, and the wid is the width of the part select,
|
||||
* or 1 for a bit select.
|
||||
*/
|
||||
class NetESelect : public NetExpr {
|
||||
|
||||
public:
|
||||
NetESelect(NetExpr*exp, NetExpr*base, unsigned wid);
|
||||
~NetESelect();
|
||||
|
||||
const NetExpr*sub_expr() const;
|
||||
const NetExpr*select() const;
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
virtual bool has_width() const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetESelect* dup_expr() const;
|
||||
|
||||
private:
|
||||
NetExpr*expr_;
|
||||
NetExpr*base_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class is a special (and magical) expression node type that
|
||||
* represents scope names. These can only be found as parameters to
|
||||
@@ -2466,11 +2493,12 @@ class NetEMemory : public NetExpr {
|
||||
NetEMemory(NetMemory*mem, NetExpr*idx =0);
|
||||
virtual ~NetEMemory();
|
||||
|
||||
const string& name () const { return mem_->name(); }
|
||||
const NetExpr* index() const { return idx_; }
|
||||
const string& name () const;
|
||||
const NetExpr* index() const;
|
||||
|
||||
virtual bool set_width(unsigned);
|
||||
|
||||
NetExpr* eval_tree();
|
||||
virtual NetEMemory*dup_expr() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
@@ -2501,10 +2529,6 @@ class NetESignal : public NetExpr {
|
||||
NetESignal(NetNet*n, unsigned msi, unsigned lsi);
|
||||
~NetESignal();
|
||||
|
||||
// a NetESignal expression is signed if the NetNet that it
|
||||
// refers to is signed.
|
||||
bool has_sign() const;
|
||||
|
||||
string name() const;
|
||||
virtual bool set_width(unsigned);
|
||||
|
||||
@@ -2867,6 +2891,20 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.231 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.230 2002/01/22 01:40:04 steve
|
||||
* Precalculate constant results of memory index expressions.
|
||||
*
|
||||
* Revision 1.229 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.228 2001/12/31 00:08:14 steve
|
||||
* Support $signed cast of expressions.
|
||||
*
|
||||
* Revision 1.227 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+5
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: nodangle.cc,v 1.13 2001/07/27 02:41:55 steve Exp $"
|
||||
#ident "$Id: nodangle.cc,v 1.14 2002/02/02 06:13:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -42,6 +42,7 @@ class nodangle_f : public functor_t {
|
||||
void nodangle_f::event(Design*des, NetEvent*ev)
|
||||
{
|
||||
if (NetEvent*match = ev->find_similar_event()) {
|
||||
assert(match != ev);
|
||||
ev->replace_event(match);
|
||||
}
|
||||
|
||||
@@ -130,6 +131,9 @@ void nodangle(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: nodangle.cc,v $
|
||||
* Revision 1.14 2002/02/02 06:13:38 steve
|
||||
* event find_similar should not find self.
|
||||
*
|
||||
* Revision 1.13 2001/07/27 02:41:55 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.140 2001/12/07 05:03:13 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.145 2002/01/23 03:35:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -31,11 +31,11 @@ extern void lex_start_table();
|
||||
extern void lex_end_table();
|
||||
|
||||
/*
|
||||
* These are the strengths to use for net declaration
|
||||
* assignments. They are stored here so that scope that contains the
|
||||
* net_decl_assigns can change them during specific statements.
|
||||
* These are some common strength pairs that are used as defaults when
|
||||
* the user is not otherwise specific.
|
||||
*/
|
||||
static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
||||
const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
|
||||
const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
||||
%}
|
||||
|
||||
%union {
|
||||
@@ -818,7 +818,6 @@ expr_primary
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
| identifier
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
@@ -901,6 +900,20 @@ function_item
|
||||
@1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_output range_opt list_of_variables ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
yyerror(@1, "Functions may not have output ports.");
|
||||
}
|
||||
| K_inout range_opt list_of_variables ';'
|
||||
{ svector<PWire*>*tmp
|
||||
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
|
||||
@1.text, @1.first_line);
|
||||
$$ = tmp;
|
||||
yyerror(@1, "Functions may not have inout ports.");
|
||||
}
|
||||
| block_item_decl
|
||||
{ $$ = 0; }
|
||||
;
|
||||
@@ -1204,16 +1217,11 @@ module_item
|
||||
}
|
||||
}
|
||||
| net_type range_delay net_decl_assigns ';'
|
||||
{ pform_makewire(@1, $2.range, $2.delay, $3, $1);
|
||||
{ pform_makewire(@1, $2.range, $2.delay, str_strength,
|
||||
$3, $1);
|
||||
}
|
||||
| net_type drive_strength { decl_strength = $2;} net_decl_assigns ';'
|
||||
{ pform_makewire(@1, 0, 0, $4, $1);
|
||||
/* The strengths are handled in the
|
||||
net_decl_assigns using the decl_strength that I
|
||||
set in the rule. Right here, just restore the
|
||||
defaults for other rules. */
|
||||
decl_strength.str0 = PGate::STRONG;
|
||||
decl_strength.str1 = PGate::STRONG;
|
||||
| net_type drive_strength net_decl_assigns ';'
|
||||
{ pform_makewire(@1, 0, 0, $2, $3, $1);
|
||||
}
|
||||
| K_trireg charge_strength_opt range_delay list_of_variables ';'
|
||||
{ yyerror(@1, "sorry: trireg nets not supported.");
|
||||
@@ -1241,11 +1249,11 @@ module_item
|
||||
three-value delay. These rules handle the different cases. */
|
||||
|
||||
| gatetype gate_instance_list ';'
|
||||
{ pform_makegates($1, decl_strength, 0, $2);
|
||||
{ pform_makegates($1, str_strength, 0, $2);
|
||||
}
|
||||
|
||||
| gatetype delay3 gate_instance_list ';'
|
||||
{ pform_makegates($1, decl_strength, $2, $3);
|
||||
{ pform_makegates($1, str_strength, $2, $3);
|
||||
}
|
||||
|
||||
| gatetype drive_strength gate_instance_list ';'
|
||||
@@ -1260,10 +1268,10 @@ module_item
|
||||
strengths are limited. */
|
||||
|
||||
| K_pullup gate_instance_list ';'
|
||||
{ pform_makegates(PGBuiltin::PULLUP, decl_strength, 0, $2);
|
||||
{ pform_makegates(PGBuiltin::PULLUP, pull_strength, 0, $2);
|
||||
}
|
||||
| K_pulldown gate_instance_list ';'
|
||||
{ pform_makegates(PGBuiltin::PULLDOWN, decl_strength, 0, $2);
|
||||
{ pform_makegates(PGBuiltin::PULLDOWN, pull_strength, 0, $2);
|
||||
}
|
||||
|
||||
| K_pullup '(' dr_strength1 ')' gate_instance_list ';'
|
||||
@@ -2246,6 +2254,11 @@ statement
|
||||
$$ = tmp;
|
||||
}
|
||||
}
|
||||
| '@' '*' statement_opt
|
||||
{ yyerror(@2, "sorry: Combinational event control "
|
||||
"is not supported yet.");
|
||||
$$ = $3;
|
||||
}
|
||||
| lpvalue '=' expression ';'
|
||||
{ PAssign*tmp = new PAssign($1,$3);
|
||||
tmp->set_file(@1.text);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.cc,v 1.87 2001/12/07 05:03:13 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.90 2002/01/31 04:10:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -401,8 +401,6 @@ static void pform_set_net_range(const char*name,
|
||||
const svector<PExpr*>*range,
|
||||
bool signed_flag)
|
||||
{
|
||||
assert(range);
|
||||
assert(range->count() == 2);
|
||||
|
||||
PWire*cur = pform_cur_module->get_wire(hier_name(name));
|
||||
if (cur == 0) {
|
||||
@@ -410,9 +408,17 @@ static void pform_set_net_range(const char*name,
|
||||
return;
|
||||
}
|
||||
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1]);
|
||||
if (range == 0) {
|
||||
/* This is the special case that we really mean a
|
||||
scalar. Set a fake range. */
|
||||
cur->set_range(0, 0);
|
||||
|
||||
} else {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1]);
|
||||
}
|
||||
cur->set_signed(signed_flag);
|
||||
}
|
||||
|
||||
@@ -756,8 +762,7 @@ void pform_makewire(const vlltype&li,
|
||||
; cur ++ ) {
|
||||
char*txt = *cur;
|
||||
pform_makewire(li, txt, type);
|
||||
if (range)
|
||||
pform_set_net_range(txt, range, false);
|
||||
pform_set_net_range(txt, range, false);
|
||||
free(txt);
|
||||
}
|
||||
|
||||
@@ -769,16 +774,13 @@ void pform_makewire(const vlltype&li,
|
||||
void pform_makewire(const vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
svector<PExpr*>*delay,
|
||||
str_pair_t str,
|
||||
net_decl_assign_t*decls,
|
||||
NetNet::Type type)
|
||||
{
|
||||
net_decl_assign_t*first = decls->next;
|
||||
decls->next = 0;
|
||||
|
||||
struct str_pair_t str;
|
||||
str.str0 = PGate::STRONG;
|
||||
str.str1 = PGate::STRONG;
|
||||
|
||||
while (first) {
|
||||
net_decl_assign_t*next = first->next;
|
||||
|
||||
@@ -805,14 +807,33 @@ void pform_set_port_type(const char*nm, NetNet::PortType pt,
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
cur = new PWire(name, NetNet::IMPLICIT, pt);
|
||||
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT);
|
||||
cur->set_file(file);
|
||||
cur->set_lineno(lineno);
|
||||
pform_cur_module->add_wire(cur);
|
||||
}
|
||||
|
||||
if (! cur->set_port_type(pt))
|
||||
VLerror("error setting port direction.");
|
||||
switch (cur->get_port_type()) {
|
||||
case NetNet::PIMPLICIT:
|
||||
if (! cur->set_port_type(pt))
|
||||
VLerror("error setting port direction.");
|
||||
break;
|
||||
|
||||
case NetNet::NOT_A_PORT:
|
||||
cerr << file << ":" << lineno << ": error: "
|
||||
<< "port " << name << " is not in the port list."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << file << ":" << lineno << ": error: "
|
||||
<< "port " << name << " already has a port declaration."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1158,6 +1179,15 @@ int pform_parse(const char*path, FILE*file)
|
||||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.90 2002/01/31 04:10:15 steve
|
||||
* Detect duplicate port declarations.
|
||||
*
|
||||
* Revision 1.89 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.88 2002/01/12 04:03:39 steve
|
||||
* Drive strengths for continuous assignments.
|
||||
*
|
||||
* Revision 1.87 2001/12/07 05:03:13 steve
|
||||
* Support integer for function return value.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.h,v 1.54 2001/12/07 05:03:13 steve Exp $"
|
||||
#ident "$Id: pform.h,v 1.55 2002/01/12 04:03:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -147,6 +147,7 @@ extern void pform_makewire(const struct vlltype&li,
|
||||
extern void pform_makewire(const struct vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
svector<PExpr*>*delay,
|
||||
str_pair_t str,
|
||||
net_decl_assign_t*assign_list,
|
||||
NetNet::Type type);
|
||||
extern void pform_make_reginit(const struct vlltype&li,
|
||||
@@ -218,6 +219,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
||||
|
||||
/*
|
||||
* $Log: pform.h,v $
|
||||
* Revision 1.55 2002/01/12 04:03:39 steve
|
||||
* Drive strengths for continuous assignments.
|
||||
*
|
||||
* Revision 1.54 2001/12/07 05:03:13 steve
|
||||
* Support integer for function return value.
|
||||
*
|
||||
|
||||
+15
-6
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform_dump.cc,v 1.68 2001/12/03 04:47:15 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.69 2002/01/26 05:28:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -227,11 +227,17 @@ void PWire::dump(ostream&out) const
|
||||
|
||||
assert(msb_.count() == lsb_.count());
|
||||
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
|
||||
assert(msb_[idx]);
|
||||
if (lsb_[idx])
|
||||
out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
|
||||
else
|
||||
out << " [" << *msb_[idx] << "]";
|
||||
|
||||
if (msb_[idx] == 0) {
|
||||
assert(lsb_[idx] == 0);
|
||||
out << " <scalar>";
|
||||
|
||||
} else {
|
||||
if (lsb_[idx])
|
||||
out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
|
||||
else
|
||||
out << " [" << *msb_[idx] << "]";
|
||||
}
|
||||
}
|
||||
|
||||
out << " " << hname_;
|
||||
@@ -814,6 +820,9 @@ void PUdp::dump(ostream&out) const
|
||||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.69 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.68 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
PKG="IVLver"
|
||||
NAME="verilog"
|
||||
ARCH="sparc"
|
||||
VERSION="0.5"
|
||||
VERSION="0.6"
|
||||
CATEGORY="application"
|
||||
VENDOR="Icarus.com"
|
||||
EMAIL="[email protected]"
|
||||
|
||||
@@ -15,6 +15,7 @@ f none include/vvm_signal.h 0644 bin bin
|
||||
f none include/vvm_thread.h 0644 bin bin
|
||||
d none lib 0755 bin bin
|
||||
d none lib/ivl 0755 bin bin
|
||||
f none lib/ivl/fpga.tgt 0644 bin bin
|
||||
f none lib/ivl/iverilog.conf 0644 bin bin
|
||||
f none lib/ivl/ivl 0755 bin bin
|
||||
f none lib/ivl/ivlpp 0755 bin bin
|
||||
|
||||
+15
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll-api.cc,v 1.73 2001/12/06 03:11:00 steve Exp $"
|
||||
#ident "$Id: t-dll-api.cc,v 1.75 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -272,6 +272,7 @@ extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
|
||||
assert(net);
|
||||
switch (net->type_) {
|
||||
case IVL_EX_BINARY:
|
||||
case IVL_EX_SELECT:
|
||||
return net->u_.binary_.lef_;
|
||||
|
||||
case IVL_EX_BITSEL:
|
||||
@@ -298,6 +299,7 @@ extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
|
||||
assert(net);
|
||||
switch (net->type_) {
|
||||
case IVL_EX_BINARY:
|
||||
case IVL_EX_SELECT:
|
||||
return net->u_.binary_.rig_;
|
||||
|
||||
case IVL_EX_TERNARY:
|
||||
@@ -564,6 +566,7 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
||||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_SUB:
|
||||
assert(idx < net->u_.arith.width);
|
||||
@@ -599,6 +602,7 @@ extern "C" ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx)
|
||||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_SUB:
|
||||
assert(idx < net->u_.arith.width);
|
||||
@@ -637,6 +641,7 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
|
||||
switch (net->type) {
|
||||
case IVL_LPM_ADD:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_SUB:
|
||||
assert(idx < net->u_.arith.width);
|
||||
@@ -756,6 +761,7 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
|
||||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_SUB:
|
||||
return net->u_.arith.width;
|
||||
@@ -1446,6 +1452,14 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
|
||||
|
||||
/*
|
||||
* $Log: t-dll-api.cc,v $
|
||||
* Revision 1.75 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.74 2002/01/03 04:19:01 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.73 2001/12/06 03:11:00 steve
|
||||
* Add ivl_logic_delay function to ivl_target.
|
||||
*
|
||||
|
||||
+32
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) & !defined(macintosh)
|
||||
#ident "$Id: t-dll-expr.cc,v 1.20 2001/10/23 04:22:41 steve Exp $"
|
||||
#ident "$Id: t-dll-expr.cc,v 1.22 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -127,7 +127,7 @@ void dll_target::expr_const(const NetEConst*net)
|
||||
char*bits;
|
||||
expr_->type_ = IVL_EX_NUMBER;
|
||||
expr_->width_= net->expr_width();
|
||||
expr_->signed_ = val.has_sign()? 1 : 0;
|
||||
expr_->signed_ = net->has_sign()? 1 : 0;
|
||||
expr_->u_.number_.bits_ = bits = (char*)malloc(expr_->width_);
|
||||
for (idx = 0 ; idx < expr_->width_ ; idx += 1)
|
||||
switch (val.get(idx)) {
|
||||
@@ -161,6 +161,28 @@ void dll_target::expr_scope(const NetEScope*net)
|
||||
expr_->u_.scope_.scope = lookup_scope_(net->scope());
|
||||
}
|
||||
|
||||
void dll_target::expr_select(const NetESelect*net)
|
||||
{
|
||||
assert(expr_ == 0);
|
||||
|
||||
net->sub_expr()->expr_scan(this);
|
||||
ivl_expr_t left = expr_;
|
||||
|
||||
expr_ = 0;
|
||||
net->select()->expr_scan(this);
|
||||
ivl_expr_t rght = expr_;
|
||||
|
||||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
assert(expr_);
|
||||
|
||||
expr_->type_ = IVL_EX_SELECT;
|
||||
expr_->width_= net->expr_width();
|
||||
expr_->signed_ = net->has_sign()? 1 : 0;
|
||||
|
||||
expr_->u_.binary_.lef_ = left;
|
||||
expr_->u_.binary_.rig_ = rght;
|
||||
}
|
||||
|
||||
void dll_target::expr_sfunc(const NetESFunc*net)
|
||||
{
|
||||
assert(expr_ == 0);
|
||||
@@ -347,6 +369,14 @@ void dll_target::expr_unary(const NetEUnary*net)
|
||||
|
||||
/*
|
||||
* $Log: t-dll-expr.cc,v $
|
||||
* Revision 1.22 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.21 2001/12/31 00:08:14 steve
|
||||
* Support $signed cast of expressions.
|
||||
*
|
||||
* Revision 1.20 2001/10/23 04:22:41 steve
|
||||
* Support bit selects of non-0 lsb for vectors.
|
||||
*
|
||||
|
||||
+16
-4
@@ -18,7 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll-proc.cc,v 1.40 2001/11/14 03:28:49 steve Exp $"
|
||||
#ident "$Id: t-dll-proc.cc,v 1.41 2002/01/19 19:02:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -421,7 +421,7 @@ bool dll_target::proc_cassign(const NetCAssign*net)
|
||||
return true;
|
||||
}
|
||||
|
||||
void dll_target::proc_condit(const NetCondit*net)
|
||||
bool dll_target::proc_condit(const NetCondit*net)
|
||||
{
|
||||
assert(stmt_cur_);
|
||||
assert(stmt_cur_->type_ == IVL_ST_NONE);
|
||||
@@ -438,12 +438,13 @@ void dll_target::proc_condit(const NetCondit*net)
|
||||
ivl_statement_t save_cur_ = stmt_cur_;
|
||||
|
||||
stmt_cur_ = save_cur_->u_.condit_.stmt_+0;
|
||||
net->emit_recurse_if(this);
|
||||
bool flag = net->emit_recurse_if(this);
|
||||
|
||||
stmt_cur_ = save_cur_->u_.condit_.stmt_+1;
|
||||
net->emit_recurse_else(this);
|
||||
flag = flag && net->emit_recurse_else(this);
|
||||
|
||||
stmt_cur_ = save_cur_;
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool dll_target::proc_deassign(const NetDeassign*net)
|
||||
@@ -531,8 +532,16 @@ bool dll_target::proc_force(const NetForce*net)
|
||||
calloc(1, sizeof(struct ivl_lval_s));
|
||||
|
||||
const NetNet*lsig = net->lval();
|
||||
assert(lsig);
|
||||
ivl_signal_t sig = find_signal(des_, lsig);
|
||||
assert(sig);
|
||||
if (sig->type_ != IVL_SIT_REG) {
|
||||
cerr << net->get_line() << ": internal error: Sorry, "
|
||||
<< "force to nets not supported by this target."
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(sig->type_ == IVL_SIT_REG);
|
||||
|
||||
stmt_cur_->u_.cassign_.lval[0].width_ = lsig->pin_count();
|
||||
@@ -784,6 +793,9 @@ void dll_target::proc_while(const NetWhile*net)
|
||||
|
||||
/*
|
||||
* $Log: t-dll-proc.cc,v $
|
||||
* Revision 1.41 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.40 2001/11/14 03:28:49 steve
|
||||
* DLL target support for force and release.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll.cc,v 1.71 2001/12/06 03:11:00 steve Exp $"
|
||||
#ident "$Id: t-dll.cc,v 1.79 2002/01/23 04:54:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -68,7 +68,7 @@ const char *dlerror(void)
|
||||
}
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_NOW); }
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{ return dlsym(dll, nm); }
|
||||
@@ -96,6 +96,45 @@ inline const char*dlerror(void)
|
||||
|
||||
static struct dll_target dll_target_obj;
|
||||
|
||||
static void drive_from_link(const Link&lnk, ivl_drive_t&drv0, ivl_drive_t&drv1)
|
||||
{
|
||||
switch (lnk.drive0()) {
|
||||
case Link::HIGHZ:
|
||||
drv0 = IVL_DR_HiZ;
|
||||
break;
|
||||
case Link::WEAK:
|
||||
drv0 = IVL_DR_WEAK;
|
||||
break;
|
||||
case Link::PULL:
|
||||
drv0 = IVL_DR_PULL;
|
||||
break;
|
||||
case Link::STRONG:
|
||||
drv0 = IVL_DR_STRONG;
|
||||
break;
|
||||
case Link::SUPPLY:
|
||||
drv0 = IVL_DR_SUPPLY;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (lnk.drive1()) {
|
||||
case Link::HIGHZ:
|
||||
drv1 = IVL_DR_HiZ;
|
||||
break;
|
||||
case Link::WEAK:
|
||||
drv1 = IVL_DR_WEAK;
|
||||
break;
|
||||
case Link::PULL:
|
||||
drv1 = IVL_DR_PULL;
|
||||
break;
|
||||
case Link::STRONG:
|
||||
drv1 = IVL_DR_STRONG;
|
||||
break;
|
||||
case Link::SUPPLY:
|
||||
drv1 = IVL_DR_SUPPLY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function locates an ivl_scope_t object that matches the
|
||||
* NetScope object. The search works by looking for the parent scope,
|
||||
@@ -124,10 +163,13 @@ static ivl_scope_t find_scope_from_root(ivl_scope_t root, const NetScope*cur)
|
||||
|
||||
ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
|
||||
{
|
||||
unsigned i;
|
||||
ivl_scope_t scope = NULL;
|
||||
for (i = 0; i < des.nroots_ && scope == NULL; i++)
|
||||
assert(cur);
|
||||
|
||||
ivl_scope_t scope = 0;
|
||||
for (unsigned i = 0; i < des.nroots_ && scope == 0; i += 1) {
|
||||
assert(des.roots_[i]);
|
||||
scope = find_scope_from_root(des.roots_[i], cur);
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
@@ -247,7 +289,9 @@ static void nexus_sig_add(ivl_nexus_t nex, ivl_signal_t net, unsigned pin)
|
||||
nex->ptrs_[top-1].l.sig= net;
|
||||
}
|
||||
|
||||
static void nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin)
|
||||
static ivl_nexus_ptr_t nexus_log_add(ivl_nexus_t nex,
|
||||
ivl_net_logic_t net,
|
||||
unsigned pin)
|
||||
{
|
||||
unsigned top = nex->nptr_ + 1;
|
||||
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
|
||||
@@ -259,9 +303,12 @@ static void nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin)
|
||||
nex->ptrs_[top-1].drive1 = (pin == 0)? IVL_DR_STRONG : IVL_DR_HiZ;
|
||||
nex->ptrs_[top-1].pin_ = pin;
|
||||
nex->ptrs_[top-1].l.log= net;
|
||||
|
||||
return nex->ptrs_ + top - 1;
|
||||
}
|
||||
|
||||
static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin)
|
||||
static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin,
|
||||
ivl_drive_t drive0, ivl_drive_t drive1)
|
||||
{
|
||||
unsigned top = nex->nptr_ + 1;
|
||||
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
|
||||
@@ -269,8 +316,8 @@ static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin)
|
||||
nex->nptr_ = top;
|
||||
|
||||
nex->ptrs_[top-1].type_= __NEXUS_PTR_CON;
|
||||
nex->ptrs_[top-1].drive0 = IVL_DR_STRONG;
|
||||
nex->ptrs_[top-1].drive1 = IVL_DR_STRONG;
|
||||
nex->ptrs_[top-1].drive0 = drive0;
|
||||
nex->ptrs_[top-1].drive1 = drive1;
|
||||
nex->ptrs_[top-1].pin_ = pin;
|
||||
nex->ptrs_[top-1].l.con= net;
|
||||
}
|
||||
@@ -470,13 +517,49 @@ bool dll_target::bufz(const NetBUFZ*net)
|
||||
|
||||
assert(net->pin(0).nexus()->t_cookie());
|
||||
obj->pins_[0] = (ivl_nexus_t) net->pin(0).nexus()->t_cookie();
|
||||
nexus_log_add(obj->pins_[0], obj, 0);
|
||||
ivl_nexus_ptr_t out_ptr = nexus_log_add(obj->pins_[0], obj, 0);
|
||||
|
||||
assert(net->pin(1).nexus()->t_cookie());
|
||||
obj->pins_[1] = (ivl_nexus_t) net->pin(1).nexus()->t_cookie();
|
||||
nexus_log_add(obj->pins_[1], obj, 1);
|
||||
|
||||
|
||||
switch (net->pin(0).drive0()) {
|
||||
case Link::HIGHZ:
|
||||
out_ptr->drive0 = IVL_DR_HiZ;
|
||||
break;
|
||||
case Link::WEAK:
|
||||
out_ptr->drive0 = IVL_DR_WEAK;
|
||||
break;
|
||||
case Link::PULL:
|
||||
out_ptr->drive0 = IVL_DR_PULL;
|
||||
break;
|
||||
case Link::STRONG:
|
||||
out_ptr->drive0 = IVL_DR_STRONG;
|
||||
break;
|
||||
case Link::SUPPLY:
|
||||
out_ptr->drive0 = IVL_DR_SUPPLY;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (net->pin(0).drive1()) {
|
||||
case Link::HIGHZ:
|
||||
out_ptr->drive1 = IVL_DR_HiZ;
|
||||
break;
|
||||
case Link::WEAK:
|
||||
out_ptr->drive1 = IVL_DR_WEAK;
|
||||
break;
|
||||
case Link::PULL:
|
||||
out_ptr->drive1 = IVL_DR_PULL;
|
||||
break;
|
||||
case Link::STRONG:
|
||||
out_ptr->drive1 = IVL_DR_STRONG;
|
||||
break;
|
||||
case Link::SUPPLY:
|
||||
out_ptr->drive1 = IVL_DR_SUPPLY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Attach the logic device to the scope that contains it. */
|
||||
|
||||
assert(net->scope());
|
||||
@@ -602,11 +685,52 @@ void dll_target::logic(const NetLogic*net)
|
||||
|
||||
obj->npins_ = net->pin_count();
|
||||
obj->pins_ = new ivl_nexus_t[obj->npins_];
|
||||
|
||||
ivl_nexus_ptr_t out_ptr = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < obj->npins_ ; idx += 1) {
|
||||
const Nexus*nex = net->pin(idx).nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->pins_[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_log_add(obj->pins_[idx], obj, idx);
|
||||
ivl_nexus_ptr_t tmp = nexus_log_add(obj->pins_[idx], obj, idx);
|
||||
if (idx == 0)
|
||||
out_ptr = tmp;
|
||||
}
|
||||
|
||||
switch (net->pin(0).drive0()) {
|
||||
case Link::HIGHZ:
|
||||
out_ptr->drive0 = IVL_DR_HiZ;
|
||||
break;
|
||||
case Link::WEAK:
|
||||
out_ptr->drive0 = IVL_DR_WEAK;
|
||||
break;
|
||||
case Link::PULL:
|
||||
out_ptr->drive0 = IVL_DR_PULL;
|
||||
break;
|
||||
case Link::STRONG:
|
||||
out_ptr->drive0 = IVL_DR_STRONG;
|
||||
break;
|
||||
case Link::SUPPLY:
|
||||
out_ptr->drive0 = IVL_DR_SUPPLY;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (net->pin(0).drive1()) {
|
||||
case Link::HIGHZ:
|
||||
out_ptr->drive1 = IVL_DR_HiZ;
|
||||
break;
|
||||
case Link::WEAK:
|
||||
out_ptr->drive1 = IVL_DR_WEAK;
|
||||
break;
|
||||
case Link::PULL:
|
||||
out_ptr->drive1 = IVL_DR_PULL;
|
||||
break;
|
||||
case Link::STRONG:
|
||||
out_ptr->drive1 = IVL_DR_STRONG;
|
||||
break;
|
||||
case Link::SUPPLY:
|
||||
out_ptr->drive1 = IVL_DR_SUPPLY;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(net->scope());
|
||||
@@ -1064,6 +1188,73 @@ void dll_target::lpm_divide(const NetDivide*net)
|
||||
scope_add_lpm(obj->scope, obj);
|
||||
}
|
||||
|
||||
void dll_target::lpm_modulo(const NetModulo*net)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
obj->type = IVL_LPM_MOD;
|
||||
obj->name = strdup(net->name());
|
||||
assert(net->scope());
|
||||
obj->scope = find_scope(des_, net->scope());
|
||||
assert(obj->scope);
|
||||
|
||||
unsigned wid = net->width_r();
|
||||
if (wid < net->width_a())
|
||||
wid = net->width_a();
|
||||
if (wid < net->width_b())
|
||||
wid = net->width_b();
|
||||
|
||||
obj->u_.arith.width = wid;
|
||||
|
||||
obj->u_.arith.q = new ivl_nexus_t[3 * obj->u_.arith.width];
|
||||
obj->u_.arith.a = obj->u_.arith.q + obj->u_.arith.width;
|
||||
obj->u_.arith.b = obj->u_.arith.a + obj->u_.arith.width;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
const Nexus*nex;
|
||||
|
||||
if (idx < net->width_r()) {
|
||||
nex = net->pin_Result(idx).nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.arith.q[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.q[idx], obj, 0,
|
||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||
|
||||
} else {
|
||||
obj->u_.arith.q[idx] = 0;
|
||||
}
|
||||
|
||||
if (idx < net->width_a()) {
|
||||
nex = net->pin_DataA(idx).nexus();
|
||||
assert(nex);
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.arith.a[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.a[idx], obj, 0,
|
||||
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
|
||||
} else {
|
||||
obj->u_.arith.a[idx] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (idx < net->width_b()) {
|
||||
nex = net->pin_DataB(idx).nexus();
|
||||
assert(nex);
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->u_.arith.b[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_lpm_add(obj->u_.arith.b[idx], obj, 0,
|
||||
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||
|
||||
} else {
|
||||
obj->u_.arith.b[idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
scope_add_lpm(obj->scope, obj);
|
||||
}
|
||||
|
||||
void dll_target::lpm_ff(const NetFF*net)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
@@ -1302,6 +1493,10 @@ void dll_target::lpm_mult(const NetMult*net)
|
||||
scope_add_lpm(obj->scope, obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook up the mux devices so that the select expression selects the
|
||||
* correct sub-expression with the ivl_lpm_data2 function.
|
||||
*/
|
||||
void dll_target::lpm_mux(const NetMux*net)
|
||||
{
|
||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||
@@ -1417,20 +1612,27 @@ bool dll_target::net_const(const NetConst*net)
|
||||
case can be handled more efficiently without allocating
|
||||
array space. */
|
||||
if (obj->width_ == 1) {
|
||||
ivl_drive_t drv0, drv1;
|
||||
drive_from_link(net->pin(0), drv0, drv1);
|
||||
const Nexus*nex = net->pin(0).nexus();
|
||||
assert(nex->t_cookie());
|
||||
obj->n.pin_ = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_con_add(obj->n.pin_, obj, 0);
|
||||
nexus_con_add(obj->n.pin_, obj, 0, drv0, drv1);
|
||||
|
||||
} else {
|
||||
obj->n.pins_ = new ivl_nexus_t[obj->width_];
|
||||
for (unsigned idx = 0 ; idx < obj->width_ ; idx += 1) {
|
||||
if (! net->pin(idx).is_linked())
|
||||
continue;
|
||||
|
||||
ivl_drive_t drv0, drv1;
|
||||
drive_from_link(net->pin(idx), drv0, drv1);
|
||||
|
||||
const Nexus*nex = net->pin(idx).nexus();
|
||||
assert(nex->t_cookie());
|
||||
|
||||
obj->n.pins_[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||
nexus_con_add(obj->n.pins_[idx], obj, idx);
|
||||
nexus_con_add(obj->n.pins_[idx], obj, idx, drv0, drv1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1605,7 +1807,7 @@ void dll_target::signal(const NetNet*net)
|
||||
|
||||
case NetNet::WIRE:
|
||||
case NetNet::IMPLICIT:
|
||||
obj->type_ = IVL_SIT_WIRE;
|
||||
obj->type_ = IVL_SIT_TRI;
|
||||
break;
|
||||
|
||||
case NetNet::WOR:
|
||||
@@ -1674,6 +1876,31 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
||||
|
||||
/*
|
||||
* $Log: t-dll.cc,v $
|
||||
* Revision 1.79 2002/01/23 04:54:37 steve
|
||||
* Load modules with RTLD_LAZY
|
||||
*
|
||||
* Revision 1.78 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.77 2002/01/12 04:03:09 steve
|
||||
* Make BUFZ device strengths available.
|
||||
*
|
||||
* Revision 1.76 2002/01/06 03:15:43 steve
|
||||
* Constant values have drive strengths.
|
||||
*
|
||||
* Revision 1.75 2002/01/03 04:19:01 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.74 2001/12/18 05:34:02 steve
|
||||
* Comments about MUX synthesis.
|
||||
*
|
||||
* Revision 1.73 2001/12/15 02:13:17 steve
|
||||
* The IVL_SIT_WIRE type does not exist, it is a
|
||||
* synonym for IVL_SIT_TRI.
|
||||
*
|
||||
* Revision 1.72 2001/12/14 02:05:13 steve
|
||||
* Parse and handle drive strengths of gates to vvp.
|
||||
*
|
||||
* Revision 1.71 2001/12/06 03:11:00 steve
|
||||
* Add ivl_logic_delay function to ivl_target.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll.h,v 1.72 2001/12/06 03:11:01 steve Exp $"
|
||||
#ident "$Id: t-dll.h,v 1.75 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
@@ -75,6 +75,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||
void lpm_compare(const NetCompare*);
|
||||
void lpm_divide(const NetDivide*);
|
||||
void lpm_ff(const NetFF*);
|
||||
void lpm_modulo(const NetModulo*);
|
||||
void lpm_mult(const NetMult*);
|
||||
void lpm_mux(const NetMux*);
|
||||
void lpm_ram_dq(const NetRamDq*);
|
||||
@@ -107,7 +108,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||
bool proc_block(const NetBlock*);
|
||||
void proc_case(const NetCase*);
|
||||
bool proc_cassign(const NetCAssign*);
|
||||
void proc_condit(const NetCondit*);
|
||||
bool proc_condit(const NetCondit*);
|
||||
bool proc_deassign(const NetDeassign*);
|
||||
bool proc_delay(const NetPDelay*);
|
||||
bool proc_disable(const NetDisable*);
|
||||
@@ -130,6 +131,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||
void expr_memory(const NetEMemory*);
|
||||
void expr_const(const NetEConst*);
|
||||
void expr_scope(const NetEScope*);
|
||||
void expr_select(const NetESelect*);
|
||||
void expr_sfunc(const NetESFunc*);
|
||||
void expr_subsignal(const NetEBitSel*);
|
||||
void expr_ternary(const NetETernary*);
|
||||
@@ -589,6 +591,17 @@ struct ivl_statement_s {
|
||||
|
||||
/*
|
||||
* $Log: t-dll.h,v $
|
||||
* Revision 1.75 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.74 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.73 2002/01/03 04:19:01 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.72 2001/12/06 03:11:01 steve
|
||||
* Add ivl_logic_delay function to ivl_target.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-vvm.cc,v 1.213 2001/10/14 03:50:53 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.214 2002/01/19 19:02:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -190,7 +190,7 @@ class target_vvm : public target_t {
|
||||
virtual void proc_case(const NetCase*net);
|
||||
void proc_case_fun(ostream&os, const NetCase*net);
|
||||
virtual bool proc_cassign(const NetCAssign*);
|
||||
virtual void proc_condit(const NetCondit*);
|
||||
virtual bool proc_condit(const NetCondit*);
|
||||
void proc_condit_fun(ostream&os, const NetCondit*);
|
||||
virtual bool proc_deassign(const NetDeassign*);
|
||||
virtual bool proc_delay(const NetPDelay*);
|
||||
@@ -3195,11 +3195,11 @@ bool target_vvm::proc_cassign(const NetCAssign*dev)
|
||||
return true;
|
||||
}
|
||||
|
||||
void target_vvm::proc_condit(const NetCondit*net)
|
||||
bool target_vvm::proc_condit(const NetCondit*net)
|
||||
{
|
||||
if (function_def_flag_) {
|
||||
proc_condit_fun(out, net);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
string expr = emit_proc_rval(this, net->expr());
|
||||
@@ -3250,6 +3250,7 @@ void target_vvm::proc_condit(const NetCondit*net)
|
||||
|
||||
defn << "static bool " << thread_class_ << "_step_" << out_step <<
|
||||
"_(vvm_thread*thr) {" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
|
||||
@@ -3658,6 +3659,9 @@ extern const struct target tgt_vvm = {
|
||||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.214 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.213 2001/10/14 03:50:53 steve
|
||||
* vvm support for pullup/down gates (PR#288)
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: target.cc,v 1.57 2001/08/25 23:50:03 steve Exp $"
|
||||
#ident "$Id: target.cc,v 1.59 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -216,11 +216,12 @@ bool target_t::proc_cassign(const NetCAssign*dev)
|
||||
return false;
|
||||
}
|
||||
|
||||
void target_t::proc_condit(const NetCondit*condit)
|
||||
bool target_t::proc_condit(const NetCondit*condit)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled conditional:" << endl;
|
||||
condit->dump(cerr, 6);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool target_t::proc_deassign(const NetDeassign*dev)
|
||||
@@ -339,6 +340,12 @@ void expr_scan_t::expr_scope(const NetEScope*)
|
||||
"unhandled expr_scope." << endl;
|
||||
}
|
||||
|
||||
void expr_scan_t::expr_select(const NetESelect*)
|
||||
{
|
||||
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
|
||||
"unhandled expr_select." << endl;
|
||||
}
|
||||
|
||||
void expr_scan_t::expr_sfunc(const NetESFunc*)
|
||||
{
|
||||
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
|
||||
@@ -383,6 +390,14 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
||||
|
||||
/*
|
||||
* $Log: target.cc,v $
|
||||
* Revision 1.59 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.58 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.57 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: target.h,v 1.54 2001/08/25 23:50:03 steve Exp $"
|
||||
#ident "$Id: target.h,v 1.56 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -105,7 +105,7 @@ struct target_t {
|
||||
virtual bool proc_block(const NetBlock*);
|
||||
virtual void proc_case(const NetCase*);
|
||||
virtual bool proc_cassign(const NetCAssign*);
|
||||
virtual void proc_condit(const NetCondit*);
|
||||
virtual bool proc_condit(const NetCondit*);
|
||||
virtual bool proc_deassign(const NetDeassign*);
|
||||
virtual bool proc_delay(const NetPDelay*);
|
||||
virtual bool proc_disable(const NetDisable*);
|
||||
@@ -132,6 +132,7 @@ struct expr_scan_t {
|
||||
virtual void expr_concat(const NetEConcat*);
|
||||
virtual void expr_memory(const NetEMemory*);
|
||||
virtual void expr_scope(const NetEScope*);
|
||||
virtual void expr_select(const NetESelect*);
|
||||
virtual void expr_sfunc(const NetESFunc*);
|
||||
virtual void expr_signal(const NetESignal*);
|
||||
virtual void expr_subsignal(const NetEBitSel*);
|
||||
@@ -162,6 +163,14 @@ extern const struct target *target_table[];
|
||||
|
||||
/*
|
||||
* $Log: target.h,v $
|
||||
* Revision 1.56 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.55 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.54 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
|
||||
+7
-3
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: stub.c,v 1.50 2001/09/30 16:45:10 steve Exp $"
|
||||
#ident "$Id: stub.c,v 1.51 2001/12/15 02:13:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -408,8 +408,8 @@ static void show_signal(ivl_signal_t net)
|
||||
case IVL_SIT_REG:
|
||||
type = "reg";
|
||||
break;
|
||||
case IVL_SIT_WIRE:
|
||||
type = "wire";
|
||||
case IVL_SIT_TRI:
|
||||
type = "tri";
|
||||
break;
|
||||
case IVL_SIT_SUPPLY0:
|
||||
type = "supply0";
|
||||
@@ -606,6 +606,10 @@ int target_design(ivl_design_t des)
|
||||
|
||||
/*
|
||||
* $Log: stub.c,v $
|
||||
* Revision 1.51 2001/12/15 02:13:17 steve
|
||||
* The IVL_SIT_WIRE type does not exist, it is a
|
||||
* synonym for IVL_SIT_TRI.
|
||||
*
|
||||
* Revision 1.50 2001/09/30 16:45:10 steve
|
||||
* Fix some Cygwin DLL handling. (Venkat Iyer)
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: verilog.c,v 1.25 2001/09/30 16:45:10 steve Exp $"
|
||||
#ident "$Id: verilog.c,v 1.26 2001/12/15 02:13:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -60,7 +60,7 @@ static void draw_scoped_objects(ivl_design_t des)
|
||||
fprintf(out, " reg %s;\n",
|
||||
ivl_signal_basename(sig));
|
||||
break;
|
||||
case IVL_SIT_WIRE:
|
||||
case IVL_SIT_TRI:
|
||||
fprintf(out, " wire %s;\n", ivl_signal_basename(sig));
|
||||
break;
|
||||
default:
|
||||
@@ -439,6 +439,10 @@ int target_design(ivl_design_t des)
|
||||
|
||||
/*
|
||||
* $Log: verilog.c,v $
|
||||
* Revision 1.26 2001/12/15 02:13:17 steve
|
||||
* The IVL_SIT_WIRE type does not exist, it is a
|
||||
* synonym for IVL_SIT_TRI.
|
||||
*
|
||||
* Revision 1.25 2001/09/30 16:45:10 steve
|
||||
* Fix some Cygwin DLL handling. (Venkat Iyer)
|
||||
*
|
||||
|
||||
+67
-66
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: eval_expr.c,v 1.53 2001/11/19 04:25:46 steve Exp $"
|
||||
#ident "$Id: eval_expr.c,v 1.56 2002/02/03 05:53:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
@@ -977,6 +977,55 @@ static struct vector_info draw_memory_expr(ivl_expr_t exp, unsigned wid)
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct vector_info draw_select_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
struct vector_info subv, shiv, res;
|
||||
ivl_expr_t sube = ivl_expr_oper1(exp);
|
||||
ivl_expr_t shift = ivl_expr_oper2(exp);
|
||||
|
||||
/* Evaluate the sub-expression. */
|
||||
subv = draw_eval_expr(sube);
|
||||
|
||||
/* Any bit select of a constant zero is another constant zero,
|
||||
so short circuit and return the value we know. */
|
||||
if (subv.base == 0) {
|
||||
subv.wid = wid;
|
||||
return subv;
|
||||
}
|
||||
|
||||
/* Evaluate the bit select base expression and store the
|
||||
result into index register 0. */
|
||||
shiv = draw_eval_expr(shift);
|
||||
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", shiv.base, shiv.wid);
|
||||
clr_vector(shiv);
|
||||
|
||||
/* If the subv result is a magic constant, then make a copy in
|
||||
writeable vector space and work from there instead. */
|
||||
if (subv.base < 4) {
|
||||
res.base = allocate_vector(subv.wid);
|
||||
res.wid = wid;
|
||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base,
|
||||
subv.base, res.wid);
|
||||
subv = res;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%shiftr/i0 %u, %u;\n", subv.base, subv.wid);
|
||||
|
||||
assert(subv.wid >= wid);
|
||||
if (subv.wid > wid) {
|
||||
res.base = subv.base;
|
||||
res.wid = wid;
|
||||
|
||||
subv.base += wid;
|
||||
clr_vector(subv);
|
||||
|
||||
} else if (subv.wid == wid) {
|
||||
res = subv;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct vector_info draw_ternary_expr(ivl_expr_t exp, unsigned wid)
|
||||
{
|
||||
struct vector_info res, tmp;
|
||||
@@ -1109,6 +1158,8 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
|
||||
case IVL_EX_SFUNC:
|
||||
if (strcmp("$time", ivl_expr_name(expr)) == 0)
|
||||
fprintf(vvp_out, ", $time");
|
||||
else if (strcmp("$stime", ivl_expr_name(expr)) == 0)
|
||||
fprintf(vvp_out, ", $stime");
|
||||
else
|
||||
fprintf(vvp_out, ", ?");
|
||||
continue;
|
||||
@@ -1413,6 +1464,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid)
|
||||
res = draw_number_expr(exp, wid);
|
||||
break;
|
||||
|
||||
case IVL_EX_SELECT:
|
||||
res = draw_select_expr(exp, wid);
|
||||
break;
|
||||
|
||||
case IVL_EX_SIGNAL:
|
||||
res = draw_signal_expr(exp, wid);
|
||||
break;
|
||||
@@ -1448,6 +1503,17 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
|
||||
|
||||
/*
|
||||
* $Log: eval_expr.c,v $
|
||||
* Revision 1.56 2002/02/03 05:53:00 steve
|
||||
* Fix parameter bit select check for magic constants.
|
||||
*
|
||||
* Revision 1.55 2002/01/28 00:52:42 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.54 2002/01/11 05:23:05 steve
|
||||
* Handle certain special cases of stime.
|
||||
*
|
||||
* Revision 1.53 2001/11/19 04:25:46 steve
|
||||
* Handle padding out of logical values.
|
||||
*
|
||||
@@ -1494,70 +1560,5 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
|
||||
*
|
||||
* Revision 1.39 2001/07/27 02:41:56 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
* Revision 1.38 2001/07/22 19:33:51 steve
|
||||
* Handle repeat for concatenation expressions.
|
||||
*
|
||||
* Revision 1.37 2001/07/22 00:17:50 steve
|
||||
* Support the NetESubSignal expressions in vvp.tgt.
|
||||
*
|
||||
* Revision 1.36 2001/07/09 15:38:35 steve
|
||||
* Properly step through wide inputs. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.35 2001/07/07 20:20:10 steve
|
||||
* Pass parameters to system functions.
|
||||
*
|
||||
* Revision 1.34 2001/06/30 21:07:26 steve
|
||||
* Support non-const right shift (unsigned).
|
||||
*
|
||||
* Revision 1.33 2001/06/23 18:40:34 steve
|
||||
* Generate %shiftl instructions for shift.
|
||||
*
|
||||
* Revision 1.32 2001/06/21 04:53:59 steve
|
||||
* Escaped identifiers in behavioral expressions. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.31 2001/06/18 01:09:32 steve
|
||||
* More behavioral unary reduction operators.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.30 2001/06/16 23:45:05 steve
|
||||
* Add support for structural multiply in t-dll.
|
||||
* Add code generators and vvp support for both
|
||||
* structural and behavioral multiply.
|
||||
*
|
||||
* Revision 1.29 2001/05/24 04:20:10 steve
|
||||
* Add behavioral modulus.
|
||||
*
|
||||
* Revision 1.28 2001/05/20 01:18:38 steve
|
||||
* Implement reduction nor.
|
||||
*
|
||||
* Revision 1.27 2001/05/20 01:02:55 steve
|
||||
* Initial support for system functions.
|
||||
*
|
||||
* Revision 1.26 2001/05/17 04:37:02 steve
|
||||
* Behavioral ternary operators for vvp.
|
||||
*
|
||||
* Revision 1.25 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.24 2001/05/06 17:54:33 steve
|
||||
* Behavioral code to read memories. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.23 2001/05/02 01:57:25 steve
|
||||
* Support behavioral subtraction.
|
||||
*
|
||||
* Revision 1.22 2001/05/01 02:07:34 steve
|
||||
* Comparisons cant leave their results in the opcode
|
||||
* result area or their values will be clobbered by other
|
||||
* parts of a complex expression.
|
||||
*
|
||||
* Revision 1.21 2001/04/30 05:11:18 steve
|
||||
* OR is %or. Get this right.
|
||||
*
|
||||
* Revision 1.20 2001/04/29 20:47:39 steve
|
||||
* Evalulate logical or (||)
|
||||
*/
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vvp_process.c,v 1.51 2001/12/05 05:41:20 steve Exp $"
|
||||
#ident "$Id: vvp_process.c,v 1.52 2002/01/11 05:23:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
@@ -877,6 +877,8 @@ static int show_system_task_call(ivl_statement_t net)
|
||||
case IVL_EX_SFUNC:
|
||||
if (strcmp("$time", ivl_expr_name(expr)) == 0)
|
||||
fprintf(vvp_out, ", $time");
|
||||
else if (strcmp("$stime", ivl_expr_name(expr)) == 0)
|
||||
fprintf(vvp_out, ", $time");
|
||||
else
|
||||
fprintf(vvp_out, ", ?");
|
||||
continue;
|
||||
@@ -1100,6 +1102,9 @@ int draw_func_definition(ivl_scope_t scope)
|
||||
|
||||
/*
|
||||
* $Log: vvp_process.c,v $
|
||||
* Revision 1.52 2002/01/11 05:23:05 steve
|
||||
* Handle certain special cases of stime.
|
||||
*
|
||||
* Revision 1.51 2001/12/05 05:41:20 steve
|
||||
* Make sure fork labels are globally unique.
|
||||
*
|
||||
|
||||
+223
-80
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vvp_scope.c,v 1.57 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: vvp_scope.c,v 1.64 2002/01/12 17:49:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
@@ -126,6 +126,77 @@ const char *vvp_mangle_name(const char *id)
|
||||
return out;
|
||||
}
|
||||
|
||||
ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
|
||||
{
|
||||
unsigned idx;
|
||||
ivl_signal_type_t out = IVL_SIT_TRI;
|
||||
|
||||
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||
ivl_signal_type_t stype;
|
||||
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
|
||||
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
|
||||
if (sig == 0)
|
||||
continue;
|
||||
|
||||
stype = ivl_signal_type(sig);
|
||||
if (stype == IVL_SIT_REG)
|
||||
continue;
|
||||
if (stype == IVL_SIT_TRI)
|
||||
continue;
|
||||
if (stype == IVL_SIT_NONE)
|
||||
continue;
|
||||
out = stype;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
ivl_nexus_ptr_t ivl_logic_pin_ptr(ivl_net_logic_t net, unsigned pin)
|
||||
{
|
||||
ivl_nexus_t nex = ivl_logic_pin(net, pin);
|
||||
unsigned idx;
|
||||
|
||||
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
|
||||
ivl_net_logic_t tmp = ivl_nexus_ptr_log(ptr);
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
if (tmp != net)
|
||||
continue;
|
||||
if (ivl_nexus_ptr_pin(ptr) != pin)
|
||||
continue;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char*drive_string(ivl_drive_t drive)
|
||||
{
|
||||
switch (drive) {
|
||||
case IVL_DR_HiZ:
|
||||
return "";
|
||||
case IVL_DR_SMALL:
|
||||
return "sm";
|
||||
case IVL_DR_MEDIUM:
|
||||
return "me";
|
||||
case IVL_DR_WEAK:
|
||||
return "we";
|
||||
case IVL_DR_LARGE:
|
||||
return "la";
|
||||
case IVL_DR_PULL:
|
||||
return "pu";
|
||||
case IVL_DR_STRONG:
|
||||
return "";
|
||||
case IVL_DR_SUPPLY:
|
||||
return "su";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The draw_scope function draws the major functional items within a
|
||||
* scope. This includes the scopes themselves, of course. All the
|
||||
@@ -171,10 +242,16 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||
ivl_lpm_t lpm;
|
||||
|
||||
lptr = ivl_nexus_ptr_log(nptr);
|
||||
if (lptr && (ivl_logic_type(lptr) == IVL_LO_BUFZ) &&
|
||||
(nptr_pin == 0)) {
|
||||
return draw_net_input(ivl_logic_pin(lptr, 1));
|
||||
}
|
||||
if (lptr && (ivl_logic_type(lptr) == IVL_LO_BUFZ) && (nptr_pin == 0))
|
||||
do {
|
||||
if (ivl_nexus_ptr_drive0(nptr) != IVL_DR_STRONG)
|
||||
break;
|
||||
|
||||
if (ivl_nexus_ptr_drive1(nptr) != IVL_DR_STRONG)
|
||||
break;
|
||||
|
||||
return draw_net_input(ivl_logic_pin(lptr, 1));
|
||||
} while(0);
|
||||
|
||||
if (lptr && (ivl_logic_type(lptr) == IVL_LO_PULLDOWN)) {
|
||||
return "C<pu0>";
|
||||
@@ -196,18 +273,29 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sptr && (ivl_signal_type(sptr) == IVL_SIT_SUPPLY1)) {
|
||||
return "C<su1>";
|
||||
}
|
||||
|
||||
if (sptr && (ivl_signal_type(sptr) == IVL_SIT_SUPPLY0)) {
|
||||
return "C<su0>";
|
||||
}
|
||||
|
||||
cptr = ivl_nexus_ptr_con(nptr);
|
||||
if (cptr) {
|
||||
const char*bits = ivl_const_bits(cptr);
|
||||
sprintf(result, "C<%c>", bits[nptr_pin]);
|
||||
ivl_drive_t drive;
|
||||
switch (bits[nptr_pin]) {
|
||||
case '0':
|
||||
drive = ivl_nexus_ptr_drive0(nptr);
|
||||
if (drive == IVL_DR_HiZ)
|
||||
sprintf(result, "C<z>");
|
||||
else
|
||||
sprintf(result, "C<%s0>", drive_string(drive));
|
||||
break;
|
||||
case '1':
|
||||
drive = ivl_nexus_ptr_drive1(nptr);
|
||||
if (drive == IVL_DR_HiZ)
|
||||
sprintf(result, "C<z>");
|
||||
else
|
||||
sprintf(result, "C<%s1>", drive_string(drive));
|
||||
break;
|
||||
default:
|
||||
sprintf(result, "C<%c>", bits[nptr_pin]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -230,6 +318,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||
case IVL_LPM_SUB:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
for (idx = 0 ; idx < ivl_lpm_width(lpm) ; idx += 1)
|
||||
if (ivl_lpm_q(lpm, idx) == nex) {
|
||||
sprintf(result, "L_%s[%u]",
|
||||
@@ -270,6 +359,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
||||
*/
|
||||
const char* draw_net_input(ivl_nexus_t nex)
|
||||
{
|
||||
ivl_signal_type_t res;
|
||||
char result[512];
|
||||
unsigned idx;
|
||||
int level;
|
||||
@@ -277,12 +367,44 @@ const char* draw_net_input(ivl_nexus_t nex)
|
||||
static ivl_nexus_ptr_t *drivers = 0x0;
|
||||
static unsigned adrivers = 0;
|
||||
|
||||
const char*resolv_type;
|
||||
|
||||
/* If this nexus already has a label, then its input is
|
||||
already figured out. Just return the existing label. */
|
||||
char*nex_private = (char*)ivl_nexus_get_private(nex);
|
||||
if (nex_private)
|
||||
return nex_private;
|
||||
|
||||
res = signal_type_of_nexus(nex);
|
||||
switch (res) {
|
||||
case IVL_SIT_TRI:
|
||||
resolv_type = "tri";
|
||||
break;
|
||||
case IVL_SIT_TRI0:
|
||||
resolv_type = "tri0";
|
||||
break;
|
||||
case IVL_SIT_TRI1:
|
||||
resolv_type = "tri1";
|
||||
break;
|
||||
|
||||
/* Catch the special cases that the nets are supply
|
||||
nets. Drive constant values uncomditionally. */
|
||||
case IVL_SIT_SUPPLY0:
|
||||
nex_private = "C<su0>";
|
||||
ivl_nexus_set_private(nex, nex_private);
|
||||
return nex_private;
|
||||
case IVL_SIT_SUPPLY1:
|
||||
nex_private = "C<su1>";
|
||||
ivl_nexus_set_private(nex, nex_private);
|
||||
return nex_private;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "vvp.tgt: Unsupported signal type: %u\n", res);
|
||||
assert(0);
|
||||
resolv_type = "tri";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||
ivl_nexus_ptr_t nptr = ivl_nexus_ptr(nex, idx);
|
||||
@@ -306,14 +428,28 @@ const char* draw_net_input(ivl_nexus_t nex)
|
||||
/* If the nexus has no drivers, then send a constant HiZ into
|
||||
the net. */
|
||||
if (ndrivers == 0) {
|
||||
nex_private = "C<z>";
|
||||
switch (res) {
|
||||
case IVL_SIT_TRI:
|
||||
nex_private = "C<z>";
|
||||
break;
|
||||
case IVL_SIT_TRI0:
|
||||
nex_private = "C<0>";
|
||||
break;
|
||||
case IVL_SIT_TRI1:
|
||||
nex_private = "C<1>";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
ivl_nexus_set_private(nex, nex_private);
|
||||
return nex_private;
|
||||
}
|
||||
|
||||
|
||||
/* If the nexus has exactly one driver, then simply draw it. */
|
||||
if (ndrivers == 1) {
|
||||
/* If the nexus has exactly one driver, then simply draw
|
||||
it. Note that this will *not* work if the nexus is not a
|
||||
TRI type nexus. */
|
||||
if (ndrivers == 1 && res == IVL_SIT_TRI) {
|
||||
nex_private = strdup(draw_net_input_drive(nex, drivers[0]));
|
||||
ivl_nexus_set_private(nex, nex_private);
|
||||
return nex_private;
|
||||
@@ -328,8 +464,9 @@ const char* draw_net_input(ivl_nexus_t nex)
|
||||
vvp_mangle_id(ivl_nexus_name(nex)),
|
||||
level, inst);
|
||||
else
|
||||
fprintf(vvp_out, "RS_%s .resolv tri",
|
||||
vvp_mangle_id(ivl_nexus_name(nex)));
|
||||
fprintf(vvp_out, "RS_%s .resolv %s",
|
||||
vvp_mangle_id(ivl_nexus_name(nex)),
|
||||
resolv_type);
|
||||
|
||||
for (idx = inst; idx < ndrivers && idx < inst+4; idx += 1) {
|
||||
if (level) {
|
||||
@@ -524,6 +661,9 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||
const char*ltype = "?";
|
||||
const char*lcasc = 0x0;
|
||||
char identity_val = '0';
|
||||
|
||||
ivl_drive_t str0, str1;
|
||||
|
||||
int level;
|
||||
int ninp = ivl_logic_pins(lptr) - 1;
|
||||
typedef const char*const_charp;
|
||||
@@ -538,10 +678,23 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||
draw_udp_in_scope(lptr);
|
||||
return;
|
||||
|
||||
case IVL_LO_BUFZ:
|
||||
/* Skip BUFZ objects. Things that have a bufz as input
|
||||
will use the input to bufz instead. */
|
||||
return;
|
||||
case IVL_LO_BUFZ: {
|
||||
/* Draw bufz objects, but only if the output drive
|
||||
is different from the input. */
|
||||
ivl_nexus_ptr_t nptr = ivl_logic_pin_ptr(lptr,0);
|
||||
ivl_drive_t dr0 = ivl_nexus_ptr_drive0(nptr);
|
||||
ivl_drive_t dr1 = ivl_nexus_ptr_drive1(nptr);
|
||||
|
||||
ltype = "BUFZ";
|
||||
|
||||
if (dr0 != IVL_DR_STRONG)
|
||||
break;
|
||||
|
||||
if (dr1 != IVL_DR_STRONG)
|
||||
break;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case IVL_LO_PULLDOWN:
|
||||
case IVL_LO_PULLUP:
|
||||
@@ -616,13 +769,11 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||
break;
|
||||
|
||||
case IVL_LO_NOTIF0:
|
||||
fprintf(stderr, "vvp.tgt: error: Unhandled logic of type NOTIF0\n");
|
||||
ltype = "?";
|
||||
ltype = "NOTIF0";
|
||||
break;
|
||||
|
||||
case IVL_LO_NOTIF1:
|
||||
fprintf(stderr, "vvp.tgt: error: Unhandled logic of type NOTIF1\n");
|
||||
ltype = "?";
|
||||
ltype = "NOTIF1";
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -632,6 +783,21 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||
break;
|
||||
}
|
||||
|
||||
{ ivl_nexus_t nex = ivl_logic_pin(lptr, 0);
|
||||
ivl_nexus_ptr_t nptr = 0;
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||
nptr = ivl_nexus_ptr(nex,idx);
|
||||
if (ivl_nexus_ptr_log(nptr) != lptr)
|
||||
continue;
|
||||
if (ivl_nexus_ptr_pin(nptr) != 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
str0 = ivl_nexus_ptr_drive0(nptr);
|
||||
str1 = ivl_nexus_ptr_drive1(nptr);
|
||||
}
|
||||
|
||||
if (!lcasc)
|
||||
lcasc = ltype;
|
||||
|
||||
@@ -656,7 +822,12 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
||||
fprintf(vvp_out, "L_%s .functor %s",
|
||||
vvp_mangle_id(ivl_logic_name(lptr)),
|
||||
ltype);
|
||||
|
||||
draw_delay(lptr);
|
||||
|
||||
if (str0 != IVL_DR_STRONG || str1 != IVL_DR_STRONG)
|
||||
fprintf(vvp_out, " [%u %u]", str0, str1);
|
||||
|
||||
}
|
||||
for (pdx = inst; pdx < ninp && pdx < inst+4 ; pdx += 1) {
|
||||
if (level) {
|
||||
@@ -917,6 +1088,9 @@ static void draw_lpm_add(ivl_lpm_t net)
|
||||
case IVL_LPM_DIVIDE:
|
||||
type = "div";
|
||||
break;
|
||||
case IVL_LPM_MOD:
|
||||
type = "mod";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@@ -1116,6 +1290,7 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
|
||||
case IVL_LPM_SUB:
|
||||
case IVL_LPM_MULT:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
draw_lpm_add(net);
|
||||
return;
|
||||
|
||||
@@ -1235,6 +1410,27 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||
|
||||
/*
|
||||
* $Log: vvp_scope.c,v $
|
||||
* Revision 1.64 2002/01/12 17:49:41 steve
|
||||
* Handle constants with drive strength z
|
||||
*
|
||||
* Revision 1.63 2002/01/12 04:03:40 steve
|
||||
* Drive strengths for continuous assignments.
|
||||
*
|
||||
* Revision 1.62 2002/01/06 03:15:43 steve
|
||||
* Constant values have drive strengths.
|
||||
*
|
||||
* Revision 1.61 2002/01/03 04:19:01 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.60 2001/12/15 02:13:33 steve
|
||||
* Support all 3 TRI net types.
|
||||
*
|
||||
* Revision 1.59 2001/12/14 06:03:34 steve
|
||||
* Generate notif functors.
|
||||
*
|
||||
* Revision 1.58 2001/12/14 02:05:13 steve
|
||||
* Parse and handle drive strengths of gates to vvp.
|
||||
*
|
||||
* Revision 1.57 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
@@ -1268,58 +1464,5 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||
*
|
||||
* Revision 1.47 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.46 2001/09/14 04:15:46 steve
|
||||
* Generate code for identity comparators.
|
||||
*
|
||||
* Revision 1.45 2001/08/10 00:40:45 steve
|
||||
* tgt-vvp generates code that skips nets as inputs.
|
||||
*
|
||||
* Revision 1.44 2001/08/03 17:06:10 steve
|
||||
* More detailed messages about unsupported things.
|
||||
*
|
||||
* Revision 1.43 2001/07/28 03:18:50 steve
|
||||
* Generate constant symbols for supply nets.
|
||||
*
|
||||
* Revision 1.42 2001/07/22 21:31:14 steve
|
||||
* supply signals give input values.
|
||||
*
|
||||
* Revision 1.41 2001/07/18 02:44:39 steve
|
||||
* Relax driver limit from 64 to forever (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.40 2001/07/16 18:31:49 steve
|
||||
* Nest resolvers when there are lots of drivers (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.39 2001/07/09 15:38:35 steve
|
||||
* Properly step through wide inputs. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.38 2001/07/07 03:01:06 steve
|
||||
* Generate code for right shift.
|
||||
*
|
||||
* Revision 1.37 2001/07/06 04:48:04 steve
|
||||
* Generate code for structural left shift.
|
||||
*
|
||||
* Revision 1.36 2001/06/19 03:01:10 steve
|
||||
* Add structural EEQ gates (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.35 2001/06/18 03:10:34 steve
|
||||
* 1. Logic with more than 4 inputs
|
||||
* 2. Id and name mangling
|
||||
* 3. A memory leak in draw_net_in_scope()
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.34 2001/06/16 23:45:05 steve
|
||||
* Add support for structural multiply in t-dll.
|
||||
* Add code generators and vvp support for both
|
||||
* structural and behavioral multiply.
|
||||
*
|
||||
* Revision 1.33 2001/06/16 02:41:42 steve
|
||||
* Generate code to support memory access in continuous
|
||||
* assignment statements. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.32 2001/06/15 04:14:19 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
*
|
||||
* Revision 1.31 2001/06/07 04:20:10 steve
|
||||
*/
|
||||
|
||||
|
||||
+5
-4
@@ -1,10 +1,10 @@
|
||||
Summary: Icarus Verilog
|
||||
Name: verilog
|
||||
Version: 0.5
|
||||
Version: 0.6
|
||||
Release: 0
|
||||
Copyright: GPL
|
||||
Group: Applications/Engineering
|
||||
Source: ftp://icarus.com/pub/eda/verilog/v0.5/verilog-0.5.tar.gz
|
||||
Source: ftp://icarus.com/pub/eda/verilog/v0.6/verilog-0.6.tar.gz
|
||||
URL: http://www.icarus.com/eda/verilog/index.html
|
||||
Packager: Stephen Williams <[email protected]>
|
||||
|
||||
@@ -20,7 +20,7 @@ engineering formats, including simulation. It strives to be true
|
||||
to the IEEE-1364 standard.
|
||||
|
||||
%prep
|
||||
%setup -n verilog-0.5
|
||||
%setup -n verilog-0.6
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
@@ -31,7 +31,7 @@ make prefix=$RPM_BUILD_ROOT/usr install
|
||||
|
||||
%files
|
||||
|
||||
%attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt netlist.txt t-dll.txt vpi.txt vvm.txt xnf.txt xilinx-hint.txt
|
||||
%attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt netlist.txt t-dll.txt vpi.txt vvm.txt xnf.txt tgt-fpga/fpga.txt xilinx-hint.txt
|
||||
%attr(-,root,root) %doc examples/*
|
||||
|
||||
%attr(-,root,root) /usr/man/man1/iverilog.1.gz
|
||||
@@ -44,6 +44,7 @@ make prefix=$RPM_BUILD_ROOT/usr install
|
||||
%attr(-,root,root) /usr/lib/ivl/system.vpi
|
||||
%attr(-,root,root) /usr/lib/ivl/null.tgt
|
||||
%attr(-,root,root) /usr/lib/ivl/vvp.tgt
|
||||
%attr(-,root,root) /usr/lib/ivl/fpga.tgt
|
||||
%attr(-,root,root) /usr/lib/ivl/iverilog.conf
|
||||
%attr(-,root,root) /usr/lib/libvpi.a
|
||||
%attr(-,root,root) /usr/lib/libvvm.a
|
||||
|
||||
+22
-9
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: verinum.cc,v 1.29 2001/11/19 02:54:12 steve Exp $"
|
||||
#ident "$Id: verinum.cc,v 1.31 2002/02/01 05:09:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -351,15 +351,16 @@ ostream& operator<< (ostream&o, verinum::V v)
|
||||
*/
|
||||
ostream& operator<< (ostream&o, const verinum&v)
|
||||
{
|
||||
if (v.has_sign()) {
|
||||
o << "+";
|
||||
}
|
||||
|
||||
/* If the verinum number has a fixed length, dump all the bits
|
||||
literally. This is how we express the fixed length in the
|
||||
output. */
|
||||
if (v.has_len()) {
|
||||
o << v.len() << "'b";
|
||||
o << v.len();
|
||||
if (v.has_sign())
|
||||
o << "'sb";
|
||||
else
|
||||
o << "'b";
|
||||
|
||||
if (v.len() == 0) {
|
||||
o << "0";
|
||||
return o;
|
||||
@@ -374,13 +375,19 @@ ostream& operator<< (ostream&o, const verinum&v)
|
||||
/* If the number is fully defined (no x or z) then print it
|
||||
out as a decimal number. */
|
||||
if (v.is_defined()) {
|
||||
o << "'d" << v.as_ulong();
|
||||
if (v.has_sign())
|
||||
o << "'sd" << v.as_ulong();
|
||||
else
|
||||
o << "'d" << v.as_ulong();
|
||||
return o;
|
||||
}
|
||||
|
||||
/* Oh, well. Print the minimum to get the value properly
|
||||
displayed. */
|
||||
o << "'b";
|
||||
if (v.has_sign())
|
||||
o << "'sb";
|
||||
else
|
||||
o << "'b";
|
||||
|
||||
if (v.len() == 0) {
|
||||
o << "0";
|
||||
@@ -588,7 +595,7 @@ verinum operator - (const verinum&left, const verinum&r)
|
||||
for (unsigned idx = min ; idx < max ; idx += 1)
|
||||
val.set(idx, add_with_carry(verinum::V0, right[idx], carry));
|
||||
|
||||
|
||||
val.has_sign(left.has_sign() && r.has_sign());
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -786,6 +793,12 @@ verinum::V operator & (verinum::V l, verinum::V r)
|
||||
|
||||
/*
|
||||
* $Log: verinum.cc,v $
|
||||
* Revision 1.31 2002/02/01 05:09:14 steve
|
||||
* Propagate sign in unary minus.
|
||||
*
|
||||
* Revision 1.30 2001/12/31 00:02:33 steve
|
||||
* Include s indicator in dump of signed numbers.
|
||||
*
|
||||
* Revision 1.29 2001/11/19 02:54:12 steve
|
||||
* Handle division and modulus by zero while
|
||||
* evaluating run-time constants.
|
||||
|
||||
+417
-43
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: sys_display.c,v 1.31 2001/11/02 05:56:47 steve Exp $"
|
||||
#ident "$Id: sys_display.c,v 1.34 2002/01/22 00:18:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -30,11 +30,51 @@
|
||||
|
||||
struct strobe_cb_info {
|
||||
char*name;
|
||||
int default_format;
|
||||
vpiHandle scope;
|
||||
vpiHandle*items;
|
||||
unsigned nitems;
|
||||
};
|
||||
|
||||
// The number of decimal digits needed to represent a
|
||||
// nr_bits binary number is floor(nr_bits*log_10(2))+1,
|
||||
// where log_10(2) = 0.30102999566398.... and I approximate
|
||||
// this transcendental number as 146/485, to avoid the vagaries
|
||||
// of floating-point. The smallest nr_bits for which this
|
||||
// approximation fails is 2621,
|
||||
// 2621*log_10(2)=789.9996, but (2621*146+484)/485=790 (exactly).
|
||||
// In cases like this, all that happens is we allocate one
|
||||
// unneeded char for the output. I add a "L" suffix to 146
|
||||
// to make sure the computation is done as long ints, otherwise
|
||||
// on a 16-bit int machine (allowed by ISO C) we would mangle
|
||||
// this computation for bit-length of 224. I'd like to put
|
||||
// in a test for nr_bits < LONG_MAX/146, but don't know how
|
||||
// to fail, other than crashing.
|
||||
//
|
||||
// In an April 2000 thread in comp.unix.programmer, with subject
|
||||
// "integer -> string", I <[email protected]> give the 28/93
|
||||
// approximation, but overstate its accuracy: that version first
|
||||
// fails when the number of bits is 289, not 671.
|
||||
//
|
||||
// This result does not include space for a trailing '\0', if any.
|
||||
//
|
||||
inline static int calc_dec_size(int nr_bits, int is_signed)
|
||||
{
|
||||
int r;
|
||||
if (is_signed) --nr_bits;
|
||||
r = (nr_bits * 146L + 484) / 485;
|
||||
if (is_signed) ++r;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int vpi_get_dec_size(vpiHandle item)
|
||||
{
|
||||
return calc_dec_size(
|
||||
vpi_get(vpiSize, item),
|
||||
vpi_get(vpiSigned, item)==1
|
||||
);
|
||||
}
|
||||
|
||||
static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
|
||||
{
|
||||
if (argv) {
|
||||
@@ -70,6 +110,7 @@ static int format_str(vpiHandle scope, unsigned int mcd,
|
||||
s_vpi_value value;
|
||||
char buf[256];
|
||||
char*cp = fmt;
|
||||
char format_char = ' ';
|
||||
int idx;
|
||||
|
||||
assert(fmt);
|
||||
@@ -87,11 +128,13 @@ static int format_str(vpiHandle scope, unsigned int mcd,
|
||||
cp += cnt;
|
||||
|
||||
} else if (*cp == '%') {
|
||||
int fsize = -1, ffsize = -1;
|
||||
int do_num = 0;
|
||||
int leading_zero = -1, fsize = -1, ffsize = -1;
|
||||
int do_arg = 0;
|
||||
|
||||
cp += 1;
|
||||
if (isdigit(*cp))
|
||||
if (*cp == '0')
|
||||
leading_zero=1;
|
||||
if (isdigit((int)*cp))
|
||||
fsize = strtoul(cp, &cp, 10);
|
||||
if (*cp == '.') {
|
||||
cp += 1;
|
||||
@@ -100,61 +143,138 @@ static int format_str(vpiHandle scope, unsigned int mcd,
|
||||
switch (*cp) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
case 'B':
|
||||
do_num = 1;
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
format_char = 'b';
|
||||
do_arg = 1;
|
||||
value.format = vpiBinStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
do_num = 1;
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
format_char = 'd';
|
||||
do_arg = 1;
|
||||
value.format = vpiDecStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
#if 0
|
||||
case 'f':
|
||||
do_num = 1;
|
||||
value.format = vpiDecStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'h':
|
||||
case 'H':
|
||||
case 'x':
|
||||
case 'X':
|
||||
do_num = 1;
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
format_char = 'h';
|
||||
do_arg = 1;
|
||||
value.format = vpiHexStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
case 'm':
|
||||
assert(scope);
|
||||
vpi_mcd_printf(mcd, "%s", vpi_get_str(vpiFullName, scope));
|
||||
cp += 1;
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
do_num = 1;
|
||||
value.format = vpiOctStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
do_num = 1;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
if (fsize != -1 && ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
ffsize = -1;
|
||||
}
|
||||
format_char = 'c';
|
||||
do_arg = 1;
|
||||
value.format = vpiStringVal;
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
if (fsize == -1)
|
||||
fsize = 0;
|
||||
assert(scope);
|
||||
vpi_mcd_printf(mcd, "%*s",
|
||||
fsize,
|
||||
vpi_get_str(vpiFullName, scope));
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
case 'O':
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
format_char = 'o';
|
||||
do_arg = 1;
|
||||
value.format = vpiOctStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
format_char = 's';
|
||||
do_arg = 1;
|
||||
value.format = vpiStringVal;
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
do_num = 1;
|
||||
if (ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
}
|
||||
format_char = 't';
|
||||
do_arg = 1;
|
||||
value.format = vpiDecStrVal;
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
if (fsize != -1 && ffsize != -1) {
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
fsize = -1;
|
||||
ffsize = -1;
|
||||
}
|
||||
vpi_mcd_printf(mcd, "%%");
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
// new Verilog 2001 format specifiers...
|
||||
case 'l':
|
||||
case 'L':
|
||||
case 'u':
|
||||
case 'U':
|
||||
case 'z':
|
||||
case 'Z':
|
||||
vpi_printf("\nERROR: Unsupported format \"%s\"\n", fmt);
|
||||
vpi_mcd_printf(mcd, "%c", *cp);
|
||||
cp += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
vpi_printf("\nERROR: Illegal format \"%s\"\n", fmt);
|
||||
vpi_mcd_printf(mcd, "%c", *cp);
|
||||
cp += 1;
|
||||
break;
|
||||
@@ -163,17 +283,96 @@ static int format_str(vpiHandle scope, unsigned int mcd,
|
||||
/* If we encountered a numeric format string, then
|
||||
grab the number value from the next parameter
|
||||
and display it in the requested format. */
|
||||
if (do_num) {
|
||||
if (do_arg) {
|
||||
if (idx >= argc) {
|
||||
vpi_printf("\ntoo few arguments for format %s\n",
|
||||
fmt);
|
||||
} else {
|
||||
vpi_get_value(argv[idx++], &value);
|
||||
if (fsize>0)
|
||||
vpi_mcd_printf(mcd, "%*s",
|
||||
fsize, value.value.str);
|
||||
else
|
||||
vpi_mcd_printf(mcd, "%s", value.value.str);
|
||||
vpi_get_value(argv[idx], &value);
|
||||
|
||||
switch(format_char){
|
||||
case 'c':
|
||||
vpi_mcd_printf(mcd, "%c", value.value.str[strlen(value.value.str)-1]);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'd':
|
||||
if (fsize==-1){
|
||||
// simple %d parameter.
|
||||
// Size is now determined by the width
|
||||
// of the vector or integer
|
||||
fsize = vpi_get_dec_size(argv[idx]);
|
||||
}
|
||||
|
||||
vpi_mcd_printf(mcd, "%*s", fsize,
|
||||
value.value.str);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
case 'h':
|
||||
case 'x':
|
||||
case 'o':
|
||||
if (fsize==-1){
|
||||
// For hex, oct and binary values, the string is already
|
||||
// prefixed with the correct number of zeros...
|
||||
vpi_mcd_printf(mcd, "%s", value.value.str);
|
||||
}
|
||||
else{
|
||||
char* value_str = value.value.str;
|
||||
|
||||
if (leading_zero==1){
|
||||
// Strip away all leading zeros from string
|
||||
int i=0;
|
||||
while(i< (strlen(value_str)-1) && value_str[i]=='0')
|
||||
i++;
|
||||
|
||||
value_str += i;
|
||||
}
|
||||
|
||||
vpi_mcd_printf(mcd, "%*s", fsize, value_str);
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (fsize==-1){
|
||||
vpi_mcd_printf(mcd, "%s", value.value.str);
|
||||
}
|
||||
else{
|
||||
char* value_str = value.value.str;
|
||||
|
||||
if (leading_zero==1){
|
||||
// Remove leading spaces from the value
|
||||
// string *except* if the argument is a
|
||||
// constant string... (hey, that's how
|
||||
// the commerical guys behave...)
|
||||
|
||||
if (!(vpi_get(vpiType, argv[idx]) == vpiConstant
|
||||
&& vpi_get(vpiConstType, argv[idx]) == vpiStringConst)) {
|
||||
int i=0;
|
||||
// Strip away all leading zeros from string
|
||||
while(i< (strlen(value_str)-1) && value_str[i]==' ')
|
||||
i++;
|
||||
|
||||
value_str += i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vpi_mcd_printf(mcd, "%*s", fsize, value_str);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (fsize > 0)
|
||||
vpi_mcd_printf(mcd, "%*s", fsize,
|
||||
value.value.str);
|
||||
else
|
||||
vpi_mcd_printf(mcd, "%s",
|
||||
value.value.str);
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +413,7 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
|
||||
{
|
||||
s_vpi_value value;
|
||||
int idx;
|
||||
int size;
|
||||
|
||||
for (idx = 0 ; idx < info->nitems ; idx += 1) {
|
||||
vpiHandle item = info->items[idx];
|
||||
@@ -241,15 +441,26 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
case vpiMemoryWord:
|
||||
value.format = vpiBinStrVal;
|
||||
value.format = info->default_format;
|
||||
vpi_get_value(item, &value);
|
||||
vpi_mcd_printf(mcd, "%s", value.value.str);
|
||||
|
||||
switch(info->default_format){
|
||||
case vpiDecStrVal:
|
||||
size = vpi_get_dec_size(item);
|
||||
vpi_mcd_printf(mcd, "%*s", size, value.value.str);
|
||||
break;
|
||||
|
||||
default:
|
||||
vpi_mcd_printf(mcd, "%s", value.value.str);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case vpiTimeVar:
|
||||
value.format = vpiTimeVal;
|
||||
vpi_get_value(item, &value);
|
||||
vpi_mcd_printf(mcd, "%u", value.value.time->low);
|
||||
vpi_mcd_printf(mcd, "%20u", value.value.time->low);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -259,6 +470,25 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
|
||||
}
|
||||
}
|
||||
|
||||
static int get_default_format(char *name)
|
||||
{
|
||||
int default_format;
|
||||
|
||||
switch(name[ strlen(name)-1 ]){
|
||||
// writE/strobE or monitoR or displaY/fdisplaY
|
||||
case 'e':
|
||||
case 'r':
|
||||
case 'y': default_format = vpiDecStrVal; break;
|
||||
case 'h': default_format = vpiHexStrVal; break;
|
||||
case 'o': default_format = vpiOctStrVal; break;
|
||||
case 'b': default_format = vpiBinStrVal; break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return default_format;
|
||||
}
|
||||
|
||||
static int sys_display_calltf(char *name)
|
||||
{
|
||||
struct strobe_cb_info info;
|
||||
@@ -268,14 +498,14 @@ static int sys_display_calltf(char *name)
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
||||
|
||||
assert(scope);
|
||||
info.default_format = get_default_format(name);
|
||||
info.scope = scope;
|
||||
array_from_iterator(&info, argv);
|
||||
|
||||
do_display(5, &info);
|
||||
|
||||
free(info.items);
|
||||
|
||||
if (strcmp(name,"$display") == 0)
|
||||
if (strncmp(name,"$display",8) == 0)
|
||||
vpi_mcd_printf(5, "\n");
|
||||
|
||||
return 0;
|
||||
@@ -318,6 +548,7 @@ static int sys_strobe_calltf(char*name)
|
||||
|
||||
array_from_iterator(info, argv);
|
||||
info->name = strdup(name);
|
||||
info->default_format = get_default_format(name);
|
||||
info->scope= scope;
|
||||
|
||||
time.type = vpiSimTime;
|
||||
@@ -342,7 +573,7 @@ static int sys_strobe_calltf(char*name)
|
||||
* though that monitor may be watching many variables).
|
||||
*/
|
||||
|
||||
static struct strobe_cb_info monitor_info = { 0, 0, 0, 0 };
|
||||
static struct strobe_cb_info monitor_info = { 0, 0, 0, 0, 0 };
|
||||
static int monitor_scheduled = 0;
|
||||
static vpiHandle *monitor_callbacks = 0;
|
||||
|
||||
@@ -420,6 +651,7 @@ static int sys_monitor_calltf(char*name)
|
||||
|
||||
array_from_iterator(&monitor_info, argv);
|
||||
monitor_info.name = strdup(name);
|
||||
monitor_info.default_format = get_default_format(name);
|
||||
monitor_info.scope = scope;
|
||||
|
||||
monitor_callbacks = calloc(monitor_info.nitems, sizeof(vpiHandle));
|
||||
@@ -550,12 +782,13 @@ static int sys_fdisplay_calltf(char *name)
|
||||
mcd = value.value.integer;
|
||||
|
||||
assert(scope);
|
||||
info.default_format = get_default_format(name);
|
||||
info.scope = scope;
|
||||
array_from_iterator(&info, argv);
|
||||
do_display(mcd, &info);
|
||||
free(info.items);
|
||||
|
||||
if (strcmp(name,"$fdisplay") == 0)
|
||||
if (strncmp(name,"$fdisplay",9) == 0)
|
||||
vpi_mcd_printf(mcd, "\n");
|
||||
|
||||
return 0;
|
||||
@@ -674,6 +907,7 @@ void sys_display_register()
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
//============================== display
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$display";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
@@ -682,6 +916,31 @@ void sys_display_register()
|
||||
tf_data.user_data = "$display";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$displayh";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$displayh";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$displayo";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$displayo";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$displayb";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$displayb";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== write
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$write";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
@@ -690,6 +949,31 @@ void sys_display_register()
|
||||
tf_data.user_data = "$write";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$writeh";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$writeh";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$writeo";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$writeo";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$writeb";
|
||||
tf_data.calltf = sys_display_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$writeb";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== strobe
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$strobe";
|
||||
tf_data.calltf = sys_strobe_calltf;
|
||||
@@ -698,6 +982,31 @@ void sys_display_register()
|
||||
tf_data.user_data = "$strobe";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$strobeh";
|
||||
tf_data.calltf = sys_strobe_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$strobeh";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$strobeo";
|
||||
tf_data.calltf = sys_strobe_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$strobeo";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$strobeb";
|
||||
tf_data.calltf = sys_strobe_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$strobeb";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== monitor
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$monitor";
|
||||
tf_data.calltf = sys_monitor_calltf;
|
||||
@@ -706,6 +1015,31 @@ void sys_display_register()
|
||||
tf_data.user_data = "$monitor";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$monitorh";
|
||||
tf_data.calltf = sys_monitor_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$monitorh";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$monitoro";
|
||||
tf_data.calltf = sys_monitor_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$monitoro";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$monitorb";
|
||||
tf_data.calltf = sys_monitor_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$monitorb";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fopen
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$fopen";
|
||||
tf_data.calltf = sys_fopen_calltf;
|
||||
@@ -714,6 +1048,7 @@ void sys_display_register()
|
||||
tf_data.user_data = "$fopen";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fclose
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fclose";
|
||||
tf_data.calltf = sys_fclose_calltf;
|
||||
@@ -722,6 +1057,7 @@ void sys_display_register()
|
||||
tf_data.user_data = "$fclose";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fdisplay
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fdisplay";
|
||||
tf_data.calltf = sys_fdisplay_calltf;
|
||||
@@ -730,6 +1066,31 @@ void sys_display_register()
|
||||
tf_data.user_data = "$fdisplay";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fdisplayh";
|
||||
tf_data.calltf = sys_fdisplay_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$fdisplayh";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fdisplayo";
|
||||
tf_data.calltf = sys_fdisplay_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$fdisplayo";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fdisplayb";
|
||||
tf_data.calltf = sys_fdisplay_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$fdisplayb";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fwrite
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fwrite";
|
||||
tf_data.calltf = sys_fdisplay_calltf;
|
||||
@@ -738,6 +1099,7 @@ void sys_display_register()
|
||||
tf_data.user_data = "$fwrite";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fputc
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$fputc";
|
||||
tf_data.calltf = sys_fputc_calltf;
|
||||
@@ -746,6 +1108,7 @@ void sys_display_register()
|
||||
tf_data.user_data = "$fputc";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
//============================== fgetc
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$fgetc";
|
||||
tf_data.calltf = sys_fgetc_calltf;
|
||||
@@ -758,6 +1121,17 @@ void sys_display_register()
|
||||
|
||||
/*
|
||||
* $Log: sys_display.c,v $
|
||||
* Revision 1.34 2002/01/22 00:18:10 steve
|
||||
* Better calcuation of dec string width (Larry Doolittle)
|
||||
*
|
||||
* Revision 1.33 2002/01/15 03:23:34 steve
|
||||
* Default widths pad out as per the standard,
|
||||
* add $displayb/o/h et al., and some better
|
||||
* error messages for incorrect formats.
|
||||
*
|
||||
* Revision 1.32 2002/01/11 04:48:01 steve
|
||||
* Add the %c format, and some warning messages.
|
||||
*
|
||||
* Revision 1.31 2001/11/02 05:56:47 steve
|
||||
* initialize scope for %m in $fdisplay.
|
||||
*
|
||||
|
||||
+201
-40
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: sys_readmem.c,v 1.8 2001/12/01 02:40:10 steve Exp $"
|
||||
#ident "$Id: sys_readmem.c,v 1.9 2002/01/31 04:28:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,11 +29,45 @@
|
||||
# include <assert.h>
|
||||
# include "sys_readmem_lex.h"
|
||||
|
||||
static int check_integer_constant(char*name, vpiHandle handle)
|
||||
{
|
||||
if (vpi_get(vpiType, handle) != vpiConstant){
|
||||
vpi_printf("ERROR: %s parameter must be a constant\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(vpi_get(vpiConstType, handle)){
|
||||
case vpiDecConst:
|
||||
case vpiBinaryConst:
|
||||
case vpiOctConst:
|
||||
case vpiHexConst:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
/* We rely on vpi_get_value for reals and strings to return a correct */
|
||||
/* integer value when this is requested. So only a warning is generated. */
|
||||
case vpiRealConst:
|
||||
vpi_printf("Warning: real supplied to %s instead of integer.\n", name);
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case vpiStringConst:
|
||||
vpi_printf("Warning: string supplied to %s instead of integer.\n", name);
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* switch statement covers all possibilities. Code should never come here... */
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_readmem_calltf(char*name)
|
||||
{
|
||||
int code;
|
||||
int wwid;
|
||||
char*path;
|
||||
char*mem_name;
|
||||
FILE*file;
|
||||
unsigned addr;
|
||||
s_vpi_value value;
|
||||
@@ -42,6 +76,28 @@ static int sys_readmem_calltf(char*name)
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
||||
vpiHandle item = vpi_scan(argv);
|
||||
vpiHandle mitem;
|
||||
vpiHandle start_item;
|
||||
vpiHandle stop_item;
|
||||
vpiHandle left_range;
|
||||
vpiHandle right_range;
|
||||
vpiHandle word_index;
|
||||
|
||||
/* These are left and right hand side parameters in the
|
||||
declaration of the memory. */
|
||||
int left_addr, right_addr;
|
||||
|
||||
/* start_addr and stop_addr are the parameters given to $readmem in the
|
||||
verilog code. When not specified, start_addr is equal to the lower of
|
||||
the [left,right]_addr and stop_addr is equal to the higher of the
|
||||
[left,right]_addr. */
|
||||
int start_addr, stop_addr, addr_incr;
|
||||
|
||||
/* min_addr and max_addr are equal to start_addr and stop_addr if
|
||||
start_addr<stop_addr or vice versa if not... */
|
||||
int min_addr, max_addr;
|
||||
|
||||
|
||||
/*======================================== Get parameters */
|
||||
|
||||
if (item == 0) {
|
||||
vpi_printf("%s: file name parameter missing.\n", name);
|
||||
@@ -55,7 +111,7 @@ static int sys_readmem_calltf(char*name)
|
||||
}
|
||||
|
||||
if (vpi_get(vpiConstType, item) != vpiStringConst) {
|
||||
vpi_printf("ERROR: %s parameter must be a constant\n", name);
|
||||
vpi_printf("ERROR: %s parameter must be a string\n", name);
|
||||
vpi_free_object(argv);
|
||||
return 0;
|
||||
}
|
||||
@@ -64,7 +120,7 @@ static int sys_readmem_calltf(char*name)
|
||||
vpi_get_value(item, &value);
|
||||
path = strdup(value.value.str);
|
||||
|
||||
/* Get and check the second paramter. It must be a memory. */
|
||||
/* Get and check the second parameter. It must be a memory. */
|
||||
mitem = vpi_scan(argv);
|
||||
if (mitem == 0) {
|
||||
vpi_printf("%s: Missing memory parameter\n", name);
|
||||
@@ -79,10 +135,40 @@ static int sys_readmem_calltf(char*name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXXX remaining parameters not supported. */
|
||||
vpi_free_object(argv);
|
||||
mem_name = vpi_get_str(vpiFullName, mitem);
|
||||
|
||||
/* Open the data file. */
|
||||
/* Get optional third parameter. It must be a constant. */
|
||||
start_item = vpi_scan(argv);
|
||||
if (start_item!=0){
|
||||
if (check_integer_constant(name, start_item) == 0){
|
||||
vpi_free_object(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get optional forth parameter. It must be a constant. */
|
||||
stop_item = vpi_scan(argv);
|
||||
if (stop_item!=0){
|
||||
if (check_integer_constant(name, stop_item) == 0){
|
||||
vpi_free_object(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that ther is no 5th parameter */
|
||||
if (vpi_scan(argv) != 0){
|
||||
vpi_printf("ERROR: %s accepts maximum 4 parameters!\n", name );
|
||||
vpi_free_object(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
stop_item = 0;
|
||||
}
|
||||
|
||||
/*======================================== Process parameters */
|
||||
|
||||
/* Open the data file. */
|
||||
file = fopen(path, "r");
|
||||
if (file == 0) {
|
||||
vpi_printf("%s: Unable to open %s for reading.\n", name, path);
|
||||
@@ -90,56 +176,128 @@ static int sys_readmem_calltf(char*name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get left addr of memory */
|
||||
left_range = vpi_handle(vpiLeftRange, mitem);
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(left_range, &value);
|
||||
left_addr = value.value.integer;
|
||||
|
||||
/* Get right addr of memory */
|
||||
right_range = vpi_handle(vpiRightRange, mitem);
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(right_range, &value);
|
||||
right_addr = value.value.integer;
|
||||
|
||||
/* Get start_addr, stop_addr and addr_incr */
|
||||
if (start_item==0){
|
||||
start_addr = left_addr<right_addr ? left_addr : right_addr;
|
||||
stop_addr = left_addr<right_addr ? right_addr : left_addr;
|
||||
addr_incr = 1;
|
||||
}
|
||||
else{
|
||||
s_vpi_value value;
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(start_item, &value);
|
||||
start_addr = value.value.integer;
|
||||
|
||||
if (stop_item==0){
|
||||
stop_addr = left_addr<right_addr ? right_addr : left_addr;
|
||||
addr_incr = 1;
|
||||
}
|
||||
else{
|
||||
s_vpi_value value;
|
||||
value.format = vpiIntVal;
|
||||
vpi_get_value(stop_item, &value);
|
||||
stop_addr = value.value.integer;
|
||||
|
||||
addr_incr = start_addr<stop_addr ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
min_addr = start_addr<stop_addr ? start_addr : stop_addr ;
|
||||
max_addr = start_addr<stop_addr ? stop_addr : start_addr;
|
||||
|
||||
/* Check that start_addr and stop_addr are within the memory
|
||||
range */
|
||||
if (left_addr<right_addr){
|
||||
if (start_addr<left_addr || start_addr > right_addr) {
|
||||
vpi_printf("%s: Start address is out of bounds for memory \'%s\'!\n", name, mem_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stop_addr<left_addr || stop_addr > right_addr) {
|
||||
vpi_printf("%s: Stop address is out of bounds for memory \'%s\'!\n", name, mem_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (start_addr<right_addr || start_addr > left_addr) {
|
||||
vpi_printf("%s: Start address is out of bounds for memory \'%s\'!\n", name, mem_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stop_addr<right_addr || stop_addr > left_addr) {
|
||||
vpi_printf("%s: Stop address is out of bounds for memory \'%s\'!\n", name, mem_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
words = vpi_iterate(vpiMemoryWord, mitem);
|
||||
assert(words);
|
||||
|
||||
item = vpi_scan(words);
|
||||
wwid = vpi_get(vpiSize, item);
|
||||
|
||||
/* variable that will be uses by the lexer to pass values
|
||||
back to this code */
|
||||
value.format = vpiVectorVal;
|
||||
value.value.vector = calloc((wwid+31)/32, sizeof (s_vpi_vecval));
|
||||
value.value.vector = calloc((wwid+31)/32, sizeof(s_vpi_vecval));
|
||||
|
||||
/* Configure the readmem lexer */
|
||||
if (strcmp(name,"$readmemb") == 0)
|
||||
sys_readmem_start_file(file, 1, wwid, value.value.vector);
|
||||
else
|
||||
sys_readmem_start_file(file, 0, wwid, value.value.vector);
|
||||
|
||||
addr = 0;
|
||||
|
||||
/*======================================== Read memory file */
|
||||
|
||||
/* Run through the input file and store the new contents in the memory */
|
||||
addr = start_addr;
|
||||
while ((code = readmemlex()) != 0) {
|
||||
switch (code) {
|
||||
case MEM_ADDRESS:
|
||||
if (addr > value.value.vector->aval) {
|
||||
vpi_free_object(words);
|
||||
words = vpi_iterate(vpiMemoryWord, mitem);
|
||||
item = vpi_scan(words);
|
||||
addr = 0;
|
||||
}
|
||||
while (item && addr < value.value.vector->aval) {
|
||||
item = vpi_scan(words);
|
||||
addr += 1;
|
||||
}
|
||||
break;
|
||||
case MEM_WORD:
|
||||
if (item) {
|
||||
vpi_put_value(item, &value, 0, vpiNoDelay);
|
||||
item = vpi_scan(words);
|
||||
addr += 1;
|
||||
} else {
|
||||
vpi_printf("%s(%s): too much data (addr=0x%x)\n",
|
||||
name, path, addr);
|
||||
goto bailout;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vpi_printf("Huh?! (%d)\n", code);
|
||||
break;
|
||||
}
|
||||
switch (code) {
|
||||
case MEM_ADDRESS:
|
||||
addr = value.value.vector->aval;
|
||||
break;
|
||||
|
||||
case MEM_WORD:
|
||||
if (addr >= min_addr && addr <= max_addr){
|
||||
word_index = vpi_handle_by_index(mitem, addr);
|
||||
assert(word_index);
|
||||
vpi_put_value(word_index, &value, 0, vpiNoDelay);
|
||||
}
|
||||
else{
|
||||
vpi_printf("%s(%s): address (0x%x) out of range (0x%x:0x%x)\n",
|
||||
name, path, addr, start_addr, stop_addr);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
addr += addr_incr;
|
||||
break;
|
||||
|
||||
default:
|
||||
vpi_printf("Huh?! (%d)\n", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bailout:
|
||||
if (item) vpi_free_object(words);
|
||||
free(path);
|
||||
bailout:
|
||||
free(value.value.vector);
|
||||
|
||||
if (item)
|
||||
vpi_free_object(words);
|
||||
free(path);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
@@ -177,7 +335,7 @@ static int sys_writemem_calltf(char*name)
|
||||
vpi_get_value(item, &value);
|
||||
path = strdup(value.value.str);
|
||||
|
||||
/* Get and check the second paramter. It must be a memory. */
|
||||
/* Get and check the second parameter. It must be a memory. */
|
||||
item = vpi_scan(argv);
|
||||
if (item == 0) {
|
||||
vpi_printf("%s: Missing memory parameter\n", name);
|
||||
@@ -253,6 +411,9 @@ void sys_readmem_register()
|
||||
|
||||
/*
|
||||
* $Log: sys_readmem.c,v $
|
||||
* Revision 1.9 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
* Revision 1.8 2001/12/01 02:40:10 steve
|
||||
* Support addresses in readmemh.
|
||||
*
|
||||
|
||||
+16
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: sys_time.c,v 1.2 2001/07/25 03:10:50 steve Exp $"
|
||||
#ident "$Id: sys_time.c,v 1.3 2002/01/11 05:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -30,6 +30,11 @@ static int sys_time_sizetf(char*x)
|
||||
return 64;
|
||||
}
|
||||
|
||||
static int sys_stime_sizetf(char*x)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int sys_time_calltf(char*name)
|
||||
{
|
||||
s_vpi_value val;
|
||||
@@ -60,10 +65,20 @@ void sys_time_register()
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = sys_time_sizetf;
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$stime";
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = sys_stime_sizetf;
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: sys_time.c,v $
|
||||
* Revision 1.3 2002/01/11 05:20:59 steve
|
||||
* Add the stime system function.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:50 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
|
||||
+6
-1
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vpi_user.h,v 1.6 2001/09/30 05:18:46 steve Exp $"
|
||||
#ident "$Id: vpi_user.h,v 1.7 2002/01/24 04:19:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -157,6 +157,8 @@ typedef struct t_vpi_value {
|
||||
#define vpiSysTaskCall 57
|
||||
#define vpiTask 59
|
||||
#define vpiTimeVar 63
|
||||
#define vpiLeftRange 79
|
||||
#define vpiRightRange 83
|
||||
#define vpiScope 84
|
||||
#define vpiSysTfCall 85
|
||||
#define vpiArgument 89
|
||||
@@ -309,6 +311,9 @@ EXTERN_C_END
|
||||
|
||||
/*
|
||||
* $Log: vpi_user.h,v $
|
||||
* Revision 1.7 2002/01/24 04:19:39 steve
|
||||
* Add the vpiLeft.. and vpiRightRange constants
|
||||
*
|
||||
* Revision 1.6 2001/09/30 05:18:46 steve
|
||||
* Reduce VCD output by removing duplicates. (Stephan Boettcher)
|
||||
*
|
||||
|
||||
+15
-10
@@ -7,30 +7,35 @@ static p_vpi_thunk vpi_thunk_p = 0;
|
||||
|
||||
#define VPITV_CALL(fn,args) { \
|
||||
if (vpi_thunk_p == 0) { \
|
||||
fprintf(stderr, "No Simulator registered, cannot handle vpi " \
|
||||
"call to " #fn "\n"); \
|
||||
return; \
|
||||
no_sim(#fn); return; \
|
||||
} \
|
||||
if (vpi_thunk_p->fn == 0) { \
|
||||
fprintf(stderr, "Simulator doesn't have a " #fn " function\n"); \
|
||||
return; \
|
||||
no_func(#fn); return; \
|
||||
} \
|
||||
vpi_thunk_p->fn args; \
|
||||
}
|
||||
|
||||
#define VPIT_CALL(fn,def,args) { \
|
||||
if (vpi_thunk_p == 0) { \
|
||||
fprintf(stderr, "No Simulator registered, cannot handle vpi " \
|
||||
"call to " #fn "\n"); \
|
||||
return def; \
|
||||
no_sim(#fn); return def; \
|
||||
} \
|
||||
if (vpi_thunk_p->fn == 0) { \
|
||||
fprintf(stderr, "Simulator doesn't have a " #fn " function\n"); \
|
||||
return; \
|
||||
no_func(#fn); return def; \
|
||||
} \
|
||||
return vpi_thunk_p->fn args; \
|
||||
}
|
||||
|
||||
static void no_sim(const char *fn)
|
||||
{
|
||||
fprintf(stderr, "No Simulator registered, cannot handle vpi "
|
||||
"call to %s\n", fn);
|
||||
}
|
||||
|
||||
static void no_func(const char *fn)
|
||||
{
|
||||
fprintf(stderr, "Simulator doesn't have a %s function\n",fn);
|
||||
}
|
||||
|
||||
DLLEXPORT int vpi_register_sim(p_vpi_thunk tp)
|
||||
{
|
||||
vpi_thunk_p = 0;
|
||||
|
||||
+5
-2
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.3 2001/05/22 02:14:47 steve Exp $"
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.4 2002/01/23 04:54:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
@@ -49,7 +49,7 @@ inline const char *dlerror(void)
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_NOW); }
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{ return dlsym(dll, nm); }
|
||||
@@ -77,6 +77,9 @@ inline const char*dlerror(void)
|
||||
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.4 2002/01/23 04:54:38 steve
|
||||
* Load modules with RTLD_LAZY
|
||||
*
|
||||
* Revision 1.3 2001/05/22 02:14:47 steve
|
||||
* Update the mingw build to not require cygwin files.
|
||||
*
|
||||
|
||||
+7
-5
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.32 2001/11/10 18:07:11 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.35 2002/02/03 01:01:51 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -39,6 +39,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
STRIP = @STRIP@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ -DMODULE_DIR=\"$(libdir)/ivl\"
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
@@ -61,7 +63,7 @@ check: all
|
||||
|
||||
V = vpi_modules.o vpi_callback.o vpi_const.o vpi_iter.o vpi_mcd.o \
|
||||
vpi_priv.o vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \
|
||||
vpi_vthr_vector.o vvp_vpi.o
|
||||
vpi_vthr_vector.o vpip_to_dec.o vvp_vpi.o
|
||||
|
||||
O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \
|
||||
functor.o fvectors.o npmos.o resolv.o symbols.o codes.o vthread.o schedule.o \
|
||||
@@ -88,11 +90,11 @@ parse.o: parse.cc
|
||||
tables.o: tables.cc
|
||||
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
bison --verbose -t -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h
|
||||
$(YACC) --verbose -t -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h || mv parse.hh parse.h
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
flex -s -olexor.cc $(srcdir)/lexor.lex
|
||||
$(LEX) -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
vvp.pdf: $(srcdir)/vvp.man
|
||||
man -t $(srcdir)/vvp.man | ps2pdf - vvp.pdf
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* $Id: README.txt,v 1.38 2001/11/01 03:00:19 steve Exp $
|
||||
* $Id: README.txt,v 1.39 2002/01/03 04:19:01 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
@@ -433,6 +433,7 @@ create special statement types for the various arithmetic operators.
|
||||
<label> .arith/sum <wid>, <symbols_list>;
|
||||
<label> .arith/mult <wid>, <symbols_list>;
|
||||
<label> .arith/div <wid>, <symbols_list>;
|
||||
<label> .arith/mod <wid>, <symbols_list>;
|
||||
|
||||
Addition is represented by the .arith/sum statement. This creates an
|
||||
array of functors based at the label. The width of the array is given
|
||||
|
||||
+45
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: arith.cc,v 1.21 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: arith.cc,v 1.22 2002/01/03 04:19:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
@@ -128,6 +128,47 @@ void vvp_arith_div::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||
output_val_(base, push, a/b);
|
||||
}
|
||||
|
||||
inline void vvp_arith_mod::wide(vvp_ipoint_t base, bool push)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_arith_mod::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||
{
|
||||
put(i, val);
|
||||
vvp_ipoint_t base = ipoint_make(i,0);
|
||||
|
||||
if(wid_ > 8*sizeof(unsigned long)) {
|
||||
wide(base, push);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long a = 0, b = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
||||
functor_t obj = functor_index(ptr);
|
||||
|
||||
unsigned val = obj->ival;
|
||||
if (val & 0xaa) {
|
||||
output_x_(base, push);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val & 0x01)
|
||||
a += 1 << idx;
|
||||
if (val & 0x04)
|
||||
b += 1 << idx;
|
||||
}
|
||||
|
||||
if (b == 0) {
|
||||
output_x_(base, push);
|
||||
return;
|
||||
}
|
||||
|
||||
output_val_(base, push, a%b);
|
||||
}
|
||||
|
||||
// Multiplication
|
||||
|
||||
void vvp_arith_mult::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||
@@ -508,6 +549,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||
|
||||
/*
|
||||
* $Log: arith.cc,v $
|
||||
* Revision 1.22 2002/01/03 04:19:02 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.21 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+13
-1
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: arith.h,v 1.11 2001/10/31 04:27:46 steve Exp $"
|
||||
#ident "$Id: arith.h,v 1.12 2002/01/03 04:19:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
@@ -75,6 +75,15 @@ class vvp_arith_div : public vvp_arith_ {
|
||||
void wide(vvp_ipoint_t base, bool push);
|
||||
};
|
||||
|
||||
class vvp_arith_mod : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_mod(unsigned wid) : vvp_arith_(wid) {}
|
||||
|
||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
void wide(vvp_ipoint_t base, bool push);
|
||||
};
|
||||
|
||||
class vvp_arith_sum : public vvp_wide_arith_ {
|
||||
|
||||
public:
|
||||
@@ -125,6 +134,9 @@ class vvp_shiftr : public vvp_arith_ {
|
||||
|
||||
/*
|
||||
* $Log: arith.h,v $
|
||||
* Revision 1.12 2002/01/03 04:19:02 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.11 2001/10/31 04:27:46 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
||||
+20
-8
@@ -17,14 +17,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: bufif.cc,v 1.4 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: bufif.cc,v 1.6 2001/12/19 23:43:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "bufif.h"
|
||||
# include "functor.h"
|
||||
# include "schedule.h"
|
||||
|
||||
void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
|
||||
void vvp_bufif_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
|
||||
{
|
||||
put(ptr, v);
|
||||
|
||||
@@ -33,17 +33,17 @@ void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
|
||||
|
||||
unsigned char out0 = 0x00 | (odrive0<<0) | (odrive0<<4);
|
||||
unsigned char out1 = 0x88 | (odrive1<<0) | (odrive1<<4);
|
||||
unsigned char outX = 0x80 | (odrive1<<0) | (odrive0<<4);
|
||||
unsigned char outX = 0x80 | (odrive0<<0) | (odrive1<<4);
|
||||
unsigned char outH = 0x88 | (0) | (odrive1<<4);
|
||||
unsigned char outL = 0x00 | (odrive1<<0) | (0);
|
||||
unsigned char outL = 0x00 | (odrive0<<0) | (0);
|
||||
|
||||
unsigned val;
|
||||
unsigned str;
|
||||
|
||||
switch (in1 ^ pol) {
|
||||
switch (in1 ^ pol_) {
|
||||
|
||||
case 1:
|
||||
switch (in0) {
|
||||
switch (in0 ^ inv_) {
|
||||
case 0:
|
||||
val = 0;
|
||||
str = out0;
|
||||
@@ -64,16 +64,22 @@ void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
|
||||
str = HiZ;
|
||||
break;
|
||||
|
||||
/* The control input is x or z, so the output is H or
|
||||
L, depending on the (possibly inverted) input. This
|
||||
is not the same as X, as it is a combination of the
|
||||
drive strength of the output and HiZ. */
|
||||
default:
|
||||
val = 2;
|
||||
switch (in0) {
|
||||
switch (in0 ^ inv_) {
|
||||
case 0:
|
||||
val = 2;
|
||||
str = outL;
|
||||
break;
|
||||
case 1:
|
||||
val = 2;
|
||||
str = outH;
|
||||
break;
|
||||
default:
|
||||
val = 2;
|
||||
str = outX;
|
||||
break;
|
||||
}
|
||||
@@ -85,6 +91,12 @@ void vvp_bufif1_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
|
||||
|
||||
/*
|
||||
* $Log: bufif.cc,v $
|
||||
* Revision 1.6 2001/12/19 23:43:03 steve
|
||||
* clarify bufif output strenghts.
|
||||
*
|
||||
* Revision 1.5 2001/12/14 06:03:17 steve
|
||||
* Arrange bufif to support notif as well.
|
||||
*
|
||||
* Revision 1.4 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+11
-10
@@ -19,28 +19,29 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: bufif.h,v 1.2 2001/10/31 04:27:46 steve Exp $"
|
||||
#ident "$Id: bufif.h,v 1.3 2001/12/14 06:03:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
||||
class vvp_bufif1_s : public functor_s {
|
||||
class vvp_bufif_s : public functor_s {
|
||||
|
||||
public:
|
||||
vvp_bufif1_s() : pol(0) {}
|
||||
vvp_bufif_s(bool en_invert, bool out_invert)
|
||||
: pol_(en_invert? 1 : 0), inv_(out_invert? 1 : 0) {}
|
||||
|
||||
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
protected:
|
||||
unsigned pol : 1;
|
||||
};
|
||||
|
||||
class vvp_bufif0_s : public vvp_bufif1_s {
|
||||
|
||||
public:
|
||||
vvp_bufif0_s() { pol = 1; }
|
||||
private:
|
||||
unsigned pol_ : 1;
|
||||
unsigned inv_ : 1;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: bufif.h,v $
|
||||
* Revision 1.3 2001/12/14 06:03:17 steve
|
||||
* Arrange bufif to support notif as well.
|
||||
*
|
||||
* Revision 1.2 2001/10/31 04:27:46 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
||||
+53
-94
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.cc,v 1.115 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.120 2002/01/11 05:21:47 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
@@ -481,7 +481,8 @@ void compile_vpi_symbol(const char*label, vpiHandle obj)
|
||||
void compile_init(void)
|
||||
{
|
||||
sym_vpi = new_symbol_table();
|
||||
compile_vpi_symbol("$time", vpip_sim_time());
|
||||
compile_vpi_symbol("$time", vpip_sim_time());
|
||||
compile_vpi_symbol("$stime", vpip_sim_time());
|
||||
|
||||
sym_functors = new_symbol_table();
|
||||
functor_init();
|
||||
@@ -529,6 +530,9 @@ void inputs_connect(vvp_ipoint_t fdx, unsigned argc, struct symb_s*argv)
|
||||
if (strcmp(argv[idx].text, "C<0>") == 0)
|
||||
iobj->set(ifdx, false, 0, St0);
|
||||
|
||||
else if (strcmp(argv[idx].text, "C<we0>") == 0)
|
||||
iobj->set(ifdx, false, 0, We0);
|
||||
|
||||
else if (strcmp(argv[idx].text, "C<pu0>") == 0)
|
||||
iobj->set(ifdx, false, 0, Pu0);
|
||||
|
||||
@@ -538,6 +542,9 @@ void inputs_connect(vvp_ipoint_t fdx, unsigned argc, struct symb_s*argv)
|
||||
else if (strcmp(argv[idx].text, "C<1>") == 0)
|
||||
iobj->set(ifdx, false, 1, St1);
|
||||
|
||||
else if (strcmp(argv[idx].text, "C<we1>") == 0)
|
||||
iobj->set(ifdx, false, 1, We1);
|
||||
|
||||
else if (strcmp(argv[idx].text, "C<pu1>") == 0)
|
||||
iobj->set(ifdx, false, 1, Pu1);
|
||||
|
||||
@@ -600,6 +607,9 @@ static void functor_reference(vvp_ipoint_t *ref, char *lab, unsigned idx)
|
||||
else if (strcmp(lab, "C<pu0>") == 0)
|
||||
*ref = make_const_functor(0,5,5);
|
||||
|
||||
else if (strcmp(lab, "C<we0>") == 0)
|
||||
*ref = make_const_functor(0,3,3);
|
||||
|
||||
else if (strcmp(lab, "C<1>") == 0)
|
||||
*ref = make_const_functor(1,6,6);
|
||||
|
||||
@@ -609,6 +619,9 @@ static void functor_reference(vvp_ipoint_t *ref, char *lab, unsigned idx)
|
||||
else if (strcmp(lab, "C<pu1>") == 0)
|
||||
*ref = make_const_functor(1,5,5);
|
||||
|
||||
else if (strcmp(lab, "C<we1>") == 0)
|
||||
*ref = make_const_functor(1,3,3);
|
||||
|
||||
else if (strcmp(lab, "C<x>") == 0)
|
||||
*ref = make_const_functor(2,6,6);
|
||||
|
||||
@@ -679,6 +692,22 @@ void compile_arith_div(char*label, long wid,
|
||||
make_arith(arith, label, wid, argc, argv);
|
||||
}
|
||||
|
||||
void compile_arith_mod(char*label, long wid,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
assert( wid > 0 );
|
||||
|
||||
if ((long)argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .arith has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
vvp_arith_ *arith = new vvp_arith_mod(wid);
|
||||
|
||||
make_arith(arith, label, wid, argc, argv);
|
||||
}
|
||||
|
||||
void compile_arith_mult(char*label, long wid,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
@@ -858,7 +887,13 @@ void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
|
||||
functor_t obj = 0;
|
||||
|
||||
if (strcmp(type,"tri") == 0) {
|
||||
obj = new resolv_functor_s;
|
||||
obj = new resolv_functor_s(HiZ);
|
||||
|
||||
} else if (strcmp(type,"tri0") == 0) {
|
||||
obj = new resolv_functor_s(Pu0);
|
||||
|
||||
} else if (strcmp(type,"tri1") == 0) {
|
||||
obj = new resolv_functor_s(Pu1);
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "invalid resolver type: %s\n", type);
|
||||
@@ -1344,6 +1379,21 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
||||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.120 2002/01/11 05:21:47 steve
|
||||
* Magic stime object support.
|
||||
*
|
||||
* Revision 1.119 2002/01/06 03:15:13 steve
|
||||
* Support weak functor inputs.
|
||||
*
|
||||
* Revision 1.118 2002/01/03 04:19:02 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.117 2001/12/15 02:11:51 steve
|
||||
* Give tri0 and tri1 their proper strengths.
|
||||
*
|
||||
* Revision 1.116 2001/12/15 01:54:38 steve
|
||||
* Support tri0 and tri1 resolvers.
|
||||
*
|
||||
* Revision 1.115 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
@@ -1370,96 +1420,5 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
||||
*
|
||||
* Revision 1.108 2001/10/16 02:47:37 steve
|
||||
* Add arith/div object.
|
||||
*
|
||||
* Revision 1.107 2001/10/16 01:26:54 steve
|
||||
* Add %div support (Anthony Bybell)
|
||||
*
|
||||
* Revision 1.106 2001/10/14 03:41:58 steve
|
||||
* Handle mode-42 functor init.
|
||||
*
|
||||
* Revision 1.105 2001/10/12 03:00:08 steve
|
||||
* M42 implementation of mode 2 (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.104 2001/10/12 02:53:47 steve
|
||||
* functor lookup includes vpi signal search.
|
||||
*
|
||||
* Revision 1.103 2001/10/11 18:29:21 steve
|
||||
* Propagate initial value of UDP.
|
||||
*
|
||||
* Revision 1.102 2001/10/09 16:57:47 steve
|
||||
* Collect functor reference handling into a single function. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.101 2001/10/09 02:28:16 steve
|
||||
* Add the PMOS and NMOS functor types.
|
||||
*
|
||||
* Revision 1.100 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.99 2001/09/11 01:54:58 steve
|
||||
* initial structural memory propagation (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.98 2001/08/26 22:59:32 steve
|
||||
* Add the assign/x0 and set/x opcodes.
|
||||
*
|
||||
* Revision 1.97 2001/08/25 17:22:32 steve
|
||||
* Only use fvectors for nets and vars.
|
||||
*
|
||||
* Revision 1.96 2001/08/10 04:31:09 steve
|
||||
* Neaten and document the resolv object.
|
||||
*
|
||||
* Revision 1.95 2001/08/10 00:50:50 steve
|
||||
* Make sure arithmetic objects run at time 0.
|
||||
*
|
||||
* Revision 1.94 2001/08/09 19:38:23 steve
|
||||
* Nets (wires) do not use their own functors.
|
||||
* Modifications to propagation of values.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.93 2001/08/08 01:05:06 steve
|
||||
* Initial implementation of vvp_fvectors.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.92 2001/07/30 03:53:01 steve
|
||||
* Initialize initial functor tables.
|
||||
*
|
||||
* Revision 1.91 2001/07/28 03:12:39 steve
|
||||
* Support C<su0> and C<su1> special symbols.
|
||||
*
|
||||
* Revision 1.90 2001/07/26 03:13:51 steve
|
||||
* Make the -M flag add module search paths.
|
||||
*
|
||||
* Revision 1.89 2001/07/22 00:04:50 steve
|
||||
* Add the load/x instruction for bit selects.
|
||||
*
|
||||
* Revision 1.88 2001/07/19 04:40:55 steve
|
||||
* Add support for the delayx opcode.
|
||||
*
|
||||
* Revision 1.87 2001/07/11 04:43:57 steve
|
||||
* support postpone of $systask parameters. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.86 2001/07/07 02:57:33 steve
|
||||
* Add the .shift/r functor.
|
||||
*
|
||||
* Revision 1.85 2001/07/06 05:02:43 steve
|
||||
* Properly initialize unconnected shift inputs.
|
||||
*
|
||||
* Revision 1.84 2001/07/06 04:46:44 steve
|
||||
* Add structural left shift (.shift/l)
|
||||
*
|
||||
* Revision 1.83 2001/06/30 23:03:16 steve
|
||||
* support fast programming by only writing the bits
|
||||
* that are listed in the input file.
|
||||
*
|
||||
* Revision 1.82 2001/06/30 21:07:26 steve
|
||||
* Support non-const right shift (unsigned).
|
||||
*
|
||||
* Revision 1.81 2001/06/23 18:26:26 steve
|
||||
* Add the %shiftl/i0 instruction.
|
||||
*
|
||||
* Revision 1.80 2001/06/23 01:04:07 steve
|
||||
* Allow forward references of task scopes. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.79 2001/06/19 03:01:10 steve
|
||||
* Add structural EEQ gates (Stephan Boettcher)
|
||||
*/
|
||||
|
||||
|
||||
+11
-2
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.h,v 1.38 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.40 2002/01/03 04:19:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
@@ -73,7 +73,8 @@ extern void compile_vpi_time_precision(long pre);
|
||||
* to existing functors to manage the linking.
|
||||
*/
|
||||
extern void compile_functor(char*label, char*type,
|
||||
vvp_delay_t delay,
|
||||
vvp_delay_t delay, unsigned ostr0,
|
||||
unsigned ostr1,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
|
||||
|
||||
@@ -96,6 +97,8 @@ extern void compile_force(char*label, struct symb_s signal,
|
||||
*/
|
||||
extern void compile_arith_div(char*label, long width,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_arith_mod(char*label, long width,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_arith_mult(char*label, long width,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_arith_sum(char*label, long width,
|
||||
@@ -222,6 +225,12 @@ extern void compile_net(char*label, char*name,
|
||||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.40 2002/01/03 04:19:02 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.39 2001/12/14 02:04:49 steve
|
||||
* Support strength syntax on functors.
|
||||
*
|
||||
* Revision 1.38 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
@@ -10,6 +10,22 @@ AC_EXEEXT
|
||||
AC_MINGW32
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
if test "$LEX" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable flex found. ***"
|
||||
echo " Please install the 'flex' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(YACC,bison,none)
|
||||
if test "$YACC" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable bison found. ***"
|
||||
echo " Please install the 'bison' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_ARG_ENABLE(vvp-debug, vvp-debug -- interactive debugger for VVP runtime.,
|
||||
|
||||
+6
-11
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: debug.cc,v 1.7 2001/09/15 18:27:05 steve Exp $"
|
||||
#ident "$Id: debug.cc,v 1.8 2001/12/18 05:32:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -71,7 +71,7 @@ static void cmd_fbreak(unsigned argc, char*argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
fp->breakpoint = 1;
|
||||
fp->break_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,15 +92,7 @@ static void cmd_functor(unsigned argc, char*argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("0x%x: out pointer = 0x%x\n", fnc, fp->out);
|
||||
printf("0x%x: input values = %c (%02x) %c (%02x)"
|
||||
" %c (%02x) %c (%02x)\n", fnc,
|
||||
bitval_tab[fp->ival&3], fp->istr[0],
|
||||
bitval_tab[(fp->ival>>2)&3], fp->istr[1],
|
||||
bitval_tab[(fp->ival>>4)&3], fp->istr[2],
|
||||
bitval_tab[(fp->ival>>6)&3], fp->istr[3]);
|
||||
printf("0x%x: out value = %c (%02x)\n", fnc,
|
||||
bitval_tab[fp->oval], fp->ostr);
|
||||
fp->debug_print(fnc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +165,9 @@ void breakpoint(void)
|
||||
#endif
|
||||
/*
|
||||
* $Log: debug.cc,v $
|
||||
* Revision 1.8 2001/12/18 05:32:11 steve
|
||||
* Improved functor debug dumps.
|
||||
*
|
||||
* Revision 1.7 2001/09/15 18:27:05 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
|
||||
+31
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: draw_tt.c,v 1.11 2001/11/06 03:07:22 steve Exp $"
|
||||
#ident "$Id: draw_tt.c,v 1.12 2002/01/12 04:02:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
@@ -122,6 +122,32 @@ static void draw_BUF(void)
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
static void draw_BUFZ(void)
|
||||
{
|
||||
unsigned i0, i1, i2, i3;
|
||||
|
||||
printf("const unsigned char ft_BUFZ[64] = {");
|
||||
|
||||
for (i3 = 0 ; i3 < 4 ; i3 += 1)
|
||||
for (i2 = 0 ; i2 < 4 ; i2 += 1) {
|
||||
printf("\n ");
|
||||
for (i1 = 0 ; i1 < 4 ; i1 += 1) {
|
||||
unsigned idx = (i3 << 4) | (i2 << 2) | i1;
|
||||
unsigned char byte = 0;
|
||||
|
||||
for (i0 = 0 ; i0 < 4 ; i0 += 1) {
|
||||
unsigned val = i0;
|
||||
|
||||
byte |= val << (i0*2);
|
||||
}
|
||||
|
||||
printf("0x%02x, ", byte);
|
||||
}
|
||||
}
|
||||
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
static void draw_BUFIF0(void)
|
||||
{
|
||||
unsigned i0, i1, i2, i3;
|
||||
@@ -599,6 +625,7 @@ main()
|
||||
draw_BUF();
|
||||
draw_BUFIF0();
|
||||
draw_BUFIF1();
|
||||
draw_BUFZ();
|
||||
draw_PMOS();
|
||||
draw_NMOS();
|
||||
draw_MUXZ();
|
||||
@@ -616,6 +643,9 @@ main()
|
||||
|
||||
/*
|
||||
* $Log: draw_tt.c,v $
|
||||
* Revision 1.12 2002/01/12 04:02:16 steve
|
||||
* Support the BUFZ logic device.
|
||||
*
|
||||
* Revision 1.11 2001/11/06 03:07:22 steve
|
||||
* Code rearrange. (Stephan Boettcher)
|
||||
*
|
||||
|
||||
+27
-4
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: event.cc,v 1.2 2001/11/16 04:22:27 steve Exp $"
|
||||
#ident "$Id: event.cc,v 1.4 2002/01/24 04:17:46 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "event.h"
|
||||
@@ -39,6 +39,10 @@ event_functor_s::event_functor_s(edge_t e)
|
||||
event_functor_s::~event_functor_s()
|
||||
{}
|
||||
|
||||
/*
|
||||
* Receive a value into an event functor, whether an edge or event/or.
|
||||
* Detect edges, if any, then schedule awakened threads.
|
||||
*/
|
||||
void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
|
||||
{
|
||||
old_ival = ival;
|
||||
@@ -49,6 +53,10 @@ void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
|
||||
|
||||
bool edge_p = true;
|
||||
|
||||
/* If there is an edge detect lookup table, then use the
|
||||
old input and new input to detect whether this is the
|
||||
requested edge. If there is no edge table, then any
|
||||
set is a match. */
|
||||
if (edge) {
|
||||
|
||||
unsigned pp = ipoint_port(ptr);
|
||||
@@ -60,14 +68,23 @@ void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
|
||||
edge_p = ((edge>>val) & 1) != 0;
|
||||
}
|
||||
|
||||
/* If we detect an edge, then schedule any threads that
|
||||
are attached to this event, then propagate the
|
||||
positive detect to the output.
|
||||
|
||||
Note that only other events (notably event/or
|
||||
functors) can be connected to event outputs. */
|
||||
|
||||
if (edge_p) {
|
||||
vthread_t tmp = threads;
|
||||
threads = 0;
|
||||
vthread_schedule_list(tmp);
|
||||
|
||||
if (out)
|
||||
// only one output? Why not propagate?
|
||||
schedule_assign(out, 0, 0);
|
||||
if (out) {
|
||||
functor_set(out, 0, St0, true);
|
||||
}
|
||||
// only one output? Why not propagate?
|
||||
//schedule_assign(out, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,6 +148,12 @@ void compile_event(char*label, char*type,
|
||||
|
||||
/*
|
||||
* $Log: event.cc,v $
|
||||
* Revision 1.4 2002/01/24 04:17:46 steve
|
||||
* Spelling in comment.
|
||||
*
|
||||
* Revision 1.3 2001/12/29 23:59:06 steve
|
||||
* push events through event/or lists.
|
||||
*
|
||||
* Revision 1.2 2001/11/16 04:22:27 steve
|
||||
* include stdlib.h for portability.
|
||||
*
|
||||
|
||||
+54
-83
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.cc,v 1.35 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.38 2002/01/06 17:50:50 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
functor_t **functor_list = 0x0;
|
||||
static unsigned functor_count = 0;
|
||||
static unsigned functors_allocated = 0;
|
||||
static unsigned functor_chunk_count = 0;
|
||||
|
||||
/*
|
||||
* This function initializes the functor address space by creating the
|
||||
@@ -60,6 +60,11 @@ void functor_init(void)
|
||||
functor_allocate(1);
|
||||
}
|
||||
|
||||
unsigned functor_limit()
|
||||
{
|
||||
return functor_count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate normally is just a matter of incrementing the functor_count
|
||||
* and returning a pointer to the next unallocated functor. However,
|
||||
@@ -71,26 +76,27 @@ vvp_ipoint_t functor_allocate(unsigned wid)
|
||||
vvp_ipoint_t idx = functor_count*4;
|
||||
functor_count += wid;
|
||||
|
||||
if (functor_count > functors_allocated*functor_chunks) {
|
||||
if (functor_count > functor_chunk_count*functor_chunk_size) {
|
||||
|
||||
// enlarge the list of chunks
|
||||
unsigned fa = (functor_count + functor_chunks - 1)/functor_chunks;
|
||||
unsigned fa = (functor_count + functor_chunk_size - 1)
|
||||
/ functor_chunk_size;
|
||||
|
||||
functor_list = (functor_t **)
|
||||
realloc(functor_list, fa*sizeof(functor_t*));
|
||||
assert(functor_list);
|
||||
|
||||
// allocate the chunks of functor pointers.
|
||||
while (fa > functors_allocated) {
|
||||
while (fa > functor_chunk_count) {
|
||||
|
||||
functor_list[functors_allocated] = (functor_t *)
|
||||
malloc(functor_chunks * sizeof(functor_t));
|
||||
assert(functor_list[functors_allocated]);
|
||||
functor_list[functor_chunk_count] = (functor_t *)
|
||||
malloc(functor_chunk_size * sizeof(functor_t));
|
||||
assert(functor_list[functor_chunk_count]);
|
||||
|
||||
memset(functor_list[functors_allocated],
|
||||
0,
|
||||
functor_chunks * sizeof(functor_t));
|
||||
memset(functor_list[functor_chunk_count], 0,
|
||||
functor_chunk_size * sizeof(functor_t));
|
||||
|
||||
functors_allocated += 1;
|
||||
functor_chunk_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +105,8 @@ vvp_ipoint_t functor_allocate(unsigned wid)
|
||||
|
||||
void functor_define(vvp_ipoint_t point, functor_t obj)
|
||||
{
|
||||
unsigned index1 = point/4/functor_chunks;
|
||||
unsigned index2 = (point/4) % functor_chunks;
|
||||
unsigned index1 = point/4/functor_chunk_size;
|
||||
unsigned index2 = (point/4) % functor_chunk_size;
|
||||
functor_list[index1][index2] = obj;
|
||||
}
|
||||
|
||||
@@ -122,7 +128,7 @@ functor_s::functor_s()
|
||||
cstr = StX;
|
||||
inhibit = 0;
|
||||
#if defined(WITH_DEBUG)
|
||||
breakpoint = 0;
|
||||
break_flag = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -169,8 +175,41 @@ void extra_inputs_functor_s::set(vvp_ipoint_t i, bool push,
|
||||
edge_inputs_functor_s::~edge_inputs_functor_s()
|
||||
{}
|
||||
|
||||
#ifdef WITH_DEBUG
|
||||
# include <stdio.h>
|
||||
static const char bitval_tab[4] = { '0', '1', 'x', 'z' };
|
||||
|
||||
void functor_s::debug_print(vvp_ipoint_t fnc)
|
||||
{
|
||||
printf("0x%x: out pointer =", fnc);
|
||||
vvp_ipoint_t cur = out;
|
||||
while (cur) {
|
||||
printf(" 0x%x", cur);
|
||||
functor_t tmp = functor_index(cur);
|
||||
cur = tmp->port[cur&3];
|
||||
}
|
||||
printf("\n");
|
||||
printf("0x%x: input values = %c %c %c %c\n", fnc,
|
||||
bitval_tab[ival&3],
|
||||
bitval_tab[(ival>>2)&3],
|
||||
bitval_tab[(ival>>4)&3],
|
||||
bitval_tab[(ival>>6)&3]);
|
||||
printf("0x%x: out value = %c (%02x)\n", fnc,
|
||||
bitval_tab[get_oval()], get_ostr());
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.38 2002/01/06 17:50:50 steve
|
||||
* Support scope for functors. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.37 2001/12/18 05:32:11 steve
|
||||
* Improved functor debug dumps.
|
||||
*
|
||||
* Revision 1.36 2001/12/14 01:59:28 steve
|
||||
* Better variable names for functor chunks.
|
||||
*
|
||||
* Revision 1.35 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
@@ -197,73 +236,5 @@ edge_inputs_functor_s::~edge_inputs_functor_s()
|
||||
*
|
||||
* Revision 1.28 2001/10/27 03:43:56 steve
|
||||
* Propagate functor push, to make assign better.
|
||||
*
|
||||
* Revision 1.27 2001/10/12 03:00:09 steve
|
||||
* M42 implementation of mode 2 (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.26 2001/08/08 01:05:06 steve
|
||||
* Initial implementation of vvp_fvectors.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.25 2001/07/30 03:53:01 steve
|
||||
* Initialize initial functor tables.
|
||||
*
|
||||
* Revision 1.24 2001/07/16 18:06:01 steve
|
||||
* Initialize allocated functors (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.23 2001/06/21 22:54:12 steve
|
||||
* Support cbValueChange callbacks.
|
||||
*
|
||||
* Revision 1.22 2001/05/31 04:12:43 steve
|
||||
* Make the bufif0 and bufif1 gates strength aware,
|
||||
* and accurately propagate strengths of outputs.
|
||||
*
|
||||
* Revision 1.21 2001/05/30 03:02:35 steve
|
||||
* Propagate strength-values instead of drive strengths.
|
||||
*
|
||||
* Revision 1.20 2001/05/12 20:38:06 steve
|
||||
* A resolver that understands some simple strengths.
|
||||
*
|
||||
* Revision 1.19 2001/05/09 04:23:18 steve
|
||||
* Now that the interactive debugger exists,
|
||||
* there is no use for the output dump.
|
||||
*
|
||||
* Revision 1.18 2001/05/09 02:53:25 steve
|
||||
* Implement the .resolv syntax.
|
||||
*
|
||||
* Revision 1.17 2001/05/08 23:32:26 steve
|
||||
* Add to the debugger the ability to view and
|
||||
* break on functors.
|
||||
*
|
||||
* Add strengths to functors at compile time,
|
||||
* and Make functors pass their strengths as they
|
||||
* propagate their output.
|
||||
*
|
||||
* Revision 1.16 2001/05/06 03:51:37 steve
|
||||
* Regularize the mode-42 functor handling.
|
||||
*
|
||||
* Revision 1.15 2001/05/03 04:54:33 steve
|
||||
* Fix handling of a mode 1 functor that feeds into a
|
||||
* mode 2 functor. Feed the result only if the event
|
||||
* is triggered, and do pass to the output even if no
|
||||
* threads are waiting.
|
||||
*
|
||||
* Revision 1.14 2001/04/26 15:52:22 steve
|
||||
* Add the mode-42 functor concept to UDPs.
|
||||
*
|
||||
* Revision 1.13 2001/04/24 02:23:59 steve
|
||||
* Support for UDP devices in VVP (Stephen Boettcher)
|
||||
*
|
||||
* Revision 1.12 2001/04/18 04:21:23 steve
|
||||
* Put threads into scopes.
|
||||
*
|
||||
* Revision 1.11 2001/04/14 05:10:56 steve
|
||||
* support the .event/or statement.
|
||||
*
|
||||
* Revision 1.10 2001/04/03 03:18:34 steve
|
||||
* support functor_set push for blocking assignment.
|
||||
*
|
||||
* Revision 1.9 2001/03/31 19:29:23 steve
|
||||
* Fix compilation warnings.
|
||||
*/
|
||||
|
||||
|
||||
+30
-7
@@ -19,11 +19,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.h,v 1.40 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.44 2002/01/06 17:50:50 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "pointers.h"
|
||||
# include "delay.h"
|
||||
#ifdef ENABLE_VVP_DEBUG
|
||||
# include "debug.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The vvp_ipoint_t is an integral type that is 32bits. The low 2 bits
|
||||
@@ -88,9 +91,11 @@ enum strength_e {
|
||||
Su0 = 0x77, /* Su0-Su0 */
|
||||
St0 = 0x66, /* St0-St0 */
|
||||
Pu0 = 0x55, /* Pu0-Pu0 */
|
||||
We0 = 0x33, /* We0-We0 */
|
||||
Su1 = 0x77|0x88, /* Su1 - Su1 */
|
||||
St1 = 0x66|0x88, /* St1 - St1 */
|
||||
Pu1 = 0x55|0x88, /* Pu1 - Pu1 */
|
||||
We1 = 0x33|0x88, /* We1 - We1 */
|
||||
StX = 0x66|0x80, /* St0 - St1 */
|
||||
};
|
||||
|
||||
@@ -112,6 +117,11 @@ extern void functor_init(void);
|
||||
*/
|
||||
extern vvp_ipoint_t functor_allocate(unsigned wid);
|
||||
|
||||
/*
|
||||
** Return the number of allocated functors
|
||||
*/
|
||||
extern unsigned functor_limit();
|
||||
|
||||
/*
|
||||
* Given an ipoint_t pointer, return a C pointer to the functor. This
|
||||
* is like a pointer dereference. The point parameter must have been
|
||||
@@ -119,12 +129,12 @@ extern vvp_ipoint_t functor_allocate(unsigned wid);
|
||||
*/
|
||||
|
||||
extern functor_t **functor_list;
|
||||
static const unsigned functor_chunks = 0x400;
|
||||
static const unsigned functor_chunk_size = 0x400;
|
||||
|
||||
inline static functor_t functor_index(vvp_ipoint_t point)
|
||||
{
|
||||
unsigned index1 = point/4/functor_chunks;
|
||||
unsigned index2 = (point/4) % functor_chunks;
|
||||
unsigned index1 = point/4/functor_chunk_size;
|
||||
unsigned index2 = (point/4) % functor_chunk_size;
|
||||
|
||||
return functor_list[index1][index2];
|
||||
}
|
||||
@@ -174,7 +184,8 @@ struct functor_s {
|
||||
public:
|
||||
#if defined(WITH_DEBUG)
|
||||
/* True if this functor triggers a breakpoint. */
|
||||
unsigned breakpoint : 1;
|
||||
unsigned break_flag : 1;
|
||||
virtual void debug_print(vvp_ipoint_t fnc);
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -220,7 +231,7 @@ inline void functor_s::propagate(unsigned val, unsigned str, bool push)
|
||||
}
|
||||
|
||||
#if defined(WITH_DEBUG)
|
||||
if (breakpoint)
|
||||
if (break_flag)
|
||||
breakpoint();
|
||||
#endif
|
||||
}
|
||||
@@ -299,7 +310,7 @@ void functor_set(vvp_ipoint_t ptr, unsigned val, unsigned str, bool push = true)
|
||||
fp->set(ptr, push, val, str);
|
||||
|
||||
#if defined(WITH_DEBUG)
|
||||
if (fp->breakpoint)
|
||||
if (fp->break_flag)
|
||||
breakpoint();
|
||||
#endif
|
||||
}
|
||||
@@ -375,6 +386,18 @@ extern vvp_fvector_t vvp_fvector_continuous_new(unsigned size, vvp_ipoint_t p);
|
||||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.44 2002/01/06 17:50:50 steve
|
||||
* Support scope for functors. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.43 2002/01/06 03:15:13 steve
|
||||
* Support weak functor inputs.
|
||||
*
|
||||
* Revision 1.42 2001/12/18 05:32:11 steve
|
||||
* Improved functor debug dumps.
|
||||
*
|
||||
* Revision 1.41 2001/12/14 01:59:28 steve
|
||||
* Better variable names for functor chunks.
|
||||
*
|
||||
* Revision 1.40 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+5
-2
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.3 2001/05/22 02:14:47 steve Exp $"
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.4 2002/01/23 04:54:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
@@ -49,7 +49,7 @@ inline const char *dlerror(void)
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_NOW); }
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{ return dlsym(dll, nm); }
|
||||
@@ -77,6 +77,9 @@ inline const char*dlerror(void)
|
||||
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.4 2002/01/23 04:54:38 steve
|
||||
* Load modules with RTLD_LAZY
|
||||
*
|
||||
* Revision 1.3 2001/05/22 02:14:47 steve
|
||||
* Update the mingw build to not require cygwin files.
|
||||
*
|
||||
|
||||
+5
-1
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: lexor.lex,v 1.28 2001/11/01 03:00:19 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.29 2002/01/03 04:19:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
@@ -67,6 +67,7 @@
|
||||
|
||||
/* These are some keywords that are recognized. */
|
||||
".arith/div" { return K_ARITH_DIV; }
|
||||
".arith/mod" { return K_ARITH_MOD; }
|
||||
".arith/mult" { return K_ARITH_MULT; }
|
||||
".arith/sub" { return K_ARITH_SUB; }
|
||||
".arith/sum" { return K_ARITH_SUM; }
|
||||
@@ -150,6 +151,9 @@ int yywrap()
|
||||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.29 2002/01/03 04:19:02 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.28 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
|
||||
+38
-15
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: logic.cc,v 1.4 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: logic.cc,v 1.7 2002/01/12 04:02:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "logic.h"
|
||||
@@ -37,9 +37,14 @@
|
||||
* to 4 inputs.
|
||||
*/
|
||||
|
||||
inline table_functor_s::table_functor_s(truth_t t)
|
||||
: table(t)
|
||||
{}
|
||||
table_functor_s::table_functor_s(truth_t t, unsigned str0, unsigned str1)
|
||||
: table(t)
|
||||
{
|
||||
assert(str0 <= 7);
|
||||
assert(str1 <= 7);
|
||||
odrive0 = str0;
|
||||
odrive1 = str1;
|
||||
}
|
||||
|
||||
table_functor_s::~table_functor_s()
|
||||
{}
|
||||
@@ -63,25 +68,28 @@ void table_functor_s::set(vvp_ipoint_t ptr, bool push, unsigned v, unsigned)
|
||||
*/
|
||||
|
||||
void compile_functor(char*label, char*type,
|
||||
vvp_delay_t delay,
|
||||
vvp_delay_t delay, unsigned ostr0, unsigned ostr1,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
functor_t obj;
|
||||
|
||||
if (strcmp(type, "OR") == 0) {
|
||||
obj = new table_functor_s(ft_OR);
|
||||
obj = new table_functor_s(ft_OR, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "AND") == 0) {
|
||||
obj = new table_functor_s(ft_AND);
|
||||
obj = new table_functor_s(ft_AND, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "BUF") == 0) {
|
||||
obj = new table_functor_s(ft_BUF);
|
||||
obj = new table_functor_s(ft_BUF, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "BUFIF0") == 0) {
|
||||
obj = new vvp_bufif0_s;
|
||||
obj = new vvp_bufif_s(true,false);
|
||||
|
||||
} else if (strcmp(type, "BUFIF1") == 0) {
|
||||
obj = new vvp_bufif1_s;
|
||||
obj = new vvp_bufif_s(false,false);
|
||||
|
||||
} else if (strcmp(type, "BUFZ") == 0) {
|
||||
obj = new table_functor_s(ft_BUFZ, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "PMOS") == 0) {
|
||||
obj = new vvp_pmos_s;
|
||||
@@ -102,19 +110,25 @@ void compile_functor(char*label, char*type,
|
||||
obj = new table_functor_s(ft_EEQ);
|
||||
|
||||
} else if (strcmp(type, "NAND") == 0) {
|
||||
obj = new table_functor_s(ft_NAND);
|
||||
obj = new table_functor_s(ft_NAND, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "NOR") == 0) {
|
||||
obj = new table_functor_s(ft_NOR);
|
||||
obj = new table_functor_s(ft_NOR, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "NOT") == 0) {
|
||||
obj = new table_functor_s(ft_NOT);
|
||||
obj = new table_functor_s(ft_NOT, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "NOTIF0") == 0) {
|
||||
obj = new vvp_bufif_s(true,true);
|
||||
|
||||
} else if (strcmp(type, "NOTIF1") == 0) {
|
||||
obj = new vvp_bufif_s(false,true);
|
||||
|
||||
} else if (strcmp(type, "XNOR") == 0) {
|
||||
obj = new table_functor_s(ft_XNOR);
|
||||
obj = new table_functor_s(ft_XNOR, ostr0, ostr1);
|
||||
|
||||
} else if (strcmp(type, "XOR") == 0) {
|
||||
obj = new table_functor_s(ft_XOR);
|
||||
obj = new table_functor_s(ft_XOR, ostr0, ostr1);
|
||||
|
||||
} else {
|
||||
yyerror("invalid functor type.");
|
||||
@@ -141,6 +155,15 @@ void compile_functor(char*label, char*type,
|
||||
|
||||
/*
|
||||
* $Log: logic.cc,v $
|
||||
* Revision 1.7 2002/01/12 04:02:16 steve
|
||||
* Support the BUFZ logic device.
|
||||
*
|
||||
* Revision 1.6 2001/12/14 06:03:17 steve
|
||||
* Arrange bufif to support notif as well.
|
||||
*
|
||||
* Revision 1.5 2001/12/14 02:04:49 steve
|
||||
* Support strength syntax on functors.
|
||||
*
|
||||
* Revision 1.4 2001/12/06 03:31:24 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+15
-3
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: logic.h,v 1.1 2001/11/06 03:07:22 steve Exp $"
|
||||
#ident "$Id: logic.h,v 1.3 2002/01/12 04:02:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
@@ -28,11 +28,16 @@
|
||||
* Table driven functor. oval = table[ival];
|
||||
*/
|
||||
|
||||
struct table_functor_s: public functor_s {
|
||||
class table_functor_s: public functor_s {
|
||||
|
||||
public:
|
||||
typedef const unsigned char *truth_t;
|
||||
explicit table_functor_s(truth_t t);
|
||||
explicit table_functor_s(truth_t t, unsigned str0 =6, unsigned str1 =6);
|
||||
virtual ~table_functor_s();
|
||||
|
||||
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
|
||||
private:
|
||||
truth_t table;
|
||||
};
|
||||
|
||||
@@ -42,6 +47,7 @@ extern const unsigned char ft_AND[];
|
||||
extern const unsigned char ft_BUF[];
|
||||
extern const unsigned char ft_BUFIF0[];
|
||||
extern const unsigned char ft_BUFIF1[];
|
||||
extern const unsigned char ft_BUFZ[];
|
||||
extern const unsigned char ft_PMOS[];
|
||||
extern const unsigned char ft_NMOS[];
|
||||
extern const unsigned char ft_MUXZ[];
|
||||
@@ -56,6 +62,12 @@ extern const unsigned char ft_var[];
|
||||
|
||||
/*
|
||||
* $Log: logic.h,v $
|
||||
* Revision 1.3 2002/01/12 04:02:16 steve
|
||||
* Support the BUFZ logic device.
|
||||
*
|
||||
* Revision 1.2 2001/12/14 02:04:49 steve
|
||||
* Support strength syntax on functors.
|
||||
*
|
||||
* Revision 1.1 2001/11/06 03:07:22 steve
|
||||
* Code rearrange. (Stephan Boettcher)
|
||||
*
|
||||
|
||||
+8
-2
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: main.cc,v 1.21 2001/10/20 01:03:42 steve Exp $"
|
||||
#ident "$Id: main.cc,v 1.22 2002/01/09 03:15:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -125,6 +125,7 @@ int main(int argc, char*argv[])
|
||||
struct rusage cycles[3];
|
||||
const char *logfile_name = 0x0;
|
||||
FILE *logfile = 0x0;
|
||||
extern void vpi_set_vlog_info(int, char**);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* In the Windows world, we get the first module path
|
||||
@@ -206,9 +207,11 @@ int main(int argc, char*argv[])
|
||||
}
|
||||
|
||||
vpi_mcd_init(logfile);
|
||||
|
||||
|
||||
vvp_vpi_init();
|
||||
|
||||
vpi_set_vlog_info(argc, argv);
|
||||
|
||||
compile_init();
|
||||
|
||||
for (unsigned idx = 0 ; idx < module_cnt ; idx += 1)
|
||||
@@ -256,6 +259,9 @@ int main(int argc, char*argv[])
|
||||
|
||||
/*
|
||||
* $Log: main.cc,v $
|
||||
* Revision 1.22 2002/01/09 03:15:23 steve
|
||||
* Add vpi_get_vlog_info support.
|
||||
*
|
||||
* Revision 1.21 2001/10/20 01:03:42 steve
|
||||
* Print memory usage information if requested (Stephan Boettcher)
|
||||
*
|
||||
|
||||
+33
-1
@@ -18,7 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: memory.cc,v 1.14 2001/12/06 03:31:24 steve Exp $"
|
||||
#ident "$Id: memory.cc,v 1.15 2002/01/31 04:28:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
@@ -63,6 +63,10 @@ struct vvp_memory_index_s
|
||||
{
|
||||
int first; // first memory address
|
||||
unsigned size; // number of valid addresses
|
||||
|
||||
// Added to correctly support vpiLeftRange and vpiRightRange
|
||||
int left;
|
||||
int right;
|
||||
};
|
||||
|
||||
struct vvp_memory_port_s : public functor_s
|
||||
@@ -95,6 +99,30 @@ unsigned memory_root(vvp_memory_t mem, unsigned ix)
|
||||
return mem->a_idx[ix].first;
|
||||
}
|
||||
|
||||
unsigned memory_left_range(vvp_memory_t mem, unsigned ix)
|
||||
{
|
||||
if (ix >= mem->a_idxs)
|
||||
return 0;
|
||||
return mem->a_idx[ix].left;
|
||||
}
|
||||
|
||||
unsigned memory_right_range(vvp_memory_t mem, unsigned ix)
|
||||
{
|
||||
if (ix >= mem->a_idxs)
|
||||
return 0;
|
||||
return mem->a_idx[ix].right;
|
||||
}
|
||||
|
||||
unsigned memory_word_left_range(vvp_memory_t mem)
|
||||
{
|
||||
return mem->msb;
|
||||
}
|
||||
|
||||
unsigned memory_word_right_range(vvp_memory_t mem)
|
||||
{
|
||||
return mem->lsb;
|
||||
}
|
||||
|
||||
char *memory_name(vvp_memory_t mem)
|
||||
{
|
||||
return mem->name;
|
||||
@@ -146,6 +174,10 @@ void memory_new(vvp_memory_t mem, char *name, int msb, int lsb,
|
||||
vvp_memory_index_t x = mem->a_idx + i;
|
||||
int msw = *(idx++);
|
||||
int lsw = *(idx++);
|
||||
|
||||
x->left = msw;
|
||||
x->right = lsw;
|
||||
|
||||
if (msw > lsw) {
|
||||
x->size = msw - lsw + 1;
|
||||
x->first = lsw;
|
||||
|
||||
+8
-1
@@ -20,7 +20,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: memory.h,v 1.4 2001/10/31 04:27:47 steve Exp $"
|
||||
#ident "$Id: memory.h,v 1.5 2002/01/31 04:28:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "pointers.h"
|
||||
@@ -52,6 +52,10 @@ unsigned memory_size(vvp_memory_t mem);
|
||||
char *memory_name(vvp_memory_t mem);
|
||||
unsigned memory_data_width(vvp_memory_t mem);
|
||||
unsigned memory_root(vvp_memory_t mem, unsigned ix = 0);
|
||||
unsigned memory_left_range(vvp_memory_t mem, unsigned ix = 0);
|
||||
unsigned memory_right_range(vvp_memory_t mem, unsigned ix = 0);
|
||||
unsigned memory_word_left_range(vvp_memory_t mem);
|
||||
unsigned memory_word_right_range(vvp_memory_t mem);
|
||||
|
||||
/*
|
||||
** Access to the memory symbol table.
|
||||
@@ -61,6 +65,9 @@ vvp_memory_t memory_create(char *label);
|
||||
|
||||
/*
|
||||
* $Log: memory.h,v $
|
||||
* Revision 1.5 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
* Revision 1.4 2001/10/31 04:27:47 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
||||
+5
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* $Id: opcodes.txt,v 1.31 2001/11/01 03:00:19 steve Exp $
|
||||
* $Id: opcodes.txt,v 1.32 2002/01/26 02:08:07 steve Exp $
|
||||
*/
|
||||
|
||||
|
||||
@@ -379,6 +379,10 @@ This sets the bit of a variable functor, the address calculated by
|
||||
using the index register <idx> (0, 1, 2 or 3) to index the functor
|
||||
address of <var-label>.
|
||||
|
||||
If the index value in index register <idx> is <0 (for example if
|
||||
%ix/get converted an unknown value into the register) then the set is
|
||||
not performed.
|
||||
|
||||
|
||||
* %shiftl/i0 <bit>, <wid>
|
||||
|
||||
|
||||
+23
-6
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: parse.y,v 1.41 2001/12/06 03:31:25 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.43 2002/01/03 04:19:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
@@ -57,7 +57,8 @@ extern FILE*yyin;
|
||||
};
|
||||
|
||||
|
||||
%token K_ARITH_DIV K_ARITH_MULT K_ARITH_SUB K_ARITH_SUM K_CMP_GE K_CMP_GT
|
||||
%token K_ARITH_DIV K_ARITH_MOD K_ARITH_MULT K_ARITH_SUB K_ARITH_SUM
|
||||
%token K_CMP_GE K_CMP_GT
|
||||
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S
|
||||
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD
|
||||
%token K_UDP K_UDP_C K_UDP_S
|
||||
@@ -119,13 +120,18 @@ program
|
||||
statement
|
||||
|
||||
/* Functor statements define functors. The functor must have a
|
||||
label and a type name, and may have operands. */
|
||||
label and a type name, and may have operands. The functor may
|
||||
also have a delay specification and output strengths. */
|
||||
|
||||
: T_LABEL K_FUNCTOR T_SYMBOL delay ',' symbols ';'
|
||||
{ compile_functor($1, $3, $4, $6.cnt, $6.vect); }
|
||||
{ compile_functor($1, $3, $4, 6, 6, $6.cnt, $6.vect); }
|
||||
|
||||
| T_LABEL K_FUNCTOR T_SYMBOL delay ',' T_NUMBER ';'
|
||||
{ compile_functor($1, $3, $4, 0, 0); }
|
||||
| T_LABEL K_FUNCTOR T_SYMBOL delay
|
||||
'[' T_NUMBER T_NUMBER ']' ',' symbols ';'
|
||||
{ unsigned str0 = $6;
|
||||
unsigned str1 = $7;
|
||||
compile_functor($1, $3, $4, str0, str1, $10.cnt, $10.vect);
|
||||
}
|
||||
|
||||
|
||||
/* UDP statements define or instantiate UDPs. Definitions take a
|
||||
@@ -177,6 +183,11 @@ statement
|
||||
compile_arith_div($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_ARITH_MOD T_NUMBER ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_arith_mod($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_ARITH_MULT T_NUMBER ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_arith_mult($1, $3, obj.cnt, obj.vect);
|
||||
@@ -527,6 +538,12 @@ int compile_design(const char*path)
|
||||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.43 2002/01/03 04:19:02 steve
|
||||
* Add structural modulus support down to vvp.
|
||||
*
|
||||
* Revision 1.42 2001/12/14 02:04:49 steve
|
||||
* Support strength syntax on functors.
|
||||
*
|
||||
* Revision 1.41 2001/12/06 03:31:25 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+37
-2
@@ -17,11 +17,12 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: resolv.cc,v 1.9 2001/12/06 03:31:25 steve Exp $"
|
||||
#ident "$Id: resolv.cc,v 1.12 2001/12/18 05:32:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "resolv.h"
|
||||
# include "schedule.h"
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* A signal value is unambiguous if the top 4 bits and the bottom 4
|
||||
@@ -132,6 +133,16 @@ static unsigned blend(unsigned a, unsigned b)
|
||||
return res;
|
||||
}
|
||||
|
||||
resolv_functor_s::resolv_functor_s(unsigned char pull)
|
||||
{
|
||||
istr[0]=istr[1]=istr[2]=istr[3]=StX;
|
||||
hiz_ = pull;
|
||||
}
|
||||
|
||||
resolv_functor_s::~resolv_functor_s()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve the strength values of the inputs, two at a time. Pairs of
|
||||
* inputs are resolved with the blend function, and the final value is
|
||||
@@ -142,7 +153,8 @@ void resolv_functor_s::set(vvp_ipoint_t i, bool push, unsigned, unsigned str)
|
||||
unsigned pp = ipoint_port(i);
|
||||
istr[pp] = str;
|
||||
|
||||
unsigned sval = istr[0];
|
||||
unsigned sval = hiz_;
|
||||
sval = blend(sval, istr[0]);
|
||||
sval = blend(sval, istr[1]);
|
||||
sval = blend(sval, istr[2]);
|
||||
sval = blend(sval, istr[3]);
|
||||
@@ -173,8 +185,31 @@ void resolv_functor_s::set(vvp_ipoint_t i, bool push, unsigned, unsigned str)
|
||||
put_ostr(val, sval, false);
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG
|
||||
# include <stdio.h>
|
||||
|
||||
static const char bitval_tab[4] = { '0', '1', 'x', 'z' };
|
||||
void resolv_functor_s::debug_print(vvp_ipoint_t fnc)
|
||||
{
|
||||
printf("0x%x: Resolver tied to %02x\n", fnc, hiz_);
|
||||
printf("0x%x: input strengths = %02x %02x %02x %02x\n", fnc,
|
||||
istr[0], istr[1], istr[2], istr[3]);
|
||||
functor_s::debug_print(fnc);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* $Log: resolv.cc,v $
|
||||
* Revision 1.12 2001/12/18 05:32:11 steve
|
||||
* Improved functor debug dumps.
|
||||
*
|
||||
* Revision 1.11 2001/12/15 02:11:51 steve
|
||||
* Give tri0 and tri1 their proper strengths.
|
||||
*
|
||||
* Revision 1.10 2001/12/15 01:54:39 steve
|
||||
* Support tri0 and tri1 resolvers.
|
||||
*
|
||||
* Revision 1.9 2001/12/06 03:31:25 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+27
-2
@@ -19,21 +19,46 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: resolv.h,v 1.3 2001/10/31 04:27:47 steve Exp $"
|
||||
#ident "$Id: resolv.h,v 1.6 2001/12/18 05:32:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "functor.h"
|
||||
|
||||
/*
|
||||
* This functor type resolves its inputs using the verilog method of
|
||||
* combining signals, and outputs that resolved value. The puller
|
||||
* value is also blended with the result. This helps with the
|
||||
* implementation of tri0 and tri1, which have pull constants attached.
|
||||
*/
|
||||
class resolv_functor_s: public functor_s {
|
||||
|
||||
public:
|
||||
resolv_functor_s() { istr[0]=istr[1]=istr[2]=istr[3]=StX; }
|
||||
explicit resolv_functor_s(unsigned char hiz_value);
|
||||
~resolv_functor_s();
|
||||
|
||||
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
|
||||
#ifdef WITH_DEBUG
|
||||
void debug_print(vvp_ipoint_t fnc);
|
||||
#endif
|
||||
|
||||
private:
|
||||
unsigned char istr[4];
|
||||
unsigned char hiz_;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: resolv.h,v $
|
||||
* Revision 1.6 2001/12/18 05:32:11 steve
|
||||
* Improved functor debug dumps.
|
||||
*
|
||||
* Revision 1.5 2001/12/15 02:11:51 steve
|
||||
* Give tri0 and tri1 their proper strengths.
|
||||
*
|
||||
* Revision 1.4 2001/12/15 01:54:39 steve
|
||||
* Support tri0 and tri1 resolvers.
|
||||
*
|
||||
* Revision 1.3 2001/10/31 04:27:47 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
||||
+11
-5
@@ -18,7 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: udp.cc,v 1.14 2001/12/06 03:31:25 steve Exp $"
|
||||
#ident "$Id: udp.cc,v 1.16 2002/01/20 23:27:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "udp.h"
|
||||
@@ -74,7 +74,7 @@ typedef unsigned int udp_vec_t;
|
||||
struct udp_table_entry_s
|
||||
{
|
||||
udp_vec_t not_0; // all inputs that must not be 0
|
||||
udp_vec_t not_1x; // all inputs that bust not be 1 or x
|
||||
udp_vec_t not_1x; // all inputs that must not be 1, x
|
||||
unsigned char edge_idx; // input index of the edge
|
||||
unsigned char edge_type; // permissible transitions. 0: no edge.
|
||||
unsigned char out; // new output, 0..2
|
||||
@@ -129,9 +129,9 @@ unsigned char vvp_udp_s::propagate(functor_t fu, vvp_ipoint_t uix)
|
||||
if (sequ)
|
||||
{
|
||||
if (edge_type == 0)
|
||||
return fu->get();
|
||||
return fu->get_oval();
|
||||
invec <<= 2;
|
||||
invec |= (fu->get() & 3);
|
||||
invec |= (fu->get_oval() & 3);
|
||||
}
|
||||
|
||||
udp_vec_t inx = invec & 0xaaaaaaaaU; // all 'x'/'z'
|
||||
@@ -163,7 +163,7 @@ unsigned char vvp_udp_s::propagate(functor_t fu, vvp_ipoint_t uix)
|
||||
}
|
||||
|
||||
if (ret>2)
|
||||
ret = fu->get();
|
||||
ret = fu->get_oval();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -350,6 +350,12 @@ void vvp_udp_s::compile_row_(udp_table_entry_t row, char *rchr)
|
||||
|
||||
/*
|
||||
* $Log: udp.cc,v $
|
||||
* Revision 1.16 2002/01/20 23:27:51 steve
|
||||
* return calculated oval from UDP (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.15 2002/01/06 17:35:01 steve
|
||||
* Feedback output, not propagated output. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.14 2001/12/06 03:31:25 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
|
||||
+220
-5
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_const.cc,v 1.7 2001/09/15 18:27:05 steve Exp $"
|
||||
#ident "$Id: vpi_const.cc,v 1.11 2002/02/03 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
@@ -29,21 +29,40 @@
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
static char buf[4096];
|
||||
|
||||
static int string_get(int code, vpiHandle ref)
|
||||
{
|
||||
struct __vpiStringConst*rfp;
|
||||
|
||||
switch (code) {
|
||||
case vpiSize:
|
||||
rfp = (struct __vpiStringConst*)ref;
|
||||
assert(ref->vpi_type->type_code == vpiConstant);
|
||||
|
||||
//fprintf(stderr, "String:|%s|, Length: %d\n", rfp->value, strlen(rfp->value));
|
||||
return strlen(rfp->value)*8;
|
||||
|
||||
case vpiSigned:
|
||||
return 0;
|
||||
|
||||
case vpiConstType:
|
||||
return vpiStringConst;
|
||||
return vpiStringConst;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
fprintf(stderr, "vvp error: get %d not supported "
|
||||
"by vpiStringConst\n", code);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void string_value(vpiHandle ref, p_vpi_value vp)
|
||||
{
|
||||
int size;
|
||||
unsigned uint_value;
|
||||
char *cp;
|
||||
|
||||
struct __vpiStringConst*rfp = (struct __vpiStringConst*)ref;
|
||||
assert(ref->vpi_type->type_code == vpiConstant);
|
||||
|
||||
@@ -54,7 +73,76 @@ static void string_value(vpiHandle ref, p_vpi_value vp)
|
||||
vp->format = vpiStringVal;
|
||||
break;
|
||||
|
||||
case vpiDecStrVal:
|
||||
size = strlen(rfp->value);
|
||||
if (size > 4){
|
||||
// We only support standard integers. Ignore other bytes...
|
||||
size = 4;
|
||||
fprintf(stderr, "Warning (vpi_const.cc): %%d on constant strings only looks "
|
||||
"at first 4 bytes!\n");
|
||||
}
|
||||
|
||||
uint_value = 0;
|
||||
for(int i=0; i<size;i ++){
|
||||
uint_value <<=8;
|
||||
uint_value += (unsigned char)(rfp->value[i]);
|
||||
}
|
||||
|
||||
sprintf(buf, "%u", uint_value);
|
||||
|
||||
vp->format = vpiDecStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiBinStrVal:
|
||||
size = strlen(rfp->value);
|
||||
if (size*8 > (int)(sizeof(buf)/sizeof(char))-1 ){
|
||||
// Avoid overflow of 'buf'
|
||||
// 4096 should be sufficient for most cases though. ;-)
|
||||
size = (sizeof(buf)/sizeof(char)-2)/8;
|
||||
}
|
||||
|
||||
cp = buf;
|
||||
for(int i=0; i<size;i ++){
|
||||
for(int bit=7;bit>=0; bit--){
|
||||
*cp++ = "01"[ (rfp->value[i]>>bit)&1 ];
|
||||
}
|
||||
}
|
||||
*cp = 0;
|
||||
|
||||
vp->format = vpiBinStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiHexStrVal:
|
||||
size = strlen(rfp->value);
|
||||
if (size*2 > (int)(sizeof(buf)/sizeof(char))-1 ){
|
||||
// Avoid overflow of 'buf'
|
||||
// 4096 should be sufficient for most cases though. ;-)
|
||||
size = (sizeof(buf)/sizeof(char)-2)/2;
|
||||
}
|
||||
|
||||
cp = buf;
|
||||
for(int i=0; i<size;i++){
|
||||
for(int nibble=1;nibble>=0; nibble--){
|
||||
*cp++ = "0123456789abcdef"[ (rfp->value[i]>>(nibble*4))&15 ];
|
||||
}
|
||||
}
|
||||
*cp = 0;
|
||||
|
||||
vp->format = vpiHexStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiOctStrVal:
|
||||
fprintf(stderr, "ERROR (vpi_const.cc): %%o display of constant strings not yet implemented\n");
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "ERROR (vpi_const.cc): vp->format: %d\n", vp->format);
|
||||
assert(0);
|
||||
|
||||
vp->format = vpiSuppressVal;
|
||||
break;
|
||||
}
|
||||
@@ -87,18 +175,27 @@ vpiHandle vpip_make_string_const(char*text)
|
||||
|
||||
static int binary_get(int code, vpiHandle ref)
|
||||
{
|
||||
struct __vpiBinaryConst*rfp = (struct __vpiBinaryConst*)ref;
|
||||
assert(ref->vpi_type->type_code == vpiConstant);
|
||||
|
||||
switch (code) {
|
||||
case vpiConstType:
|
||||
return vpiBinaryConst;
|
||||
|
||||
case vpiSigned: // FIXME: Need to get signed flag right.
|
||||
return 0;
|
||||
|
||||
case vpiSize:
|
||||
return rfp->nbits;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "vvp error: get %d not supported "
|
||||
"by vpiBinaryConst\n", code);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static char buf[4096];
|
||||
|
||||
static void binary_value(vpiHandle ref, p_vpi_value vp)
|
||||
{
|
||||
@@ -109,6 +206,7 @@ static void binary_value(vpiHandle ref, p_vpi_value vp)
|
||||
|
||||
case vpiObjTypeVal:
|
||||
case vpiBinStrVal:
|
||||
assert(rfp->nbits < sizeof buf);
|
||||
for (unsigned idx = 0 ; idx < rfp->nbits ; idx += 1) {
|
||||
unsigned nibble = idx/4;
|
||||
unsigned shift = 2 * (idx%4);
|
||||
@@ -121,6 +219,14 @@ static void binary_value(vpiHandle ref, p_vpi_value vp)
|
||||
vp->format = vpiBinStrVal;
|
||||
break;
|
||||
|
||||
case vpiDecStrVal:
|
||||
vpip_bits_to_dec_str(rfp->bits, rfp->nbits,
|
||||
buf, sizeof buf, 0);
|
||||
|
||||
vp->value.str = buf;
|
||||
vp->format = vpiDecStrVal;
|
||||
break;
|
||||
|
||||
case vpiIntVal: {
|
||||
unsigned val = 0;
|
||||
|
||||
@@ -195,8 +301,117 @@ vpiHandle vpip_make_binary_const(unsigned wid, char*bits)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int dec_get(int code, vpiHandle ref)
|
||||
{
|
||||
|
||||
switch (code) {
|
||||
case vpiConstType:
|
||||
return vpiDecConst;
|
||||
|
||||
case vpiSigned:
|
||||
return 1;
|
||||
|
||||
case vpiSize:
|
||||
return 32;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "vvp error: get %d not supported "
|
||||
"by vpiDecConst\n", code);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dec_value(vpiHandle ref, p_vpi_value vp)
|
||||
{
|
||||
struct __vpiDecConst*rfp = (struct __vpiDecConst*)ref;
|
||||
char* cp;
|
||||
assert(ref->vpi_type->type_code == vpiConstant);
|
||||
|
||||
switch (vp->format) {
|
||||
|
||||
case vpiObjTypeVal:
|
||||
case vpiIntVal: {
|
||||
vp->value.integer = rfp->value;
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiDecStrVal:
|
||||
sprintf(buf, "%d", rfp->value);
|
||||
|
||||
vp->format = vpiDecStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiBinStrVal:
|
||||
cp = buf;
|
||||
for(int bit=31; bit<=0;bit--){
|
||||
*cp++ = "01"[ (rfp->value>>bit)&1 ];
|
||||
}
|
||||
*cp = 0;
|
||||
|
||||
vp->format = vpiBinStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiHexStrVal:
|
||||
sprintf(buf, "%08x", rfp->value);
|
||||
|
||||
vp->format = vpiHexStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiOctStrVal:
|
||||
sprintf(buf, "%011x", rfp->value);
|
||||
|
||||
vp->format = vpiOctStrVal;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "vvp error (vpi_const.cc): format %d not supported "
|
||||
"by vpiDecConst\n", vp->format);
|
||||
vp->format = vpiSuppressVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct __vpirt vpip_dec_rt = {
|
||||
vpiConstant,
|
||||
dec_get,
|
||||
0,
|
||||
dec_value,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
vpiHandle vpip_make_dec_const(int value)
|
||||
{
|
||||
struct __vpiDecConst*obj;
|
||||
|
||||
obj = (struct __vpiDecConst*)
|
||||
malloc(sizeof (struct __vpiDecConst));
|
||||
obj->base.vpi_type = &vpip_dec_rt;
|
||||
obj->value = value;
|
||||
|
||||
return &(obj->base);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: vpi_const.cc,v $
|
||||
* Revision 1.11 2002/02/03 01:01:51 steve
|
||||
* Use Larrys bits-to-decimal-string code.
|
||||
*
|
||||
* Revision 1.10 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
* Revision 1.8 2002/01/15 03:21:18 steve
|
||||
* Support DesSTrVal for binary constants.
|
||||
*
|
||||
* Revision 1.7 2001/09/15 18:27:05 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
|
||||
+14
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vpi_mcd.cc,v 1.5 2001/07/16 18:40:19 steve Exp $"
|
||||
#ident "$Id: vpi_mcd.cc,v 1.6 2002/01/04 02:26:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
@@ -107,6 +107,10 @@ extern "C" int vpi_mcd_vprintf(unsigned int mcd, const char*fmt, va_list ap)
|
||||
int len;
|
||||
int rc;
|
||||
|
||||
// don't print to stderr twice
|
||||
if (mcd_table[1].fp == mcd_table[2].fp && (mcd&6) == 6)
|
||||
mcd &= ~2;
|
||||
|
||||
rc = len = 0;
|
||||
for(i = 0; i < 31; i++) {
|
||||
if( (mcd>>i) & 1) {
|
||||
@@ -123,6 +127,15 @@ extern "C" int vpi_mcd_vprintf(unsigned int mcd, const char*fmt, va_list ap)
|
||||
return len;
|
||||
}
|
||||
|
||||
extern "C" int vpi_mcd_printf(unsigned int mcd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int r = vpi_mcd_vprintf(mcd,fmt,ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
int vpi_mcd_fputc(unsigned int mcd, unsigned char x)
|
||||
{
|
||||
int i;
|
||||
|
||||
+53
-4
@@ -27,7 +27,7 @@
|
||||
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vpi_memory.cc,v 1.3 2001/12/07 23:23:05 steve Exp $"
|
||||
#ident "$Id: vpi_memory.cc,v 1.4 2002/01/31 04:28:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
@@ -40,6 +40,8 @@ struct __vpiMemoryWord {
|
||||
struct __vpiHandle base;
|
||||
struct __vpiMemory*mem;
|
||||
int index;
|
||||
struct __vpiDecConst*left_range;
|
||||
struct __vpiDecConst*right_range;
|
||||
};
|
||||
|
||||
struct __vpiMemory {
|
||||
@@ -47,8 +49,28 @@ struct __vpiMemory {
|
||||
/* The signal has a name (this points to static memory.) */
|
||||
struct __vpiMemoryWord word;
|
||||
vvp_memory_t mem;
|
||||
struct __vpiDecConst*left_range;
|
||||
struct __vpiDecConst*right_range;
|
||||
|
||||
};
|
||||
|
||||
static vpiHandle memory_get_handle(int code, vpiHandle obj)
|
||||
{
|
||||
struct __vpiMemory*rfp = (struct __vpiMemory*)obj;
|
||||
|
||||
assert(obj->vpi_type->type_code==vpiMemory);
|
||||
|
||||
switch(code){
|
||||
case vpiLeftRange:
|
||||
return &(rfp->left_range->base);
|
||||
|
||||
case vpiRightRange:
|
||||
return &(rfp->right_range->base);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpi_memory_get(int code, vpiHandle ref)
|
||||
{
|
||||
struct __vpiMemory*rfp = (struct __vpiMemory*)ref;
|
||||
@@ -139,6 +161,25 @@ static vpiHandle memory_index(vpiHandle ref, int index)
|
||||
return &rfp->word.base;
|
||||
}
|
||||
|
||||
//==============================
|
||||
|
||||
static vpiHandle memory_word_get_handle(int code, vpiHandle obj)
|
||||
{
|
||||
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)obj;
|
||||
|
||||
assert(obj->vpi_type->type_code==vpiMemoryWord);
|
||||
|
||||
switch(code){
|
||||
case vpiLeftRange:
|
||||
return &(rfp->left_range->base);
|
||||
|
||||
case vpiRightRange:
|
||||
return &(rfp->right_range->base);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memory_word_get(int code, vpiHandle ref)
|
||||
{
|
||||
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref;
|
||||
@@ -234,7 +275,7 @@ static const struct __vpirt vpip_memory_rt = {
|
||||
memory_get_str,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
memory_get_handle,
|
||||
memory_iterate,
|
||||
memory_index,
|
||||
};
|
||||
@@ -245,7 +286,7 @@ static const struct __vpirt vpip_memory_word_rt = {
|
||||
0,
|
||||
memory_word_get_value,
|
||||
memory_word_put,
|
||||
0,
|
||||
memory_word_get_handle,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
@@ -256,15 +297,23 @@ vpiHandle vpip_make_memory(vvp_memory_t mem)
|
||||
malloc(sizeof(struct __vpiMemory));
|
||||
|
||||
obj->base.vpi_type = &vpip_memory_rt;
|
||||
obj->word.base.vpi_type = &vpip_memory_word_rt;
|
||||
obj->mem = mem;
|
||||
obj->left_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_left_range(mem));
|
||||
obj->right_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_right_range(mem));
|
||||
|
||||
obj->word.base.vpi_type = &vpip_memory_word_rt;
|
||||
obj->word.mem = obj;
|
||||
obj->word.left_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_word_left_range(mem));
|
||||
obj->word.right_range = (struct __vpiDecConst*)vpip_make_dec_const(memory_word_right_range(mem));
|
||||
|
||||
return &(obj->base);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vpi_memory.cc,v $
|
||||
* Revision 1.4 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
* Revision 1.3 2001/12/07 23:23:05 steve
|
||||
* vpi_put_value of vpiIntVal for memory words.
|
||||
*
|
||||
|
||||
+44
-1
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_priv.cc,v 1.10 2001/10/31 04:27:47 steve Exp $"
|
||||
#ident "$Id: vpi_priv.cc,v 1.12 2002/01/09 03:15:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_priv.h"
|
||||
@@ -87,6 +87,27 @@ void vpi_get_time(vpiHandle obj, s_vpi_time*vp)
|
||||
vp->low = schedule_simtime();
|
||||
}
|
||||
|
||||
static s_vpi_vlog_info vpi_vlog_info;
|
||||
|
||||
int vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p)
|
||||
{
|
||||
if (vlog_info_p != 0)
|
||||
{
|
||||
*vlog_info_p = vpi_vlog_info;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vpi_set_vlog_info(int argc, char** argv)
|
||||
{
|
||||
vpi_vlog_info.product = "Icarus Verilog";
|
||||
vpi_vlog_info.version = "$Name: $";
|
||||
vpi_vlog_info.argc = argc;
|
||||
vpi_vlog_info.argv = argv;
|
||||
}
|
||||
|
||||
void vpi_get_value(vpiHandle expr, s_vpi_value*vp)
|
||||
{
|
||||
if (expr->vpi_type->vpi_get_value_) {
|
||||
@@ -122,8 +143,24 @@ vpiHandle vpi_handle(int type, vpiHandle ref)
|
||||
* the specified reference. It is up to the iterate_ method to
|
||||
* allocate a properly formed iterator.
|
||||
*/
|
||||
static vpiHandle vpi_iterate_global(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case vpiModule:
|
||||
return vpip_make_root_iterator();
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vpiHandle vpi_iterate(int type, vpiHandle ref)
|
||||
{
|
||||
if (ref == 0)
|
||||
return vpi_iterate_global(type);
|
||||
|
||||
assert(ref->vpi_type->iterate_);
|
||||
return (ref->vpi_type->iterate_)(type, ref);
|
||||
}
|
||||
@@ -154,6 +191,12 @@ extern "C" void vpi_sim_vcontrol(int operation, va_list ap)
|
||||
|
||||
/*
|
||||
* $Log: vpi_priv.cc,v $
|
||||
* Revision 1.12 2002/01/09 03:15:23 steve
|
||||
* Add vpi_get_vlog_info support.
|
||||
*
|
||||
* Revision 1.11 2002/01/06 00:48:39 steve
|
||||
* VPI access to root module scopes.
|
||||
*
|
||||
* Revision 1.10 2001/10/31 04:27:47 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
||||
+40
-1
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_priv.h,v 1.24 2001/10/31 04:27:47 steve Exp $"
|
||||
#ident "$Id: vpi_priv.h,v 1.28 2002/02/03 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
@@ -93,6 +93,7 @@ struct __vpiScope {
|
||||
|
||||
extern struct __vpiScope* vpip_peek_current_scope(void);
|
||||
extern void vpip_attach_to_current_scope(vpiHandle obj);
|
||||
extern vpiHandle vpip_make_root_iterator(void);
|
||||
|
||||
/*
|
||||
* Signals include the variable types (reg, integer, time) and are
|
||||
@@ -182,6 +183,13 @@ struct __vpiBinaryConst {
|
||||
|
||||
vpiHandle vpip_make_binary_const(unsigned wid, char*bits);
|
||||
|
||||
struct __vpiDecConst {
|
||||
struct __vpiHandle base;
|
||||
int value;
|
||||
};
|
||||
|
||||
vpiHandle vpip_make_dec_const(int value);
|
||||
|
||||
/*
|
||||
* This one looks like a constant, but really is a vector in the current
|
||||
* thread.
|
||||
@@ -239,8 +247,39 @@ vpiHandle vpip_sim_time(void);
|
||||
extern int vpip_get_time_precision(void);
|
||||
extern void vpip_set_time_precision(int pres);
|
||||
|
||||
|
||||
/*
|
||||
** Functions defined in vpi_scope.cc, to keep track of functor scope.
|
||||
*/
|
||||
|
||||
extern vpiHandle ipoint_get_scope(vvp_ipoint_t ipt);
|
||||
extern void functor_set_scope(vpiHandle scope);
|
||||
|
||||
/*
|
||||
* This function is used to make decimal string versions of various
|
||||
* vectors. The input format is an array of bit values (0, 1, 2, 3)
|
||||
* lsb first, and the result is written into buf, without overflowing
|
||||
* nbuf.
|
||||
*/
|
||||
extern unsigned vpip_bits_to_dec_str(const unsigned char *bits,
|
||||
unsigned int nbits,
|
||||
char *buf, unsigned int nbuf,
|
||||
int signed_flag);
|
||||
|
||||
/*
|
||||
* $Log: vpi_priv.h,v $
|
||||
* Revision 1.28 2002/02/03 01:01:51 steve
|
||||
* Use Larrys bits-to-decimal-string code.
|
||||
*
|
||||
* Revision 1.27 2002/01/31 04:28:17 steve
|
||||
* Full support for $readmem ranges (Tom Verbeure)
|
||||
*
|
||||
* Revision 1.26 2002/01/06 17:50:50 steve
|
||||
* Support scope for functors. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.25 2002/01/06 00:48:39 steve
|
||||
* VPI access to root module scopes.
|
||||
*
|
||||
* Revision 1.24 2001/10/31 04:27:47 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
||||
+117
-23
@@ -17,18 +17,27 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_scope.cc,v 1.10 2001/11/02 05:43:11 steve Exp $"
|
||||
#ident "$Id: vpi_scope.cc,v 1.12 2002/01/06 17:50:50 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
# include "vpi_priv.h"
|
||||
# include "symbols.h"
|
||||
# include "functor.h"
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <assert.h>
|
||||
|
||||
static vpiHandle *vpip_root_table_ptr = 0;
|
||||
static unsigned vpip_root_table_cnt = 0;
|
||||
|
||||
vpiHandle vpip_make_root_iterator(void)
|
||||
{
|
||||
return vpip_make_iterator(vpip_root_table_cnt, vpip_root_table_ptr);
|
||||
}
|
||||
|
||||
static char* scope_get_str(int code, vpiHandle obj)
|
||||
{
|
||||
struct __vpiScope*ref = (struct __vpiScope*)obj;
|
||||
@@ -97,6 +106,93 @@ static vpiHandle module_iter(int code, vpiHandle obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Keeping track of functor scope. When the scope changes during
|
||||
** compilation, we record the current number of functors in a list.
|
||||
**
|
||||
** Why are we doing this? The SDF annotator needs this for
|
||||
** INTERCONNECT delays. The INTERCONNECT delay is specified between
|
||||
** a source modules output port and a target module input port, which
|
||||
** are connected with a wire. The vpiSignal for both ports point to
|
||||
** the same functor output, together with all other ports that may be
|
||||
** connected to the same wire. The SDF annotator need to find those
|
||||
** functors which are inside the scope of the target module, which
|
||||
** are driven by the source functor. And even this is only an
|
||||
** aproximation, in case the wire is connected to multiple inputs of
|
||||
** the same module. But those should have the same delays anyway.
|
||||
**
|
||||
*/
|
||||
|
||||
struct functor_scope_s {
|
||||
vpiHandle scope;
|
||||
unsigned start;
|
||||
};
|
||||
|
||||
static struct functor_scope_s * functor_scopes = 0;
|
||||
static unsigned n_functor_scopes = 0;
|
||||
static unsigned a_functor_scopes = 0;
|
||||
|
||||
void functor_set_scope(vpiHandle scope)
|
||||
{
|
||||
unsigned nfun = functor_limit();
|
||||
|
||||
if (n_functor_scopes) {
|
||||
functor_scope_s *last = &functor_scopes[n_functor_scopes - 1];
|
||||
|
||||
if (last->scope == scope) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (last->start == nfun) {
|
||||
last->scope = scope;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
n_functor_scopes += 1;
|
||||
if (n_functor_scopes >= a_functor_scopes) {
|
||||
a_functor_scopes += 512;
|
||||
functor_scopes = (struct functor_scope_s *)
|
||||
realloc(functor_scopes,
|
||||
a_functor_scopes*sizeof(struct functor_scope_s));
|
||||
assert(functor_scopes);
|
||||
}
|
||||
|
||||
functor_scope_s *last = &functor_scopes[n_functor_scopes - 1];
|
||||
last->start = nfun;
|
||||
last->scope = scope;
|
||||
}
|
||||
|
||||
/*
|
||||
** Lockup the scope of a functor.
|
||||
**
|
||||
** Cannot use bserach, since we are not looking for an exact match
|
||||
*/
|
||||
vpiHandle ipoint_get_scope(vvp_ipoint_t ipt)
|
||||
{
|
||||
if (n_functor_scopes == 0)
|
||||
return NULL;
|
||||
|
||||
unsigned fidx = ipt/4;
|
||||
|
||||
unsigned first = 0;
|
||||
unsigned last = n_functor_scopes;
|
||||
while (first < last) {
|
||||
unsigned next = (first+last)/2;
|
||||
functor_scope_s *cur = &functor_scopes[next];
|
||||
|
||||
if (cur->start > fidx)
|
||||
last = next;
|
||||
else if (next == first)
|
||||
break;
|
||||
else
|
||||
first = next;
|
||||
}
|
||||
|
||||
functor_scope_s *cur = &functor_scopes[first];
|
||||
return cur->scope;
|
||||
}
|
||||
|
||||
static const struct __vpirt vpip_scope_module_rt = {
|
||||
vpiModule,
|
||||
0,
|
||||
@@ -175,19 +271,19 @@ void compile_scope_decl(char*label, char*type, char*name, char*parent)
|
||||
struct __vpiScope*scope = new struct __vpiScope;
|
||||
|
||||
switch(type[2]) {
|
||||
case 'd': /* type == module */
|
||||
case 'd': /* type == moDule */
|
||||
scope->base.vpi_type = &vpip_scope_module_rt;
|
||||
break;
|
||||
case 'n': /* type == function */
|
||||
case 'n': /* type == fuNction */
|
||||
scope->base.vpi_type = &vpip_scope_function_rt;
|
||||
break;
|
||||
case 's': /* type == task */
|
||||
case 's': /* type == taSk */
|
||||
scope->base.vpi_type = &vpip_scope_task_rt;
|
||||
break;
|
||||
case 'r': /* type == fork */
|
||||
case 'r': /* type == foRk */
|
||||
scope->base.vpi_type = &vpip_scope_fork_rt;
|
||||
break;
|
||||
case 'g': /* type == begin */
|
||||
case 'g': /* type == beGin */
|
||||
scope->base.vpi_type = &vpip_scope_begin_rt;
|
||||
break;
|
||||
default:
|
||||
@@ -216,13 +312,22 @@ void compile_scope_decl(char*label, char*type, char*name, char*parent)
|
||||
scope->scope = (struct __vpiScope*)obj;
|
||||
} else {
|
||||
scope->scope = 0x0;
|
||||
|
||||
unsigned cnt = vpip_root_table_cnt + 1;
|
||||
vpip_root_table_ptr = (vpiHandle*)
|
||||
realloc(vpip_root_table_ptr, cnt * sizeof(vpiHandle));
|
||||
vpip_root_table_ptr[vpip_root_table_cnt] = &scope->base;
|
||||
vpip_root_table_cnt = cnt;
|
||||
}
|
||||
|
||||
functor_set_scope(¤t_scope->base);
|
||||
}
|
||||
|
||||
void compile_scope_recall(char*symbol)
|
||||
{
|
||||
compile_vpi_lookup((vpiHandle*)¤t_scope, symbol);
|
||||
assert(current_scope);
|
||||
functor_set_scope(¤t_scope->base);
|
||||
}
|
||||
|
||||
struct __vpiScope* vpip_peek_current_scope(void)
|
||||
@@ -238,6 +343,12 @@ void vpip_attach_to_current_scope(vpiHandle obj)
|
||||
|
||||
/*
|
||||
* $Log: vpi_scope.cc,v $
|
||||
* Revision 1.12 2002/01/06 17:50:50 steve
|
||||
* Support scope for functors. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.11 2002/01/06 00:48:39 steve
|
||||
* VPI access to root module scopes.
|
||||
*
|
||||
* Revision 1.10 2001/11/02 05:43:11 steve
|
||||
* Comment the scope type parser.
|
||||
*
|
||||
@@ -252,22 +363,5 @@ void vpip_attach_to_current_scope(vpiHandle obj)
|
||||
*
|
||||
* Revision 1.6 2001/07/11 04:43:57 steve
|
||||
* support postpone of $systask parameters. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/06/10 16:47:49 steve
|
||||
* support scan of scope from VPI.
|
||||
*
|
||||
* Revision 1.4 2001/04/18 04:21:23 steve
|
||||
* Put threads into scopes.
|
||||
*
|
||||
* Revision 1.3 2001/04/03 03:46:14 steve
|
||||
* VPI access time as a decimal string, and
|
||||
* stub vpi access to the scopes.
|
||||
*
|
||||
* Revision 1.2 2001/03/21 05:13:03 steve
|
||||
* Allow var objects as vpiHandle arguments to %vpi_call.
|
||||
*
|
||||
* Revision 1.1 2001/03/18 00:37:55 steve
|
||||
* Add support for vpi scopes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+83
-140
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_signal.cc,v 1.30 2001/12/06 03:31:25 steve Exp $"
|
||||
#ident "$Id: vpi_signal.cc,v 1.33 2002/02/03 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -50,6 +50,23 @@ extern const char hex_digits[256];
|
||||
|
||||
extern const char oct_digits[256];
|
||||
|
||||
/*
|
||||
* The string values need a result buf to hold the results. This
|
||||
* buffer can be reused for that purpose. Whenever I have a need, the
|
||||
* need_result_buf function makes sure that need can be met.
|
||||
*/
|
||||
static char*result_buf = 0;
|
||||
static size_t result_buf_size = 0;
|
||||
static void need_result_buf(size_t cnt)
|
||||
{
|
||||
if (result_buf_size == 0) {
|
||||
result_buf = (char*)malloc(cnt);
|
||||
} else if (result_buf_size < cnt) {
|
||||
result_buf = (char*)realloc(result_buf, cnt);
|
||||
}
|
||||
result_buf_size = cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* implement vpi_get for vpiReg objects.
|
||||
*/
|
||||
@@ -122,7 +139,6 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char buf[4096];
|
||||
|
||||
static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
|
||||
{
|
||||
@@ -130,97 +146,55 @@ static void signal_vpiDecStrVal(struct __vpiSignal*rfp, s_vpi_value*vp)
|
||||
? (rfp->msb - rfp->lsb + 1)
|
||||
: (rfp->lsb - rfp->msb + 1);
|
||||
|
||||
unsigned long val = 0;
|
||||
unsigned count_x = 0, count_z = 0;
|
||||
|
||||
unsigned char*bits = new unsigned char[wid];
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, wid-idx-1);
|
||||
val *= 2;
|
||||
switch (functor_get(fptr)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
val += 1;
|
||||
break;
|
||||
case 2:
|
||||
count_x += 1;
|
||||
break;
|
||||
case 3:
|
||||
count_z += 1;
|
||||
break;
|
||||
}
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
|
||||
bits[idx] = functor_get(fptr);
|
||||
}
|
||||
|
||||
if (count_x == wid) {
|
||||
buf[0] = 'x';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
need_result_buf((wid+2) / 3 + 1);
|
||||
|
||||
if (count_x > 0) {
|
||||
buf[0] = 'X';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
vpip_bits_to_dec_str(bits, wid, result_buf, result_buf_size,
|
||||
rfp->signed_flag);
|
||||
|
||||
if (count_z == wid) {
|
||||
buf[0] = 'z';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_z > 0) {
|
||||
buf[0] = 'Z';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rfp->signed_flag) {
|
||||
long tmp;
|
||||
assert(sizeof(tmp) == sizeof(val));
|
||||
if (val & (1<<(wid-1)) && wid < 8*sizeof(tmp)) {
|
||||
tmp = -1;
|
||||
tmp <<= wid;
|
||||
tmp |= val;
|
||||
} else {
|
||||
tmp = val;
|
||||
}
|
||||
sprintf(buf, "%ld", tmp);
|
||||
|
||||
} else {
|
||||
sprintf(buf, "%lu", val);
|
||||
}
|
||||
delete[]bits;
|
||||
}
|
||||
|
||||
|
||||
static void signal_vpiStringVal(struct __vpiSignal*rfp, s_vpi_value*vp)
|
||||
{
|
||||
char*cp;
|
||||
unsigned idx;
|
||||
unsigned wid = (rfp->msb >= rfp->lsb)
|
||||
? (rfp->msb - rfp->lsb + 1)
|
||||
: (rfp->lsb - rfp->msb + 1);
|
||||
|
||||
assert(wid % 8 == 0);
|
||||
|
||||
cp = buf;
|
||||
for (idx = wid ; idx >= 8 ; idx -= 8) {
|
||||
char tmp = 0;
|
||||
unsigned bdx;
|
||||
/* The result will use a character for each 8 bits of the
|
||||
vector. Add one extra character for the highest bits that
|
||||
don't form an 8 bit group. */
|
||||
need_result_buf(wid/8 + ((wid&7)!=0) + 1);
|
||||
|
||||
for (bdx = 8 ; bdx > 0 ; bdx -= 1) {
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx-8+bdx-1);
|
||||
tmp <<= 1;
|
||||
switch (functor_get(fptr)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
tmp |= 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*cp++ = tmp? tmp : ' ';
|
||||
cp = result_buf;
|
||||
char tmp = 0;
|
||||
int bitnr;
|
||||
for(bitnr=wid-1; bitnr>=0; bitnr--){
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, bitnr);
|
||||
tmp <<= 1;
|
||||
|
||||
switch (functor_get(fptr)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
tmp |= 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((bitnr&7)==0){
|
||||
*cp++ = tmp? tmp : ' ';
|
||||
tmp = 0;
|
||||
}
|
||||
}
|
||||
*cp++ = 0;
|
||||
}
|
||||
@@ -263,18 +237,22 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
break;
|
||||
|
||||
case vpiBinStrVal:
|
||||
need_result_buf(wid+1);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
|
||||
buf[wid-idx-1] = "01xz"[functor_get(fptr)];
|
||||
result_buf[wid-idx-1] = "01xz"[functor_get(fptr)];
|
||||
}
|
||||
buf[wid] = 0;
|
||||
vp->value.str = buf;
|
||||
result_buf[wid] = 0;
|
||||
vp->value.str = result_buf;
|
||||
break;
|
||||
|
||||
case vpiHexStrVal: {
|
||||
unsigned hval, hwid;
|
||||
hwid = (wid + 3) / 4;
|
||||
buf[hwid] = 0;
|
||||
|
||||
need_result_buf(hwid+1);
|
||||
result_buf[hwid] = 0;
|
||||
hval = 0;
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
|
||||
@@ -282,16 +260,16 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
|
||||
if (idx%4 == 3) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = hex_digits[hval];
|
||||
result_buf[hwid] = hex_digits[hval];
|
||||
hval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hwid > 0) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = hex_digits[hval];
|
||||
result_buf[hwid] = hex_digits[hval];
|
||||
unsigned padd = 0;
|
||||
switch(buf[hwid]) {
|
||||
switch(result_buf[hwid]) {
|
||||
case 'X': padd = 2; break;
|
||||
case 'Z': padd = 3; break;
|
||||
}
|
||||
@@ -299,17 +277,19 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
for (unsigned idx = wid % 4; idx < 4; idx += 1) {
|
||||
hval = hval | padd << 2*idx;
|
||||
}
|
||||
buf[hwid] = hex_digits[hval];
|
||||
result_buf[hwid] = hex_digits[hval];
|
||||
}
|
||||
}
|
||||
vp->value.str = buf;
|
||||
vp->value.str = result_buf;
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiOctStrVal: {
|
||||
unsigned hval, hwid;
|
||||
hwid = (wid + 2) / 3;
|
||||
buf[hwid] = 0;
|
||||
|
||||
need_result_buf(hwid+1);
|
||||
result_buf[hwid] = 0;
|
||||
hval = 0;
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
vvp_ipoint_t fptr = vvp_fvector_get(rfp->bits, idx);
|
||||
@@ -317,16 +297,16 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
|
||||
if (idx%3 == 2) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = oct_digits[hval];
|
||||
result_buf[hwid] = oct_digits[hval];
|
||||
hval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hwid > 0) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = oct_digits[hval];
|
||||
result_buf[hwid] = oct_digits[hval];
|
||||
unsigned padd = 0;
|
||||
switch(buf[hwid]) {
|
||||
switch(result_buf[hwid]) {
|
||||
case 'X': padd = 2; break;
|
||||
case 'Z': padd = 3; break;
|
||||
}
|
||||
@@ -334,21 +314,21 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
for (unsigned idx = wid % 3; idx < 3; idx += 1) {
|
||||
hval = hval | padd << 2*idx;
|
||||
}
|
||||
buf[hwid] = oct_digits[hval];
|
||||
result_buf[hwid] = oct_digits[hval];
|
||||
}
|
||||
}
|
||||
vp->value.str = buf;
|
||||
vp->value.str = result_buf;
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiDecStrVal:
|
||||
signal_vpiDecStrVal(rfp, vp);
|
||||
vp->value.str = buf;
|
||||
vp->value.str = result_buf;
|
||||
break;
|
||||
|
||||
case vpiStringVal:
|
||||
signal_vpiStringVal(rfp, vp);
|
||||
vp->value.str = buf;
|
||||
vp->value.str = result_buf;
|
||||
break;
|
||||
|
||||
case vpiVectorVal:
|
||||
@@ -552,6 +532,15 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
|
||||
|
||||
/*
|
||||
* $Log: vpi_signal.cc,v $
|
||||
* Revision 1.33 2002/02/03 01:01:51 steve
|
||||
* Use Larrys bits-to-decimal-string code.
|
||||
*
|
||||
* Revision 1.32 2002/01/09 03:29:12 steve
|
||||
* String prints of non-round vectors (PR378)
|
||||
*
|
||||
* Revision 1.31 2001/12/18 05:31:54 steve
|
||||
* Remove result length restrictions for vpi_get_value.
|
||||
*
|
||||
* Revision 1.30 2001/12/06 03:31:25 steve
|
||||
* Support functor delays for gates and UDP devices.
|
||||
* (Stephan Boettcher)
|
||||
@@ -580,51 +569,5 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
|
||||
* Nets (wires) do not use their own functors.
|
||||
* Modifications to propagation of values.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.22 2001/08/08 01:05:06 steve
|
||||
* Initial implementation of vvp_fvectors.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.21 2001/07/24 01:34:56 steve
|
||||
* Implement string value for signals.
|
||||
*
|
||||
* Revision 1.20 2001/07/16 18:48:07 steve
|
||||
* Properly pad unknow values. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.19 2001/07/13 03:02:34 steve
|
||||
* Rewire signal callback support for fast lookup. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.18 2001/06/29 00:44:56 steve
|
||||
* Properly support signal full names.
|
||||
*
|
||||
* Revision 1.17 2001/06/21 23:05:08 steve
|
||||
* Some documentation of callback behavior.
|
||||
*
|
||||
* Revision 1.16 2001/06/21 22:54:12 steve
|
||||
* Support cbValueChange callbacks.
|
||||
*
|
||||
* Revision 1.15 2001/05/30 03:02:35 steve
|
||||
* Propagate strength-values instead of drive strengths.
|
||||
*
|
||||
* Revision 1.14 2001/05/22 04:08:49 steve
|
||||
* correctly interpret signed decimal values.
|
||||
*
|
||||
* Revision 1.13 2001/05/15 15:09:08 steve
|
||||
* Add the glossary file.
|
||||
*
|
||||
* Revision 1.12 2001/05/14 00:42:32 steve
|
||||
* test width of target with bit size of long.
|
||||
*
|
||||
* Revision 1.11 2001/05/09 04:23:19 steve
|
||||
* Now that the interactive debugger exists,
|
||||
* there is no use for the output dump.
|
||||
*
|
||||
* Revision 1.10 2001/05/08 23:32:26 steve
|
||||
* Add to the debugger the ability to view and
|
||||
* break on functors.
|
||||
*
|
||||
* Add strengths to functors at compile time,
|
||||
* and Make functors pass their strengths as they
|
||||
* propagate their output.
|
||||
*/
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user