Compare commits
240 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
27be6e88bc | |
|
|
918b0a410f | |
|
|
ec85377d13 | |
|
|
a22124a198 | |
|
|
e8bc5aefb4 | |
|
|
ca5d265350 | |
|
|
113312a0c1 | |
|
|
12d5aa08e2 | |
|
|
15702f1b87 | |
|
|
9b5ef0bbb9 | |
|
|
b8d9f19eb0 | |
|
|
8d9f7e2e26 | |
|
|
65326fd6a9 | |
|
|
bb92974839 | |
|
|
7dc473db8d | |
|
|
abc2aa17d2 | |
|
|
c8bffe728a | |
|
|
d134f6f074 | |
|
|
8deb2c0b60 | |
|
|
451783056d | |
|
|
322bbed7c7 | |
|
|
e8bb9b1f76 | |
|
|
f112b77d3b | |
|
|
ddf68ca14c | |
|
|
d8fdcd5a38 | |
|
|
408e25f6bc | |
|
|
3dd2c74ebe | |
|
|
d260052940 | |
|
|
146f64992c | |
|
|
74e2343e52 | |
|
|
b4b9667def | |
|
|
5e401055e8 | |
|
|
e89bce48ed | |
|
|
cf01d1a75f | |
|
|
6df10a082b | |
|
|
22ad8c42bc | |
|
|
f418bea775 | |
|
|
568e601212 | |
|
|
b7e7d3cb04 | |
|
|
8a1543aaaf | |
|
|
c6ba9269bc | |
|
|
3af373667a | |
|
|
d49e44594b | |
|
|
4d3f592b5f | |
|
|
d1e82d3d12 | |
|
|
d70ccb6895 | |
|
|
e34647f79c | |
|
|
24b097ce89 | |
|
|
83ee7e7988 | |
|
|
f33d477166 | |
|
|
3f16d3402a | |
|
|
304a63d8e3 | |
|
|
23d56d8198 | |
|
|
a8f68fe416 | |
|
|
5dc4202929 | |
|
|
281b4edbab | |
|
|
3eb86a2376 | |
|
|
1fb93c0565 | |
|
|
bdb900b25f | |
|
|
28da79dcc3 | |
|
|
bbd61823b9 | |
|
|
0f716d6dca | |
|
|
a44236f8cb | |
|
|
4be2ccb3fa | |
|
|
9f4dc5411f | |
|
|
545d20eba5 | |
|
|
b2159d1e64 | |
|
|
4c8df2a370 | |
|
|
eed0885dd0 | |
|
|
0fc10d0262 | |
|
|
1775c78aa9 | |
|
|
85652e24e0 | |
|
|
eb4fc8fb7b | |
|
|
043b7ae684 | |
|
|
2946f30ffc | |
|
|
5530aea6a3 | |
|
|
40e09cd719 | |
|
|
c67f3b0081 | |
|
|
95254aa27e | |
|
|
468e3bb702 | |
|
|
be8c8a8eb7 | |
|
|
5cae6b64af | |
|
|
f600e774d5 | |
|
|
d16dd26660 | |
|
|
8c04d669f9 | |
|
|
5d2dcfd7f7 | |
|
|
0b3f1e4119 | |
|
|
8bd9fc7128 | |
|
|
1b551aaf94 | |
|
|
a3dda80fb2 | |
|
|
9e9d5ccfdd | |
|
|
07daee9438 | |
|
|
82808d8b5d | |
|
|
c045f51a7f | |
|
|
d72eadb885 | |
|
|
e99f0a8f51 | |
|
|
ed2cb380cd | |
|
|
dc8e941260 | |
|
|
d486b81f23 | |
|
|
59c2f16a5f | |
|
|
1470a061fd | |
|
|
c1333a21ef | |
|
|
04ef0b7d80 | |
|
|
2fc9413d1f | |
|
|
c94bdbcdb0 | |
|
|
1820cd0244 | |
|
|
aa3cbbdf99 | |
|
|
0a9b6f34ae | |
|
|
5c2c5453ac | |
|
|
0c6bb476ea | |
|
|
568924dcb5 | |
|
|
33b3f7bdda | |
|
|
3a04e0a051 | |
|
|
66ae377801 | |
|
|
898db57405 | |
|
|
0fe45b5046 | |
|
|
20cfe99457 | |
|
|
4ec8b38a5c | |
|
|
79add47002 | |
|
|
c429f4c9a7 | |
|
|
7f6a0b652a | |
|
|
9f3f9154eb | |
|
|
498fd06412 | |
|
|
6d3b780791 | |
|
|
a0ec981c50 | |
|
|
930cd598a0 | |
|
|
77adab0f33 | |
|
|
0e3768f829 | |
|
|
22884f2e64 | |
|
|
62da6aca28 | |
|
|
525ebddb0c | |
|
|
521750c007 | |
|
|
85d2833a62 | |
|
|
e2cc258283 | |
|
|
f09cf85c76 | |
|
|
c32de1dba0 | |
|
|
628b866c36 | |
|
|
08dbe801c1 | |
|
|
101810df21 | |
|
|
3877b636df | |
|
|
9d028a63f2 | |
|
|
35e5cea9df | |
|
|
ec510071f1 | |
|
|
7413c533f6 | |
|
|
dde69cebb6 | |
|
|
f942657ad5 | |
|
|
fad1620828 | |
|
|
a9931e7a58 | |
|
|
6cd4adb135 | |
|
|
9643b86ab3 | |
|
|
452eaeaea8 | |
|
|
3a6e2df958 | |
|
|
e73b7e2656 | |
|
|
469ec11190 | |
|
|
e0bbfa512c | |
|
|
94c9af2a5d | |
|
|
9f2e7df0ff | |
|
|
f02b2c9d7a | |
|
|
058dac4290 | |
|
|
ce4e21a962 | |
|
|
065d6bc1e3 | |
|
|
312d09dc1d | |
|
|
faf7f30283 | |
|
|
5d41e98c1f | |
|
|
5e8330a4ff | |
|
|
ef8964c65a | |
|
|
aa42ec381c | |
|
|
c9d4aab9cb | |
|
|
b8bc531f05 | |
|
|
79cb8c883a | |
|
|
27e633410c | |
|
|
7527c466ed | |
|
|
3ea1214160 | |
|
|
782542922d | |
|
|
1f8102c4dc | |
|
|
c4b34e8720 | |
|
|
e494be7cbf | |
|
|
eb0a78e9ce | |
|
|
e80138ec8c | |
|
|
943316c6f6 | |
|
|
52b8ed9077 | |
|
|
fc227aa3e1 | |
|
|
41993815e9 | |
|
|
c5063f5d2f | |
|
|
f28aa11936 | |
|
|
3131fa68b7 | |
|
|
def3809b3f | |
|
|
3429c24a6a | |
|
|
f47627d752 | |
|
|
9468f3d06f | |
|
|
b997de63a5 | |
|
|
f50f06ab4e | |
|
|
d5d03812cd | |
|
|
b6d5a0675e | |
|
|
e63e830d62 | |
|
|
74ca34bd82 | |
|
|
c9d480028e | |
|
|
cc89ba66af | |
|
|
05e6d51004 | |
|
|
ae583204e3 | |
|
|
018476f7cd | |
|
|
bfabeab6b9 | |
|
|
4a3f1a3641 | |
|
|
d97560caa7 | |
|
|
393102d43a | |
|
|
8e97a0e4d4 | |
|
|
4ea789a2d7 | |
|
|
354f7ad920 | |
|
|
f4a6206790 | |
|
|
fd29ba3398 | |
|
|
44fbf60885 | |
|
|
a0d69113c3 | |
|
|
86942ac592 | |
|
|
075f9cbc4b | |
|
|
9dab368880 | |
|
|
5f6027fb66 | |
|
|
53156793fe | |
|
|
4644c220e8 | |
|
|
c30cd9afea | |
|
|
a8f45a18f0 | |
|
|
6828e3e2ea | |
|
|
75eb372adf | |
|
|
3b753fe52b | |
|
|
8c73fa7840 | |
|
|
d310e656c7 | |
|
|
0510367b70 | |
|
|
3e11207a56 | |
|
|
665f31271f | |
|
|
9a2b56675c | |
|
|
c9f38f5ffa | |
|
|
5ea4152162 | |
|
|
327c897d7e | |
|
|
29ebe486b7 | |
|
|
4af0acb3be | |
|
|
8435774c26 | |
|
|
6172748c65 | |
|
|
ca0ae9040a | |
|
|
d9cdbde3f6 | |
|
|
307a97116f | |
|
|
83d2c6dfd1 |
11
LineInfo.cc
11
LineInfo.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: LineInfo.cc,v 1.4 2003/01/17 05:49:03 steve Exp $"
|
#ident "$Id: LineInfo.cc,v 1.4.2.1 2005/08/13 00:45:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -34,12 +34,12 @@ LineInfo::~LineInfo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
string LineInfo::get_line() const
|
std::string LineInfo::get_line() const
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
std::ostringstream buf;
|
||||||
buf << (file_? file_ : "") << ":" << lineno_;
|
buf << (file_? file_ : "") << ":" << lineno_;
|
||||||
|
|
||||||
string res = buf.str();
|
std::string res = buf.str();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,6 +61,9 @@ void LineInfo::set_lineno(unsigned n)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: LineInfo.cc,v $
|
* $Log: LineInfo.cc,v $
|
||||||
|
* Revision 1.4.2.1 2005/08/13 00:45:53 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
* Revision 1.4 2003/01/17 05:49:03 steve
|
* Revision 1.4 2003/01/17 05:49:03 steve
|
||||||
* Use stringstream in place of sprintf.
|
* Use stringstream in place of sprintf.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
LineInfo.h
12
LineInfo.h
|
|
@ -19,11 +19,13 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: LineInfo.h,v 1.7 2003/01/17 05:49:03 steve Exp $"
|
#ident "$Id: LineInfo.h,v 1.7.2.2 2005/08/13 00:45:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class holds line information for an internal object.
|
* This class holds line information for an internal object.
|
||||||
*
|
*
|
||||||
|
|
@ -38,7 +40,7 @@ class LineInfo {
|
||||||
LineInfo();
|
LineInfo();
|
||||||
~LineInfo();
|
~LineInfo();
|
||||||
|
|
||||||
string get_line() const;
|
std::string get_line() const;
|
||||||
|
|
||||||
void set_line(const LineInfo&that);
|
void set_line(const LineInfo&that);
|
||||||
|
|
||||||
|
|
@ -52,6 +54,12 @@ class LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: LineInfo.h,v $
|
* $Log: LineInfo.h,v $
|
||||||
|
* Revision 1.7.2.2 2005/08/13 00:45:53 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
|
* Revision 1.7.2.1 2005/06/14 15:33:54 steve
|
||||||
|
* Fix gcc4 build issues.
|
||||||
|
*
|
||||||
* Revision 1.7 2003/01/17 05:49:03 steve
|
* Revision 1.7 2003/01/17 05:49:03 steve
|
||||||
* Use stringstream in place of sprintf.
|
* Use stringstream in place of sprintf.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
131
Makefile.in
131
Makefile.in
|
|
@ -16,16 +16,16 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.169 2004/10/13 22:01:34 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.169.2.7 2007/05/30 17:48:53 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
# This version string is only used in the version message printed
|
# This string is used as an installation suffix. It modifies certain
|
||||||
# by the compiler. It reflects the assigned version number for the
|
# key install paths/files such that a build and install of Icarus Verilog
|
||||||
# product as a whole. Most components also print the CVS Name: token
|
# with the same $(prefix) but a different $(suffix) will not interfere.
|
||||||
# in order to get a more automatic version stamp as well.
|
# The normal configuratin leaves suffix empty
|
||||||
VERSION = 0.8
|
suffix = @install_suffix@
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
@ -37,7 +37,9 @@ VPATH = $(srcdir)
|
||||||
|
|
||||||
bindir = @bindir@
|
bindir = @bindir@
|
||||||
libdir = @libdir@
|
libdir = @libdir@
|
||||||
includedir = @includedir@
|
# This is actually the directory where we install our own header files.
|
||||||
|
# It is a little different from the generic includedir.
|
||||||
|
includedir = @includedir@/iverilog$(suffix)
|
||||||
mandir = @mandir@
|
mandir = @mandir@
|
||||||
|
|
||||||
libdir64 = @libdir64@
|
libdir64 = @libdir64@
|
||||||
|
|
@ -54,6 +56,8 @@ INSTALL_DATA = @INSTALL_DATA@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
LEX = @LEX@
|
LEX = @LEX@
|
||||||
YACC = @YACC@
|
YACC = @YACC@
|
||||||
|
MAN = @MAN@
|
||||||
|
PS2PDF = @PS2PDF@
|
||||||
|
|
||||||
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
|
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
|
||||||
CXXFLAGS = -Wall @CXXFLAGS@
|
CXXFLAGS = -Wall @CXXFLAGS@
|
||||||
|
|
@ -70,7 +74,7 @@ all: dep ivl@EXEEXT@
|
||||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||||
for dir in ivlpp tgt-verilog tgt-stub; \
|
for dir in ivlpp tgt-verilog tgt-stub; \
|
||||||
do (cd $$dir ; $(MAKE) $@); done
|
do (cd $$dir ; $(MAKE) $@); done
|
||||||
cd driver ; $(MAKE) VERSION=$(VERSION) $@
|
cd driver ; $(MAKE) $@
|
||||||
|
|
||||||
# In the windows world, the installer will need a dosify program to
|
# In the windows world, the installer will need a dosify program to
|
||||||
# dosify text files.
|
# dosify text files.
|
||||||
|
|
@ -103,6 +107,7 @@ distclean: clean
|
||||||
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
||||||
do (cd $$dir ; $(MAKE) $@); done
|
do (cd $$dir ; $(MAKE) $@); done
|
||||||
rm -f Makefile config.status config.log config.cache config.h
|
rm -f Makefile config.status config.log config.cache config.h
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
|
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
|
||||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
|
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
|
||||||
|
|
@ -111,7 +116,7 @@ O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||||
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
|
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
|
||||||
elab_sig.o emit.o eval.o eval_attrib.o \
|
elab_sig.o emit.o eval.o eval_attrib.o \
|
||||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||||
load_module.o netlist.o netmisc.o net_assign.o \
|
load_module.o netlist.o NetLatch.o netmisc.o net_assign.o \
|
||||||
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||||
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
|
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
|
||||||
|
|
@ -136,7 +141,7 @@ ivl@EXEEXT@: $O ivl.def
|
||||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||||
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
|
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
|
||||||
--output-lib libivl.a --output-exp ivl.exp
|
--output-lib libivl.a --output-exp ivl.exp
|
||||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||||
else
|
else
|
||||||
ivl@EXEEXT@: $O
|
ivl@EXEEXT@: $O
|
||||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||||
|
|
@ -150,9 +155,13 @@ all: dep iverilog-vpi
|
||||||
|
|
||||||
iverilog-vpi: iverilog-vpi.sh
|
iverilog-vpi: iverilog-vpi.sh
|
||||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||||
-e 's;@INCLUDEDIR@;@includedir@;' \
|
-e 's;@SUFFIX@;$(suffix);' \
|
||||||
|
-e 's;@IVCC@;$(CC);' \
|
||||||
|
-e 's;@IVCXX@;$(CXX);' \
|
||||||
|
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
|
||||||
-e 's;@LIBDIR64@;@libdir64@;' \
|
-e 's;@LIBDIR64@;@libdir64@;' \
|
||||||
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
|
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
|
||||||
|
-e 's;@INCLUDEDIR@;$(includedir);' \
|
||||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||||
chmod +x $@
|
chmod +x $@
|
||||||
endif
|
endif
|
||||||
|
|
@ -161,7 +170,7 @@ dep:
|
||||||
mkdir dep
|
mkdir dep
|
||||||
|
|
||||||
%.o: %.cc
|
%.o: %.cc
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o $(DEBUGFLAGS)
|
||||||
mv $*.d dep/$*.d
|
mv $*.d dep/$*.d
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -169,10 +178,8 @@ lexor.o: lexor.cc parse.h
|
||||||
|
|
||||||
parse.o: parse.cc
|
parse.o: parse.cc
|
||||||
|
|
||||||
parse.cc: $(srcdir)/parse.y
|
parse.cc parse.h: $(srcdir)/parse.y
|
||||||
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||||
|
|
||||||
parse.h: parse.cc
|
|
||||||
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
|
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
|
||||||
|
|
||||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||||
|
|
@ -187,46 +194,55 @@ lexor_keyword.cc: lexor_keyword.gperf
|
||||||
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||||
|
|
||||||
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
|
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
|
||||||
man -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
|
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
|
||||||
|
|
||||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||||
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
|
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
|
||||||
|
|
||||||
|
# Build and install the iverilog-vpi.pdf only if there is a man
|
||||||
|
# program *and* a ps2pdf program.
|
||||||
ifeq (@WIN32@,yes)
|
ifeq (@WIN32@,yes)
|
||||||
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
|
ifeq ($(MAN),none)
|
||||||
INSTALL_DOCDIR = $(mandir)/man1
|
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||||
all: dep iverilog-vpi.pdf
|
|
||||||
else
|
else
|
||||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
ifeq ($(PS2PDF),none)
|
||||||
|
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||||
|
else
|
||||||
|
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||||
|
all: dep iverilog-vpi.pdf
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
INSTALL_DOCDIR = $(mandir)/man1
|
||||||
|
else
|
||||||
|
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||||
INSTALL_DOCDIR = $(mandir)/man1
|
INSTALL_DOCDIR = $(mandir)/man1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (@MINGW32@,yes)
|
ifeq (@MINGW32@,yes)
|
||||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
|
WIN32_INSTALL =
|
||||||
else
|
else
|
||||||
WIN32_INSTALL = $(bindir)/iverilog-vpi
|
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
|
XNF_INSTALL = $(libdir)/ivl$(suffix)/xnf.conf $(libdir)/ivl$(suffix)/xnf-s.conf
|
||||||
|
|
||||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) $(XNF_INSTALL)
|
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) $(XNF_INSTALL)
|
||||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||||
for dir in vpi ivlpp driver; \
|
for dir in vpi ivlpp driver; \
|
||||||
do (cd $$dir ; $(MAKE) $@); done
|
do (cd $$dir ; $(MAKE) $@); done
|
||||||
|
|
||||||
$(bindir)/iverilog-vpi: ./iverilog-vpi
|
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
|
||||||
$(INSTALL_SCRIPT) ./iverilog-vpi $(bindir)/iverilog-vpi
|
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)
|
||||||
|
|
||||||
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
|
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
|
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@
|
||||||
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
|
|
||||||
|
|
||||||
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
|
$(libdir)/ivl$(suffix)/xnf-s.conf: $(srcdir)/xnf-s.conf
|
||||||
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl/xnf-s.conf
|
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl$(suffix)/xnf-s.conf
|
||||||
|
|
||||||
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
|
$(libdir)/ivl$(suffix)/xnf.conf: $(srcdir)/xnf.conf
|
||||||
$(INSTALL_DATA) $(srcdir)/xnf.conf $(libdir)/ivl/xnf.conf
|
$(INSTALL_DATA) $(srcdir)/xnf.conf $(libdir)/ivl$(suffix)/xnf.conf
|
||||||
|
|
||||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
|
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
|
||||||
|
|
@ -243,49 +259,32 @@ $(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
||||||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||||
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
|
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
|
||||||
|
|
||||||
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
|
$(mandir)/man1/iverilog-vpi$(suffix).1: $(srcdir)/iverilog-vpi.man
|
||||||
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi.1
|
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1
|
||||||
|
|
||||||
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
|
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
|
||||||
$(INSTALL_DATA) iverilog-vpi.pdf $(prefix)/iverilog-vpi.pdf
|
$(INSTALL_DATA) iverilog-vpi.pdf $(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf
|
||||||
|
|
||||||
# In windows installations, put a few examples and the quick_start
|
|
||||||
# into the destination directory.
|
|
||||||
ifeq (@MINGW32@,yes)
|
|
||||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
|
||||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
|
||||||
mv tmp.vl $(prefix)/hello.vl
|
|
||||||
|
|
||||||
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
|
|
||||||
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
|
|
||||||
mv tmp.vl $(prefix)/sqrt.vl
|
|
||||||
|
|
||||||
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
|
|
||||||
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
|
|
||||||
mv tmp.vl $(prefix)/sqrt-virtex.v
|
|
||||||
|
|
||||||
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
|
|
||||||
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
|
|
||||||
mv tmp.txt $(prefix)/QUICK_START.txt
|
|
||||||
endif
|
|
||||||
|
|
||||||
installdirs: mkinstalldirs
|
installdirs: mkinstalldirs
|
||||||
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl \
|
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/ivl$(suffix) \
|
||||||
$(mandir) $(mandir)/man1
|
$(DESTDIR)$(libdir)/ivl$(suffix)/include $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||||
for dir in vpi ivlpp driver; \
|
for dir in vpi ivlpp driver; \
|
||||||
do (cd $$dir ; $(MAKE) $@); done
|
do (cd $$dir ; $(MAKE) $@); done
|
||||||
for f in xnf.conf xnf-s.conf ivl; \
|
for f in xnf.conf xnf-s.conf ivl@EXEEXT@; \
|
||||||
do rm -f $(libdir)/ivl/$$f; done
|
do rm -f $(DESTDIR)$(libdir)/ivl$(suffix)/$$f; done
|
||||||
-rmdir $(libdir)/ivl
|
-rmdir $(DESTDIR)$(libdir)/ivl$(suffix)/include
|
||||||
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
|
-rmdir $(DESTDIR)$(libdir)/ivl$(suffix)
|
||||||
do rm -f $(bindir)/$$f; done
|
for f in verilog$(suffix) iverilog-vpi$(suffix); \
|
||||||
|
do rm -f $(DESTDIR)$(bindir)/$$f; done
|
||||||
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
|
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
|
||||||
do rm -f $(includedir)/$$f; done
|
do rm -f $(DESTDIR)$(includedir)/$$f; done
|
||||||
rm -f $(mandir)/man1/iverilog-vpi.1
|
-test X$(suffix) = X || rmdir $(DESTDIR)/$(includedir)
|
||||||
|
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1 $(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf
|
||||||
|
|
||||||
|
|
||||||
-include $(patsubst %.o, dep/%.d, $O)
|
-include $(patsubst %.o, dep/%.d, $O)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// NetLatch.cc
|
||||||
|
// Author: Alan M. Feldstein
|
||||||
|
// Class NetLatch member-function definitions
|
||||||
|
|
||||||
|
#include "NetLatch.h" // NetLatch class definition
|
||||||
|
#include "target.h" // target_t structure definition
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
NetLatch::NetLatch( NetScope *scope, perm_string name, unsigned width )
|
||||||
|
// explicitly call base-class constructor
|
||||||
|
: NetNode( scope, name, 2U * width + 1U )
|
||||||
|
{
|
||||||
|
} // end NetLatch constructor
|
||||||
|
|
||||||
|
unsigned NetLatch::width() const
|
||||||
|
{
|
||||||
|
return ( pin_count() - 1U ) / 2U;
|
||||||
|
} // end function width
|
||||||
|
|
||||||
|
Link &NetLatch::pin_Data( unsigned w )
|
||||||
|
{
|
||||||
|
unsigned pn = 1 + 2 * w;
|
||||||
|
assert( pn < pin_count() );
|
||||||
|
return pin( pn );
|
||||||
|
} // end function pin_Data
|
||||||
|
|
||||||
|
Link &NetLatch::pin_Q( unsigned w )
|
||||||
|
{
|
||||||
|
unsigned pn = 2 + 2 * w;
|
||||||
|
assert( pn < pin_count() );
|
||||||
|
return pin( pn );
|
||||||
|
} // end function pin_Q
|
||||||
|
|
||||||
|
Link &NetLatch::pin_Gate()
|
||||||
|
{
|
||||||
|
return pin( 0 );
|
||||||
|
} // end function pin_Gate
|
||||||
|
|
||||||
|
const Link &NetLatch::pin_Gate() const
|
||||||
|
{
|
||||||
|
return pin( 0 );
|
||||||
|
} // end function pin_Gate
|
||||||
|
|
||||||
|
bool NetLatch::emit_node( target_t *driverPtr ) const
|
||||||
|
{
|
||||||
|
driverPtr->lpm_latch( this );
|
||||||
|
return true;
|
||||||
|
} // end function emit_node
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// NetLatch.h
|
||||||
|
// Author: Alan M. Feldstein
|
||||||
|
// This class represents an LPM_LATCH device. In Verilog, storage components of this type can be inferred.
|
||||||
|
// The pinout is assigned like so:
|
||||||
|
// 0 -- Gate
|
||||||
|
//
|
||||||
|
// 1 -- Data[0]
|
||||||
|
// 2 -- Q[0]
|
||||||
|
// ...
|
||||||
|
#ifndef NETLATCH_H
|
||||||
|
#define NETLATCH_H
|
||||||
|
|
||||||
|
#include "netlist.h" // NetNode, NetScope, Link class definitions
|
||||||
|
#include "StringHeap.h" // perm_string class definition
|
||||||
|
|
||||||
|
class NetLatch : public NetNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NetLatch( NetScope *, perm_string, unsigned );
|
||||||
|
|
||||||
|
unsigned width() const;
|
||||||
|
|
||||||
|
Link &pin_Data( unsigned );
|
||||||
|
Link &pin_Q( unsigned );
|
||||||
|
Link &pin_Gate();
|
||||||
|
|
||||||
|
const Link &pin_Data( unsigned ) const;
|
||||||
|
const Link &pin_Q( unsigned ) const;
|
||||||
|
const Link &pin_Gate() const;
|
||||||
|
|
||||||
|
virtual bool emit_node( target_t * ) const;
|
||||||
|
}; // end class NetLatch
|
||||||
|
|
||||||
|
#endif
|
||||||
20
PDelays.cc
20
PDelays.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PDelays.cc,v 1.11 2003/06/21 01:21:42 steve Exp $"
|
#ident "$Id: PDelays.cc,v 1.11.2.1 2006/10/04 00:37:03 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -72,6 +72,20 @@ static unsigned long calculate_val(Design*des, NetScope*scope,
|
||||||
dex = tmp;
|
dex = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int shift = scope->time_unit() - des->get_precision();
|
||||||
|
if (sizeof(unsigned) <= 4 && shift > 9) {
|
||||||
|
cerr << expr->get_line() << ": error: Precision overflow"
|
||||||
|
<< " in scope " << scope->name() << "." << endl;
|
||||||
|
cerr << expr->get_line() << ": :"
|
||||||
|
<< " Units are 10e" << scope->time_unit()
|
||||||
|
<< " minus precision 10e" << des->get_precision()
|
||||||
|
<< " is 10e" << shift << "." << endl;
|
||||||
|
cerr << expr->get_line() << ": : Perhaps a timescale "
|
||||||
|
<< "is missing or incorrect?" << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the delay expression is a real constant or vector
|
/* If the delay expression is a real constant or vector
|
||||||
constant, then evaluate it, scale it to the local time
|
constant, then evaluate it, scale it to the local time
|
||||||
units, and return an adjusted value. */
|
units, and return an adjusted value. */
|
||||||
|
|
@ -79,7 +93,6 @@ static unsigned long calculate_val(Design*des, NetScope*scope,
|
||||||
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
|
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
|
||||||
verireal fn = tmp->value();
|
verireal fn = tmp->value();
|
||||||
|
|
||||||
int shift = scope->time_unit() - des->get_precision();
|
|
||||||
long delay = fn.as_long(shift);
|
long delay = fn.as_long(shift);
|
||||||
if (delay < 0)
|
if (delay < 0)
|
||||||
delay = 0;
|
delay = 0;
|
||||||
|
|
@ -146,6 +159,9 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PDelays.cc,v $
|
* $Log: PDelays.cc,v $
|
||||||
|
* Revision 1.11.2.1 2006/10/04 00:37:03 steve
|
||||||
|
* Detect delay precision overflow.
|
||||||
|
*
|
||||||
* Revision 1.11 2003/06/21 01:21:42 steve
|
* Revision 1.11 2003/06/21 01:21:42 steve
|
||||||
* Harmless fixup of warnings.
|
* Harmless fixup of warnings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
7
PExpr.cc
7
PExpr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PExpr.cc,v 1.35 2004/10/04 01:10:51 steve Exp $"
|
#ident "$Id: PExpr.cc,v 1.35.2.1 2006/02/07 22:46:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -90,6 +90,8 @@ bool PEConcat::is_constant(Module *mod) const
|
||||||
{
|
{
|
||||||
bool constant = repeat_? repeat_->is_constant(mod) : true;
|
bool constant = repeat_? repeat_->is_constant(mod) : true;
|
||||||
for (unsigned i = 0; constant && i < parms_.count(); ++i) {
|
for (unsigned i = 0; constant && i < parms_.count(); ++i) {
|
||||||
|
if (parms_[i] == 0)
|
||||||
|
continue;
|
||||||
constant = constant && parms_[i]->is_constant(mod);
|
constant = constant && parms_[i]->is_constant(mod);
|
||||||
}
|
}
|
||||||
return constant;
|
return constant;
|
||||||
|
|
@ -262,6 +264,9 @@ bool PEUnary::is_constant(Module*m) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.cc,v $
|
* $Log: PExpr.cc,v $
|
||||||
|
* Revision 1.35.2.1 2006/02/07 22:46:23 steve
|
||||||
|
* More robust test for concat constant-ness.
|
||||||
|
*
|
||||||
* Revision 1.35 2004/10/04 01:10:51 steve
|
* Revision 1.35 2004/10/04 01:10:51 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
16
PExpr.h
16
PExpr.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PExpr.h,v 1.66 2004/10/04 01:10:51 steve Exp $"
|
#ident "$Id: PExpr.h,v 1.66.2.2 2006/07/28 16:26:17 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -115,6 +115,8 @@ class PEConcat : public PExpr {
|
||||||
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
|
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
|
||||||
~PEConcat();
|
~PEConcat();
|
||||||
|
|
||||||
|
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||||
|
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
// Concatenated Regs can be on the left of procedural
|
// Concatenated Regs can be on the left of procedural
|
||||||
|
|
@ -324,7 +326,7 @@ class PEString : public PExpr {
|
||||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||||
bool sys_task_arg =false) const;
|
bool sys_task_arg =false) const;
|
||||||
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||||
verinum* PEString::eval_const(const Design*, const NetScope*) const;
|
verinum* eval_const(const Design*, const NetScope*) const;
|
||||||
|
|
||||||
virtual bool is_constant(Module*) const;
|
virtual bool is_constant(Module*) const;
|
||||||
|
|
||||||
|
|
@ -374,7 +376,7 @@ class PEBinary : public PExpr {
|
||||||
unsigned long decay,
|
unsigned long decay,
|
||||||
Link::strength_t drive0,
|
Link::strength_t drive0,
|
||||||
Link::strength_t drive1) const;
|
Link::strength_t drive1) const;
|
||||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||||
bool sys_task_arg =false) const;
|
bool sys_task_arg =false) const;
|
||||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||||
|
|
@ -384,7 +386,7 @@ class PEBinary : public PExpr {
|
||||||
PExpr*left_;
|
PExpr*left_;
|
||||||
PExpr*right_;
|
PExpr*right_;
|
||||||
|
|
||||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
||||||
|
|
||||||
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
||||||
unsigned lwidth,
|
unsigned lwidth,
|
||||||
|
|
@ -492,6 +494,12 @@ class PECallFunction : public PExpr {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.h,v $
|
* $Log: PExpr.h,v $
|
||||||
|
* Revision 1.66.2.2 2006/07/28 16:26:17 steve
|
||||||
|
* Remove excess PEString:: prefix for stubborn compilers.
|
||||||
|
*
|
||||||
|
* Revision 1.66.2.1 2005/12/07 03:28:44 steve
|
||||||
|
* Support constant concatenation of constants.
|
||||||
|
*
|
||||||
* Revision 1.66 2004/10/04 01:10:51 steve
|
* Revision 1.66 2004/10/04 01:10:51 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
9
PTask.h
9
PTask.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PTask.h,v 1.13 2004/05/31 23:34:36 steve Exp $"
|
#ident "$Id: PTask.h,v 1.13.2.1 2005/08/13 00:45:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
|
@ -70,7 +70,7 @@ class PTask : public LineInfo {
|
||||||
// Elaborate the statement to finish off the task definition.
|
// Elaborate the statement to finish off the task definition.
|
||||||
void elaborate(Design*des, NetScope*scope) const;
|
void elaborate(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(std::ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
svector<PWire*>*ports_;
|
svector<PWire*>*ports_;
|
||||||
|
|
@ -106,7 +106,7 @@ class PFunction : public LineInfo {
|
||||||
/* Elaborate the behavioral statement. */
|
/* Elaborate the behavioral statement. */
|
||||||
void elaborate(Design *des, NetScope*) const;
|
void elaborate(Design *des, NetScope*) const;
|
||||||
|
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(std::ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
|
|
@ -117,6 +117,9 @@ class PFunction : public LineInfo {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PTask.h,v $
|
* $Log: PTask.h,v $
|
||||||
|
* Revision 1.13.2.1 2005/08/13 00:45:53 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
* Revision 1.13 2004/05/31 23:34:36 steve
|
* Revision 1.13 2004/05/31 23:34:36 steve
|
||||||
* Rewire/generalize parsing an elaboration of
|
* Rewire/generalize parsing an elaboration of
|
||||||
* function return values to allow for better
|
* function return values to allow for better
|
||||||
|
|
|
||||||
13
PUdp.h
13
PUdp.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
|
#ident "$Id: PUdp.h,v 1.12.2.1 2005/08/13 00:45:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <map>
|
# include <map>
|
||||||
|
|
@ -55,20 +55,20 @@ class PUdp {
|
||||||
public:
|
public:
|
||||||
explicit PUdp(perm_string n, unsigned nports);
|
explicit PUdp(perm_string n, unsigned nports);
|
||||||
|
|
||||||
svector<string>ports;
|
svector<std::string>ports;
|
||||||
unsigned find_port(const char*name);
|
unsigned find_port(const char*name);
|
||||||
|
|
||||||
bool sequential;
|
bool sequential;
|
||||||
|
|
||||||
svector<string>tinput;
|
svector<std::string>tinput;
|
||||||
svector<char> tcurrent;
|
svector<char> tcurrent;
|
||||||
svector<char> toutput;
|
svector<char> toutput;
|
||||||
|
|
||||||
verinum::V initial;
|
verinum::V initial;
|
||||||
|
|
||||||
map<string,PExpr*> attributes;
|
std::map<std::string,PExpr*> attributes;
|
||||||
|
|
||||||
void dump(ostream&out) const;
|
void dump(std::ostream&out) const;
|
||||||
|
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
private:
|
private:
|
||||||
|
|
@ -80,6 +80,9 @@ class PUdp {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PUdp.h,v $
|
* $Log: PUdp.h,v $
|
||||||
|
* Revision 1.12.2.1 2005/08/13 00:45:53 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
* Revision 1.12 2004/03/08 00:47:44 steve
|
* Revision 1.12 2004/03/08 00:47:44 steve
|
||||||
* primitive ports can bind bi name.
|
* primitive ports can bind bi name.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
17
README.txt
17
README.txt
|
|
@ -88,10 +88,6 @@ Normally, this command automatically figures out everything it needs
|
||||||
to know. It generally works pretty well. There are a few flags to the
|
to know. It generally works pretty well. There are a few flags to the
|
||||||
configure script that modify its behavior:
|
configure script that modify its behavior:
|
||||||
|
|
||||||
--without-ipal
|
|
||||||
This turns off support for Icarus PAL, whether ipal
|
|
||||||
libraries are installed or not.
|
|
||||||
|
|
||||||
--prefix=<root>
|
--prefix=<root>
|
||||||
The default is /usr/local, which causes the tool suite to
|
The default is /usr/local, which causes the tool suite to
|
||||||
be compiled for install in /usr/local/bin,
|
be compiled for install in /usr/local/bin,
|
||||||
|
|
@ -107,6 +103,17 @@ configure script that modify its behavior:
|
||||||
compilation of 32bit compatible vvp (vvp32) and the vpi
|
compilation of 32bit compatible vvp (vvp32) and the vpi
|
||||||
modules that match.
|
modules that match.
|
||||||
|
|
||||||
|
--enable-suffix
|
||||||
|
--enable-suffix=<your-suffix>
|
||||||
|
--disable-suffix
|
||||||
|
Enable/disable changing the names of install files to use
|
||||||
|
a suffix string so that this version or install can co-
|
||||||
|
exist with other versions. This renames the installed
|
||||||
|
commands (iverilog, iverilog-vpi, vvp) and the installed
|
||||||
|
library files and include directory so that installations
|
||||||
|
with the same prefix but different suffix are guaranteed
|
||||||
|
to not interfere with each other.
|
||||||
|
|
||||||
2.2.1 Special AMD64 Instructions
|
2.2.1 Special AMD64 Instructions
|
||||||
|
|
||||||
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
|
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
|
||||||
|
|
@ -114,7 +121,7 @@ configure script that modify its behavior:
|
||||||
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
|
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
|
||||||
most out of your install, first make sure you have both 64bit and
|
most out of your install, first make sure you have both 64bit and
|
||||||
32bit development libraries installed. Then configure with this
|
32bit development libraries installed. Then configure with this
|
||||||
somewhat more compilcated command:
|
somewhat more complex command:
|
||||||
|
|
||||||
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
|
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
|
||||||
|
|
||||||
|
|
|
||||||
10
Statement.h
10
Statement.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: Statement.h,v 1.40 2004/02/20 18:53:33 steve Exp $"
|
#ident "$Id: Statement.h,v 1.40.2.1 2006/07/10 00:21:49 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -71,12 +71,15 @@ class PProcess : public LineInfo {
|
||||||
* fact, the Statement class is abstract and represents all the
|
* fact, the Statement class is abstract and represents all the
|
||||||
* possible kinds of statements that exist in Verilog.
|
* possible kinds of statements that exist in Verilog.
|
||||||
*/
|
*/
|
||||||
class Statement : public LineInfo {
|
class Statement : public LineInfo, public Attrib {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Statement() { }
|
Statement() { }
|
||||||
virtual ~Statement() =0;
|
virtual ~Statement() =0;
|
||||||
|
|
||||||
|
map<perm_string,PExpr*> attributes;
|
||||||
|
|
||||||
|
void dump_attributes(ostream&out, unsigned ind) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
|
@ -456,6 +459,9 @@ class PWhile : public Statement {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: Statement.h,v $
|
* $Log: Statement.h,v $
|
||||||
|
* Revision 1.40.2.1 2006/07/10 00:21:49 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
* Revision 1.40 2004/02/20 18:53:33 steve
|
* Revision 1.40 2004/02/20 18:53:33 steve
|
||||||
* Addtrbute keys are perm_strings.
|
* Addtrbute keys are perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
|
#ident "$Id: StringHeap.cc,v 1.6.2.1 2005/08/13 00:45:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
|
|
@ -131,7 +131,7 @@ perm_string StringHeapLex::make(const char*text)
|
||||||
return perm_string(add(text));
|
return perm_string(add(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string StringHeapLex::make(const string&text)
|
perm_string StringHeapLex::make(const std::string&text)
|
||||||
{
|
{
|
||||||
return perm_string(add(text.c_str()));
|
return perm_string(add(text.c_str()));
|
||||||
}
|
}
|
||||||
|
|
@ -181,6 +181,9 @@ bool operator < (perm_string a, perm_string b)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: StringHeap.cc,v $
|
* $Log: StringHeap.cc,v $
|
||||||
|
* Revision 1.6.2.1 2005/08/13 00:45:53 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
* Revision 1.6 2004/02/18 17:11:54 steve
|
* Revision 1.6 2004/02/18 17:11:54 steve
|
||||||
* Use perm_strings for named langiage items.
|
* Use perm_strings for named langiage items.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
StringHeap.h
12
StringHeap.h
|
|
@ -19,12 +19,14 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: StringHeap.h,v 1.5 2004/02/18 17:11:54 steve Exp $"
|
#ident "$Id: StringHeap.h,v 1.5.2.2 2005/08/13 00:45:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class perm_string {
|
class perm_string {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -101,7 +103,7 @@ class StringHeapLex : private StringHeap {
|
||||||
|
|
||||||
const char*add(const char*);
|
const char*add(const char*);
|
||||||
perm_string make(const char*);
|
perm_string make(const char*);
|
||||||
perm_string make(const string&);
|
perm_string make(const std::string&);
|
||||||
|
|
||||||
unsigned add_count() const;
|
unsigned add_count() const;
|
||||||
unsigned add_hit_count() const;
|
unsigned add_hit_count() const;
|
||||||
|
|
@ -120,6 +122,12 @@ class StringHeapLex : private StringHeap {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: StringHeap.h,v $
|
* $Log: StringHeap.h,v $
|
||||||
|
* Revision 1.5.2.2 2005/08/13 00:45:53 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
|
* Revision 1.5.2.1 2005/06/14 15:33:54 steve
|
||||||
|
* Fix gcc4 build issues.
|
||||||
|
*
|
||||||
* Revision 1.5 2004/02/18 17:11:54 steve
|
* Revision 1.5 2004/02/18 17:11:54 steve
|
||||||
* Use perm_strings for named langiage items.
|
* Use perm_strings for named langiage items.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
AC_DEFUN([AX_CPP_IDENT],
|
AC_DEFUN([AX_CPP_IDENT],
|
||||||
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
|
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
|
||||||
[AC_TRY_COMPILE([
|
[AC_TRY_COMPILE([
|
||||||
#ident "$Id: aclocal.m4,v 1.6 2004/10/04 01:10:52 steve Exp $"
|
#ident "$Id: aclocal.m4,v 1.6.2.2 2007/05/16 23:51:42 steve Exp $"
|
||||||
],[while (0) {}],
|
],[while (0) {}],
|
||||||
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
|
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
|
||||||
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
|
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
|
||||||
|
|
@ -24,6 +24,23 @@ fi
|
||||||
AC_SUBST(ident_support)
|
AC_SUBST(ident_support)
|
||||||
])# AC_CPP_IDENT
|
])# AC_CPP_IDENT
|
||||||
|
|
||||||
|
# AX_ENABLE_SUFFIX
|
||||||
|
# ----------------
|
||||||
|
# Create the configure option --enable-suffix[=suffix] to generate suffix
|
||||||
|
# strings for the installed commands. This allows for shared installs of
|
||||||
|
# different builds. Remember to change the default suffix string to some
|
||||||
|
# value appropriate for the current version.
|
||||||
|
AC_DEFUN([AX_ENABLE_SUFFIX],
|
||||||
|
[AC_ARG_ENABLE([suffix],[Set the installation command suffix],[true],[enable_suffix=yes])
|
||||||
|
if test X$enable_suffix = Xyes; then
|
||||||
|
install_suffix='-0.8'
|
||||||
|
elif test X$enable_suffix = Xno; then
|
||||||
|
install_suffix=''
|
||||||
|
else
|
||||||
|
install_suffix="$enable_suffix"
|
||||||
|
fi
|
||||||
|
AC_SUBST(install_suffix)
|
||||||
|
])# AX_ENABLE_SUFFIX
|
||||||
|
|
||||||
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
@ -48,7 +65,7 @@ AC_DEFUN([AX_C_UNDERSCORES_LEADING],
|
||||||
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
|
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
|
||||||
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
|
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
|
||||||
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||||
AC_DEFINE(NEED_LU)
|
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
|
||||||
fi
|
fi
|
||||||
])# AX_C_UNDERSCORES_LEADING
|
])# AX_C_UNDERSCORES_LEADING
|
||||||
|
|
||||||
|
|
@ -63,7 +80,7 @@ AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
|
||||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
|
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
|
||||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
|
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
|
||||||
if test $ax_cv_c_underscores_trailing = yes; then
|
if test $ax_cv_c_underscores_trailing = yes; then
|
||||||
AC_DEFINE(NEED_TU)
|
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
|
||||||
fi
|
fi
|
||||||
])# AX_C_UNDERSCORES_TRAILING
|
])# AX_C_UNDERSCORES_TRAILING
|
||||||
|
|
||||||
|
|
@ -91,13 +108,9 @@ AC_MSG_RESULT($WIN32)
|
||||||
AC_DEFUN([AX_LD_EXTRALIBS],
|
AC_DEFUN([AX_LD_EXTRALIBS],
|
||||||
[AC_MSG_CHECKING([for extra libs needed])
|
[AC_MSG_CHECKING([for extra libs needed])
|
||||||
EXTRALIBS=
|
EXTRALIBS=
|
||||||
case "${host}" in
|
if test "$MINGW32" = "yes"; then
|
||||||
*-*-cygwin* )
|
EXTRALIBS="-liberty"
|
||||||
if test "$MINGW32" = "yes"; then
|
fi
|
||||||
EXTRALIBS="-liberty"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
AC_SUBST(EXTRALIBS)
|
AC_SUBST(EXTRALIBS)
|
||||||
AC_MSG_RESULT($EXTRALIBS)
|
AC_MSG_RESULT($EXTRALIBS)
|
||||||
])# AX_LD_EXTRALIBS
|
])# AX_LD_EXTRALIBS
|
||||||
|
|
@ -109,7 +122,7 @@ AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
|
||||||
[AC_MSG_CHECKING([for shared library link flag])
|
[AC_MSG_CHECKING([for shared library link flag])
|
||||||
shared=-shared
|
shared=-shared
|
||||||
case "${host}" in
|
case "${host}" in
|
||||||
*-*-cygwin*)
|
*-*-cygwin* | *-*-mingw32*)
|
||||||
shared="-shared -Wl,--enable-auto-image-base"
|
shared="-shared -Wl,--enable-auto-image-base"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
@ -138,7 +151,7 @@ AC_DEFUN([AX_C_PICFLAG],
|
||||||
PICFLAG=-fPIC
|
PICFLAG=-fPIC
|
||||||
case "${host}" in
|
case "${host}" in
|
||||||
|
|
||||||
*-*-cygwin*)
|
*-*-cygwin* | *-*-mingw32*)
|
||||||
PICFLAG=
|
PICFLAG=
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
@ -173,7 +186,7 @@ case "${host}" in
|
||||||
rdynamic=""
|
rdynamic=""
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*-*-cygwin*)
|
*-*-cygwin* | *-*-mingw32*)
|
||||||
rdynamic=""
|
rdynamic=""
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
|
||||||
14
async.cc
14
async.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
|
#ident "$Id: async.cc,v 1.7.2.2 2007/05/30 17:48:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -66,6 +66,10 @@ bool NetEvWait::is_asynchronous()
|
||||||
|
|
||||||
NexusSet*inputs = statement_->nex_input();
|
NexusSet*inputs = statement_->nex_input();
|
||||||
|
|
||||||
|
/* All the inputs of the statement must be accounted for in
|
||||||
|
the sensitivity list. Otherwise, there are inputs that can
|
||||||
|
change without the event being triggered, and that implies
|
||||||
|
a latch, not a combinational circuit. */
|
||||||
if (! sense->contains(*inputs)) {
|
if (! sense->contains(*inputs)) {
|
||||||
delete sense;
|
delete sense;
|
||||||
delete inputs;
|
delete inputs;
|
||||||
|
|
@ -85,7 +89,7 @@ bool NetProc::is_asynchronous()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetProcTop::is_asynchronous()
|
bool NetProcTop::is_asynchronous() const
|
||||||
{
|
{
|
||||||
if (type_ == NetProcTop::KINITIAL)
|
if (type_ == NetProcTop::KINITIAL)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -95,6 +99,12 @@ bool NetProcTop::is_asynchronous()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: async.cc,v $
|
* $Log: async.cc,v $
|
||||||
|
* Revision 1.7.2.2 2007/05/30 17:48:53 steve
|
||||||
|
* Support Latch synthesis (Alan Feldstein)
|
||||||
|
*
|
||||||
|
* Revision 1.7.2.1 2006/05/21 21:58:46 steve
|
||||||
|
* NetESignal input is only selected bits.
|
||||||
|
*
|
||||||
* Revision 1.7 2004/01/18 23:26:54 steve
|
* Revision 1.7 2004/01/18 23:26:54 steve
|
||||||
* The is_combinational function really need not recurse.
|
* The is_combinational function really need not recurse.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,14 @@ warning.)
|
||||||
|
|
||||||
* Other Attributes
|
* Other Attributes
|
||||||
|
|
||||||
|
(* ivl_full_case *)
|
||||||
|
|
||||||
|
This attribute only has meaning when attached to case statements,
|
||||||
|
and only when doing synthesis. The statement means to ignore the
|
||||||
|
possibility that some cases are not defined. Presume that the
|
||||||
|
device really is fully specified and do not emit any warnings
|
||||||
|
about missing guards.
|
||||||
|
|
||||||
[ none defined yet ]
|
[ none defined yet ]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@
|
||||||
echo "Autoconf in root..."
|
echo "Autoconf in root..."
|
||||||
autoconf
|
autoconf
|
||||||
|
|
||||||
for dir in vpip vpi vvp tgt-vvp tgt-fpga libveriuser cadpli
|
for dir in vpip vpi vvp tgt-vvp tgt-edif tgt-fpga libveriuser cadpli
|
||||||
do
|
do
|
||||||
echo "Autoconf in $dir..."
|
echo "Autoconf in $dir..."
|
||||||
( cd ./$dir ; autoconf --include=.. )
|
( cd ./$dir ; autoconf -f --include=.. )
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Precompiling lexor_keyword.gperf"
|
echo "Precompiling lexor_keyword.gperf"
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.11 2004/10/04 01:09:07 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.11.2.1 2005/02/23 18:40:23 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
VERSION = 0.0
|
suffix = @install_suffix@
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
@ -33,7 +33,7 @@ bindir = @bindir@
|
||||||
libdir = @libdir@
|
libdir = @libdir@
|
||||||
includedir = $(prefix)/include
|
includedir = $(prefix)/include
|
||||||
|
|
||||||
vpidir = @libdir@/ivl/@vpidir1@
|
vpidir = @libdir@/ivl$(suffix)/@vpidir1@
|
||||||
|
|
||||||
strip_dynamic=@strip_dynamic@
|
strip_dynamic=@strip_dynamic@
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ SHARED = @shared@
|
||||||
all:
|
all:
|
||||||
|
|
||||||
ifeq (@enable_vvp32@,yes)
|
ifeq (@enable_vvp32@,yes)
|
||||||
vpidir32 = $(libdir)/ivl/@vpidir2@
|
vpidir32 = $(libdir)/ivl$(suffix)/@vpidir2@
|
||||||
ALL32 = all32
|
ALL32 = all32
|
||||||
INSTALL32 = install32
|
INSTALL32 = install32
|
||||||
UNINSTALL32 = uninistall32
|
UNINSTALL32 = uninistall32
|
||||||
|
|
@ -86,6 +86,7 @@ clean:
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f Makefile config.status config.log config.cache
|
rm -f Makefile config.status config.log config.cache
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
|
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ AC_SUBST(EXEEXT)
|
||||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||||
AX_WIN32
|
AX_WIN32
|
||||||
|
|
||||||
|
AX_ENABLE_SUFFIX
|
||||||
|
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
# vvp32 is by default disabled
|
# vvp32 is by default disabled
|
||||||
|
|
@ -37,7 +39,7 @@ AC_SUBST(DLLIB)
|
||||||
|
|
||||||
AX_CPP_PRECOMP
|
AX_CPP_PRECOMP
|
||||||
|
|
||||||
# Compiler option for position independent code, needed whan making shared objects.
|
# Compiler option for position independent code, needed when making shared objects.
|
||||||
AX_C_PICFLAG
|
AX_C_PICFLAG
|
||||||
|
|
||||||
# Linker option used when compiling the target
|
# Linker option used when compiling the target
|
||||||
|
|
|
||||||
16
compiler.h
16
compiler.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: compiler.h,v 1.26 2004/10/04 01:10:52 steve Exp $"
|
#ident "$Id: compiler.h,v 1.26.2.3 2006/06/12 00:16:50 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <list>
|
# include <list>
|
||||||
|
|
@ -78,12 +78,17 @@ extern bool warn_timescale;
|
||||||
/* Warn about legal but questionable module port bindings. */
|
/* Warn about legal but questionable module port bindings. */
|
||||||
extern bool warn_portbinding;
|
extern bool warn_portbinding;
|
||||||
|
|
||||||
|
/* Warn about unused or unassigned variables. */
|
||||||
|
extern bool warn_unused;
|
||||||
|
|
||||||
/* This is true if verbose output is requested. */
|
/* This is true if verbose output is requested. */
|
||||||
extern bool verbose_flag;
|
extern bool verbose_flag;
|
||||||
|
|
||||||
extern bool debug_scopes;
|
extern bool debug_scopes;
|
||||||
extern bool debug_eval_tree;
|
extern bool debug_eval_tree;
|
||||||
extern bool debug_elaborate;
|
extern bool debug_elaborate;
|
||||||
|
extern bool debug_synth;
|
||||||
|
extern bool debug_cprop;
|
||||||
|
|
||||||
/* Path to a directory useful for finding subcomponents. */
|
/* Path to a directory useful for finding subcomponents. */
|
||||||
extern const char*basedir;
|
extern const char*basedir;
|
||||||
|
|
@ -136,6 +141,15 @@ extern int load_sys_func_table(const char*path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: compiler.h,v $
|
* $Log: compiler.h,v $
|
||||||
|
* Revision 1.26.2.3 2006/06/12 00:16:50 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
|
* Revision 1.26.2.2 2006/04/23 04:25:45 steve
|
||||||
|
* Add cprop debugging.
|
||||||
|
*
|
||||||
|
* Revision 1.26.2.1 2006/04/01 01:37:24 steve
|
||||||
|
* Add synth debug flag
|
||||||
|
*
|
||||||
* Revision 1.26 2004/10/04 01:10:52 steve
|
* Revision 1.26 2004/10/04 01:10:52 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
14
configure.in
14
configure.in
|
|
@ -9,6 +9,9 @@ AC_PROG_CC
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_CHECK_TOOL(STRIP, strip, true)
|
AC_CHECK_TOOL(STRIP, strip, true)
|
||||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||||
|
AC_CHECK_PROGS(MAN,man,none)
|
||||||
|
AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
|
||||||
|
|
||||||
if test "$XGPERF" = "none"
|
if test "$XGPERF" = "none"
|
||||||
then
|
then
|
||||||
echo ""
|
echo ""
|
||||||
|
|
@ -56,9 +59,12 @@ AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
|
||||||
AC_SUBST(HAVE_LIBZ)
|
AC_SUBST(HAVE_LIBZ)
|
||||||
if test "$WIN32" = "yes"; then
|
if test "$WIN32" = "yes"; then
|
||||||
AC_CHECK_LIB(bz2, main)
|
AC_CHECK_LIB(bz2, main)
|
||||||
|
AC_CHECK_LIB(bz2, main, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
|
||||||
else
|
else
|
||||||
AC_CHECK_LIB(bz2, BZ2_bzdopen)
|
AC_CHECK_LIB(bz2, BZ2_bzdopen)
|
||||||
|
AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
|
||||||
fi
|
fi
|
||||||
|
AC_SUBST(HAVE_LIBBZ2)
|
||||||
|
|
||||||
AC_MSG_CHECKING(for sys/times)
|
AC_MSG_CHECKING(for sys/times)
|
||||||
AC_TRY_LINK(
|
AC_TRY_LINK(
|
||||||
|
|
@ -66,7 +72,7 @@ AC_TRY_LINK(
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
|
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
|
||||||
do_times=yes
|
do_times=yes
|
||||||
AC_DEFINE(HAVE_TIMES,1),
|
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
|
||||||
do_times=no
|
do_times=no
|
||||||
)
|
)
|
||||||
AC_MSG_RESULT($do_times)
|
AC_MSG_RESULT($do_times)
|
||||||
|
|
@ -91,9 +97,11 @@ AC_C_BIGENDIAN
|
||||||
|
|
||||||
# $host
|
# $host
|
||||||
|
|
||||||
|
AX_ENABLE_SUFFIX
|
||||||
|
|
||||||
AX_LD_EXTRALIBS
|
AX_LD_EXTRALIBS
|
||||||
|
|
||||||
# Compiler option for position independent code, needed whan making shared objects.
|
# Compiler option for position independent code, needed when making shared objects.
|
||||||
# CFLAGS inherited by cadpli/Makefile?
|
# CFLAGS inherited by cadpli/Makefile?
|
||||||
AX_C_PICFLAG
|
AX_C_PICFLAG
|
||||||
|
|
||||||
|
|
@ -141,6 +149,6 @@ AC_SUBST(vpidir1)
|
||||||
AC_SUBST(vpidir2)
|
AC_SUBST(vpidir2)
|
||||||
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
||||||
|
|
||||||
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-fpga libveriuser cadpli)
|
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-edif tgt-fpga libveriuser cadpli)
|
||||||
|
|
||||||
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||||
|
|
|
||||||
414
cprop.cc
414
cprop.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2006 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: cprop.cc,v 1.47 2004/02/20 18:53:34 steve Exp $"
|
#ident "$Id: cprop.cc,v 1.47.2.7 2007/02/26 19:51:38 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "functor.h"
|
# include "functor.h"
|
||||||
|
# include "compiler.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -47,6 +48,9 @@ struct cprop_functor : public functor_t {
|
||||||
virtual void lpm_ff(Design*des, NetFF*obj);
|
virtual void lpm_ff(Design*des, NetFF*obj);
|
||||||
virtual void lpm_logic(Design*des, NetLogic*obj);
|
virtual void lpm_logic(Design*des, NetLogic*obj);
|
||||||
virtual void lpm_mux(Design*des, NetMux*obj);
|
virtual void lpm_mux(Design*des, NetMux*obj);
|
||||||
|
virtual void lpm_mux_large(Design*des, NetMux*obj);
|
||||||
|
virtual void lpm_ram_dq(Design*des, NetRamDq*obj);
|
||||||
|
bool lpm_ram_dq_const_address_(Design*des, NetRamDq*obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cprop_functor::signal(Design*des, NetNet*obj)
|
void cprop_functor::signal(Design*des, NetNet*obj)
|
||||||
|
|
@ -842,84 +846,378 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This detects the case where the mux selects between a value and
|
* This detects the case where the mux selects between a value and
|
||||||
* Vz. In this case, replace the device with a bufif with the sel
|
* Vz. In this case, replace the device with a MOS with the sel
|
||||||
* input used to enable the output.
|
* input used to enable the output.
|
||||||
*/
|
*/
|
||||||
void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||||
{
|
{
|
||||||
|
if (obj->size() > 2) {
|
||||||
|
lpm_mux_large(des, obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (obj->size() != 2)
|
if (obj->size() != 2)
|
||||||
return;
|
return;
|
||||||
if (obj->sel_width() != 1)
|
if (obj->sel_width() != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If the first input is all constant Vz, then replace the
|
NetScope*scope = obj->scope();
|
||||||
NetMux with an array of BUFIF1 devices, with the enable
|
|
||||||
connected to the select input. */
|
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||||
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
|
bool cflag_a = obj->pin_Data(idx, 0).nexus()->drivers_constant();
|
||||||
flag = false;
|
bool cflag_b = obj->pin_Data(idx, 1).nexus()->drivers_constant();
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
|
/* If both data inputs are constant, we'll be able to do
|
||||||
flag = false;
|
a substitution. */
|
||||||
break;
|
if (cflag_a && cflag_b)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
verinum::V va = cflag_a
|
||||||
|
? obj->pin_Data(idx, 0).nexus()->driven_value()
|
||||||
|
: verinum::Vx;
|
||||||
|
verinum::V vb = cflag_b
|
||||||
|
? obj->pin_Data(idx, 1).nexus()->driven_value()
|
||||||
|
: verinum::Vx;
|
||||||
|
|
||||||
|
/* If only one Data input is constant, but a constant
|
||||||
|
HiZ, then we will be able to do a MOS
|
||||||
|
substitution. */
|
||||||
|
if (cflag_a && va==verinum::Vz)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cflag_b && vb==verinum::Vz)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Otherwise, we cannot accurately do a substitution. If
|
||||||
|
one input is non-constant, then that input may have a
|
||||||
|
HiZ value, and there is no Verilog logic other then a
|
||||||
|
MUX that can pass a HiZ value. */
|
||||||
|
flag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag) {
|
if (! flag) {
|
||||||
NetScope*scope = obj->scope();
|
return;
|
||||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
}
|
||||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
|
||||||
scope->local_symbol(),
|
|
||||||
3, NetLogic::BUFIF1);
|
|
||||||
|
|
||||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
/* Create a temporary net to hold the result value that we
|
||||||
|
build up. When we are done, we will connect this to the
|
||||||
|
Result pins of the mux, then delete the mux *and* this
|
||||||
|
net. That will cause all the proper connectivity to
|
||||||
|
happen. */
|
||||||
|
NetNet result_tmp(scope, scope->local_symbol(),
|
||||||
|
NetNet::WIRE, obj->width());
|
||||||
|
|
||||||
|
/* We know that every slice has at least one constant. Run
|
||||||
|
through the slices again, creating boolean devices to
|
||||||
|
replace the MUX slice. */
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||||
|
|
||||||
|
/* If the Sel==0 input is constant Z, make a NMOS. */
|
||||||
|
if (obj->pin_Data(idx, 0).nexus()->drivers_constant()
|
||||||
|
&& obj->pin_Data(idx, 0).nexus()->driven_value()==verinum::Vz) {
|
||||||
|
|
||||||
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
3, NetLogic::NMOS);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
connect(obj->pin_Data(idx,1), tmp->pin(1));
|
connect(obj->pin_Data(idx,1), tmp->pin(1));
|
||||||
connect(obj->pin_Sel(0), tmp->pin(2));
|
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||||
des->add_node(tmp);
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
count += 1;
|
/* If the Sel==1 input is constant Z, make a PMOS. */
|
||||||
delete obj;
|
if (obj->pin_Data(idx, 1).nexus()->drivers_constant()
|
||||||
return;
|
&& obj->pin_Data(idx, 1).nexus()->driven_value()==verinum::Vz) {
|
||||||
}
|
|
||||||
|
|
||||||
/* If instead the second input is all constant Vz, replace the
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
NetMux with an array of BUFIF0 devices. */
|
|
||||||
flag = true;
|
|
||||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
|
||||||
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
|
|
||||||
flag = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
|
|
||||||
flag = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag) {
|
|
||||||
NetScope*scope = obj->scope();
|
|
||||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
|
||||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
|
||||||
scope->local_symbol(),
|
scope->local_symbol(),
|
||||||
3, NetLogic::BUFIF0);
|
3, NetLogic::PMOS);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
|
||||||
connect(obj->pin_Data(idx,0), tmp->pin(1));
|
connect(obj->pin_Data(idx,0), tmp->pin(1));
|
||||||
connect(obj->pin_Sel(0), tmp->pin(2));
|
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||||
des->add_node(tmp);
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
count += 1;
|
/* At this point, the only cases that are left are where
|
||||||
delete obj;
|
the data inputs are both constant, and neither are
|
||||||
|
HiZ. From this we know how to generate the output
|
||||||
|
from only the S input. */
|
||||||
|
if (! (obj->pin_Data(idx, 0).nexus()->drivers_constant()
|
||||||
|
&& obj->pin_Data(idx, 1).nexus()->drivers_constant())) {
|
||||||
|
cerr << obj->get_line() << ": internal error: "
|
||||||
|
<< "Drivers not constant where expected?"
|
||||||
|
<< " obj->width()=" << obj->width()
|
||||||
|
<< " idx=" << idx
|
||||||
|
<< endl;
|
||||||
|
obj->dump_node(cerr, 4);
|
||||||
|
}
|
||||||
|
assert(obj->pin_Data(idx, 0).nexus()->drivers_constant()
|
||||||
|
&& obj->pin_Data(idx, 1).nexus()->drivers_constant());
|
||||||
|
|
||||||
|
|
||||||
|
verinum::V a = obj->pin_Data(idx, 0).nexus()->driven_value();
|
||||||
|
verinum::V b = obj->pin_Data(idx, 1).nexus()->driven_value();
|
||||||
|
|
||||||
|
if (a == b) {
|
||||||
|
connect(result_tmp.pin(idx), obj->pin_Data(idx,0));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == verinum::V0 && b == verinum::V1) {
|
||||||
|
connect(result_tmp.pin(idx), obj->pin_Sel(0));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == verinum::V1 && b == verinum::V0) {
|
||||||
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
2, NetLogic::NOT);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
|
connect(obj->pin_Sel(0), tmp->pin(1));
|
||||||
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A==0: Q = B & S */
|
||||||
|
if (a == verinum::V0) {
|
||||||
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
3, NetLogic::AND);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
|
connect(obj->pin_Data(idx,1), tmp->pin(1));
|
||||||
|
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||||
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* B==1: Q = A | S */
|
||||||
|
if (b == verinum::V1) {
|
||||||
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
3, NetLogic::OR);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
|
connect(obj->pin_Data(idx,0), tmp->pin(1));
|
||||||
|
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||||
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* A==1: Q = B | ~S */
|
||||||
|
if (a == verinum::V1) {
|
||||||
|
NetLogic*inv = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
2, NetLogic::NOT);
|
||||||
|
NetNet*invs = new NetNet(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
NetNet::TRI, 1);
|
||||||
|
invs->local_flag(true);
|
||||||
|
connect(inv->pin(0), invs->pin(0));
|
||||||
|
connect(inv->pin(1), obj->pin_Sel(0));
|
||||||
|
des->add_node(inv);
|
||||||
|
|
||||||
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
3, NetLogic::OR);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
|
connect(obj->pin_Data(idx,1), tmp->pin(1));
|
||||||
|
connect(inv->pin(0), tmp->pin(2));
|
||||||
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* B==0: Q = A & ~S */
|
||||||
|
if (b == verinum::V0) {
|
||||||
|
NetLogic*inv = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
2, NetLogic::NOT);
|
||||||
|
NetNet*invs = new NetNet(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
NetNet::TRI, 1);
|
||||||
|
invs->local_flag(true);
|
||||||
|
connect(inv->pin(0), invs->pin(0));
|
||||||
|
connect(inv->pin(1), obj->pin_Sel(0));
|
||||||
|
des->add_node(inv);
|
||||||
|
|
||||||
|
NetLogic*tmp = new NetLogic(scope,
|
||||||
|
scope->local_symbol(),
|
||||||
|
3, NetLogic::AND);
|
||||||
|
connect(result_tmp.pin(idx), tmp->pin(0));
|
||||||
|
connect(obj->pin_Data(idx,0), tmp->pin(1));
|
||||||
|
connect(inv->pin(0), tmp->pin(2));
|
||||||
|
des->add_node(tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
|
||||||
|
connect(result_tmp.pin(idx), obj->pin_Result(idx));
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cprop_functor::lpm_mux_large(Design*des, NetMux*obj)
|
||||||
|
{
|
||||||
|
NetScope*scope = obj->scope();
|
||||||
|
unsigned width = obj->width();
|
||||||
|
unsigned size = obj->size();
|
||||||
|
|
||||||
|
/* This test looks for bit slices that are constant
|
||||||
|
throughout. If we find any, we can reduce the width of the
|
||||||
|
MUX to eliminate the fixed value. */
|
||||||
|
|
||||||
|
/* After the following for loop, this array of bools will
|
||||||
|
contain "true" for each bit slice that is constant and
|
||||||
|
identical, and "false" otherwise. The reduce_width will
|
||||||
|
count the number of true entries in the flags array. */
|
||||||
|
bool*flags = new bool[width];
|
||||||
|
unsigned reduce_width = 0;
|
||||||
|
|
||||||
|
for (unsigned bit = 0 ; bit < width ; bit += 1) {
|
||||||
|
|
||||||
|
flags[bit] = true;
|
||||||
|
|
||||||
|
/* If not even the first selection is constant, then the
|
||||||
|
slice cannot be reduced. */
|
||||||
|
if (! obj->pin_Data(bit, 0).nexus()->drivers_constant()) {
|
||||||
|
flags[bit] = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If any of the remaining selections in non-consant, or
|
||||||
|
constant with a different value, then this slice
|
||||||
|
cannot be reduced. */
|
||||||
|
verinum::V val = obj->pin_Data(bit, 0).nexus()->driven_value();
|
||||||
|
|
||||||
|
for (unsigned idx = 1; flags[bit] && idx < size ; idx += 1) {
|
||||||
|
|
||||||
|
if (!obj->pin_Data(bit,idx).nexus()->drivers_constant()) {
|
||||||
|
flags[bit] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val != obj->pin_Data(bit,idx).nexus()->driven_value()) {
|
||||||
|
flags[bit] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! flags[bit]) {
|
||||||
|
/* This bit slice is too complex. Go on. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_width += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no slices can be reduced, then we are finished. */
|
||||||
|
if (reduce_width == 0) {
|
||||||
|
delete[]flags;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle the very special case that all the slices can be
|
||||||
|
reduced. We don't need a MUX at all! */
|
||||||
|
if (reduce_width == width) {
|
||||||
|
for (unsigned idx = 0 ; idx < width ; idx += 1)
|
||||||
|
connect(obj->pin_Result(idx), obj->pin_Data(idx,0));
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
count += 1;
|
||||||
|
delete[]flags;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a reduced mux with the same name and size, but fewer
|
||||||
|
slices. Connect all the slices that we are keeping. */
|
||||||
|
NetMux*tmp = new NetMux(scope, obj->name(),
|
||||||
|
width-reduce_width, size, obj->sel_width());
|
||||||
|
tmp->set_line(*obj);
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < obj->sel_width() ; idx += 1)
|
||||||
|
connect(obj->pin_Sel(idx), tmp->pin_Sel(idx));
|
||||||
|
|
||||||
|
unsigned dst_bit = 0;
|
||||||
|
|
||||||
|
for (unsigned bit = 0 ; bit < width ; bit += 1) {
|
||||||
|
if (flags[bit]) {
|
||||||
|
connect(obj->pin_Result(bit), obj->pin_Data(bit,0));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(obj->pin_Result(bit), tmp->pin_Result(dst_bit));
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < size ; idx += 1)
|
||||||
|
connect(obj->pin_Data(bit,idx), tmp->pin_Data(dst_bit,idx));
|
||||||
|
|
||||||
|
dst_bit += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the new node. Delete the old node. Signal that we
|
||||||
|
change the design and may use a rescan. */
|
||||||
|
des->add_node(tmp);
|
||||||
|
delete obj;
|
||||||
|
delete[]flags;
|
||||||
|
count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cprop_functor::lpm_ram_dq(Design*des, NetRamDq*obj)
|
||||||
|
{
|
||||||
|
if (lpm_ram_dq_const_address_(des,obj))
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to evaluate a constant address input. If we find it, then
|
||||||
|
* replace the NetRamDq with a direct link to the addressed word.
|
||||||
|
*/
|
||||||
|
bool cprop_functor::lpm_ram_dq_const_address_(Design*des, NetRamDq*obj)
|
||||||
|
{
|
||||||
|
NetMemory*mem = obj->mem();
|
||||||
|
NetNet* reg = mem->reg_from_explode();
|
||||||
|
|
||||||
|
/* I only know how to do this on exploded memories. */
|
||||||
|
if (reg == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
verinum sel (0UL, obj->awidth());
|
||||||
|
for (unsigned idx = 0 ; idx < obj->awidth() ; idx += 1) {
|
||||||
|
if (! obj->pin_Address(idx).nexus()->drivers_constant())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sel.set(idx, obj->pin_Address(idx).nexus()->driven_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long address = sel.as_ulong();
|
||||||
|
|
||||||
|
/* If the address is outside the ram, then leave this to the
|
||||||
|
code generator to figure out. */
|
||||||
|
if (address >= obj->size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned base = address * obj->width();
|
||||||
|
assert(base+obj->width() <= reg->pin_count());
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
|
||||||
|
connect(reg->pin(base+idx), obj->pin_Q(idx));
|
||||||
|
|
||||||
|
if (debug_cprop) {
|
||||||
|
cerr << obj->get_line() << ": debug: Replace read port with"
|
||||||
|
<< " fixed link to word " << address << "." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete obj;
|
||||||
|
count += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This functor looks to see if the constant is connected to nothing
|
* This functor looks to see if the constant is connected to nothing
|
||||||
* but signals. If that is the case, delete the dangling constant and
|
* but signals. If that is the case, delete the dangling constant and
|
||||||
|
|
@ -1038,6 +1336,24 @@ void cprop(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: cprop.cc,v $
|
* $Log: cprop.cc,v $
|
||||||
|
* Revision 1.47.2.7 2007/02/26 19:51:38 steve
|
||||||
|
* Spelling fixes (larry doolittle)
|
||||||
|
*
|
||||||
|
* Revision 1.47.2.6 2006/11/12 01:20:45 steve
|
||||||
|
* Prevent constant mux outputs from confusing itself.
|
||||||
|
*
|
||||||
|
* Revision 1.47.2.5 2006/04/23 04:26:13 steve
|
||||||
|
* Constant propagate addresses through NetRamDq read ports.
|
||||||
|
*
|
||||||
|
* Revision 1.47.2.4 2005/09/11 02:50:51 steve
|
||||||
|
* Fix overly agressive constant propagation through MUX causing lost Z bits.
|
||||||
|
*
|
||||||
|
* Revision 1.47.2.3 2005/08/28 22:00:39 steve
|
||||||
|
* Reduce mux slices that are constant throughout range.
|
||||||
|
*
|
||||||
|
* Revision 1.47.2.2 2005/08/28 19:51:02 steve
|
||||||
|
* More thorough constant propagation through MUX devices.
|
||||||
|
*
|
||||||
* Revision 1.47 2004/02/20 18:53:34 steve
|
* Revision 1.47 2004/02/20 18:53:34 steve
|
||||||
* Addtrbute keys are perm_strings.
|
* Addtrbute keys are perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: design_dump.cc,v 1.149 2004/10/04 01:10:52 steve Exp $"
|
#ident "$Id: design_dump.cc,v 1.149.2.7 2006/08/23 04:09:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -77,6 +77,8 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||||
o << " (local)";
|
o << " (local)";
|
||||||
if (signed_)
|
if (signed_)
|
||||||
o << " signed";
|
o << " signed";
|
||||||
|
if (mref_)
|
||||||
|
o << " mref_=" << mref_->name();
|
||||||
switch (port_type_) {
|
switch (port_type_) {
|
||||||
case NetNet::NOT_A_PORT:
|
case NetNet::NOT_A_PORT:
|
||||||
break;
|
break;
|
||||||
|
|
@ -171,7 +173,8 @@ void NetObj::dump_node_pins(ostream&o, unsigned ind) const
|
||||||
|
|
||||||
if (pin(idx).is_linked()) {
|
if (pin(idx).is_linked()) {
|
||||||
const Nexus*nex = pin(idx).nexus();
|
const Nexus*nex = pin(idx).nexus();
|
||||||
o << nex << " " << nex->name();
|
const char*nex_name = nex->name();
|
||||||
|
o << nex << " " << (nex_name? nex_name : "????");
|
||||||
}
|
}
|
||||||
o << endl;
|
o << endl;
|
||||||
|
|
||||||
|
|
@ -216,6 +219,23 @@ void NetCompare::dump_node(ostream&o, unsigned ind) const
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetDecode::dump_node(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
o << setw(ind) << "" << "LPM_DECODE (NetDecode): " << name()
|
||||||
|
<< " ff=" << ff_->name() << ", word width=" << width() << endl;
|
||||||
|
dump_node_pins(o, ind+4);
|
||||||
|
dump_obj_attr(o, ind+4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetDemux::dump_node(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
o << setw(ind) << "" << "LPM_DEMUX (NetDemux): " << name()
|
||||||
|
<< " bus width=" << width() << ", address width=" << awidth()
|
||||||
|
<< ", word count=" << size() << endl;
|
||||||
|
dump_node_pins(o, ind+4);
|
||||||
|
dump_obj_attr(o, ind+4);
|
||||||
|
}
|
||||||
|
|
||||||
void NetDivide::dump_node(ostream&o, unsigned ind) const
|
void NetDivide::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
|
o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
|
||||||
|
|
@ -240,6 +260,7 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
|
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
|
||||||
<< " scope=" << scope()->name() << endl;
|
<< " scope=" << scope()->name() << endl;
|
||||||
|
o << setw(ind+6) << "" << "source=" << get_line() << endl;
|
||||||
dump_node_pins(o, ind+4);
|
dump_node_pins(o, ind+4);
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +293,12 @@ void NetFF::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "LPM_FF: " << name()
|
o << setw(ind) << "" << "LPM_FF: " << name()
|
||||||
<< " scope=" << (scope()? scope()->name() : "")
|
<< " scope=" << (scope()? scope()->name() : "")
|
||||||
<< " aset_value=" << aset_value_ << endl;
|
<< " aset_value=" << aset_value_
|
||||||
|
<< " sset_value=" << sset_value_;
|
||||||
|
|
||||||
|
if (demux_) o << " demux=" << demux_->name();
|
||||||
|
|
||||||
|
o << endl;
|
||||||
|
|
||||||
dump_node_pins(o, ind+4);
|
dump_node_pins(o, ind+4);
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
|
|
@ -355,8 +381,16 @@ void NetModulo::dump_node(ostream&o, unsigned ind) const
|
||||||
|
|
||||||
void NetRamDq::dump_node(ostream&o, unsigned ind) const
|
void NetRamDq::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "LPM_RAM_DQ (" << mem_->name() << "): "
|
o << setw(ind) << "" << "LPM_RAM_DQ (";
|
||||||
<< name() << endl;
|
|
||||||
|
if (mem_)
|
||||||
|
if (NetNet*tmp = mem_->reg_from_explode())
|
||||||
|
o << "exploded mem=" << tmp->name();
|
||||||
|
else
|
||||||
|
o << "mem=" << mem_->name();
|
||||||
|
|
||||||
|
o << "): " << name() << endl;
|
||||||
|
|
||||||
dump_node_pins(o, ind+4);
|
dump_node_pins(o, ind+4);
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
@ -432,7 +466,7 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||||
void NetAssign_::dump_lval(ostream&o) const
|
void NetAssign_::dump_lval(ostream&o) const
|
||||||
{
|
{
|
||||||
if (sig_) {
|
if (sig_) {
|
||||||
o << sig_->name();
|
o << "sig=" << sig_->name();
|
||||||
if (bmux_) {
|
if (bmux_) {
|
||||||
o << "[" << *bmux_ << "]";
|
o << "[" << *bmux_ << "]";
|
||||||
|
|
||||||
|
|
@ -443,7 +477,7 @@ void NetAssign_::dump_lval(ostream&o) const
|
||||||
// Is there an obvious way to flag memories in the dump
|
// Is there an obvious way to flag memories in the dump
|
||||||
// as different from the _real_ bit mux case?
|
// as different from the _real_ bit mux case?
|
||||||
// o << "**memory**";
|
// o << "**memory**";
|
||||||
o << mem_->name() << "[";
|
o << "mem=" << mem_->name() << "[";
|
||||||
if (bmux_) o << *bmux_;
|
if (bmux_) o << *bmux_;
|
||||||
else o << "**oops**";
|
else o << "**oops**";
|
||||||
o << "]";
|
o << "]";
|
||||||
|
|
@ -537,6 +571,8 @@ void NetCase::dump(ostream&o, unsigned ind) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_proc_attr(o, ind+2);
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
|
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
|
||||||
o << setw(ind+2) << "";
|
o << setw(ind+2) << "";
|
||||||
if (items_[idx].guard)
|
if (items_[idx].guard)
|
||||||
|
|
@ -842,6 +878,15 @@ void NetProc::dump(ostream&o, unsigned ind) const
|
||||||
o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
|
o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetProc::dump_proc_attr(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
unsigned idx;
|
||||||
|
for (idx = 0 ; idx < attr_cnt() ; idx += 1) {
|
||||||
|
o << setw(ind) << "" << "(* " << attr_key(idx) << " = "
|
||||||
|
<< attr_value(idx) << " *)" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Dump an expression that no one wrote a dump method for. */
|
/* Dump an expression that no one wrote a dump method for. */
|
||||||
void NetExpr::dump(ostream&o) const
|
void NetExpr::dump(ostream&o) const
|
||||||
{
|
{
|
||||||
|
|
@ -1089,6 +1134,27 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $Log: design_dump.cc,v $
|
||||||
|
* Revision 1.149.2.7 2006/08/23 04:09:14 steve
|
||||||
|
* missing sig diagnostics.
|
||||||
|
*
|
||||||
|
* Revision 1.149.2.6 2006/07/10 00:21:50 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
|
* Revision 1.149.2.5 2006/04/16 19:26:37 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.149.2.4 2006/03/26 23:09:21 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.149.2.3 2006/03/12 07:34:16 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.149.2.2 2006/02/19 00:11:31 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
|
* Revision 1.149.2.1 2006/01/18 01:23:23 steve
|
||||||
|
* Rework l-value handling to allow for more l-value type flexibility.
|
||||||
|
*
|
||||||
* Revision 1.149 2004/10/04 01:10:52 steve
|
* Revision 1.149 2004/10/04 01:10:52 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.7 2004/10/13 22:01:34 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.7.2.1 2006/10/04 17:08:59 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
VERSION = 0.8
|
suffix = @install_suffix@
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
@ -29,6 +29,8 @@ srcdir = @srcdir@
|
||||||
|
|
||||||
VPATH = $(srcdir)
|
VPATH = $(srcdir)
|
||||||
|
|
||||||
|
suffix = @install_suffix@
|
||||||
|
|
||||||
bindir = $(exec_prefix)/bin
|
bindir = $(exec_prefix)/bin
|
||||||
libdir = $(exec_prefix)/lib
|
libdir = $(exec_prefix)/lib
|
||||||
includedir = $(prefix)/include
|
includedir = $(prefix)/include
|
||||||
|
|
@ -41,14 +43,14 @@ INSTALL = @INSTALL@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
|
||||||
CFLAGS = -Wall @CFLAGS@
|
CFLAGS = -Wall @CFLAGS@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
all: iverilog-vpi@EXEEXT@
|
all: iverilog-vpi@EXEEXT@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o
|
rm -f *.o config.h
|
||||||
rm -f iverilog-vpi@EXEEXT@
|
rm -f iverilog-vpi@EXEEXT@
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
|
|
@ -60,21 +62,27 @@ iverilog-vpi@EXEEXT@: $O
|
||||||
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
|
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
|
||||||
|
|
||||||
|
|
||||||
main.o: main.c
|
main.o: main.c config.h
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||||
|
|
||||||
|
config.h: config.h.in
|
||||||
|
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
|
||||||
|
-e 's;@SUFFIX@;$(suffix);g' \
|
||||||
|
-e 's;@IVLCFLAGS@;@CXXFLAGS@;' \
|
||||||
|
-e 's;@SHARED@;@shared@;' $< > $@
|
||||||
|
|
||||||
# Windows specific...
|
# Windows specific...
|
||||||
res.o: res.rc
|
res.o: res.rc
|
||||||
windres -i res.rc -o res.o
|
windres -i res.rc -o res.o
|
||||||
#
|
#
|
||||||
|
|
||||||
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
|
install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
|
||||||
|
|
||||||
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
|
$(bindir)/iverilog-vpi$(suffix)@EXEEXT@: ./iverilog-vpi@EXEEXT@
|
||||||
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
|
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
|
||||||
|
|
||||||
installdirs: ../mkinstalldirs
|
installdirs: ../mkinstalldirs
|
||||||
$(srcdir)/../mkinstalldirs $(bindir)
|
$(srcdir)/../mkinstalldirs $(bindir)
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(bindir)/iverilog-vpi@EXEEXT@
|
rm -f $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* For now do not put the Icarus Verilog include or library paths here.
|
||||||
|
* They are generated from a registry entry the user must set (-ivl=).
|
||||||
|
* This may change in the future once I have thought about it more. */
|
||||||
|
#define IVERILOG_VPI_CC "@IVLCC@"
|
||||||
|
#define IVERILOG_VPI_CXX "@IVLCXX@"
|
||||||
|
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
|
||||||
|
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
|
||||||
|
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
|
||||||
|
#define IVERILOG_SUFFIX "@SUFFIX@"
|
||||||
|
|
@ -32,28 +32,28 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
/* Macros used for compiling and linking */
|
static void setup_ivl_environment();
|
||||||
|
static void assign(char **ptr, char *str);
|
||||||
|
|
||||||
#define IVERILOG_VPI_CC "gcc" /* no .exe extension */
|
/* The compile options: compiler, flags, etc. are in here */
|
||||||
#define IVERILOG_VPI_CXX "gcc" /* no .exe extension */
|
#include "config.h"
|
||||||
#define IVERILOG_VPI_CFLAGS "-O" /* -I appended later */
|
|
||||||
#define IVERILOG_VPI_LD "gcc" /* no .exe extension */
|
|
||||||
#define IVERILOG_VPI_LDFLAGS "-shared -Wl,--enable-auto-image-base"
|
|
||||||
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi" /* -L prepended later */
|
|
||||||
|
|
||||||
/* pointers to global strings */
|
/* pointers to global strings */
|
||||||
|
|
||||||
static struct global_strings {
|
static struct global_strings {
|
||||||
char *pCCSRC; /* list of C source files */
|
char *pCCSRC; /* list of C source files (*.c) */
|
||||||
char *pCXSRC; /* list of C++ source files */
|
char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */
|
||||||
char *pOBJ; /* list of object files */
|
char *pOBJ; /* list of object files */
|
||||||
char *pLIB; /* list of library files */
|
char *pLIB; /* list of library files */
|
||||||
|
char *pINCS; /* list of include directories */
|
||||||
|
char *pDEFS; /* list of definitions */
|
||||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||||
char *pMINGW; /* path to MinGW directory */
|
char *pMINGW; /* path to MinGW directory */
|
||||||
char *pIVL; /* path to IVL directory */
|
char *pIVL; /* path to IVL directory */
|
||||||
char *pCFLAGS; /* CFLAGS option */
|
char *pCFLAGS; /* CFLAGS option */
|
||||||
char *pLDLIBS; /* LDLIBS option */
|
char *pLDLIBS; /* LDLIBS option */
|
||||||
char *pNewPath; /* new PATH environment variable setting */
|
char *pNewPath; /* new PATH environment variable setting */
|
||||||
|
char *pLD; /* what to use for a linker */
|
||||||
} gstr;
|
} gstr;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,12 +70,15 @@ static void myExit(int exitVal)
|
||||||
deInitDynString(gstr.pCXSRC);
|
deInitDynString(gstr.pCXSRC);
|
||||||
deInitDynString(gstr.pOBJ);
|
deInitDynString(gstr.pOBJ);
|
||||||
deInitDynString(gstr.pLIB);
|
deInitDynString(gstr.pLIB);
|
||||||
|
deInitDynString(gstr.pINCS);
|
||||||
|
deInitDynString(gstr.pDEFS);
|
||||||
deInitDynString(gstr.pOUT);
|
deInitDynString(gstr.pOUT);
|
||||||
deInitDynString(gstr.pMINGW);
|
deInitDynString(gstr.pMINGW);
|
||||||
deInitDynString(gstr.pIVL);
|
deInitDynString(gstr.pIVL);
|
||||||
deInitDynString(gstr.pCFLAGS);
|
deInitDynString(gstr.pCFLAGS);
|
||||||
deInitDynString(gstr.pLDLIBS);
|
deInitDynString(gstr.pLDLIBS);
|
||||||
deInitDynString(gstr.pNewPath);
|
deInitDynString(gstr.pNewPath);
|
||||||
|
free(gstr.pLD);
|
||||||
|
|
||||||
exit(exitVal);
|
exit(exitVal);
|
||||||
}
|
}
|
||||||
|
|
@ -84,9 +87,9 @@ static void myExit(int exitVal)
|
||||||
|
|
||||||
static void usage()
|
static void usage()
|
||||||
{
|
{
|
||||||
fprintf(stderr,"usage: iverilog-vpi [--name=name] [-llibrary] [-mingw=dir] [-ivl=dir] sourcefile...\n");
|
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
|
||||||
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
|
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
|
||||||
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
|
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=dir\n");
|
||||||
myExit(1);
|
myExit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,12 +113,16 @@ static void init()
|
||||||
initDynString(&gstr.pCXSRC);
|
initDynString(&gstr.pCXSRC);
|
||||||
initDynString(&gstr.pOBJ);
|
initDynString(&gstr.pOBJ);
|
||||||
initDynString(&gstr.pLIB);
|
initDynString(&gstr.pLIB);
|
||||||
|
initDynString(&gstr.pINCS);
|
||||||
|
initDynString(&gstr.pDEFS);
|
||||||
initDynString(&gstr.pOUT);
|
initDynString(&gstr.pOUT);
|
||||||
initDynString(&gstr.pMINGW);
|
initDynString(&gstr.pMINGW);
|
||||||
initDynString(&gstr.pIVL);
|
initDynString(&gstr.pIVL);
|
||||||
initDynString(&gstr.pCFLAGS);
|
initDynString(&gstr.pCFLAGS);
|
||||||
initDynString(&gstr.pLDLIBS);
|
initDynString(&gstr.pLDLIBS);
|
||||||
initDynString(&gstr.pNewPath);
|
initDynString(&gstr.pNewPath);
|
||||||
|
/* By default use the C compiler to link the programs. */
|
||||||
|
assign(&gstr.pLD, IVERILOG_VPI_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return true if "str" is terminated with with "end", case insensitive */
|
/* return true if "str" is terminated with with "end", case insensitive */
|
||||||
|
|
@ -277,63 +284,124 @@ static int parse(int argc, char *argv[])
|
||||||
|
|
||||||
char dot_c_ext[] = ".c";
|
char dot_c_ext[] = ".c";
|
||||||
char dot_cc_ext[] = ".cc";
|
char dot_cc_ext[] = ".cc";
|
||||||
|
char dot_cpp_ext[] = ".cpp";
|
||||||
char dot_o_ext[] = ".o";
|
char dot_o_ext[] = ".o";
|
||||||
char name_option[] = "--name=";
|
char name_option[] = "--name=";
|
||||||
char lib_option[] = "-l";
|
char lib_option[] = "-l";
|
||||||
|
char inc_option[] = "-I";
|
||||||
char mingw_option[] = "-mingw=";
|
char mingw_option[] = "-mingw=";
|
||||||
char ivl_option[] = "-ivl=";
|
char ivl_option[] = "-ivl=";
|
||||||
|
char def_option[] = "-D";
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (idx=1; idx<argc; ++idx) {
|
for (idx=1; idx<argc; ++idx) {
|
||||||
if (endsIn(dot_c_ext,argv[idx])) { /* check for C source files */
|
/* Check for C source files (*.c) */
|
||||||
|
if (endsIn(dot_c_ext, argv[idx])) {
|
||||||
++srcFileCnt;
|
++srcFileCnt;
|
||||||
append(&gstr.pCCSRC,argv[idx]);
|
append(&gstr.pCCSRC, argv[idx]);
|
||||||
append(&gstr.pCCSRC," ");
|
append(&gstr.pCCSRC, " ");
|
||||||
if (!*gstr.pOUT)
|
if (!*gstr.pOUT)
|
||||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_c_ext));
|
assignn(&gstr.pOUT, argv[idx],
|
||||||
|
strlen(argv[idx])-strlen(dot_c_ext));
|
||||||
}
|
}
|
||||||
else if (endsIn(dot_cc_ext,argv[idx])) { /* check for C++ source files */
|
/* Check for C++ source files (*.cc) */
|
||||||
|
else if (endsIn(dot_cc_ext, argv[idx])) {
|
||||||
|
/* We need to link with the C++ compiler. */
|
||||||
|
assign(&gstr.pLD, IVERILOG_VPI_CXX);
|
||||||
++srcFileCnt;
|
++srcFileCnt;
|
||||||
append(&gstr.pCXSRC,argv[idx]);
|
append(&gstr.pCXSRC, argv[idx]);
|
||||||
append(&gstr.pCXSRC," ");
|
append(&gstr.pCXSRC, " ");
|
||||||
if (!*gstr.pOUT)
|
if (!*gstr.pOUT)
|
||||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cc_ext));
|
assignn(&gstr.pOUT, argv[idx],
|
||||||
|
strlen(argv[idx])-strlen(dot_cc_ext));
|
||||||
}
|
}
|
||||||
else if (endsIn(dot_o_ext,argv[idx])) { /* check for compiled object files */
|
/* Check for C++ source files (*.cpp) */
|
||||||
|
else if (endsIn(dot_cpp_ext, argv[idx])) {
|
||||||
|
/* We need to link with the C++ compiler. */
|
||||||
|
assign(&gstr.pLD, IVERILOG_VPI_CXX);
|
||||||
|
++srcFileCnt;
|
||||||
|
append(&gstr.pCXSRC, argv[idx]);
|
||||||
|
append(&gstr.pCXSRC, " ");
|
||||||
|
if (!*gstr.pOUT)
|
||||||
|
assignn(&gstr.pOUT, argv[idx],
|
||||||
|
strlen(argv[idx])-strlen(dot_cpp_ext));
|
||||||
|
}
|
||||||
|
/* Check for compiled object files */
|
||||||
|
else if (endsIn(dot_o_ext, argv[idx])) {
|
||||||
++srcFileCnt;
|
++srcFileCnt;
|
||||||
append(&gstr.pOBJ,argv[idx]);
|
|
||||||
append(&gstr.pOBJ," ");
|
append(&gstr.pOBJ," ");
|
||||||
|
append(&gstr.pOBJ, argv[idx]);
|
||||||
if (!*gstr.pOUT)
|
if (!*gstr.pOUT)
|
||||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_o_ext));
|
assignn(&gstr.pOUT, argv[idx],
|
||||||
|
strlen(argv[idx])-strlen(dot_o_ext));
|
||||||
}
|
}
|
||||||
else if (startsWith(name_option,argv[idx])) { /* check for --name option */
|
/* Check for the -mingw option */
|
||||||
assignn(&gstr.pOUT,argv[idx]+sizeof(name_option)-1,strlen(argv[idx])-(sizeof(name_option)-1));
|
else if (startsWith(mingw_option, argv[idx]))
|
||||||
|
assignn(&gstr.pMINGW, argv[idx]+sizeof(mingw_option)-1,
|
||||||
|
strlen(argv[idx])-(sizeof(mingw_option)-1));
|
||||||
|
/* Check for the -ivl option */
|
||||||
|
else if (startsWith(ivl_option, argv[idx]))
|
||||||
|
assignn(&gstr.pIVL, argv[idx]+sizeof(ivl_option)-1,
|
||||||
|
strlen(argv[idx])-(sizeof(ivl_option)-1));
|
||||||
|
/* Check for the --name option */
|
||||||
|
else if (startsWith(name_option, argv[idx])) {
|
||||||
|
assignn(&gstr.pOUT, argv[idx]+sizeof(name_option)-1,
|
||||||
|
strlen(argv[idx])-(sizeof(name_option)-1));
|
||||||
}
|
}
|
||||||
else if (startsWith(lib_option,argv[idx])) { /* check for -l option */
|
/* Check for the -l option */
|
||||||
append(&gstr.pLIB,argv[idx]);
|
else if (startsWith(lib_option, argv[idx])) {
|
||||||
append(&gstr.pLIB," ");
|
append(&gstr.pLIB, " ");
|
||||||
|
append(&gstr.pLIB, argv[idx]);
|
||||||
}
|
}
|
||||||
else if (startsWith(mingw_option,argv[idx])) /* check for -mingw option */
|
/* Check for the -I option */
|
||||||
assignn(&gstr.pMINGW,argv[idx]+sizeof(mingw_option)-1,strlen(argv[idx])-(sizeof(mingw_option)-1));
|
else if (startsWith(inc_option, argv[idx])) {
|
||||||
else if (startsWith(ivl_option,argv[idx])) /* check for -ivl option */
|
append(&gstr.pINCS, " ");
|
||||||
assignn(&gstr.pIVL,argv[idx]+sizeof(ivl_option)-1,strlen(argv[idx])-(sizeof(ivl_option)-1));
|
append(&gstr.pINCS, argv[idx]);
|
||||||
else
|
}
|
||||||
return 0; /* different from iverilog-vpi.sh, we don't ignore accept arguments */
|
/* Check for the -D option */
|
||||||
|
else if (startsWith(def_option, argv[idx])) {
|
||||||
|
append(&gstr.pDEFS, " ");
|
||||||
|
append(&gstr.pDEFS, argv[idx]);
|
||||||
|
}
|
||||||
|
/* Check for the --cflags option */
|
||||||
|
else if (stricmp("--cflags", argv[idx]) == 0) {
|
||||||
|
setup_ivl_environment();
|
||||||
|
printf("%s\n", gstr.pCFLAGS);
|
||||||
|
myExit(0);
|
||||||
|
}
|
||||||
|
/* Check for the --ldflags option */
|
||||||
|
else if (stricmp("--ldflags", argv[idx]) == 0) {
|
||||||
|
printf("%s\n", IVERILOG_VPI_LDFLAGS);
|
||||||
|
myExit(0);
|
||||||
|
}
|
||||||
|
/* Check for the --ldlibs option */
|
||||||
|
else if (stricmp("--ldlibs", argv[idx]) == 0) {
|
||||||
|
setup_ivl_environment();
|
||||||
|
printf("%s\n", gstr.pLDLIBS);
|
||||||
|
myExit(0);
|
||||||
|
}
|
||||||
|
/* Check for the --install-dir option */
|
||||||
|
else if (stricmp("--install-dir", argv[idx]) == 0) {
|
||||||
|
setup_ivl_environment();
|
||||||
|
printf("%s\\\\lib\\\\ivl" IVERILOG_SUFFIX "\\\\.\n", gstr.pIVL);
|
||||||
|
myExit(0);
|
||||||
|
}
|
||||||
|
/* This is different than iverilog-vpi.sh, we don't
|
||||||
|
* ignore unknown arguments */
|
||||||
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == srcFileCnt)
|
/* In case there is a --name without source/object files */
|
||||||
assign(&gstr.pOUT,""); /* in case they used --name with no source files */
|
if (0 == srcFileCnt) assign(&gstr.pOUT,"");
|
||||||
|
|
||||||
if (!*gstr.pOUT) { /* normally it's an error if there are no *.c,*.cc,*.o files */
|
/* Normally it's an error if there are no source or object files */
|
||||||
if (!*gstr.pMINGW && !*gstr.pIVL) /* unless they are just setting the IVL or MinGW registry entries */
|
/* Unless we are setting the IVL or MinGW registry entries */
|
||||||
usage();
|
if (!*gstr.pOUT) {
|
||||||
}
|
if (!*gstr.pMINGW && !*gstr.pIVL) return 0;
|
||||||
else {
|
} else
|
||||||
append(&gstr.pOUT,".vpi"); /* the result file should have a .vpi extension */
|
/* We have a valid result file so add the .vpi extension */
|
||||||
append(&gstr.pOUT," ");
|
append(&gstr.pOUT, ".vpi");
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -376,14 +444,14 @@ static void checkIvlDir(char *root)
|
||||||
initDynString(&path);
|
initDynString(&path);
|
||||||
assign(&path,gstr.pIVL);
|
assign(&path,gstr.pIVL);
|
||||||
appendBackSlash(&path);
|
appendBackSlash(&path);
|
||||||
append(&path,"bin\\vvp.exe");
|
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
|
||||||
|
|
||||||
irv = _stat(path,&stat_buf);
|
irv = _stat(path,&stat_buf);
|
||||||
deInitDynString(path);
|
deInitDynString(path);
|
||||||
|
|
||||||
if (irv) {
|
if (irv) {
|
||||||
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
|
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
|
||||||
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
|
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi" IVERILOG_SUFFIX " to\n");
|
||||||
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
|
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
|
||||||
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
|
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
|
||||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||||
|
|
@ -403,9 +471,7 @@ static void setup_mingw_environment()
|
||||||
if (*gstr.pMINGW) {
|
if (*gstr.pMINGW) {
|
||||||
checkMingwDir(gstr.pMINGW);
|
checkMingwDir(gstr.pMINGW);
|
||||||
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
|
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
|
||||||
}
|
} else if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
|
||||||
else
|
|
||||||
if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
|
|
||||||
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
|
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
|
||||||
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||||
fprintf(stderr," a Windows command shell the option would be something like\n");
|
fprintf(stderr," a Windows command shell the option would be something like\n");
|
||||||
|
|
@ -414,13 +480,16 @@ static void setup_mingw_environment()
|
||||||
myExit(5);
|
myExit(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
assign(&gstr.pNewPath,"PATH="); /* create new path */
|
/* Create new path with MinGW in it */
|
||||||
|
assign(&gstr.pNewPath,"PATH=");
|
||||||
append(&gstr.pNewPath,gstr.pMINGW);
|
append(&gstr.pNewPath,gstr.pMINGW);
|
||||||
appendBackSlash(&gstr.pNewPath);
|
appendBackSlash(&gstr.pNewPath);
|
||||||
|
append(&gstr.pNewPath, "\\");
|
||||||
append(&gstr.pNewPath,"bin;");
|
append(&gstr.pNewPath,"bin;");
|
||||||
append(&gstr.pNewPath,pOldPATH);
|
append(&gstr.pNewPath,pOldPATH);
|
||||||
|
|
||||||
_putenv(gstr.pNewPath); /* place new path in environment variable */
|
/* Place new path in environment */
|
||||||
|
_putenv(gstr.pNewPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if we can find iverilog root */
|
/* see if we can find iverilog root */
|
||||||
|
|
@ -432,67 +501,73 @@ static void setup_ivl_environment()
|
||||||
if (*gstr.pIVL) {
|
if (*gstr.pIVL) {
|
||||||
checkIvlDir(gstr.pIVL);
|
checkIvlDir(gstr.pIVL);
|
||||||
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
|
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
|
||||||
}
|
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
|
||||||
else
|
|
||||||
if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
|
|
||||||
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
|
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
|
||||||
fprintf(stderr," of iverilog-vpi.exe to point to the Icarus Verilog root directory.\n");
|
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
|
||||||
fprintf(stderr," For a Windows command shell the option would be something like\n");
|
fprintf(stderr," For a Windows command shell the option would be something like\n");
|
||||||
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
|
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
|
||||||
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
|
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
|
||||||
myExit(6);
|
myExit(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build up the CFLAGS option string */
|
/* Build up the CFLAGS option string */
|
||||||
|
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I");
|
||||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
|
|
||||||
append(&gstr.pCFLAGS," -I");
|
|
||||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||||
appendBackSlash(&gstr.pCFLAGS);
|
appendBackSlash(&gstr.pCFLAGS);
|
||||||
append(&gstr.pCFLAGS,"include");
|
append(&gstr.pCFLAGS,"\\include\\\\iverilog" IVERILOG_SUFFIX);
|
||||||
|
|
||||||
/* build up the LDFLAGS option string */
|
|
||||||
|
|
||||||
|
/* Build up the LDFLAGS option string */
|
||||||
assign(&gstr.pLDLIBS,"-L");
|
assign(&gstr.pLDLIBS,"-L");
|
||||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||||
appendBackSlash(&gstr.pLDLIBS);
|
appendBackSlash(&gstr.pLDLIBS);
|
||||||
append(&gstr.pLDLIBS,"lib ");
|
append(&gstr.pLDLIBS,"\\lib " IVERILOG_VPI_LDLIBS);
|
||||||
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compile source modules */
|
/* compile source modules */
|
||||||
|
|
||||||
static void compile(char *pSource, char **pObject, char *ext, int *compile_errors, char *compiler)
|
static void compile(char *pSource, char **pObject, int *compile_errors, char *compiler)
|
||||||
{
|
{
|
||||||
char *ptr1 = pSource;
|
char *ptr1 = pSource;
|
||||||
char *ptr2 = strchr(pSource,' ');
|
char *ptr2 = strchr(ptr1, ' ');
|
||||||
char *buf=0,*src=0,*obj=0;
|
char *buf=0, *src=0, *obj=0;
|
||||||
|
|
||||||
while (ptr2) {
|
while (ptr2) {
|
||||||
int len = ptr2 - ptr1;
|
int len = ptr2 - ptr1;
|
||||||
assignn(&src,ptr1,len);
|
char *ostart;
|
||||||
|
int olen;
|
||||||
|
assignn(&src, ptr1, len);
|
||||||
|
|
||||||
assignn(&obj,ptr1,len-strlen(ext)); /* strip off the extension */
|
/* Build the object file name */
|
||||||
append (&obj,".o");
|
ostart = strrchr(ptr1, '/');
|
||||||
|
if (ostart == NULL) ostart = ptr1;
|
||||||
|
else ostart += 1;
|
||||||
|
olen = strrchr(ptr1, '.') - ostart;
|
||||||
|
assignn(&obj, ostart, olen);
|
||||||
|
append(&obj, ".o");
|
||||||
|
|
||||||
assign (&buf,compiler);
|
/* Build the compile line */
|
||||||
append (&buf," -c -o ");
|
assign(&buf, compiler);
|
||||||
append (&buf,obj);
|
append(&buf, " -c -o ");
|
||||||
append (&buf," ");
|
append(&buf, obj);
|
||||||
append (&buf,gstr.pCFLAGS);
|
append(&buf, " ");
|
||||||
append (&buf," ");
|
append(&buf, gstr.pDEFS);
|
||||||
append (&buf,src);
|
append(&buf, " ");
|
||||||
|
append(&buf, gstr.pCFLAGS);
|
||||||
|
append(&buf, " ");
|
||||||
|
append(&buf, gstr.pINCS);
|
||||||
|
append(&buf, " ");
|
||||||
|
append(&buf, src);
|
||||||
|
|
||||||
append (pObject,obj);
|
append (pObject, " ");
|
||||||
append (pObject," ");
|
append (pObject, obj);
|
||||||
|
|
||||||
printf("%s\n",buf);
|
printf("Compiling %s...\n", src);
|
||||||
|
|
||||||
if (system(buf))
|
if (system(buf)) ++*compile_errors;
|
||||||
++*compile_errors;
|
|
||||||
|
|
||||||
ptr1 = ptr2 + 1; /* advance to next token */
|
/* advance to next token */
|
||||||
ptr2 = strchr(ptr1,' ');
|
ptr1 = ptr2 + 1;
|
||||||
|
ptr2 = strchr(ptr1, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
@ -507,43 +582,44 @@ static void compile_and_link()
|
||||||
char *buf=0;
|
char *buf=0;
|
||||||
int iRet, compile_errors = 0;
|
int iRet, compile_errors = 0;
|
||||||
|
|
||||||
/* print out the mingw and ivl directories to help the user debug problems */
|
/* To make the output match iverilog-vpi.sh do not print out the
|
||||||
|
* root directories */
|
||||||
|
|
||||||
printf("info: %s will be used as the MinGW root directory.\n",gstr.pMINGW);
|
// printf("MinGW root directory: %s.\n", gstr.pMINGW);
|
||||||
checkMingwDir(gstr.pMINGW);
|
checkMingwDir(gstr.pMINGW);
|
||||||
|
|
||||||
printf("info: %s will be used as the Icarus Verilog root directory.\n",gstr.pIVL);
|
// printf("Icarus Verilog root directory: %s.\n", gstr.pIVL);
|
||||||
checkIvlDir(gstr.pIVL);
|
checkIvlDir(gstr.pIVL);
|
||||||
|
|
||||||
/* compile */
|
/* compile the C source files (*.c) */
|
||||||
|
compile(gstr.pCCSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
|
||||||
compile(gstr.pCCSRC,&gstr.pOBJ,".c" ,&compile_errors,IVERILOG_VPI_CC ); /* compile the C source files */
|
/* compile the C++ source files (*.cc, *.cpp) */
|
||||||
compile(gstr.pCXSRC,&gstr.pOBJ,".cc",&compile_errors,IVERILOG_VPI_CXX); /* compile the C++ source files */
|
compile(gstr.pCXSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
|
||||||
|
|
||||||
if (compile_errors) {
|
if (compile_errors) {
|
||||||
fprintf(stderr,"iverilog-vpi: Some %d files failed to compile.\n",compile_errors);
|
fprintf(stderr,"iverilog-vpi: %d file(s) failed to compile.\n",
|
||||||
|
compile_errors);
|
||||||
myExit(2);
|
myExit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* link */
|
/* link */
|
||||||
|
assign(&buf, gstr.pLD);
|
||||||
|
append(&buf, " -o ");
|
||||||
|
append(&buf, gstr.pOUT);
|
||||||
|
append(&buf, " ");
|
||||||
|
append(&buf, IVERILOG_VPI_LDFLAGS);
|
||||||
|
append(&buf, " ");
|
||||||
|
append(&buf, gstr.pOBJ);
|
||||||
|
append(&buf, " ");
|
||||||
|
append(&buf, gstr.pLIB);
|
||||||
|
append(&buf, " ");
|
||||||
|
append(&buf, gstr.pLDLIBS);
|
||||||
|
|
||||||
assign(&buf,IVERILOG_VPI_LD);
|
printf("Making %s from %s...\n", gstr.pOUT,gstr.pOBJ);
|
||||||
append(&buf," -o ");
|
|
||||||
append(&buf,gstr.pOUT); /* has a trailing space */
|
|
||||||
append(&buf,IVERILOG_VPI_LDFLAGS);
|
|
||||||
append(&buf," ");
|
|
||||||
append(&buf,gstr.pOBJ) /* has a trailing space */;
|
|
||||||
append(&buf,gstr.pLIB); /* has a trailing space */
|
|
||||||
append(&buf,gstr.pLDLIBS);
|
|
||||||
|
|
||||||
printf("%s\n",buf);
|
|
||||||
|
|
||||||
iRet = system(buf);
|
iRet = system(buf);
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
if (iRet) myExit(3);
|
||||||
if (iRet)
|
|
||||||
myExit(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* program execution starts here */
|
/* program execution starts here */
|
||||||
|
|
@ -552,14 +628,14 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
|
||||||
if (!parse(argc,argv))
|
if (!parse(argc,argv)) usage();
|
||||||
usage();
|
|
||||||
|
|
||||||
setup_mingw_environment();
|
setup_mingw_environment();
|
||||||
setup_ivl_environment();
|
setup_ivl_environment();
|
||||||
|
|
||||||
if (*gstr.pOUT) /* are there any *.c,*.cc,*.o files specified */
|
/* are there any source or object files specified */
|
||||||
compile_and_link();
|
if (*gstr.pOUT) compile_and_link();
|
||||||
|
|
||||||
myExit(0);
|
myExit(0);
|
||||||
|
return 0; // eliminate warnings.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.24 2004/10/13 22:01:34 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.24.2.3 2007/05/30 17:48:26 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
VERSION = 0.8
|
suffix = @install_suffix@
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
@ -40,8 +40,10 @@ CC = @CC@
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
MAN = @MAN@
|
||||||
|
PS2PDF = @PS2PDF@
|
||||||
|
|
||||||
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
|
||||||
CFLAGS = -Wall @CFLAGS@
|
CFLAGS = -Wall @CFLAGS@
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
|
|
@ -54,6 +56,7 @@ clean:
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f Makefile
|
rm -f Makefile
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
O = main.o substit.o cflexor.o cfparse.o
|
O = main.o substit.o cflexor.o cfparse.o
|
||||||
|
|
||||||
|
|
@ -68,41 +71,49 @@ cfparse.h cfparse.c: cfparse.y
|
||||||
|
|
||||||
|
|
||||||
main.o: main.c globals.h
|
main.o: main.c globals.h
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(DEBUGFLAGS) $(srcdir)/main.c
|
||||||
|
|
||||||
build_string.o: build_string.c globals.h
|
build_string.o: build_string.c globals.h
|
||||||
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
||||||
cfparse.o: cfparse.c globals.h cfparse_misc.h
|
cfparse.o: cfparse.c globals.h cfparse_misc.h
|
||||||
|
|
||||||
iverilog.ps: $(srcdir)/iverilog.man
|
iverilog.ps: $(srcdir)/iverilog.man
|
||||||
man -t $(srcdir)/iverilog.man > iverilog.ps
|
$(MAN) -t $(srcdir)/iverilog.man > iverilog.ps
|
||||||
|
|
||||||
iverilog.pdf: iverilog.ps
|
iverilog.pdf: iverilog.ps
|
||||||
ps2pdf iverilog.ps iverilog.pdf
|
$(PS2PDF) iverilog.ps iverilog.pdf
|
||||||
|
|
||||||
ifeq (@WIN32@,yes)
|
ifeq (@WIN32@,yes)
|
||||||
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
|
ifeq ($(MAN),none)
|
||||||
INSTALL_DOCDIR = $(mandir)/man1
|
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||||
all: iverilog.pdf
|
|
||||||
else
|
else
|
||||||
INSTALL_DOC = $(mandir)/man1/iverilog.1
|
ifeq ($(PS2PDF),none)
|
||||||
|
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||||
|
else
|
||||||
|
INSTALL_DOC = $(prefix)/iverilog$(suffix).pdf $(mandir)/man1/iverilog$(suffix).1
|
||||||
|
all: iverilog.pdf
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
INSTALL_DOCDIR = $(mandir)/man1
|
||||||
|
else
|
||||||
|
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||||
INSTALL_DOCDIR = $(mandir)/man1
|
INSTALL_DOCDIR = $(mandir)/man1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
|
install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
|
||||||
|
|
||||||
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
|
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
|
||||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
|
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog$(suffix)@EXEEXT@
|
||||||
|
|
||||||
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
|
$(mandir)/man1/iverilog$(suffix).1: $(srcdir)/iverilog.man
|
||||||
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
|
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog$(suffix).1
|
||||||
|
|
||||||
$(prefix)/iverilog.pdf: iverilog.pdf
|
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf
|
||||||
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
|
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog$(suffix).pdf
|
||||||
|
|
||||||
installdirs: ../mkinstalldirs
|
installdirs: ../mkinstalldirs
|
||||||
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
|
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(bindir)/iverilog@EXEEXT@
|
rm -f $(bindir)/iverilog$(suffix)@EXEEXT@
|
||||||
rm -f $(mandir)/man1/iverilog.1
|
rm -f $(mandir)/man1/iverilog$(suffix).1
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.TH iverilog 1 "$Date: 2004/10/04 01:10:56 $" Version "$Date: 2004/10/04 01:10:56 $"
|
.TH iverilog 1 "$Date: 2006/06/12 00:16:53 $" Version "$Date: 2006/06/12 00:16:53 $"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
iverilog - Icarus Verilog compiler
|
iverilog - Icarus Verilog compiler
|
||||||
|
|
||||||
|
|
@ -212,6 +212,12 @@ inherit timescale from another file. Both probably mean that
|
||||||
timescales are inconsistent, and simulation timing can be confusing
|
timescales are inconsistent, and simulation timing can be confusing
|
||||||
and dependent on compilation order.
|
and dependent on compilation order.
|
||||||
|
|
||||||
|
.TP 8
|
||||||
|
.B unused
|
||||||
|
This enables warnings for unused variables. This may detect variables
|
||||||
|
that are not assigned, or variables and nets that are not used, or
|
||||||
|
similar possible misuses of variables and nets.
|
||||||
|
|
||||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
||||||
a system function table file. A System function table file is used to
|
a system function table file. A System function table file is used to
|
||||||
|
|
|
||||||
165
driver/main.c
165
driver/main.c
|
|
@ -17,10 +17,11 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: main.c,v 1.65 2004/06/17 14:47:22 steve Exp $"
|
#ident "$Id: main.c,v 1.65.2.6 2007/05/30 17:48:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
# include "version.h"
|
||||||
|
|
||||||
const char NOTICE[] =
|
const char NOTICE[] =
|
||||||
" This program is free software; you can redistribute it and/or modify\n"
|
" This program is free software; you can redistribute it and/or modify\n"
|
||||||
|
|
@ -88,6 +89,10 @@ extern const char*optarg;
|
||||||
# define IVL_ROOT "."
|
# define IVL_ROOT "."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef IVL_ROOT_VARIABLE
|
||||||
|
# define IVL_ROOT_VARIABLE "IVERILOG_ROOT"
|
||||||
|
#endif
|
||||||
|
|
||||||
# include "globals.h"
|
# include "globals.h"
|
||||||
#include "cfparse_misc.h" /* cfparse() */
|
#include "cfparse_misc.h" /* cfparse() */
|
||||||
|
|
||||||
|
|
@ -262,15 +267,72 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
char *original_cmd = malloc( strlen( cmd ) + (size_t)1 );
|
||||||
|
strcpy( original_cmd, cmd );
|
||||||
|
|
||||||
|
cmd = realloc( cmd, strlen( original_cmd ) + (size_t)19 ); /* more than enough memory for the ivlpp command and ">/tmp/ivlpp_stdout" */
|
||||||
|
if( cmd == NULL ){
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
|
||||||
|
char *debug_ivl = malloc( strlen( original_cmd ) + (size_t)5 ); /* more than enough memory for "gdb " and ivl program_name */
|
||||||
|
strcpy( debug_ivl, "gdb " );
|
||||||
|
|
||||||
|
static char whitespace[] = " \t\f\r\v\n";
|
||||||
|
char *token;
|
||||||
|
int found_pipe = 0;
|
||||||
|
unsigned long token_counter = 0UL;
|
||||||
|
|
||||||
|
strcpy( cmd, "" );
|
||||||
|
for( token = strtok( original_cmd, whitespace ); token != NULL; token = strtok( NULL, whitespace ) ){
|
||||||
|
|
||||||
|
if( strcmp( token, "|" ) == 0 ){
|
||||||
|
found_pipe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( found_pipe ){
|
||||||
|
token_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( token_counter == 0UL ){
|
||||||
|
strcat( cmd, token );
|
||||||
|
strcat( cmd, " " ); /* harmless space after last token, and it was already there anyway */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( token_counter == 2UL ){
|
||||||
|
strcat( debug_ivl, token );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( token_counter > 2UL ){
|
||||||
|
printf( "%s\n", token );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free( original_cmd );
|
||||||
|
strcat( cmd, ">/tmp/ivlpp_stdout" );
|
||||||
|
#endif
|
||||||
|
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
printf("translate: %s\n", cmd);
|
printf("translate: %s\n", cmd);
|
||||||
|
|
||||||
|
|
||||||
rc = system(cmd);
|
rc = system(cmd);
|
||||||
|
#ifdef DEBUG
|
||||||
|
if( verbose_flag ){
|
||||||
|
printf( "%s\n", debug_ivl );
|
||||||
|
}
|
||||||
|
|
||||||
|
system( debug_ivl ); /* For simplicity, ignore any return value, which is implementation dependent anyway. */
|
||||||
|
free( debug_ivl );
|
||||||
|
#endif
|
||||||
remove(source_path);
|
remove(source_path);
|
||||||
if ( ! getenv("IVERILOG_ICONFIG"))
|
if ( ! getenv("IVERILOG_ICONFIG"))
|
||||||
remove(iconfig_path);
|
remove(iconfig_path);
|
||||||
|
#ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */
|
||||||
|
return rc;
|
||||||
|
#else
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
if (rc == 127) {
|
if (rc == 127) {
|
||||||
fprintf(stderr, "Failed to execute: %s\n", cmd);
|
fprintf(stderr, "Failed to execute: %s\n", cmd);
|
||||||
|
|
@ -285,13 +347,14 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void process_warning_switch(const char*name)
|
static void process_warning_switch(const char*name)
|
||||||
{
|
{
|
||||||
if (strcmp(name,"all") == 0) {
|
if (strcmp(name,"all") == 0) {
|
||||||
strcat(warning_flags, "ipt");
|
strcat(warning_flags, "iptu");
|
||||||
|
|
||||||
} else if (strcmp(name,"implicit") == 0) {
|
} else if (strcmp(name,"implicit") == 0) {
|
||||||
if (! strchr(warning_flags+2, 'i'))
|
if (! strchr(warning_flags+2, 'i'))
|
||||||
|
|
@ -302,6 +365,9 @@ static void process_warning_switch(const char*name)
|
||||||
} else if (strcmp(name,"timescale") == 0) {
|
} else if (strcmp(name,"timescale") == 0) {
|
||||||
if (! strchr(warning_flags+2, 't'))
|
if (! strchr(warning_flags+2, 't'))
|
||||||
strcat(warning_flags, "t");
|
strcat(warning_flags, "t");
|
||||||
|
} else if (strcmp(name,"unused") == 0) {
|
||||||
|
if (! strchr(warning_flags+2, 'u'))
|
||||||
|
strcat(warning_flags, "u");
|
||||||
} else if (strcmp(name,"no-implicit") == 0) {
|
} else if (strcmp(name,"no-implicit") == 0) {
|
||||||
char*cp = strchr(warning_flags+2, 'i');
|
char*cp = strchr(warning_flags+2, 'i');
|
||||||
if (cp) while (*cp) {
|
if (cp) while (*cp) {
|
||||||
|
|
@ -320,6 +386,12 @@ static void process_warning_switch(const char*name)
|
||||||
cp[0] = cp[1];
|
cp[0] = cp[1];
|
||||||
cp += 1;
|
cp += 1;
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(name,"no-unused") == 0) {
|
||||||
|
char*cp = strchr(warning_flags+2, 'u');
|
||||||
|
if (cp) while (*cp) {
|
||||||
|
cp[0] = cp[1];
|
||||||
|
cp += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,14 +481,13 @@ int process_generation(const char*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
/*
|
||||||
|
* This function fills in th ivl_root directory with the appropriate
|
||||||
|
* path, based on operating system, build time configuration, and
|
||||||
|
* environment.
|
||||||
|
*/
|
||||||
|
static char* get_root_dir()
|
||||||
{
|
{
|
||||||
char*cmd;
|
|
||||||
unsigned ncmd;
|
|
||||||
int e_flag = 0;
|
|
||||||
int version_flag = 0;
|
|
||||||
int opt, idx, rc;
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
{ char * s;
|
{ char * s;
|
||||||
char basepath[1024];
|
char basepath[1024];
|
||||||
|
|
@ -443,16 +514,56 @@ int main(int argc, char **argv)
|
||||||
s = strrchr(ivl_root, sep);
|
s = strrchr(ivl_root, sep);
|
||||||
if (s) *s = 0;
|
if (s) *s = 0;
|
||||||
strcat(ivl_root, "\\lib\\ivl");
|
strcat(ivl_root, "\\lib\\ivl");
|
||||||
|
|
||||||
base = ivl_root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* In a UNIX environment, the IVL_ROOT from the Makefile is
|
|
||||||
dependable. It points to the $prefix/lib/ivl directory,
|
{ char*var = 0;
|
||||||
where the sub-parts are installed. */
|
|
||||||
strcpy(ivl_root, IVL_ROOT);
|
/* In other systems, use the configured root. */
|
||||||
base = ivl_root;
|
strcpy(ivl_root, IVL_ROOT);
|
||||||
|
|
||||||
|
/* In any case, the IVL_ROOT variable can be used to override
|
||||||
|
the install location at run time. If it is set, use that
|
||||||
|
value instead. */
|
||||||
|
if ( (var = getenv(IVL_ROOT_VARIABLE)) ) {
|
||||||
|
strncpy(ivl_root, var, MAXSIZE);
|
||||||
|
strcat(ivl_root, "/lib/ivl");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ivl_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char*cmd;
|
||||||
|
unsigned ncmd;
|
||||||
|
int e_flag = 0;
|
||||||
|
int version_flag = 0;
|
||||||
|
int opt, idx, rc;
|
||||||
|
|
||||||
|
base = get_root_dir();
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
/* Under Windows, there is no point checking the root
|
||||||
|
directory. */
|
||||||
|
#else
|
||||||
|
/* On other systems, check that the root directory seems
|
||||||
|
reasonable. */
|
||||||
|
{ size_t tmp_len = strlen(base) + 16;
|
||||||
|
char* tmp = malloc(tmp_len);
|
||||||
|
snprintf(tmp, tmp_len, "%s%civl", base, sep);
|
||||||
|
|
||||||
|
if (0 != access(tmp, F_OK)) {
|
||||||
|
fprintf(stderr, "%s: INSTALLATION ERROR: Directory %s"
|
||||||
|
" does not contain ivl files.\n", argv[0], base);
|
||||||
|
fprintf(stderr, "%s: : Check installation"
|
||||||
|
" or set " IVL_ROOT_VARIABLE " correctly.\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a temporary file for communicating input parameters
|
/* Create a temporary file for communicating input parameters
|
||||||
|
|
@ -594,7 +705,7 @@ int main(int argc, char **argv)
|
||||||
pbase = base;
|
pbase = base;
|
||||||
|
|
||||||
if (version_flag || verbose_flag) {
|
if (version_flag || verbose_flag) {
|
||||||
printf("Icarus Verilog version " VERSION " ($Name: $)\n");
|
printf("Icarus Verilog version " VERSION "\n\n");
|
||||||
printf("Copyright 1998-2003 Stephen Williams\n");
|
printf("Copyright 1998-2003 Stephen Williams\n");
|
||||||
puts(NOTICE);
|
puts(NOTICE);
|
||||||
|
|
||||||
|
|
@ -735,6 +846,24 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: main.c,v $
|
* $Log: main.c,v $
|
||||||
|
* Revision 1.65.2.6 2007/05/30 17:48:26 steve
|
||||||
|
* DEBUG aids. (Alan Feldstein)
|
||||||
|
*
|
||||||
|
* Revision 1.65.2.5 2006/07/07 21:31:50 steve
|
||||||
|
* Root dir variable does not include lib/ivl components.
|
||||||
|
*
|
||||||
|
* Revision 1.65.2.4 2006/06/27 01:30:20 steve
|
||||||
|
* Fix unused var warning for mingw32 build.
|
||||||
|
*
|
||||||
|
* Revision 1.65.2.3 2006/06/14 03:01:49 steve
|
||||||
|
* Remove redundant call to get_root_dir.
|
||||||
|
*
|
||||||
|
* Revision 1.65.2.2 2006/06/12 00:16:53 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
|
* Revision 1.65.2.1 2006/03/26 21:47:26 steve
|
||||||
|
* More installation directory flexibility.
|
||||||
|
*
|
||||||
* Revision 1.65 2004/06/17 14:47:22 steve
|
* Revision 1.65 2004/06/17 14:47:22 steve
|
||||||
* Add a .sft file for the system functions.
|
* Add a .sft file for the system functions.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
11
dup_expr.cc
11
dup_expr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: dup_expr.cc,v 1.18 2004/06/17 16:06:18 steve Exp $"
|
#ident "$Id: dup_expr.cc,v 1.18.2.2 2006/11/02 02:13:15 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -29,6 +29,7 @@ NetEBComp* NetEBComp::dup_expr() const
|
||||||
{
|
{
|
||||||
NetEBComp*result = new NetEBComp(op_, left_->dup_expr(),
|
NetEBComp*result = new NetEBComp(op_, left_->dup_expr(),
|
||||||
right_->dup_expr());
|
right_->dup_expr());
|
||||||
|
result->set_line(*this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,6 +91,7 @@ NetESignal* NetESignal::dup_expr() const
|
||||||
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
|
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
tmp->expr_width(expr_width());
|
tmp->expr_width(expr_width());
|
||||||
|
tmp->set_line(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,6 +120,7 @@ NetEUFunc* NetEUFunc::dup_expr() const
|
||||||
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
|
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
|
||||||
|
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
tmp->set_line(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,6 +146,12 @@ NetEVariable* NetEVariable::dup_expr() const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: dup_expr.cc,v $
|
* $Log: dup_expr.cc,v $
|
||||||
|
* Revision 1.18.2.2 2006/11/02 02:13:15 steve
|
||||||
|
* Error message for condit expression not synthesized.
|
||||||
|
*
|
||||||
|
* Revision 1.18.2.1 2006/06/12 00:16:50 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
* Revision 1.18 2004/06/17 16:06:18 steve
|
* Revision 1.18 2004/06/17 16:06:18 steve
|
||||||
* Help system function signedness survive elaboration.
|
* Help system function signedness survive elaboration.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
105
elab_expr.cc
105
elab_expr.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2003 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2006 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_expr.cc,v 1.91 2004/10/04 01:10:52 steve Exp $"
|
#ident "$Id: elab_expr.cc,v 1.91.2.2 2006/11/02 02:13:15 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -43,7 +43,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
|
||||||
* and right sides, and creating one of a variety of different NetExpr
|
* and right sides, and creating one of a variety of different NetExpr
|
||||||
* types.
|
* types.
|
||||||
*/
|
*/
|
||||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
NetExpr* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
{
|
{
|
||||||
assert(left_);
|
assert(left_);
|
||||||
assert(right_);
|
assert(right_);
|
||||||
|
|
@ -73,7 +73,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
|
NetExpr*tmp = elaborate_expr_base_(des, lp, rp);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,11 +82,11 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
* operands are elaborated as necessary, and all I need to do is make
|
* operands are elaborated as necessary, and all I need to do is make
|
||||||
* the correct NetEBinary object and connect the parameters.
|
* the correct NetEBinary object and connect the parameters.
|
||||||
*/
|
*/
|
||||||
NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
NetExpr* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
NetExpr*lp, NetExpr*rp) const
|
NetExpr*lp, NetExpr*rp) const
|
||||||
{
|
{
|
||||||
bool flag;
|
bool flag;
|
||||||
NetEBinary*tmp;
|
NetExpr*tmp;
|
||||||
|
|
||||||
switch (op_) {
|
switch (op_) {
|
||||||
default:
|
default:
|
||||||
|
|
@ -112,6 +112,51 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l': // <<
|
case 'l': // <<
|
||||||
|
if (NetEConst*lpc = dynamic_cast<NetEConst*> (lp)) {
|
||||||
|
if (NetEConst*rpc = dynamic_cast<NetEConst*> (rp)) {
|
||||||
|
// Handle the super-special case that both
|
||||||
|
// operands are constants. Precalculate the
|
||||||
|
// entire value here.
|
||||||
|
verinum lpval = lpc->value();
|
||||||
|
unsigned shift = rpc->value().as_ulong();
|
||||||
|
verinum result = lpc->value() << shift;
|
||||||
|
// If the l-value has explicit size, use that.
|
||||||
|
if (lpval.has_len()) {
|
||||||
|
result = verinum(result, lpval.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = new NetEConst(result);
|
||||||
|
if (debug_elaborate)
|
||||||
|
cerr << get_line() << ": debug: "
|
||||||
|
<< "Precalculate " << *this
|
||||||
|
<< " to constant " << *tmp << endl;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Handle the special case that the left
|
||||||
|
// operand is constant. If it is unsized, we
|
||||||
|
// may have to expand it to an integer width.
|
||||||
|
verinum lpval = lpc->value();
|
||||||
|
if (lpval.len() < 32 && !lpval.has_len()) {
|
||||||
|
lpval = verinum(lpval, 32);
|
||||||
|
lpc = new NetEConst(lpval);
|
||||||
|
lpc->set_line(*lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = new NetEBShift(op_, lpc, rp);
|
||||||
|
if (debug_elaborate)
|
||||||
|
cerr << get_line() << ": debug: "
|
||||||
|
<< "Adjust " << *this
|
||||||
|
<< " to this " << *tmp
|
||||||
|
<< " to allow for integer widths." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Left side is not constant, so handle it the
|
||||||
|
// default way.
|
||||||
|
tmp = new NetEBShift(op_, lp, rp);
|
||||||
|
}
|
||||||
|
tmp->set_line(*this);
|
||||||
|
break;
|
||||||
case 'r': // >>
|
case 'r': // >>
|
||||||
case 'R': // >>>
|
case 'R': // >>>
|
||||||
tmp = new NetEBShift(op_, lp, rp);
|
tmp = new NetEBShift(op_, lp, rp);
|
||||||
|
|
@ -387,13 +432,16 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
if (NetNet*res = dscope->find_signal(dscope->basename())) {
|
if (NetNet*res = dscope->find_signal(dscope->basename())) {
|
||||||
NetESignal*eres = new NetESignal(res);
|
NetESignal*eres = new NetESignal(res);
|
||||||
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
||||||
|
eres->set_line(*this);
|
||||||
|
func->set_line(*this);
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetVariable*res = dscope->find_variable(dscope->basename())) {
|
if (NetVariable*res = dscope->find_variable(dscope->basename())) {
|
||||||
NetEVariable*eres = new NetEVariable(res);
|
NetEVariable*eres = new NetEVariable(res);
|
||||||
eres->set_line(*res);
|
|
||||||
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
||||||
|
eres->set_line(*res);
|
||||||
|
func->set_line(*this);
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,6 +473,29 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rep->value().is_defined()) {
|
||||||
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
<< "may not be undefined (" << rep->value()
|
||||||
|
<< ")." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rep->value().is_negative()) {
|
||||||
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
<< "may not be negative (" << rep->value().as_long()
|
||||||
|
<< ")." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rep->value().is_zero()) {
|
||||||
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
<< "may not be zero." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
repeat = rep;
|
repeat = rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -497,6 +568,17 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
NetScope*found_in = symbol_search(des, scope, path_,
|
NetScope*found_in = symbol_search(des, scope, path_,
|
||||||
net, mem, var, par, eve);
|
net, mem, var, par, eve);
|
||||||
|
|
||||||
|
if (net && mem) {
|
||||||
|
assert(net == mem->reg_from_explode());
|
||||||
|
net = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net && net->mref()) {
|
||||||
|
mem = net->mref();
|
||||||
|
assert(net == mem->reg_from_explode());
|
||||||
|
net = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// If the identifier name is a parameter name, then return
|
// If the identifier name is a parameter name, then return
|
||||||
// a reference to the parameter expression.
|
// a reference to the parameter expression.
|
||||||
if (par != 0) {
|
if (par != 0) {
|
||||||
|
|
@ -742,6 +824,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
NetESignal*node = new NetESignal(net);
|
NetESignal*node = new NetESignal(net);
|
||||||
|
node->set_line(*this);
|
||||||
assert(idx_ == 0);
|
assert(idx_ == 0);
|
||||||
|
|
||||||
// Non-constant bit select? punt and make a subsignal
|
// Non-constant bit select? punt and make a subsignal
|
||||||
|
|
@ -1005,6 +1088,12 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_expr.cc,v $
|
* $Log: elab_expr.cc,v $
|
||||||
|
* Revision 1.91.2.2 2006/11/02 02:13:15 steve
|
||||||
|
* Error message for condit expression not synthesized.
|
||||||
|
*
|
||||||
|
* Revision 1.91.2.1 2006/06/12 00:16:50 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
* Revision 1.91 2004/10/04 01:10:52 steve
|
* Revision 1.91 2004/10/04 01:10:52 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
77
elab_net.cc
77
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_net.cc,v 1.138 2004/10/04 03:09:38 steve Exp $"
|
#ident "$Id: elab_net.cc,v 1.138.2.3 2005/09/11 02:56:37 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a state flag that determines whether an elaborate_net must
|
* This is a state flag that determines whether an elaborate_net must
|
||||||
|
|
@ -498,7 +499,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||||
use of the situation, or 0 if it cannot. */
|
use of the situation, or 0 if it cannot. */
|
||||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(rexp)) {
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(rexp)) {
|
||||||
|
|
||||||
lsig = lexp->synthesize(des);
|
lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||||
if (lsig == 0) {
|
if (lsig == 0) {
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
"Cannot elaborate net for " << *lexp << endl;
|
"Cannot elaborate net for " << *lexp << endl;
|
||||||
|
|
@ -518,7 +519,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(lexp)) {
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(lexp)) {
|
||||||
|
|
||||||
rsig = rexp->synthesize(des);
|
rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||||
assert(rsig);
|
assert(rsig);
|
||||||
delete rexp;
|
delete rexp;
|
||||||
|
|
||||||
|
|
@ -532,13 +533,13 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lsig == 0) {
|
if (lsig == 0) {
|
||||||
lsig = lexp->synthesize(des);
|
lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||||
assert(lsig);
|
assert(lsig);
|
||||||
delete lexp;
|
delete lexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsig == 0) {
|
if (rsig == 0) {
|
||||||
rsig = rexp->synthesize(des);
|
rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||||
assert(rsig);
|
assert(rsig);
|
||||||
delete rexp;
|
delete rexp;
|
||||||
}
|
}
|
||||||
|
|
@ -1216,6 +1217,13 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path_.peek_name(0)[0] == '$') {
|
||||||
|
cerr << get_line() << ": sorry: System functions " << path_ <<
|
||||||
|
" not supported in continuous assignments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Look up the function definition. */
|
/* Look up the function definition. */
|
||||||
NetFuncDef*def = des->find_function(scope, path_);
|
NetFuncDef*def = des->find_function(scope, path_);
|
||||||
if (def == 0) {
|
if (def == 0) {
|
||||||
|
|
@ -1312,21 +1320,47 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope,
|
||||||
unsigned repeat = 1;
|
unsigned repeat = 1;
|
||||||
|
|
||||||
if (repeat_) {
|
if (repeat_) {
|
||||||
verinum*rep = repeat_->eval_const(des, scope);
|
auto_ptr<NetExpr> etmp (elab_and_eval(des, scope, repeat_));
|
||||||
if (rep == 0) {
|
assert(etmp.get());
|
||||||
|
NetEConst*erep = dynamic_cast<NetEConst*>(etmp.get());
|
||||||
|
|
||||||
|
if (erep == 0) {
|
||||||
cerr << get_line() << ": internal error: Unable to "
|
cerr << get_line() << ": internal error: Unable to "
|
||||||
<< "evaluate constant repeat expression." << endl;
|
<< "evaluate constant repeat expression." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
repeat = rep->as_ulong();
|
repeat = erep->value().as_ulong();
|
||||||
|
|
||||||
if (repeat == 0) {
|
if (repeat == 0) {
|
||||||
cerr << get_line() << ": error: Invalid repeat value."
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
"may not be 0."
|
||||||
<< endl;
|
<< endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
delete rep;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!erep->value().is_defined()) {
|
||||||
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
<< "may not be undefined (" << erep->value()
|
||||||
|
<< ")." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (erep->value().is_negative()) {
|
||||||
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
<< "may not be negative (" << erep->value().as_long()
|
||||||
|
<< ")." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (erep->value().is_zero()) {
|
||||||
|
cerr << get_line() << ": error: Concatenation repeat "
|
||||||
|
<< "may not be zero." << endl;
|
||||||
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1435,6 +1469,7 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetMux*mux = new NetMux(scope, scope->local_symbol(), 1,
|
NetMux*mux = new NetMux(scope, scope->local_symbol(), 1,
|
||||||
sig_width, sel->pin_count());
|
sig_width, sel->pin_count());
|
||||||
|
mux->set_line(*this);
|
||||||
|
|
||||||
/* Connect the signal bits to the mux. Account for the
|
/* Connect the signal bits to the mux. Account for the
|
||||||
direction of the numbering (lsb to msb vs. msb to lsb) by
|
direction of the numbering (lsb to msb vs. msb to lsb) by
|
||||||
|
|
@ -2268,6 +2303,7 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope,
|
||||||
(true) connected to tru_sig. */
|
(true) connected to tru_sig. */
|
||||||
|
|
||||||
NetMux*mux = new NetMux(scope, scope->local_symbol(), dwidth, 2, 1);
|
NetMux*mux = new NetMux(scope, scope->local_symbol(), dwidth, 2, 1);
|
||||||
|
mux->set_line(*this);
|
||||||
connect(mux->pin_Sel(0), expr_sig->pin(0));
|
connect(mux->pin_Sel(0), expr_sig->pin(0));
|
||||||
|
|
||||||
/* Connect the data inputs. */
|
/* Connect the data inputs. */
|
||||||
|
|
@ -2413,6 +2449,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
reduction=true; gtype = NetLogic::XNOR; break;
|
reduction=true; gtype = NetLogic::XNOR; break;
|
||||||
|
|
||||||
case '-': // Unary 2's complement.
|
case '-': // Unary 2's complement.
|
||||||
|
if (owidth == 0)
|
||||||
|
owidth = sub_sig->pin_count();
|
||||||
|
|
||||||
sig = new NetNet(scope, scope->local_symbol(),
|
sig = new NetNet(scope, scope->local_symbol(),
|
||||||
NetNet::WIRE, owidth);
|
NetNet::WIRE, owidth);
|
||||||
sig->local_flag(true);
|
sig->local_flag(true);
|
||||||
|
|
@ -2459,15 +2498,15 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(),
|
NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(),
|
||||||
sig->pin_count());
|
owidth);
|
||||||
sub->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
|
sub->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
|
||||||
|
|
||||||
des->add_node(sub);
|
des->add_node(sub);
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < sig->pin_count(); idx += 1)
|
for (unsigned idx = 0 ; idx < owidth ; idx += 1)
|
||||||
connect(sig->pin(idx), sub->pin_Result(idx));
|
connect(sig->pin(idx), sub->pin_Result(idx));
|
||||||
|
|
||||||
for (unsigned idx = 0; idx < sub_sig->pin_count(); idx += 1)
|
for (unsigned idx = 0; idx < owidth; idx += 1)
|
||||||
connect(sub_sig->pin(idx), sub->pin_DataB(idx));
|
connect(sub_sig->pin(idx), sub->pin_DataB(idx));
|
||||||
|
|
||||||
verinum tmp_num (verinum::V0, sub->width(), true);
|
verinum tmp_num (verinum::V0, sub->width(), true);
|
||||||
|
|
@ -2477,8 +2516,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
des->add_node(tmp_con);
|
des->add_node(tmp_con);
|
||||||
|
|
||||||
NetNet*tmp_sig = new NetNet(scope, scope->local_symbol(),
|
NetNet*tmp_sig = new NetNet(scope, scope->local_symbol(),
|
||||||
NetNet::WIRE,
|
NetNet::WIRE, owidth);
|
||||||
sub_sig->pin_count());
|
|
||||||
tmp_sig->local_flag(true);
|
tmp_sig->local_flag(true);
|
||||||
|
|
||||||
for (unsigned idx = 0; idx < sig->pin_count(); idx += 1) {
|
for (unsigned idx = 0; idx < sig->pin_count(); idx += 1) {
|
||||||
|
|
@ -2513,6 +2551,15 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_net.cc,v $
|
* $Log: elab_net.cc,v $
|
||||||
|
* Revision 1.138.2.3 2005/09/11 02:56:37 steve
|
||||||
|
* Attach line numbers to NetMux devices.
|
||||||
|
*
|
||||||
|
* Revision 1.138.2.2 2005/02/19 16:39:30 steve
|
||||||
|
* Spellig fixes.
|
||||||
|
*
|
||||||
|
* Revision 1.138.2.1 2005/01/29 00:18:23 steve
|
||||||
|
* Fix evaluate of constants in netlist concatenation repeats.
|
||||||
|
*
|
||||||
* Revision 1.138 2004/10/04 03:09:38 steve
|
* Revision 1.138 2004/10/04 03:09:38 steve
|
||||||
* Fix excessive error message.
|
* Fix excessive error message.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
|
NetExpr*tmp = elaborate_expr_base_(des, lp, rp);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Elaboration happens in two passes, generally. The first scans the
|
* Elaboration happens in two passes, generally. The first scans the
|
||||||
|
|
@ -432,6 +433,9 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
; cur != replace.end() ; cur ++ ) {
|
; cur != replace.end() ; cur ++ ) {
|
||||||
|
|
||||||
PExpr*tmp = (*cur).second;
|
PExpr*tmp = (*cur).second;
|
||||||
|
// No expression means that the parameter is not
|
||||||
|
// replaced at all.
|
||||||
|
if (tmp == 0) continue;
|
||||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||||
if (! flag) {
|
if (! flag) {
|
||||||
|
|
@ -444,7 +448,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
|
|
||||||
/* Stash the instance array of scopes into the parent
|
/* Stash the instance array of scopes into the parent
|
||||||
scope. Later elaboration passes will use this vector to
|
scope. Later elaboration passes will use this vector to
|
||||||
further elaborate the array. */
|
further elaborate the array.
|
||||||
|
|
||||||
|
Note that the array is ordered from LSB to MSB. We will use
|
||||||
|
that fact in the main elaborate to connect things in the
|
||||||
|
correct order. */
|
||||||
sc->instance_arrays[get_name()] = instances;
|
sc->instance_arrays[get_name()] = instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
# include <cstdlib>
|
||||||
|
|
||||||
# include "Module.h"
|
# include "Module.h"
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
|
|
|
||||||
317
elaborate.cc
317
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elaborate.cc,v 1.308 2004/10/04 01:10:52 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.308.2.6 2006/11/27 01:47:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -67,6 +67,21 @@ void PGate::elaborate(Design*des, NetScope*scope) const
|
||||||
typeid(*this).name() << endl;
|
typeid(*this).name() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_attributes(Design*des, NetScope*scope,
|
||||||
|
Attrib*dest, const map<perm_string,PExpr*>&table)
|
||||||
|
{
|
||||||
|
struct attrib_list_t*attrib_list = 0;
|
||||||
|
unsigned attrib_list_n = 0;
|
||||||
|
attrib_list = evaluate_attributes(table, attrib_list_n,
|
||||||
|
des, scope);
|
||||||
|
|
||||||
|
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
|
||||||
|
dest->attribute(attrib_list[adx].key,
|
||||||
|
attrib_list[adx].val);
|
||||||
|
|
||||||
|
delete[]attrib_list;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Elaborate the continuous assign. (This is *not* the procedural
|
* Elaborate the continuous assign. (This is *not* the procedural
|
||||||
* assign.) Elaborate the lvalue and rvalue, and do the assignment.
|
* assign.) Elaborate the lvalue and rvalue, and do the assignment.
|
||||||
|
|
@ -354,76 +369,212 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case AND:
|
case AND:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::AND);
|
cerr << get_line() << ": error: the AND "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::AND);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BUF:
|
case BUF:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::BUF);
|
cerr << get_line() << ": error: the BUF "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else if (pin_count() > 2) {
|
||||||
|
cerr << get_line() << ": sorry: the BUF "
|
||||||
|
"primitive may only have one output in V0.8." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::BUF);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BUFIF0:
|
case BUFIF0:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::BUFIF0);
|
cerr << get_line() << ": error: the BUFIF0 "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::BUFIF0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BUFIF1:
|
case BUFIF1:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::BUFIF1);
|
cerr << get_line() << ": error: the BUFIF1 "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::BUFIF1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NAND:
|
case NAND:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::NAND);
|
cerr << get_line() << ": error: the NAND "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::NAND);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NMOS:
|
case NMOS:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::NMOS);
|
cerr << get_line() << ": error: the NMOS "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::NMOS);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NOR:
|
case NOR:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::NOR);
|
cerr << get_line() << ": error: the NOR "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::NOR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NOT:
|
case NOT:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::NOT);
|
cerr << get_line() << ": error: the NOT "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else if (pin_count() > 2) {
|
||||||
|
cerr << get_line() << ": sorry: the NOT "
|
||||||
|
"primitive may only have one output in V0.8." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::NOT);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NOTIF0:
|
case NOTIF0:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::NOTIF0);
|
cerr << get_line() << ": error: the NOTIF0 "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::NOTIF0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NOTIF1:
|
case NOTIF1:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::NOTIF1);
|
cerr << get_line() << ": error: the NOTIF1 "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::NOTIF1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OR:
|
case OR:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::OR);
|
cerr << get_line() << ": error: the OR "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::OR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case RNMOS:
|
case RNMOS:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::RNMOS);
|
cerr << get_line() << ": error: the RNMOS "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::RNMOS);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case RPMOS:
|
case RPMOS:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::RPMOS);
|
cerr << get_line() << ": error: the RPMOS "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::RPMOS);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PMOS:
|
case PMOS:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 3) {
|
||||||
NetLogic::PMOS);
|
cerr << get_line() << ": error: the PMOS "
|
||||||
|
"primitive must have three arguments." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::PMOS);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PULLDOWN:
|
case PULLDOWN:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 1) {
|
||||||
NetLogic::PULLDOWN);
|
cerr << get_line() << ": sorry: the PULLDOWN "
|
||||||
|
"primitive may only have one output in V0.8." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::PULLDOWN);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PULLUP:
|
case PULLUP:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() != 1) {
|
||||||
NetLogic::PULLUP);
|
cerr << get_line() << ": sorry: the PULLUP "
|
||||||
|
"primitive may only have one output in V0.8." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::PULLUP);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XNOR:
|
case XNOR:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::XNOR);
|
cerr << get_line() << ": error: the XNOR "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::XNOR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XOR:
|
case XOR:
|
||||||
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
if (pin_count() < 2) {
|
||||||
NetLogic::XOR);
|
cerr << get_line() << ": error: the XOR "
|
||||||
|
"primitive must have an input." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cur[idx] = new NetLogic(scope, inm, pin_count(),
|
||||||
|
NetLogic::XOR);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cerr << get_line() << ": internal error: unhandled "
|
cerr << get_line() << ": internal error: unhandled "
|
||||||
|
|
@ -454,6 +605,12 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||||
const PExpr*ex = pin(idx);
|
const PExpr*ex = pin(idx);
|
||||||
|
if (ex == 0) {
|
||||||
|
cerr << get_line() << ": error: Logic gate port "
|
||||||
|
"expressions are not optional." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
NetNet*sig = (idx == 0)
|
NetNet*sig = (idx == 0)
|
||||||
? ex->elaborate_lnet(des, scope, true)
|
? ex->elaborate_lnet(des, scope, true)
|
||||||
: ex->elaborate_net(des, scope, 0, 0, 0, 0);
|
: ex->elaborate_net(des, scope, 0, 0, 0, 0);
|
||||||
|
|
@ -642,7 +799,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
unsigned prts_pin_count = 0;
|
unsigned prts_pin_count = 0;
|
||||||
|
|
||||||
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
|
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
|
||||||
NetScope*inst_scope = instance[inst];
|
// Scan the instances from MSB to LSB. The port
|
||||||
|
// will be assembled in that order as well.
|
||||||
|
NetScope*inst_scope = instance[instance.count()-inst-1];
|
||||||
|
|
||||||
// Scan the module sub-ports for this instance...
|
// Scan the module sub-ports for this instance...
|
||||||
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
|
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
|
||||||
|
|
@ -1179,6 +1338,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
|
|
||||||
NetESignal*sig = new NetESignal(tmp);
|
NetESignal*sig = new NetESignal(tmp);
|
||||||
|
sig->set_line(*this);
|
||||||
|
|
||||||
/* Generate an assignment of the l-value to the temporary... */
|
/* Generate an assignment of the l-value to the temporary... */
|
||||||
string n = scope->local_hsymbol();
|
string n = scope->local_hsymbol();
|
||||||
|
|
@ -1215,6 +1375,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/* And build up the complex statement. */
|
/* And build up the complex statement. */
|
||||||
NetBlock*bl = new NetBlock(NetBlock::SEQU, 0);
|
NetBlock*bl = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
bl->set_line(*this);
|
||||||
bl->append(a1);
|
bl->append(a1);
|
||||||
bl->append(st);
|
bl->append(st);
|
||||||
|
|
||||||
|
|
@ -1318,6 +1479,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
NetBlock*cur = new NetBlock(type, nscope);
|
NetBlock*cur = new NetBlock(type, nscope);
|
||||||
|
cur->set_line(*this);
|
||||||
bool fail_flag = false;
|
bool fail_flag = false;
|
||||||
|
|
||||||
if (nscope == 0)
|
if (nscope == 0)
|
||||||
|
|
@ -1388,6 +1550,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
NetCase*res = new NetCase(type_, expr, icount);
|
NetCase*res = new NetCase(type_, expr, icount);
|
||||||
res->set_line(*this);
|
res->set_line(*this);
|
||||||
|
process_attributes(des, scope, res, attributes);
|
||||||
|
|
||||||
/* Iterate over all the case items (guard/statement pairs)
|
/* Iterate over all the case items (guard/statement pairs)
|
||||||
elaborating them. If the guard has no expression, then this
|
elaborating them. If the guard has no expression, then this
|
||||||
|
|
@ -1403,8 +1566,12 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||||
/* If there are no expressions, then this is the
|
/* If there are no expressions, then this is the
|
||||||
default case. */
|
default case. */
|
||||||
NetProc*st = 0;
|
NetProc*st = 0;
|
||||||
if (cur->stat)
|
if (cur->stat) {
|
||||||
st = cur->stat->elaborate(des, scope);
|
st = cur->stat->elaborate(des, scope);
|
||||||
|
} else {
|
||||||
|
st = new NetBlock(NetBlock::SEQU, scope);
|
||||||
|
st->set_line(*this);
|
||||||
|
}
|
||||||
|
|
||||||
res->set_case(inum, 0, st);
|
res->set_case(inum, 0, st);
|
||||||
inum += 1;
|
inum += 1;
|
||||||
|
|
@ -1413,16 +1580,19 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/* If there are one or more expressions, then
|
/* If there are one or more expressions, then
|
||||||
iterate over the guard expressions, elaborating
|
iterate over the guard expressions, elaborating
|
||||||
a separate case for each. (Yes, the statement
|
a separate case for each. If the statement is
|
||||||
will be elaborated again for each.) */
|
nul, then put an appropriate stub in place. */
|
||||||
NetExpr*gu = 0;
|
NetExpr*gu = 0;
|
||||||
NetProc*st = 0;
|
NetProc*st = 0;
|
||||||
assert(cur->expr[e]);
|
assert(cur->expr[e]);
|
||||||
gu = elab_and_eval(des, scope, cur->expr[e]);
|
gu = elab_and_eval(des, scope, cur->expr[e]);
|
||||||
|
|
||||||
if (cur->stat)
|
if (cur->stat) {
|
||||||
st = cur->stat->elaborate(des, scope);
|
st = cur->stat->elaborate(des, scope);
|
||||||
|
} else {
|
||||||
|
st = new NetBlock(NetBlock::SEQU, scope);
|
||||||
|
st->set_line(*this);
|
||||||
|
}
|
||||||
res->set_case(inum, gu, st);
|
res->set_case(inum, gu, st);
|
||||||
inum += 1;
|
inum += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1451,12 +1621,26 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
||||||
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
|
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
|
||||||
verinum val = ce->value();
|
verinum val = ce->value();
|
||||||
delete expr;
|
delete expr;
|
||||||
if (val[0] == verinum::V1)
|
|
||||||
return if_->elaborate(des, scope);
|
verinum::V val_reduced = verinum::V0;
|
||||||
|
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||||
|
val_reduced = val_reduced | val[idx];
|
||||||
|
|
||||||
|
if (val_reduced == verinum::V1)
|
||||||
|
if (if_) {
|
||||||
|
return if_->elaborate(des, scope);
|
||||||
|
} else {
|
||||||
|
NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
else if (else_)
|
else if (else_)
|
||||||
return else_->elaborate(des, scope);
|
return else_->elaborate(des, scope);
|
||||||
else
|
else {
|
||||||
return new NetBlock(NetBlock::SEQU, 0);
|
NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the condition expression is more then 1 bits, then
|
// If the condition expression is more then 1 bits, then
|
||||||
|
|
@ -1625,6 +1809,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
NetBlock*block = new NetBlock(NetBlock::SEQU, 0);
|
NetBlock*block = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
block->set_line(*this);
|
||||||
|
|
||||||
|
|
||||||
/* Detect the case where the definition of the task is known
|
/* Detect the case where the definition of the task is known
|
||||||
|
|
@ -1702,6 +1887,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
NetESignal*sig = new NetESignal(port);
|
NetESignal*sig = new NetESignal(port);
|
||||||
|
sig->set_line(*this);
|
||||||
|
|
||||||
/* Generate the assignment statement. */
|
/* Generate the assignment statement. */
|
||||||
NetAssign*ass = new NetAssign(lv, sig);
|
NetAssign*ass = new NetAssign(lv, sig);
|
||||||
|
|
@ -1922,10 +2108,15 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
||||||
|
|
||||||
if (expr_.count() == 0) {
|
if (expr_.count() == 0) {
|
||||||
assert(enet);
|
assert(enet);
|
||||||
NexusSet*nset = enet->nex_input();
|
/* For synthesis we want just the inputs, but for the rest we
|
||||||
|
* want inputs and outputs that may cause a value to change. */
|
||||||
|
extern bool synthesis; /* Synthesis flag from main.cc */
|
||||||
|
bool rem_out = false;
|
||||||
|
if (synthesis) rem_out = true;
|
||||||
|
NexusSet*nset = enet->nex_input(rem_out);
|
||||||
if (nset == 0) {
|
if (nset == 0) {
|
||||||
cerr << get_line() << ": internal error: No NexusSet"
|
cerr << get_line() << ": error: Unable to elaborate:"
|
||||||
<< " from statement." << endl;
|
<< endl;
|
||||||
enet->dump(cerr, 6);
|
enet->dump(cerr, 6);
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return enet;
|
return enet;
|
||||||
|
|
@ -2314,6 +2505,13 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
the for loop. This is also a very specific assignment
|
the for loop. This is also a very specific assignment
|
||||||
statement. Put this into the "body" block. */
|
statement. Put this into the "body" block. */
|
||||||
sig = des->find_signal(scope, id2->path());
|
sig = des->find_signal(scope, id2->path());
|
||||||
|
if (sig == 0) {
|
||||||
|
cerr << get_line() << ": error: Unable to find variable "
|
||||||
|
<< id2->path() << " in for-loop increment expression." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
assert(sig);
|
assert(sig);
|
||||||
lv = new NetAssign_(sig);
|
lv = new NetAssign_(sig);
|
||||||
|
|
||||||
|
|
@ -2481,6 +2679,7 @@ void PTask::elaborate(Design*des, NetScope*task) const
|
||||||
NetProc*st;
|
NetProc*st;
|
||||||
if (statement_ == 0) {
|
if (statement_ == 0) {
|
||||||
st = new NetBlock(NetBlock::SEQU, 0);
|
st = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
st->set_line(*this);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -2769,6 +2968,24 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.308.2.6 2006/11/27 01:47:14 steve
|
||||||
|
* Fix crash handling constant true conditional.
|
||||||
|
*
|
||||||
|
* Revision 1.308.2.5 2006/11/27 01:32:24 steve
|
||||||
|
* Fix evaluate of constant condition expressions.
|
||||||
|
*
|
||||||
|
* Revision 1.308.2.4 2006/07/10 00:21:50 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
|
* Revision 1.308.2.3 2006/06/12 00:16:51 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
|
* Revision 1.308.2.2 2005/12/10 03:30:50 steve
|
||||||
|
* Fix crash on block with assignments that assign lval to self.
|
||||||
|
*
|
||||||
|
* Revision 1.308.2.1 2005/11/13 22:28:14 steve
|
||||||
|
* Do not panic if case statement is nul.
|
||||||
|
*
|
||||||
* Revision 1.308 2004/10/04 01:10:52 steve
|
* Revision 1.308 2004/10/04 01:10:52 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
19
emit.cc
19
emit.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: emit.cc,v 1.77 2004/10/04 01:10:53 steve Exp $"
|
#ident "$Id: emit.cc,v 1.77.2.2 2006/03/26 23:09:21 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
bool NetNode::emit_node(struct target_t*tgt) const
|
bool NetNode::emit_node(struct target_t*tgt) const
|
||||||
{
|
{
|
||||||
|
|
@ -86,6 +87,16 @@ bool NetConst::emit_node(struct target_t*tgt) const
|
||||||
return tgt->net_const(this);
|
return tgt->net_const(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NetDecode::emit_node(struct target_t*tgt) const
|
||||||
|
{
|
||||||
|
return tgt->lpm_decode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetDemux::emit_node(struct target_t*tgt) const
|
||||||
|
{
|
||||||
|
return tgt->lpm_demux(this);
|
||||||
|
}
|
||||||
|
|
||||||
bool NetDivide::emit_node(struct target_t*tgt) const
|
bool NetDivide::emit_node(struct target_t*tgt) const
|
||||||
{
|
{
|
||||||
tgt->lpm_divide(this);
|
tgt->lpm_divide(this);
|
||||||
|
|
@ -511,6 +522,12 @@ bool emit(const Design*des, const char*type)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: emit.cc,v $
|
* $Log: emit.cc,v $
|
||||||
|
* Revision 1.77.2.2 2006/03/26 23:09:21 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.77.2.1 2006/02/19 00:11:31 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
* Revision 1.77 2004/10/04 01:10:53 steve
|
* Revision 1.77 2004/10/04 01:10:53 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
37
eval.cc
37
eval.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: eval.cc,v 1.36 2003/06/21 01:21:43 steve Exp $"
|
#ident "$Id: eval.cc,v 1.36.2.3 2006/09/20 20:27:02 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -112,7 +112,10 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||||
case 'l': { // left shift (<<)
|
case 'l': { // left shift (<<)
|
||||||
assert(r->is_defined());
|
assert(r->is_defined());
|
||||||
unsigned long rv = r->as_ulong();
|
unsigned long rv = r->as_ulong();
|
||||||
res = new verinum(verinum::V0, l->len());
|
unsigned use_wid = l->len();
|
||||||
|
if (! l->has_len())
|
||||||
|
use_wid += rv;
|
||||||
|
res = new verinum(verinum::V0, use_wid);
|
||||||
if (rv < res->len()) {
|
if (rv < res->len()) {
|
||||||
unsigned cnt = res->len() - rv;
|
unsigned cnt = res->len() - rv;
|
||||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||||
|
|
@ -143,6 +146,27 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verinum* PEConcat::eval_const(const Design*des, const NetScope*scope) const
|
||||||
|
{
|
||||||
|
verinum*accum = parms_[0]->eval_const(des, scope);
|
||||||
|
if (accum == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||||
|
verinum*tmp = parms_[idx]->eval_const(des, scope);
|
||||||
|
/* Oops, found an argument that is not constant. Give up. */
|
||||||
|
if (tmp == 0) {
|
||||||
|
delete accum;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
*accum = concat(*accum, *tmp);
|
||||||
|
delete tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Evaluate an identifier as a constant expression. This is only
|
* Evaluate an identifier as a constant expression. This is only
|
||||||
|
|
@ -240,6 +264,15 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: eval.cc,v $
|
* $Log: eval.cc,v $
|
||||||
|
* Revision 1.36.2.3 2006/09/20 20:27:02 steve
|
||||||
|
* Fix left shift of small unsized constants.
|
||||||
|
*
|
||||||
|
* Revision 1.36.2.2 2005/12/18 21:06:01 steve
|
||||||
|
* Properly fail when concat is not actually constant.
|
||||||
|
*
|
||||||
|
* Revision 1.36.2.1 2005/12/07 03:28:44 steve
|
||||||
|
* Support constant concatenation of constants.
|
||||||
|
*
|
||||||
* Revision 1.36 2003/06/21 01:21:43 steve
|
* Revision 1.36 2003/06/21 01:21:43 steve
|
||||||
* Harmless fixup of warnings.
|
* Harmless fixup of warnings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
130
eval_tree.cc
130
eval_tree.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: eval_tree.cc,v 1.62 2004/10/04 01:10:53 steve Exp $"
|
#ident "$Id: eval_tree.cc,v 1.62.2.5 2007/03/23 23:02:31 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -215,6 +215,11 @@ NetEConst* NetEBComp::eval_eqeq_()
|
||||||
|
|
||||||
NetEConst* NetEBComp::eval_less_()
|
NetEConst* NetEBComp::eval_less_()
|
||||||
{
|
{
|
||||||
|
if (right_->expr_type() == ET_REAL)
|
||||||
|
return eval_leeq_real_(false, false);
|
||||||
|
if (left_->expr_type() == ET_REAL)
|
||||||
|
return eval_leeq_real_(false, false);
|
||||||
|
|
||||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||||
if (r == 0) return 0;
|
if (r == 0) return 0;
|
||||||
|
|
||||||
|
|
@ -224,12 +229,24 @@ NetEConst* NetEBComp::eval_less_()
|
||||||
return new NetEConst(result);
|
return new NetEConst(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left_->expr_width() == 0) {
|
||||||
|
cerr << get_line() << ": internal error: "
|
||||||
|
<< "Having trouble evaluating left expression of < op."
|
||||||
|
<< endl;
|
||||||
|
cerr << get_line() << ": : "
|
||||||
|
<< "Expression is: "
|
||||||
|
<< *this << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Detect the case where the right side is greater that or
|
/* Detect the case where the right side is greater that or
|
||||||
equal to the largest value the left side can possibly
|
equal to the largest value the left side can possibly
|
||||||
have. */
|
have. */
|
||||||
assert(left_->expr_width() > 0);
|
assert(left_->expr_width() > 0);
|
||||||
verinum lv (verinum::V1, left_->expr_width());
|
verinum lv (verinum::V1, left_->expr_width() + 1);
|
||||||
if (lv < rv) {
|
lv.set(left_->expr_width(), verinum::V0);
|
||||||
|
lv.has_sign( left_->has_sign() );
|
||||||
|
if ((lv < rv) == verinum::V1) {
|
||||||
verinum result(verinum::V1, 1);
|
verinum result(verinum::V1, 1);
|
||||||
return new NetEConst(result);
|
return new NetEConst(result);
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +276,7 @@ NetEConst* NetEBComp::eval_less_()
|
||||||
return new NetEConst(result);
|
return new NetEConst(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEConst* NetEBComp::eval_leeq_real_()
|
NetEConst* NetEBComp::eval_leeq_real_(bool gt_flag, bool include_eq_flag)
|
||||||
{
|
{
|
||||||
NetEConst*vtmp;
|
NetEConst*vtmp;
|
||||||
NetECReal*rtmp;
|
NetECReal*rtmp;
|
||||||
|
|
@ -308,7 +325,16 @@ NetEConst* NetEBComp::eval_leeq_real_()
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum result((lv <= rv)? verinum::V1 : verinum::V0, 1);
|
/* This function supports < and <=. If the eq_flag is true,
|
||||||
|
then include <=. Otherwise, include only <. */
|
||||||
|
bool flag;
|
||||||
|
if (gt_flag)
|
||||||
|
flag = include_eq_flag? (lv >= rv) : (lv > rv);
|
||||||
|
else
|
||||||
|
flag = include_eq_flag? (lv <= rv) : (lv < rv);
|
||||||
|
|
||||||
|
|
||||||
|
verinum result(flag? verinum::V1 : verinum::V0, 1);
|
||||||
vtmp = new NetEConst(result);
|
vtmp = new NetEConst(result);
|
||||||
vtmp->set_line(*this);
|
vtmp->set_line(*this);
|
||||||
|
|
||||||
|
|
@ -318,9 +344,9 @@ NetEConst* NetEBComp::eval_leeq_real_()
|
||||||
NetEConst* NetEBComp::eval_leeq_()
|
NetEConst* NetEBComp::eval_leeq_()
|
||||||
{
|
{
|
||||||
if (right_->expr_type() == ET_REAL)
|
if (right_->expr_type() == ET_REAL)
|
||||||
return eval_leeq_real_();
|
return eval_leeq_real_(false, true);
|
||||||
if (left_->expr_type() == ET_REAL)
|
if (left_->expr_type() == ET_REAL)
|
||||||
return eval_leeq_real_();
|
return eval_leeq_real_(false, true);
|
||||||
|
|
||||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||||
if (r == 0) return 0;
|
if (r == 0) return 0;
|
||||||
|
|
@ -337,11 +363,17 @@ NetEConst* NetEBComp::eval_leeq_()
|
||||||
cerr << get_line() << ": : " << *this << endl;
|
cerr << get_line() << ": : " << *this << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect the case where the right side is greater that or
|
/* Detect the case where the right side is greater than or
|
||||||
equal to the largest value the left side can possibly
|
equal to the largest value the left side can possibly
|
||||||
have. */
|
have. */
|
||||||
assert(left_->expr_width() > 0);
|
assert(left_->expr_width() > 0);
|
||||||
verinum lv (verinum::V1, left_->expr_width());
|
verinum lv (verinum::V1, left_->expr_width() + 1);
|
||||||
|
if (left_->has_sign() && rv.has_sign()) {
|
||||||
|
lv.set(lv.len()-1, verinum::V0);
|
||||||
|
lv.has_sign(true);
|
||||||
|
}
|
||||||
|
lv.set(left_->expr_width(), verinum::V0);
|
||||||
|
lv.has_sign( left_->has_sign() );
|
||||||
if (lv <= rv) {
|
if (lv <= rv) {
|
||||||
verinum result(verinum::V1, 1);
|
verinum result(verinum::V1, 1);
|
||||||
return new NetEConst(result);
|
return new NetEConst(result);
|
||||||
|
|
@ -374,23 +406,10 @@ NetEConst* NetEBComp::eval_leeq_()
|
||||||
|
|
||||||
NetEConst* NetEBComp::eval_gt_()
|
NetEConst* NetEBComp::eval_gt_()
|
||||||
{
|
{
|
||||||
if ((left_->expr_type() == NetExpr::ET_REAL)
|
if (right_->expr_type() == ET_REAL)
|
||||||
&& (right_->expr_type() == NetExpr::ET_REAL)) {
|
return eval_leeq_real_(true, false);
|
||||||
|
if (left_->expr_type() == ET_REAL)
|
||||||
NetECReal*tmpl = dynamic_cast<NetECReal*>(left_);
|
return eval_leeq_real_(true, false);
|
||||||
if (tmpl == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
NetECReal*tmpr = dynamic_cast<NetECReal*>(right_);
|
|
||||||
if (tmpr == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
double ll = tmpl->value().as_double();
|
|
||||||
double rr = tmpr->value().as_double();
|
|
||||||
|
|
||||||
verinum result ((ll > rr)? verinum::V1 : verinum::V0, 1, true);
|
|
||||||
return new NetEConst(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||||
if (l == 0) return 0;
|
if (l == 0) return 0;
|
||||||
|
|
@ -450,23 +469,10 @@ NetEConst* NetEBComp::eval_gt_()
|
||||||
|
|
||||||
NetEConst* NetEBComp::eval_gteq_()
|
NetEConst* NetEBComp::eval_gteq_()
|
||||||
{
|
{
|
||||||
if ((left_->expr_type() == NetExpr::ET_REAL)
|
if (right_->expr_type() == ET_REAL)
|
||||||
&& (right_->expr_type() == NetExpr::ET_REAL)) {
|
return eval_leeq_real_(true, true);
|
||||||
|
if (left_->expr_type() == ET_REAL)
|
||||||
NetECReal*tmpl = dynamic_cast<NetECReal*>(left_);
|
return eval_leeq_real_(true, true);
|
||||||
if (tmpl == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
NetECReal*tmpr = dynamic_cast<NetECReal*>(right_);
|
|
||||||
if (tmpr == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
double ll = tmpl->value().as_double();
|
|
||||||
double rr = tmpr->value().as_double();
|
|
||||||
|
|
||||||
verinum result ((ll >= rr)? verinum::V1 : verinum::V0, 1, true);
|
|
||||||
return new NetEConst(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||||
if (l == 0) return 0;
|
if (l == 0) return 0;
|
||||||
|
|
@ -1069,6 +1075,12 @@ NetEConst* NetEConcat::eval_tree()
|
||||||
val = verinum(val.as_string());
|
val = verinum(val.as_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normally, concatenations are unsigned. However, the
|
||||||
|
// $signed() function works by marking the expression as
|
||||||
|
// signed, so we really have to check.
|
||||||
|
val.has_sign( this->has_sign() );
|
||||||
|
|
||||||
|
|
||||||
NetEConst*res = new NetEConst(val);
|
NetEConst*res = new NetEConst(val);
|
||||||
res->set_width(val.len());
|
res->set_width(val.len());
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -1477,6 +1489,7 @@ NetEConst* NetEUReduce::eval_tree()
|
||||||
|
|
||||||
verinum val = rval->value();
|
verinum val = rval->value();
|
||||||
verinum::V res;
|
verinum::V res;
|
||||||
|
bool invert = false;
|
||||||
|
|
||||||
switch (op_) {
|
switch (op_) {
|
||||||
|
|
||||||
|
|
@ -1505,6 +1518,8 @@ NetEConst* NetEUReduce::eval_tree()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'A':
|
||||||
|
invert = true;
|
||||||
case '&': {
|
case '&': {
|
||||||
res = verinum::V1;
|
res = verinum::V1;
|
||||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||||
|
|
@ -1512,6 +1527,8 @@ NetEConst* NetEUReduce::eval_tree()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
invert = true;
|
||||||
case '|': {
|
case '|': {
|
||||||
res = verinum::V0;
|
res = verinum::V0;
|
||||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||||
|
|
@ -1519,6 +1536,8 @@ NetEConst* NetEUReduce::eval_tree()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'X':
|
||||||
|
invert = true;
|
||||||
case '^': {
|
case '^': {
|
||||||
/* Reduction XOR. */
|
/* Reduction XOR. */
|
||||||
unsigned ones = 0, unknown = 0;
|
unsigned ones = 0, unknown = 0;
|
||||||
|
|
@ -1534,23 +1553,38 @@ NetEConst* NetEUReduce::eval_tree()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unknown)
|
if (unknown) res = verinum::Vx;
|
||||||
return new NetEConst(verinum(verinum::Vx,1,true));
|
else if (ones%2) res = verinum::V1;
|
||||||
if (ones%2)
|
else res = verinum::V0;
|
||||||
return new NetEConst(verinum(verinum::V1,1,true));
|
break;
|
||||||
return new NetEConst(verinum(verinum::V0,1,true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (invert) res = ~res;
|
||||||
return new NetEConst(verinum(res, 1));
|
return new NetEConst(verinum(res, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: eval_tree.cc,v $
|
* $Log: eval_tree.cc,v $
|
||||||
|
* Revision 1.62.2.5 2007/03/23 23:02:31 steve
|
||||||
|
* Fix compile time eval of <= comparison.
|
||||||
|
*
|
||||||
|
* Revision 1.62.2.4 2007/03/23 20:59:25 steve
|
||||||
|
* Fix compile time evaluation of < operator.
|
||||||
|
*
|
||||||
|
* Revision 1.62.2.3 2005/09/09 02:17:08 steve
|
||||||
|
* Evaluate magnitude compare with real operands.
|
||||||
|
*
|
||||||
|
* Revision 1.62.2.2 2005/09/04 15:41:54 steve
|
||||||
|
* More explicit internal error message.
|
||||||
|
*
|
||||||
|
* Revision 1.62.2.1 2005/09/04 15:39:19 steve
|
||||||
|
* More explicit internal error message.
|
||||||
|
*
|
||||||
* Revision 1.62 2004/10/04 01:10:53 steve
|
* Revision 1.62 2004/10/04 01:10:53 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*
|
*
|
||||||
* $Id: sqrt-virtex.v,v 1.4 2003/11/25 18:35:31 steve Exp $"
|
* $Id: sqrt-virtex.v,v 1.4.2.2 2005/02/23 18:37:52 steve Exp $"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This module is a synthesizeable square-root function. It is also a
|
* This module is a synthesizeable square-root function. It is also a
|
||||||
* detailed example of how to target Xilinx Virtex parts using
|
* detailed example of how to target Xilinx Virtex parts using
|
||||||
* Icarus Verilog. In fact, for no particular reason other then to
|
* Icarus Verilog. In fact, for no particular reason other than to
|
||||||
* be excessively specific, I will step through the process of
|
* be excessively specific, I will step through the process of
|
||||||
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
|
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
|
||||||
* generate a generic library part for larger Virtex designs.
|
* generate a generic library part for larger Virtex designs.
|
||||||
|
|
@ -129,8 +129,8 @@
|
||||||
* This command creates from the chip.ngd the file "chip_root.v" that
|
* This command creates from the chip.ngd the file "chip_root.v" that
|
||||||
* contains Verilog code that simulates the mapped design. This output
|
* contains Verilog code that simulates the mapped design. This output
|
||||||
* Verilog has the single root module "chip_root", which came from the
|
* Verilog has the single root module "chip_root", which came from the
|
||||||
* name of the root module when we were making hte EDIF file in the
|
* name of the root module when we were making the EDIF file in the
|
||||||
* first place. The module has ports named just line the ports of the
|
* first place. The module has ports named just like the ports of the
|
||||||
* chip_root module below.
|
* chip_root module below.
|
||||||
*
|
*
|
||||||
* The generated Verilog uses the library in the directory
|
* The generated Verilog uses the library in the directory
|
||||||
|
|
|
||||||
343
expr_synth.cc
343
expr_synth.cc
|
|
@ -17,24 +17,65 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: expr_synth.cc,v 1.59 2004/06/30 02:16:26 steve Exp $"
|
#ident "$Id: expr_synth.cc,v 1.59.2.11 2007/02/26 19:51:38 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
# include <typeinfo>
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
# include "compiler.h"
|
||||||
|
|
||||||
NetNet* NetExpr::synthesize(Design*des)
|
NetNet* NetExpr::synthesize(Design*des)
|
||||||
{
|
{
|
||||||
cerr << get_line() << ": internal error: cannot synthesize expression: "
|
cerr << get_line() << ": internal error: cannot synthesize expression: "
|
||||||
<< *this << endl;
|
<< *this << endl;
|
||||||
|
cerr << get_line() << ": : typeid="
|
||||||
|
<< typeid(*this).name() << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the NetEBitSel expression, create a NetMux node that selects a
|
||||||
|
* bit from the input.
|
||||||
|
*/
|
||||||
|
NetNet* NetEBitSel::synthesize(Design*des)
|
||||||
|
{
|
||||||
|
NetNet*net = sig_->synthesize(des);
|
||||||
|
assert(net);
|
||||||
|
|
||||||
|
NetNet*adr = idx_->synthesize(des);
|
||||||
|
if (adr == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
NetScope*scope = adr->scope();
|
||||||
|
|
||||||
|
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||||
|
NetNet::WIRE, 1);
|
||||||
|
osig->set_line(*this);
|
||||||
|
osig->local_flag(true);
|
||||||
|
|
||||||
|
NetMux*mux = new NetMux(scope, scope->local_symbol(),
|
||||||
|
1, net->pin_count(), adr->pin_count());
|
||||||
|
mux->set_line(*this);
|
||||||
|
des->add_node(mux);
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1)
|
||||||
|
connect(mux->pin_Data(0, idx), net->pin(idx));
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < adr->pin_count() ; idx += 1)
|
||||||
|
connect(mux->pin_Sel(idx), adr->pin(idx));
|
||||||
|
|
||||||
|
connect(mux->pin_Result(0), osig->pin(0));
|
||||||
|
|
||||||
|
return osig;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make an LPM_ADD_SUB device from addition operators.
|
* Make an LPM_ADD_SUB device from addition operators.
|
||||||
*/
|
*/
|
||||||
|
|
@ -408,7 +449,7 @@ NetNet* NetEBDiv::synthesize(Design*des)
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
cerr << get_line() << ": internal error: "
|
cerr << get_line() << ": internal error: "
|
||||||
<< "NetEBDiv has unexpeced op() code: "
|
<< "NetEBDiv has unexpected op() code: "
|
||||||
<< op() << endl;
|
<< op() << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
||||||
|
|
@ -472,13 +513,18 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||||
perm_string oname = scope->local_symbol();
|
perm_string oname = scope->local_symbol();
|
||||||
|
|
||||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
|
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
|
||||||
|
olog->set_line(*this);
|
||||||
|
|
||||||
connect(osig->pin(0), olog->pin(0));
|
connect(osig->pin(0), olog->pin(0));
|
||||||
des->add_node(olog);
|
des->add_node(olog);
|
||||||
|
|
||||||
/* XXXX Here, I need to reduce the parameters with
|
/* Here, I need to reduce the parameters with
|
||||||
reduction or. */
|
reduction or. Only do this if we must. */
|
||||||
|
if (lsig->pin_count() > 1)
|
||||||
|
lsig = reduction_or(des, lsig);
|
||||||
|
|
||||||
|
if (rsig->pin_count() > 1)
|
||||||
|
rsig = reduction_or(des, rsig);
|
||||||
|
|
||||||
/* By this point, the left and right parameters have been
|
/* By this point, the left and right parameters have been
|
||||||
reduced to single bit values. Now we just connect them to
|
reduced to single bit values. Now we just connect them to
|
||||||
|
|
@ -486,6 +532,11 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||||
assert(lsig->pin_count() == 1);
|
assert(lsig->pin_count() == 1);
|
||||||
connect(lsig->pin(0), olog->pin(1));
|
connect(lsig->pin(0), olog->pin(1));
|
||||||
|
|
||||||
|
if (rsig->pin_count() != 1) {
|
||||||
|
cerr << olog->get_line() << ": internal error: "
|
||||||
|
<< "right argument not reduced. expr=" << *this << endl;
|
||||||
|
}
|
||||||
|
|
||||||
assert(rsig->pin_count() == 1);
|
assert(rsig->pin_count() == 1);
|
||||||
connect(rsig->pin(0), olog->pin(2));
|
connect(rsig->pin(0), olog->pin(2));
|
||||||
}
|
}
|
||||||
|
|
@ -566,7 +617,6 @@ NetNet* NetEBShift::synthesize(Design*des)
|
||||||
NetNet::IMPLICIT, expr_width());
|
NetNet::IMPLICIT, expr_width());
|
||||||
osig->local_flag(true);
|
osig->local_flag(true);
|
||||||
|
|
||||||
assert(op() == 'l');
|
|
||||||
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
||||||
osig->pin_count(),
|
osig->pin_count(),
|
||||||
rsig->pin_count(),
|
rsig->pin_count(),
|
||||||
|
|
@ -640,6 +690,71 @@ NetNet* NetEConst::synthesize(Design*des)
|
||||||
return osig;
|
return osig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet* NetEMemory::synthesize(Design*des)
|
||||||
|
{
|
||||||
|
NetScope*scope = mem_->scope();
|
||||||
|
|
||||||
|
NetNet*explode = mem_->explode_to_reg();
|
||||||
|
unsigned width = expr_width();
|
||||||
|
|
||||||
|
assert(idx_);
|
||||||
|
NetNet*addr = idx_->synthesize(des);
|
||||||
|
|
||||||
|
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||||
|
NetNet::IMPLICIT,
|
||||||
|
width);
|
||||||
|
osig->set_line(*this);
|
||||||
|
|
||||||
|
if (explode) {
|
||||||
|
if (debug_synth)
|
||||||
|
cerr << get_line() << ": debug: synthesize read of "
|
||||||
|
<< explode->pin_count() << " bit exploded memory." << endl;
|
||||||
|
|
||||||
|
/* Only make a mux big enough to address the words that
|
||||||
|
the address can generate. (If the address is
|
||||||
|
0-extended, then only the low words are addressable.) */
|
||||||
|
unsigned use_count = mem_->count();
|
||||||
|
if (use_count > (1U << addr->pin_count())) {
|
||||||
|
use_count = 1 << addr->pin_count();
|
||||||
|
|
||||||
|
if (debug_synth)
|
||||||
|
cerr << get_line() << ": debug: "
|
||||||
|
<< "Index expression can only address "
|
||||||
|
<< use_count << " of "
|
||||||
|
<< mem_->count() << " words." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a reference to an exploded memory. So locate
|
||||||
|
the reg vector and use the addr expression as a
|
||||||
|
select into a MUX. */
|
||||||
|
NetMux*mux = new NetMux(scope, scope->local_symbol(),
|
||||||
|
width, use_count, addr->pin_count());
|
||||||
|
des->add_node(mux);
|
||||||
|
mux->set_line(*this);
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < width ; idx += 1)
|
||||||
|
connect(mux->pin_Result(idx), osig->pin(idx));
|
||||||
|
for (unsigned idx = 0 ; idx < mux->sel_width() ; idx += 1)
|
||||||
|
connect(mux->pin_Sel(idx), addr->pin(idx));
|
||||||
|
|
||||||
|
for (unsigned wrd = 0 ; wrd < use_count ; wrd += 1)
|
||||||
|
for (unsigned idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
unsigned bit = wrd*width + idx;
|
||||||
|
connect(mux->pin_Data(idx, wrd), explode->pin(bit));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug_synth)
|
||||||
|
cerr << get_line() << ": debug: synthesis done." << endl;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cerr << get_line() << ": internal error: Synthesize memory "
|
||||||
|
<< "expression that is not exploded?" << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return osig;
|
||||||
|
}
|
||||||
|
|
||||||
NetNet* NetECReal::synthesize(Design*des)
|
NetNet* NetECReal::synthesize(Design*des)
|
||||||
{
|
{
|
||||||
cerr << get_line() << ": error: Real constants are "
|
cerr << get_line() << ": error: Real constants are "
|
||||||
|
|
@ -684,6 +799,97 @@ NetNet* NetEUBits::synthesize(Design*des)
|
||||||
return osig;
|
return osig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet* NetEUFunc::synthesize(Design*des)
|
||||||
|
{
|
||||||
|
assert(func_);
|
||||||
|
|
||||||
|
NetFuncDef* def = func_->func_def();
|
||||||
|
assert(def);
|
||||||
|
|
||||||
|
assert(parms_.count() == def->port_count());
|
||||||
|
|
||||||
|
svector<NetNet*> inports (parms_.count());
|
||||||
|
|
||||||
|
unsigned errors = 0;
|
||||||
|
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||||
|
inports[idx] = parms_[idx]->synthesize(des);
|
||||||
|
if (inports[idx] == 0)
|
||||||
|
errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors > 0) {
|
||||||
|
cerr << get_line() << ": error: "
|
||||||
|
<< "Cannot continue with function instance synthesis."
|
||||||
|
<< endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet*out = def->synthesize(des, inports);
|
||||||
|
|
||||||
|
if (! out) {
|
||||||
|
cerr << get_line() << ": error: "
|
||||||
|
<< "User defined functions do not synthesize." << endl;
|
||||||
|
def->dump(cerr, 4);
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet* NetFuncDef::synthesize(Design*des, const svector<NetNet*>&inports_)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* First run synthesis for the function definition as if this
|
||||||
|
where a toplevel process. This will create the logic that
|
||||||
|
the function represents, but connected to the port nets for
|
||||||
|
the function definition. We will detach those common ports
|
||||||
|
later. */
|
||||||
|
NexusSet nex_set;
|
||||||
|
statement_->nex_output(nex_set);
|
||||||
|
|
||||||
|
const perm_string tmp1 = scope()->local_symbol();
|
||||||
|
NetNet*nex_out = new NetNet(scope(), tmp1, NetNet::WIRE,
|
||||||
|
nex_set.count());
|
||||||
|
for (unsigned idx = 0 ; idx < nex_out->pin_count() ; idx += 1)
|
||||||
|
connect(nex_set[idx], nex_out->pin(idx));
|
||||||
|
|
||||||
|
bool flag = statement_->synth_async_noaccum(des, scope(), false, 0,
|
||||||
|
nex_out, nex_out);
|
||||||
|
|
||||||
|
if (!flag) {
|
||||||
|
delete nex_out;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect the inports_ vectors to the input ports and detach
|
||||||
|
the static arg ports themselves. This moves the input from
|
||||||
|
the synthesized device from the static ports to the actual
|
||||||
|
ports from the instance context. */
|
||||||
|
for (unsigned idx = 0 ; idx < port_count() ; idx += 1) {
|
||||||
|
NetNet*in = inports_[idx];
|
||||||
|
NetNet*arg = ports_[idx];
|
||||||
|
|
||||||
|
in = pad_to_width(des, in, arg->pin_count());
|
||||||
|
|
||||||
|
for (unsigned pin = 0 ; pin < arg->pin_count() ; pin += 1) {
|
||||||
|
connect(in->pin(pin), arg->pin(pin));
|
||||||
|
arg->pin(pin).unlink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach the output signal from the synthesized result. We
|
||||||
|
use instead the nex_out that was returned from the
|
||||||
|
synthesis of the function. This is how we account for the
|
||||||
|
fact that the function may be synthesized multiple times to
|
||||||
|
go into multiple expression. Each synthesis needs a unique
|
||||||
|
output. */
|
||||||
|
for (unsigned idx = 0 ; idx < result_sig_->pin_count() ; idx += 1)
|
||||||
|
result_sig_->pin(idx).unlink();
|
||||||
|
|
||||||
|
return nex_out;
|
||||||
|
}
|
||||||
|
|
||||||
NetNet* NetEUReduce::synthesize(Design*des)
|
NetNet* NetEUReduce::synthesize(Design*des)
|
||||||
{
|
{
|
||||||
NetNet*isig = expr_->synthesize(des);
|
NetNet*isig = expr_->synthesize(des);
|
||||||
|
|
@ -811,6 +1017,7 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||||
|
|
||||||
perm_string oname = csig->scope()->local_symbol();
|
perm_string oname = csig->scope()->local_symbol();
|
||||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
|
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
|
||||||
|
mux->set_line(*this);
|
||||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||||
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
|
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
|
||||||
connect(fsig->pin(idx), mux->pin_Data(idx, 0));
|
connect(fsig->pin(idx), mux->pin_Data(idx, 0));
|
||||||
|
|
@ -854,6 +1061,21 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||||
*/
|
*/
|
||||||
NetNet* NetESignal::synthesize(Design*des)
|
NetNet* NetESignal::synthesize(Design*des)
|
||||||
{
|
{
|
||||||
|
if (warn_unused) {
|
||||||
|
if (net_->peek_lref() == 0 && net_->type()==NetNet::REG) {
|
||||||
|
cerr << get_line() << ": warning: "
|
||||||
|
<< "reg " << net_->name()
|
||||||
|
<< " is used by logic but never assigned." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net_->peek_lref() == 0 && net_->type()==NetNet::INTEGER) {
|
||||||
|
cerr << get_line() << ": warning: "
|
||||||
|
<< "reg " << net_->name()
|
||||||
|
<< " is used by logic but never assigned." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is no part select, then the synthesis is trivial. */
|
||||||
if ((lsi_ == 0) && (msi_ == (net_->pin_count() - 1)))
|
if ((lsi_ == 0) && (msi_ == (net_->pin_count() - 1)))
|
||||||
return net_;
|
return net_;
|
||||||
|
|
||||||
|
|
@ -866,6 +1088,7 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||||
perm_string name = scope->local_symbol();
|
perm_string name = scope->local_symbol();
|
||||||
NetNet*tmp = new NetNet(scope, name, NetNet::WIRE, wid);
|
NetNet*tmp = new NetNet(scope, name, NetNet::WIRE, wid);
|
||||||
tmp->local_flag(true);
|
tmp->local_flag(true);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||||
connect(tmp->pin(idx), net_->pin(idx+lsi_));
|
connect(tmp->pin(idx), net_->pin(idx+lsi_));
|
||||||
|
|
@ -875,6 +1098,39 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: expr_synth.cc,v $
|
* $Log: expr_synth.cc,v $
|
||||||
|
* Revision 1.59.2.11 2007/02/26 19:51:38 steve
|
||||||
|
* Spelling fixes (larry doolittle)
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.10 2006/11/26 01:54:05 steve
|
||||||
|
* Add synthesis of user defined functions.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.9 2006/08/08 02:17:48 steve
|
||||||
|
* Improved nexus management performance.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.8 2006/06/15 01:57:26 steve
|
||||||
|
* Handle simple memory addressing in expression synthesis.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.7 2006/06/14 03:02:54 steve
|
||||||
|
* synthesis for NetEBitSel.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.6 2006/06/12 00:16:52 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.5 2006/05/15 03:55:22 steve
|
||||||
|
* Fix synthesis of expressions with land of vectors.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.4 2006/04/10 03:43:39 steve
|
||||||
|
* Exploded memories accessed by constant indices.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.3 2006/03/16 05:39:20 steve
|
||||||
|
* Right shifts really are allowed.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.2 2005/09/11 02:56:37 steve
|
||||||
|
* Attach line numbers to NetMux devices.
|
||||||
|
*
|
||||||
|
* Revision 1.59.2.1 2005/02/19 16:39:31 steve
|
||||||
|
* Spellig fixes.
|
||||||
|
*
|
||||||
* Revision 1.59 2004/06/30 02:16:26 steve
|
* Revision 1.59 2004/06/30 02:16:26 steve
|
||||||
* Implement signed divide and signed right shift in nets.
|
* Implement signed divide and signed right shift in nets.
|
||||||
*
|
*
|
||||||
|
|
@ -883,82 +1139,5 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||||
*
|
*
|
||||||
* Revision 1.57 2004/06/12 15:00:02 steve
|
* Revision 1.57 2004/06/12 15:00:02 steve
|
||||||
* Support / and % in synthesized contexts.
|
* Support / and % in synthesized contexts.
|
||||||
*
|
|
||||||
* Revision 1.56 2004/06/01 01:04:57 steve
|
|
||||||
* Fix synthesis method for logical and/or
|
|
||||||
*
|
|
||||||
* Revision 1.55 2004/02/20 18:53:35 steve
|
|
||||||
* Addtrbute keys are perm_strings.
|
|
||||||
*
|
|
||||||
* Revision 1.54 2004/02/18 17:11:56 steve
|
|
||||||
* Use perm_strings for named langiage items.
|
|
||||||
*
|
|
||||||
* Revision 1.53 2004/02/15 04:23:48 steve
|
|
||||||
* Fix evaluation of compare to constant expression.
|
|
||||||
*
|
|
||||||
* Revision 1.52 2003/11/10 19:39:20 steve
|
|
||||||
* Remove redundant scope tokens.
|
|
||||||
*
|
|
||||||
* Revision 1.51 2003/10/27 06:04:21 steve
|
|
||||||
* More flexible width handling for synthesized add.
|
|
||||||
*
|
|
||||||
* Revision 1.50 2003/09/26 02:44:27 steve
|
|
||||||
* Assure ternary arguments are wide enough.
|
|
||||||
*
|
|
||||||
* Revision 1.49 2003/09/03 23:31:36 steve
|
|
||||||
* Support synthesis of constant downshifts.
|
|
||||||
*
|
|
||||||
* Revision 1.48 2003/08/28 04:11:18 steve
|
|
||||||
* Spelling patch.
|
|
||||||
*
|
|
||||||
* Revision 1.47 2003/08/09 03:23:40 steve
|
|
||||||
* Add support for IVL_LPM_MULT device.
|
|
||||||
*
|
|
||||||
* Revision 1.46 2003/07/26 03:34:42 steve
|
|
||||||
* Start handling pad of expressions in code generators.
|
|
||||||
*
|
|
||||||
* Revision 1.45 2003/06/24 01:38:02 steve
|
|
||||||
* Various warnings fixed.
|
|
||||||
*
|
|
||||||
* Revision 1.44 2003/04/19 04:52:56 steve
|
|
||||||
* Less picky about expression widths while synthesizing ternary.
|
|
||||||
*
|
|
||||||
* Revision 1.43 2003/04/08 05:07:15 steve
|
|
||||||
* Detect constant shift distances in synthesis.
|
|
||||||
*
|
|
||||||
* Revision 1.42 2003/04/08 04:33:55 steve
|
|
||||||
* Synthesize shift expressions.
|
|
||||||
*
|
|
||||||
* Revision 1.41 2003/03/06 00:28:41 steve
|
|
||||||
* All NetObj objects have lex_string base names.
|
|
||||||
*
|
|
||||||
* Revision 1.40 2003/02/26 01:29:24 steve
|
|
||||||
* LPM objects store only their base names.
|
|
||||||
*
|
|
||||||
* Revision 1.39 2003/01/30 16:23:07 steve
|
|
||||||
* Spelling fixes.
|
|
||||||
*
|
|
||||||
* Revision 1.38 2003/01/26 21:15:58 steve
|
|
||||||
* Rework expression parsing and elaboration to
|
|
||||||
* accommodate real/realtime values and expressions.
|
|
||||||
*
|
|
||||||
* Revision 1.37 2002/11/17 23:37:55 steve
|
|
||||||
* Magnitude compare to 0.
|
|
||||||
*
|
|
||||||
* Revision 1.36 2002/08/12 01:34:59 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.35 2002/07/07 22:31:39 steve
|
|
||||||
* Smart synthesis of binary AND expressions.
|
|
||||||
*
|
|
||||||
* Revision 1.34 2002/07/05 21:26:17 steve
|
|
||||||
* Avoid emitting to vvp local net symbols.
|
|
||||||
*
|
|
||||||
* Revision 1.33 2002/05/26 01:39:02 steve
|
|
||||||
* Carry Verilog 2001 attributes with processes,
|
|
||||||
* all the way through to the ivl_target API.
|
|
||||||
*
|
|
||||||
* Divide signal reference counts between rval
|
|
||||||
* and lval references.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
13
functor.cc
13
functor.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: functor.cc,v 1.32 2004/10/04 01:10:53 steve Exp $"
|
#ident "$Id: functor.cc,v 1.32.2.1 2006/04/23 04:26:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -79,6 +79,9 @@ void functor_t::lpm_mux(class Design*, class NetMux*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void functor_t::lpm_ram_dq(class Design*, class NetRamDq*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void NetScope::run_functor(Design*des, functor_t*fun)
|
void NetScope::run_functor(Design*des, functor_t*fun)
|
||||||
{
|
{
|
||||||
|
|
@ -206,6 +209,11 @@ void NetMux::functor_node(Design*des, functor_t*fun)
|
||||||
fun->lpm_mux(des, this);
|
fun->lpm_mux(des, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetRamDq::functor_node(Design*des, functor_t*fun)
|
||||||
|
{
|
||||||
|
fun->lpm_ram_dq(des, this);
|
||||||
|
}
|
||||||
|
|
||||||
proc_match_t::~proc_match_t()
|
proc_match_t::~proc_match_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -267,6 +275,9 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: functor.cc,v $
|
* $Log: functor.cc,v $
|
||||||
|
* Revision 1.32.2.1 2006/04/23 04:26:14 steve
|
||||||
|
* Constant propagate addresses through NetRamDq read ports.
|
||||||
|
*
|
||||||
* Revision 1.32 2004/10/04 01:10:53 steve
|
* Revision 1.32 2004/10/04 01:10:53 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $"
|
#ident "$Id: functor.h,v 1.20.2.1 2006/04/23 04:26:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -77,6 +77,9 @@ struct functor_t {
|
||||||
|
|
||||||
/* This method is called for each MUX. */
|
/* This method is called for each MUX. */
|
||||||
virtual void lpm_mux(class Design*des, class NetMux*);
|
virtual void lpm_mux(class Design*des, class NetMux*);
|
||||||
|
|
||||||
|
/* This is called for eacm RamDq device. */
|
||||||
|
virtual void lpm_ram_dq(class Design*des, class NetRamDq*);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proc_match_t {
|
struct proc_match_t {
|
||||||
|
|
@ -92,6 +95,9 @@ struct proc_match_t {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: functor.h,v $
|
* $Log: functor.h,v $
|
||||||
|
* Revision 1.20.2.1 2006/04/23 04:26:14 steve
|
||||||
|
* Constant propagate addresses through NetRamDq read ports.
|
||||||
|
*
|
||||||
* Revision 1.20 2002/08/12 01:34:59 steve
|
* Revision 1.20 2002/08/12 01:34:59 steve
|
||||||
* conditional ident string using autoconfig.
|
* conditional ident string using autoconfig.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,15 @@ first source file is named \fIfoo.c\fP, the output becomes
|
||||||
Include the named library in the link of the VPI module. This allows
|
Include the named library in the link of the VPI module. This allows
|
||||||
VPI modules to further reference external libraries.
|
VPI modules to further reference external libraries.
|
||||||
|
|
||||||
|
.TP 8
|
||||||
|
.B -I\fIdirectory\fP
|
||||||
|
Add \fIdirectory\fP to the list of directories that will be search for
|
||||||
|
header files.
|
||||||
|
|
||||||
|
.TP 8
|
||||||
|
.B -D\fIdefine\fP
|
||||||
|
Define a macro named \fIdefine\fP.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B --name=\fIname\fP
|
.B --name=\fIname\fP
|
||||||
Normally, the output VPI module will be named after the first source
|
Normally, the output VPI module will be named after the first source
|
||||||
|
|
@ -39,6 +48,10 @@ This flag causes the program to print the install directory for VPI
|
||||||
modules, then exit. It is a convenience for makefiles or automated
|
modules, then exit. It is a convenience for makefiles or automated
|
||||||
plug-in installers.
|
plug-in installers.
|
||||||
|
|
||||||
|
.TP 8
|
||||||
|
.B --cflags, --ldflags and -ldlibs
|
||||||
|
These flags provide compile time information.
|
||||||
|
|
||||||
.SH "PC-ONLY OPTIONS"
|
.SH "PC-ONLY OPTIONS"
|
||||||
|
|
||||||
The PC port of \fIiverilog-vpi\fP includes two special flags needed to
|
The PC port of \fIiverilog-vpi\fP includes two special flags needed to
|
||||||
|
|
|
||||||
|
|
@ -17,19 +17,20 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: iverilog-vpi.sh,v 1.14 2004/05/20 00:40:34 steve Exp $"
|
|
||||||
|
|
||||||
# These are the variables used for compiling files
|
# These are the variables used for compiling files
|
||||||
CC=gcc
|
CC=@IVCC@
|
||||||
CXX=gcc
|
CXX=@IVCXX@
|
||||||
CFLAGS="@PIC@ -O -I@INCLUDEDIR@"
|
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
|
||||||
|
|
||||||
|
SUFFIX=@SUFFIX@
|
||||||
|
|
||||||
# These are used for linking...
|
# These are used for linking...
|
||||||
LD=gcc
|
LD=$CC
|
||||||
LDFLAGS32="@SHARED@ -L@LIBDIR@"
|
LDFLAGS32="@SHARED@ -L@LIBDIR@"
|
||||||
LDFLAGS64="@SHARED@ -L@LIBDIR64@"
|
LDFLAGS64="@SHARED@ -L@LIBDIR64@"
|
||||||
LDFLAGS="$LDFLAGS64"
|
LDFLAGS="$LDFLAGS64"
|
||||||
LDLIBS="-lveriuser -lvpi"
|
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
|
||||||
|
|
||||||
INSTDIR64="@VPIDIR1@"
|
INSTDIR64="@VPIDIR1@"
|
||||||
INSTDIR32="@VPIDIR2@"
|
INSTDIR32="@VPIDIR2@"
|
||||||
|
|
@ -46,6 +47,7 @@ OBJ=
|
||||||
LIB=
|
LIB=
|
||||||
OUT=
|
OUT=
|
||||||
INCOPT=
|
INCOPT=
|
||||||
|
DEFS=
|
||||||
|
|
||||||
# --
|
# --
|
||||||
# parse the command line switches. This collects the source files
|
# parse the command line switches. This collects the source files
|
||||||
|
|
@ -63,11 +65,19 @@ do
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*.cc) CXSRC="$CXSRC $parm"
|
*.cc) CXSRC="$CXSRC $parm"
|
||||||
|
LD=$CXX
|
||||||
if [ x$OUT = x ]; then
|
if [ x$OUT = x ]; then
|
||||||
OUT=`basename $parm .cc`
|
OUT=`basename $parm .cc`
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
*.cpp) CXSRC="$CXSRC $parm"
|
||||||
|
LD=$CXX
|
||||||
|
if [ x$OUT = x ]; then
|
||||||
|
OUT=`basename $parm .cpp`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
*.o) OBJ="$OBJ $parm"
|
*.o) OBJ="$OBJ $parm"
|
||||||
if [ x$OUT = x ]; then
|
if [ x$OUT = x ]; then
|
||||||
OUT=`basename $parm .o`
|
OUT=`basename $parm .o`
|
||||||
|
|
@ -82,7 +92,9 @@ do
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-I*) INCOPT="$INCOPT $parm"
|
-I*) INCOPT="$INCOPT $parm"
|
||||||
echo "$parm"
|
;;
|
||||||
|
|
||||||
|
-D*) DEFS="$DEFS $parm"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-m32) LDFLAGS="-m32 $LDFLAGS32"
|
-m32) LDFLAGS="-m32 $LDFLAGS32"
|
||||||
|
|
@ -106,7 +118,7 @@ do
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--install-dir)
|
--install-dir)
|
||||||
echo "@LIBDIR@/ivl/$INSTDIR"
|
echo "@LIBDIR@/ivl$SUFFIX/$INSTDIR"
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -130,7 +142,7 @@ do
|
||||||
obj=$base".o"
|
obj=$base".o"
|
||||||
|
|
||||||
echo "Compiling $src..."
|
echo "Compiling $src..."
|
||||||
$CC -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
$CC -c -o $obj $DEFS $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
||||||
OBJ="$OBJ $obj"
|
OBJ="$OBJ $obj"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -140,13 +152,13 @@ do
|
||||||
obj=$base".o"
|
obj=$base".o"
|
||||||
|
|
||||||
echo "Compiling $src..."
|
echo "Compiling $src..."
|
||||||
$CXX -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
$CXX -c -o $obj $DEFS $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
||||||
OBJ="$OBJ $obj"
|
OBJ="$OBJ $obj"
|
||||||
done
|
done
|
||||||
|
|
||||||
if test $compile_errors -gt 0
|
if test $compile_errors -gt 0
|
||||||
then
|
then
|
||||||
echo "Some ($compile_errors) files failed to compile."
|
echo "$0: $compile_errors file(s) failed to compile."
|
||||||
exit $compile_errors
|
exit $compile_errors
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
3
ivl.def
3
ivl.def
|
|
@ -62,12 +62,15 @@ ivl_logic_udp
|
||||||
ivl_lpm_aset_value
|
ivl_lpm_aset_value
|
||||||
ivl_lpm_async_clr
|
ivl_lpm_async_clr
|
||||||
ivl_lpm_async_set
|
ivl_lpm_async_set
|
||||||
|
ivl_lpm_attr_cnt
|
||||||
|
ivl_lpm_attr_val
|
||||||
ivl_lpm_basename
|
ivl_lpm_basename
|
||||||
ivl_lpm_clk
|
ivl_lpm_clk
|
||||||
ivl_lpm_data
|
ivl_lpm_data
|
||||||
ivl_lpm_datab
|
ivl_lpm_datab
|
||||||
ivl_lpm_data2
|
ivl_lpm_data2
|
||||||
ivl_lpm_data2_width
|
ivl_lpm_data2_width
|
||||||
|
ivl_lpm_decode
|
||||||
ivl_lpm_define
|
ivl_lpm_define
|
||||||
ivl_lpm_enable
|
ivl_lpm_enable
|
||||||
ivl_lpm_memory
|
ivl_lpm_memory
|
||||||
|
|
|
||||||
114
ivl_target.h
114
ivl_target.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: ivl_target.h,v 1.126 2004/10/04 01:10:53 steve Exp $"
|
#ident "$Id: ivl_target.h,v 1.126.2.5 2006/04/16 19:26:37 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -226,8 +226,11 @@ typedef enum ivl_lpm_type_e {
|
||||||
IVL_LPM_CMP_GE = 1,
|
IVL_LPM_CMP_GE = 1,
|
||||||
IVL_LPM_CMP_GT = 2,
|
IVL_LPM_CMP_GT = 2,
|
||||||
IVL_LPM_CMP_NE = 11,
|
IVL_LPM_CMP_NE = 11,
|
||||||
|
IVL_LPM_DECODE = 15,
|
||||||
|
IVL_LPM_DEMUX = 16,
|
||||||
IVL_LPM_DIVIDE = 12,
|
IVL_LPM_DIVIDE = 12,
|
||||||
IVL_LPM_FF = 3,
|
IVL_LPM_FF = 3,
|
||||||
|
IVL_LPM_LATCH = 17,
|
||||||
IVL_LPM_MOD = 13,
|
IVL_LPM_MOD = 13,
|
||||||
IVL_LPM_MULT = 4,
|
IVL_LPM_MULT = 4,
|
||||||
IVL_LPM_MUX = 5,
|
IVL_LPM_MUX = 5,
|
||||||
|
|
@ -629,6 +632,11 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
||||||
* the LPM type, but it generally has to do with the width of the
|
* the LPM type, but it generally has to do with the width of the
|
||||||
* output data path.
|
* output data path.
|
||||||
*
|
*
|
||||||
|
* ivl_lpm_attr_cnt
|
||||||
|
* ivl_lpm_attr_val
|
||||||
|
* These functions access attributes attached to LPM devices. These
|
||||||
|
* attributes may be explicit attributes collected from the Verilog
|
||||||
|
* source, or implicit attributes generated by the compiler.
|
||||||
*
|
*
|
||||||
* These functions apply to a subset of the LPM devices, or may have
|
* These functions apply to a subset of the LPM devices, or may have
|
||||||
* varying meaning depending on the device:
|
* varying meaning depending on the device:
|
||||||
|
|
@ -642,13 +650,18 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
||||||
* Return the input data nexus for device types that have a second
|
* Return the input data nexus for device types that have a second
|
||||||
* input vector. For example, arithmetic devices are like this.
|
* input vector. For example, arithmetic devices are like this.
|
||||||
*
|
*
|
||||||
|
* ivl_lpm_decode
|
||||||
|
* Return the DECODER associated with this LPM_FF device. The
|
||||||
|
* decoder for a FF takes an input address and generates an enable
|
||||||
|
* input for no more then 1 bit (can be none) of the FF device.
|
||||||
|
*
|
||||||
* ivl_lpm_q
|
* ivl_lpm_q
|
||||||
* Return the output data nexus for device types that have a single
|
* Return the output data nexus for device types that have a single
|
||||||
* output vector. This is most devices, it turns out.
|
* output vector. This is most devices, it turns out.
|
||||||
*
|
*
|
||||||
* ivl_lpm_selects
|
* ivl_lpm_selects
|
||||||
* This is the size of the select input for a LPM_MUX device, or the
|
* This is the size of the select input for a LPM_MUX or LPM_DECODE
|
||||||
* address bus width of an LPM_RAM.
|
* device, or the address bus width of an LPM_RAM.
|
||||||
*
|
*
|
||||||
* ivl_lpm_signed
|
* ivl_lpm_signed
|
||||||
* Arithmetic LPM devices may be signed or unsigned if there is a
|
* Arithmetic LPM devices may be signed or unsigned if there is a
|
||||||
|
|
@ -658,6 +671,64 @@ extern const char* ivl_udp_name(ivl_udp_t net);
|
||||||
* In addition to a width, some devices have a size. The size is
|
* In addition to a width, some devices have a size. The size is
|
||||||
* often the number of inputs per out, i.e., the number of inputs
|
* often the number of inputs per out, i.e., the number of inputs
|
||||||
* per bit for a MUX.
|
* per bit for a MUX.
|
||||||
|
*
|
||||||
|
* SEMANTIC NOTES:
|
||||||
|
*
|
||||||
|
* - IVL_LPM_FF
|
||||||
|
* The IVL_LPM_FF and IVL_LPM_DECODE devices are closely related. If
|
||||||
|
* the ivl_lpm_decode function returns a non-nil value, then the
|
||||||
|
* decoder represents an extra ENABLE-like input, where exactly <N>
|
||||||
|
* bits of the width of the FF is enabled. The ivl_lpm_width of the
|
||||||
|
* decoder defines <N>.
|
||||||
|
*
|
||||||
|
* The decoder inputs are the address that selects the FF to be
|
||||||
|
* enabled, and the ivl_lpm_selects for the decoder gives the width of
|
||||||
|
* the address. The address of the LSB of the memory, then, is the
|
||||||
|
* word width times the input address. For a simple l-value bit
|
||||||
|
* select, the word width <N> will be 1, and the address goes directly
|
||||||
|
* to the bit. Otherwise, <N>*address gets to the first bit of the word.
|
||||||
|
*
|
||||||
|
* The core compiler generates these attributes in certain cases:
|
||||||
|
*
|
||||||
|
* - ivl:clock_polarity
|
||||||
|
* If present, the string value can be "INVERT". That indicates
|
||||||
|
* that the clock is negedge sensitive instead of the default
|
||||||
|
* posedge sensitive.
|
||||||
|
*
|
||||||
|
* - IVL_LPM_RAM
|
||||||
|
* The IVL_LPM_RAM may also appear as a READ port for a FF array. In
|
||||||
|
* this case, the IVL_LPM_RAM device has an ivl_lpm_width that is the
|
||||||
|
* width of the word, and an ivl_lpm_size that is the number of words
|
||||||
|
* in the array. In effect, the IVL_LPM_RAM reorganizes a vector into
|
||||||
|
* an array of words. If this is happening, then the ivl_lpm_memory
|
||||||
|
* will return 0.
|
||||||
|
*
|
||||||
|
* The ivl_lpm_q function gets the output nexa of the read port. The
|
||||||
|
* "q" port has as many bits as the width. The ivl_lpm_data2 function
|
||||||
|
* gets the nexa of the input, with the sdx the word address and the
|
||||||
|
* idx the bit within the word.
|
||||||
|
*
|
||||||
|
* - IVL_LPM_DEMUX
|
||||||
|
* This device is a form of bit replacement. The device has a data bus
|
||||||
|
* width (ivl_lpm_width) and an address width. The Data outputs are
|
||||||
|
* ivl_lpm_q and have the data bus width. The ivl_lpm_data functions are
|
||||||
|
* inputs to the device. Normally, the device passes the data inputs
|
||||||
|
* through to the Q output.
|
||||||
|
*
|
||||||
|
* The IVL_LPM_DEMUX also has a size (ivl_lpm_size) which is the
|
||||||
|
* number of addressable units in the device. If the device is bit-
|
||||||
|
* addressable, then the size is the same as the width. I.e. if
|
||||||
|
* ivl_lpm_width == ivl_lpm_size, then the address selects a single
|
||||||
|
* bit. If ivl_lpm_width/ivl_lpm_size == 8, then the address selects
|
||||||
|
* words of 8 bits and there are ivl_lpm_size of them. The
|
||||||
|
* ivl_lpm_width will always be an exact multiple of
|
||||||
|
* ivl_lpm_size. This is slightly different from the meaning of width
|
||||||
|
* in memory ports, but reflects that the DEMUX manipulates fixed
|
||||||
|
* width ranges within a single vector.
|
||||||
|
*
|
||||||
|
* The ivl_lpm_select inputs address a bit of the device. The
|
||||||
|
* addressed bit is substituted by the replacement bit. This
|
||||||
|
* replacement bit comes from the ivl_lpm_datab(net,0) nexus.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
|
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
|
||||||
|
|
@ -667,6 +738,9 @@ extern int ivl_lpm_signed(ivl_lpm_t net);
|
||||||
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
|
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
|
||||||
extern unsigned ivl_lpm_width(ivl_lpm_t net);
|
extern unsigned ivl_lpm_width(ivl_lpm_t net);
|
||||||
|
|
||||||
|
extern unsigned ivl_lpm_attr_cnt(ivl_lpm_t net);
|
||||||
|
extern ivl_attribute_t ivl_lpm_attr_val(ivl_lpm_t net, unsigned idx);
|
||||||
|
|
||||||
/* IVL_LPM_FF */
|
/* IVL_LPM_FF */
|
||||||
extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net);
|
extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net);
|
||||||
extern ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net);
|
extern ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net);
|
||||||
|
|
@ -676,26 +750,31 @@ extern ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net);
|
||||||
extern ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net);
|
extern ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net);
|
||||||
/* IVL_LPM_FF IVL_LPM_RAM */
|
/* IVL_LPM_FF IVL_LPM_RAM */
|
||||||
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
|
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
|
||||||
|
/* IVL_LPM_LATCH */
|
||||||
|
extern ivl_nexus_t ivl_lpm_gate( ivl_lpm_t netPtr );
|
||||||
|
/* IVL_LPM_FF */
|
||||||
|
extern ivl_lpm_t ivl_lpm_decode(ivl_lpm_t net);
|
||||||
/* IVL_LPM_UFUNC */
|
/* IVL_LPM_UFUNC */
|
||||||
extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
||||||
/* IVL_LPM_FF IVL_LPM_RAM */
|
/* IVL_LPM_FF IVL_LPM_RAM */
|
||||||
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
|
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
|
||||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
|
/* IVL_LPM_ADD IVL_LPM_DEMUX IVL_LPM_FF IVL_LPM_MULT */
|
||||||
|
/* IVL_LPM_RAM IVL_LPM_SUB IVL_LPM_LATCH */
|
||||||
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
|
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
|
||||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
|
/* IVL_LPM_ADD IVL_LPM_DEMUX IVL_LPM_MULT IVL_LPM_SUB */
|
||||||
/* IVL_LPM_MUX IVL_LPM_UFUNC */
|
/* IVL_LPM_MUX IVL_LPM_UFUNC */
|
||||||
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
||||||
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
|
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
|
||||||
/* IVL_LPM_UFUNC */
|
/* IVL_LPM_UFUNC */
|
||||||
extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx);
|
extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx);
|
||||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB
|
/* IVL_LPM_ADD IVL_LPM_DEMUX IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB
|
||||||
IVL_LPM_UFUNC */
|
IVL_LPM_UFUNC IVL_LPM_LATCH */
|
||||||
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
|
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
|
||||||
/* IVL_LPM_MUX IVL_LPM_RAM */
|
/* IVL_LPM_MUX IVL_LPM_DECODE IVL_LPM_DEMUX IVL_LPM_RAM */
|
||||||
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
|
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
|
||||||
/* IVL_LPM_MUX IVL_LPM_RAM */
|
/* IVL_LPM_MUX IVL_LPM_DECODE IVL_LPM_DEMUX IVL_LPM_RAM */
|
||||||
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx);
|
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx);
|
||||||
/* IVL_LPM_MUX */
|
/* IVL_LPM_DEMUX, IVL_LPM_MUX, IVL_LPM_RAM */
|
||||||
extern unsigned ivl_lpm_size(ivl_lpm_t net);
|
extern unsigned ivl_lpm_size(ivl_lpm_t net);
|
||||||
/* IVL_LPM_RAM */
|
/* IVL_LPM_RAM */
|
||||||
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
|
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
|
||||||
|
|
@ -1236,6 +1315,21 @@ _END_DECL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: ivl_target.h,v $
|
* $Log: ivl_target.h,v $
|
||||||
|
* Revision 1.126.2.5 2006/04/16 19:26:37 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.126.2.4 2006/03/26 23:09:22 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.126.2.3 2006/03/12 07:34:16 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.126.2.2 2006/02/25 05:03:28 steve
|
||||||
|
* Add support for negedge FFs by using attributes.
|
||||||
|
*
|
||||||
|
* Revision 1.126.2.1 2006/02/19 00:11:31 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
* Revision 1.126 2004/10/04 01:10:53 steve
|
* Revision 1.126 2004/10/04 01:10:53 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
VERSION = 0.0
|
suffix = @install_suffix@
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
@ -63,16 +63,16 @@ lexor.c: lexor.lex
|
||||||
parse.h parse.c: parse.y
|
parse.h parse.c: parse.y
|
||||||
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
||||||
|
|
||||||
install: all installdirs $(libdir)/ivl/ivlpp
|
install: all installdirs $(libdir)/ivl$(suffix)/ivlpp
|
||||||
|
|
||||||
$(libdir)/ivl/ivlpp: ivlpp
|
$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@: ivlpp@EXEEXT@
|
||||||
$(INSTALL_PROGRAM) ./ivlpp $(libdir)/ivl/ivlpp
|
$(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ $(libdir)/ivl$(suffix)/ivlpp@EXEEXT@
|
||||||
|
|
||||||
installdirs: ../mkinstalldirs
|
installdirs: ../mkinstalldirs
|
||||||
$(srcdir)/../mkinstalldirs $(libdir)/ivl
|
$(srcdir)/../mkinstalldirs $(libdir)/ivl$(suffix)
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(libdir)/ivl/ivlpp
|
rm -f $(libdir)/ivl$(suffix)/ivlpp@EXEEXT@
|
||||||
|
|
||||||
lexor.o: lexor.c parse.h globals.h
|
lexor.o: lexor.c parse.h globals.h
|
||||||
main.o: main.c globals.h
|
main.o: main.c globals.h
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ valid options include:
|
||||||
Predefine the symbol ``name'' to have the specified
|
Predefine the symbol ``name'' to have the specified
|
||||||
value. If the value is not specified, then ``1'' is
|
value. If the value is not specified, then ``1'' is
|
||||||
used. This is mostly of use for controlling conditional
|
used. This is mostly of use for controlling conditional
|
||||||
compilaiton.
|
compilation.
|
||||||
|
|
||||||
This option does *not* override existing `define
|
This option does *not* override existing `define
|
||||||
directives in the source file.
|
directives in the source file.
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: lexor.lex,v 1.46 2004/09/10 00:15:45 steve Exp $"
|
#ident "$Id: lexor.lex,v 1.46.2.1 2007/05/25 18:35:45 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -93,7 +93,7 @@ static void ifdef_enter(void)
|
||||||
|
|
||||||
cur = (struct ifdef_stack_t*)
|
cur = (struct ifdef_stack_t*)
|
||||||
calloc(1, sizeof(struct ifdef_stack_t));
|
calloc(1, sizeof(struct ifdef_stack_t));
|
||||||
cur->path = strdup(istack->path);
|
if (istack->path) cur->path = strdup(istack->path);
|
||||||
cur->lineno = istack->lineno;
|
cur->lineno = istack->lineno;
|
||||||
cur->next = ifdef_stack;
|
cur->next = ifdef_stack;
|
||||||
ifdef_stack = cur;
|
ifdef_stack = cur;
|
||||||
|
|
@ -108,7 +108,10 @@ static void ifdef_leave(void)
|
||||||
cur = ifdef_stack;
|
cur = ifdef_stack;
|
||||||
ifdef_stack = cur->next;
|
ifdef_stack = cur->next;
|
||||||
|
|
||||||
if (strcmp(istack->path,cur->path) != 0) {
|
/* If either path is from a non-file context e.g.(macro expansion)
|
||||||
|
* we assume that the non-file part is from this file. */
|
||||||
|
if (istack->path != NULL && cur->path != NULL &&
|
||||||
|
strcmp(istack->path,cur->path) != 0) {
|
||||||
fprintf(stderr, "%s:%u: warning: "
|
fprintf(stderr, "%s:%u: warning: "
|
||||||
"This `endif matches an ifdef in another file.\n",
|
"This `endif matches an ifdef in another file.\n",
|
||||||
istack->path, istack->lineno);
|
istack->path, istack->lineno);
|
||||||
|
|
@ -142,6 +145,7 @@ static int comment_enter = 0;
|
||||||
%x PPINCLUDE
|
%x PPINCLUDE
|
||||||
%x PPDEFINE
|
%x PPDEFINE
|
||||||
%x CCOMMENT
|
%x CCOMMENT
|
||||||
|
%x IFCCOMMENT
|
||||||
%x PCOMENT
|
%x PCOMENT
|
||||||
%x CSTRING
|
%x CSTRING
|
||||||
%x ERROR_LINE
|
%x ERROR_LINE
|
||||||
|
|
@ -309,11 +313,37 @@ W [ \t\b\f]+
|
||||||
yy_push_state(IFDEF_SUPR);
|
yy_push_state(IFDEF_SUPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<IFDEF_TRUE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||||
|
BEGIN(IFDEF_SUPR);
|
||||||
|
}
|
||||||
|
<IFDEF_FALSE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||||
|
char*name = strchr(yytext, '`');
|
||||||
|
assert(name);
|
||||||
|
name += 6;
|
||||||
|
name += strspn(name, " \t\b\f");
|
||||||
|
|
||||||
|
if (is_defined(name)) {
|
||||||
|
BEGIN(IFDEF_TRUE);
|
||||||
|
} else {
|
||||||
|
BEGIN(IFDEF_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<IFDEF_SUPR>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { }
|
||||||
|
|
||||||
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
|
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
|
||||||
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
|
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
|
||||||
<IFDEF_SUPR>`else { }
|
<IFDEF_SUPR>`else { }
|
||||||
|
|
||||||
<IFDEF_FALSE,IFDEF_SUPR>"//"[^\r\n]* { }
|
<IFDEF_FALSE,IFDEF_SUPR>"//"[^\r\n]* { }
|
||||||
|
|
||||||
|
<IFDEF_FALSE,IFDEF_SUPR>"/*" { comment_enter = YY_START; BEGIN(IFCCOMMENT); }
|
||||||
|
<IFCCOMMENT>[^\r\n] { }
|
||||||
|
<IFCCOMMENT>\n\r { istack->lineno += 1; }
|
||||||
|
<IFCCOMMENT>\r\n { istack->lineno += 1; }
|
||||||
|
<IFCCOMMENT>\n { istack->lineno += 1; }
|
||||||
|
<IFCCOMMENT>\r { istack->lineno += 1; }
|
||||||
|
<IFCCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||||
|
|
||||||
<IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { }
|
<IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { }
|
||||||
<IFDEF_FALSE,IFDEF_SUPR>\n\r { istack->lineno += 1; fputc('\n', yyout); }
|
<IFDEF_FALSE,IFDEF_SUPR>\n\r { istack->lineno += 1; fputc('\n', yyout); }
|
||||||
<IFDEF_FALSE,IFDEF_SUPR>\r\n { istack->lineno += 1; fputc('\n', yyout); }
|
<IFDEF_FALSE,IFDEF_SUPR>\r\n { istack->lineno += 1; fputc('\n', yyout); }
|
||||||
|
|
@ -322,8 +352,44 @@ W [ \t\b\f]+
|
||||||
|
|
||||||
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif { ifdef_leave(); yy_pop_state(); }
|
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif { ifdef_leave(); yy_pop_state(); }
|
||||||
|
|
||||||
|
`ifdef {
|
||||||
|
fprintf(stderr, "%s:%u: `ifdef without a macro name - ignored.\n",
|
||||||
|
istack->path, istack->lineno+1);
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
`ifndef {
|
||||||
|
fprintf(stderr, "%s:%u: `ifndef without a macro name - ignored.\n",
|
||||||
|
istack->path, istack->lineno+1);
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
`elsif {
|
||||||
|
fprintf(stderr, "%s:%u: `elsif without a macro name - ignored.\n",
|
||||||
|
istack->path, istack->lineno+1);
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||||
|
fprintf(stderr, "%s:%u: `elsif without a matching `ifdef - ignored.\n",
|
||||||
|
istack->path, istack->lineno+1);
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
`else {
|
||||||
|
fprintf(stderr, "%s:%u: `else without a matching `ifdef - ignored.\n",
|
||||||
|
istack->path, istack->lineno+1);
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
`endif {
|
||||||
|
fprintf(stderr, "%s:%u: `endif without a matching `ifdef - ignored.\n",
|
||||||
|
istack->path, istack->lineno+1);
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* This pattern notices macros and arranges for them to be replaced. */
|
/* This pattern notices macros and arranges for them to be replaced. */
|
||||||
`[a-zA-Z][a-zA-Z0-9_$]* { def_match(); }
|
`[a-zA-Z_][a-zA-Z0-9_$]* { def_match(); }
|
||||||
|
|
||||||
/* Any text that is not a directive just gets passed through to the
|
/* Any text that is not a directive just gets passed through to the
|
||||||
output. Very easy. */
|
output. Very easy. */
|
||||||
|
|
@ -854,6 +920,7 @@ void reset_lexor(FILE*out, char*paths[])
|
||||||
isp->path = strdup(paths[0]);
|
isp->path = strdup(paths[0]);
|
||||||
isp->file = fopen(paths[0], "r");
|
isp->file = fopen(paths[0], "r");
|
||||||
isp->str = 0;
|
isp->str = 0;
|
||||||
|
isp->lineno = 0;
|
||||||
if (isp->file == 0) {
|
if (isp->file == 0) {
|
||||||
perror(paths[0]);
|
perror(paths[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -876,8 +943,10 @@ void reset_lexor(FILE*out, char*paths[])
|
||||||
for (idx = 1 ; paths[idx] ; idx += 1) {
|
for (idx = 1 ; paths[idx] ; idx += 1) {
|
||||||
isp = malloc(sizeof(struct include_stack_t));
|
isp = malloc(sizeof(struct include_stack_t));
|
||||||
isp->path = strdup(paths[idx]);
|
isp->path = strdup(paths[idx]);
|
||||||
|
isp->file = 0;
|
||||||
isp->str = 0;
|
isp->str = 0;
|
||||||
isp->next = 0;
|
isp->next = 0;
|
||||||
|
isp->lineno = 0;
|
||||||
if (tail)
|
if (tail)
|
||||||
tail->next = isp;
|
tail->next = isp;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
14
ivlpp/main.c
14
ivlpp/main.c
|
|
@ -17,10 +17,11 @@ const char COPYRIGHT[] =
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: main.c,v 1.20 2004/09/10 00:15:45 steve Exp $"
|
#ident "$Id: main.c,v 1.20.2.1 2006/06/27 01:37:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
# include "version.h"
|
||||||
|
|
||||||
const char NOTICE[] =
|
const char NOTICE[] =
|
||||||
" This program is free software; you can redistribute it and/or modify\n"
|
" This program is free software; you can redistribute it and/or modify\n"
|
||||||
|
|
@ -38,8 +39,6 @@ const char NOTICE[] =
|
||||||
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
|
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
const char VERSION[] = "$Name: $ $State: Exp $";
|
|
||||||
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
#ifdef HAVE_MALLOC_H
|
#ifdef HAVE_MALLOC_H
|
||||||
|
|
@ -126,8 +125,8 @@ int main(int argc, char*argv[])
|
||||||
int opt, idx;
|
int opt, idx;
|
||||||
const char*flist_path = 0;
|
const char*flist_path = 0;
|
||||||
unsigned flag_errors = 0;
|
unsigned flag_errors = 0;
|
||||||
char*out_path = 0;
|
const char*out_path = 0;
|
||||||
char *dep_path = NULL;
|
const char*dep_path = NULL;
|
||||||
FILE*out;
|
FILE*out;
|
||||||
|
|
||||||
/* Define preprocessor keywords that I plan to just pass. */
|
/* Define preprocessor keywords that I plan to just pass. */
|
||||||
|
|
@ -213,7 +212,7 @@ int main(int argc, char*argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
fprintf(stderr, "Icarus Verilog Preprocessor version %s\n",
|
fprintf(stderr, "Icarus Verilog Preprocessor version %s\n\n",
|
||||||
VERSION);
|
VERSION);
|
||||||
fprintf(stderr, "%s\n", COPYRIGHT);
|
fprintf(stderr, "%s\n", COPYRIGHT);
|
||||||
fputs(NOTICE, stderr);
|
fputs(NOTICE, stderr);
|
||||||
|
|
@ -290,6 +289,9 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: main.c,v $
|
* $Log: main.c,v $
|
||||||
|
* Revision 1.20.2.1 2006/06/27 01:37:14 steve
|
||||||
|
* Fix const/non-const warnings.
|
||||||
|
*
|
||||||
* Revision 1.20 2004/09/10 00:15:45 steve
|
* Revision 1.20 2004/09/10 00:15:45 steve
|
||||||
* Remove bad casts.
|
* Remove bad casts.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
55
lexor.lex
55
lexor.lex
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
%option never-interactive
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
||||||
|
|
@ -19,7 +21,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: lexor.lex,v 1.86 2004/06/13 04:56:54 steve Exp $"
|
#ident "$Id: lexor.lex,v 1.86.2.4 2007/02/09 05:29:24 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -90,6 +92,7 @@ static int dec_buf_div2(char *buf);
|
||||||
static void process_timescale(const char*txt);
|
static void process_timescale(const char*txt);
|
||||||
|
|
||||||
static int comment_enter;
|
static int comment_enter;
|
||||||
|
static bool in_module = false;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%x CCOMMENT
|
%x CCOMMENT
|
||||||
|
|
@ -99,6 +102,7 @@ static int comment_enter;
|
||||||
%s UDPTABLE
|
%s UDPTABLE
|
||||||
%x PPTIMESCALE
|
%x PPTIMESCALE
|
||||||
%x PPDEFAULT_NETTYPE
|
%x PPDEFAULT_NETTYPE
|
||||||
|
%s EDGES
|
||||||
|
|
||||||
W [ \t\b\f\r]+
|
W [ \t\b\f\r]+
|
||||||
|
|
||||||
|
|
@ -156,11 +160,12 @@ W [ \t\b\f\r]+
|
||||||
with "*" and return that. */
|
with "*" and return that. */
|
||||||
"(*"{W}*")" { return '*'; }
|
"(*"{W}*")" { return '*'; }
|
||||||
|
|
||||||
|
<EDGES>"]" { BEGIN(0); return yytext[0]; }
|
||||||
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
|
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
|
||||||
|
|
||||||
\" { BEGIN(CSTRING); }
|
\" { BEGIN(CSTRING); }
|
||||||
<CSTRING>\\\" { yymore(); }
|
<CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
|
||||||
|
<CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
|
||||||
<CSTRING>\n { BEGIN(0);
|
<CSTRING>\n { BEGIN(0);
|
||||||
yylval.text = strdup(yytext);
|
yylval.text = strdup(yytext);
|
||||||
VLerror(yylloc, "Missing close quote of string.");
|
VLerror(yylloc, "Missing close quote of string.");
|
||||||
|
|
@ -179,6 +184,8 @@ W [ \t\b\f\r]+
|
||||||
<UDPTABLE>\(01\) { return 'r'; }
|
<UDPTABLE>\(01\) { return 'r'; }
|
||||||
<UDPTABLE>\(0[xX]\) { return 'Q'; }
|
<UDPTABLE>\(0[xX]\) { return 'Q'; }
|
||||||
<UDPTABLE>\(b[xX]\) { return 'q'; }
|
<UDPTABLE>\(b[xX]\) { return 'q'; }
|
||||||
|
<UDPTABLE>\(b0\) { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
|
||||||
|
<UDPTABLE>\(b1\) { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
|
||||||
<UDPTABLE>\(0\?\) { return 'P'; }
|
<UDPTABLE>\(0\?\) { return 'P'; }
|
||||||
<UDPTABLE>\(10\) { return 'f'; }
|
<UDPTABLE>\(10\) { return 'f'; }
|
||||||
<UDPTABLE>\(1[xX]\) { return 'M'; }
|
<UDPTABLE>\(1[xX]\) { return 'M'; }
|
||||||
|
|
@ -196,14 +203,42 @@ W [ \t\b\f\r]+
|
||||||
<UDPTABLE>[pP] { return 'p'; }
|
<UDPTABLE>[pP] { return 'p'; }
|
||||||
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
|
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
|
||||||
|
|
||||||
|
<EDGES>"01" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"0x" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"0z" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"10" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"1x" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"1z" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"x0" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"x1" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"z0" { return K_edge_descriptor; }
|
||||||
|
<EDGES>"z1" { return K_edge_descriptor; }
|
||||||
|
|
||||||
[a-zA-Z_][a-zA-Z0-9$_]* {
|
[a-zA-Z_][a-zA-Z0-9$_]* {
|
||||||
int rc = lexor_keyword_code(yytext, yyleng);
|
int rc = lexor_keyword_code(yytext, yyleng);
|
||||||
if (rc == IDENTIFIER) {
|
switch (rc) {
|
||||||
|
case IDENTIFIER:
|
||||||
yylval.text = strdup(yytext);
|
yylval.text = strdup(yytext);
|
||||||
if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
|
if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
|
||||||
rc = PATHPULSE_IDENTIFIER;
|
rc = PATHPULSE_IDENTIFIER;
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
case K_edge:
|
||||||
|
BEGIN(EDGES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_module:
|
||||||
|
case K_macromodule:
|
||||||
|
in_module = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_endmodule:
|
||||||
|
in_module = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
yylval.text = 0;
|
yylval.text = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -262,6 +297,12 @@ W [ \t\b\f\r]+
|
||||||
^{W}?`timescale { BEGIN(PPTIMESCALE); }
|
^{W}?`timescale { BEGIN(PPTIMESCALE); }
|
||||||
<PPTIMESCALE>.* { process_timescale(yytext); }
|
<PPTIMESCALE>.* { process_timescale(yytext); }
|
||||||
<PPTIMESCALE>\n {
|
<PPTIMESCALE>\n {
|
||||||
|
if (in_module) {
|
||||||
|
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
|
||||||
|
"`timescale directive can not be inside a module "
|
||||||
|
"definition." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
yylloc.first_line += 1;
|
yylloc.first_line += 1;
|
||||||
BEGIN(0); }
|
BEGIN(0); }
|
||||||
|
|
||||||
|
|
@ -276,10 +317,10 @@ W [ \t\b\f\r]+
|
||||||
^{W}?`disable_portfaults{W}?.* { }
|
^{W}?`disable_portfaults{W}?.* { }
|
||||||
^{W}?`enable_portfaults{W}?.* { }
|
^{W}?`enable_portfaults{W}?.* { }
|
||||||
^{W}?`endcelldefine{W}?.* { }
|
^{W}?`endcelldefine{W}?.* { }
|
||||||
^{W}?`endprotect{W}?.* { }
|
`endprotect { }
|
||||||
^{W}?`nosuppress_faults{W}?.* { }
|
^{W}?`nosuppress_faults{W}?.* { }
|
||||||
^{W}?`nounconnected_drive{W}?.* { }
|
^{W}?`nounconnected_drive{W}?.* { }
|
||||||
^{W}?`protect{W}?.* { }
|
`protect { }
|
||||||
^{W}?`resetall{W}?.* { }
|
^{W}?`resetall{W}?.* { }
|
||||||
^{W}?`suppress_faults{W}?.* { }
|
^{W}?`suppress_faults{W}?.* { }
|
||||||
^{W}?`unconnected_drive{W}?.* { }
|
^{W}?`unconnected_drive{W}?.* { }
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ function, K_function
|
||||||
highz0, K_highz0
|
highz0, K_highz0
|
||||||
highz1, K_highz1
|
highz1, K_highz1
|
||||||
if, K_if
|
if, K_if
|
||||||
|
ifnone, K_ifnone
|
||||||
initial, K_initial
|
initial, K_initial
|
||||||
inout, K_inout
|
inout, K_inout
|
||||||
input, K_input
|
input, K_input
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@
|
||||||
# 59 Temple Place - Suite 330
|
# 59 Temple Place - Suite 330
|
||||||
# Boston, MA 02111-1307, USA
|
# Boston, MA 02111-1307, USA
|
||||||
#
|
#
|
||||||
#ident "$Id: Makefile.in,v 1.34 2004/10/04 01:10:07 steve Exp $"
|
#ident "$Id: Makefile.in,v 1.34.2.1 2005/02/23 18:40:24 steve Exp $"
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
suffix = @install_suffix@
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
@ -93,17 +94,18 @@ clean:
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f Makefile config.status config.log config.cache
|
rm -f Makefile config.status config.log config.cache
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
install:: all installdirs $(libdir64)/libveriuser.a $(INSTALL32)
|
install:: all installdirs $(libdir64)/libveriuser$(suffix).a $(INSTALL32)
|
||||||
|
|
||||||
$(libdir64)/libveriuser.a: ./libveriuser.a
|
$(libdir64)/libveriuser$(suffix).a: ./libveriuser.a
|
||||||
$(INSTALL_DATA) ./libveriuser.a $(libdir64)/libveriuser.a
|
$(INSTALL_DATA) ./libveriuser.a $(libdir64)/libveriuser$(suffix).a
|
||||||
|
|
||||||
installdirs: mkinstalldirs
|
installdirs: mkinstalldirs
|
||||||
$(srcdir)/mkinstalldirs $(includedir) $(libdir64)
|
$(srcdir)/mkinstalldirs $(includedir) $(libdir64)
|
||||||
|
|
||||||
uninstall::
|
uninstall::
|
||||||
rm -f $(libdir64)/libveriuser.a
|
rm -f $(libdir64)/libveriuser$(suffix).a
|
||||||
|
|
||||||
ifeq (@enable_vvp32@,yes)
|
ifeq (@enable_vvp32@,yes)
|
||||||
all32: bin32 bin32/libveriuser.a
|
all32: bin32 bin32/libveriuser.a
|
||||||
|
|
@ -122,10 +124,13 @@ bin32/libveriuser.a: bin32/libveriuser.o
|
||||||
ar cvq $@ bin32/libveriuser.o
|
ar cvq $@ bin32/libveriuser.o
|
||||||
$(RANLIB) $@
|
$(RANLIB) $@
|
||||||
|
|
||||||
install32: $(libdir)/libveriuser.a
|
install32: $(libdir)/libveriuser$(suffix).a
|
||||||
|
|
||||||
$(libdir)/libveriuser.a: bin32/libveriuser.a
|
$(libdir)/libveriuser$(suffix).a: bin32/libveriuser.a
|
||||||
$(INSTALL_DATA) bin32/libveriuser.a $(libdir)/libveriuser.a
|
$(INSTALL_DATA) bin32/libveriuser.a $(libdir)/libveriuser$(suffix).a
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
rm -f $(DESTDIR)$(libdir)/libveriuser$(suffix).a
|
||||||
|
|
||||||
-include $(patsubst bin32/%.o, bin32/%.d, $(addprefix bin32/,$O))
|
-include $(patsubst bin32/%.o, bin32/%.d, $(addprefix bin32/,$O))
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ handle acc_next(PLI_INT32 *type, handle scope, handle prev)
|
||||||
|
|
||||||
/* trace */
|
/* trace */
|
||||||
if (pli_trace) {
|
if (pli_trace) {
|
||||||
int *ip;
|
PLI_INT32 *ip;
|
||||||
fprintf(pli_trace, "acc_next(%p <", type);
|
fprintf(pli_trace, "acc_next(%p <", type);
|
||||||
for (ip = type; *ip; ip++) {
|
for (ip = type; *ip; ip++) {
|
||||||
fprintf(pli_trace, "%s%d", ip != type ? "," : "", *ip);
|
fprintf(pli_trace, "%s%d", ip != type ? "," : "", *ip);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
AC_INIT(Makefile.in)
|
AC_INIT(Makefile.in)
|
||||||
AC_CONFIG_HEADER(config.h)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_RANLIB
|
AC_PROG_RANLIB
|
||||||
|
|
@ -12,6 +14,8 @@ AX_CPP_IDENT
|
||||||
#enable_vvp32=no
|
#enable_vvp32=no
|
||||||
AC_SUBST(enable_vvp32)
|
AC_SUBST(enable_vvp32)
|
||||||
|
|
||||||
|
AX_ENABLE_SUFFIX
|
||||||
|
|
||||||
AC_CHECK_HEADERS(malloc.h)
|
AC_CHECK_HEADERS(malloc.h)
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(unsigned long long)
|
AC_CHECK_SIZEOF(unsigned long long)
|
||||||
|
|
@ -21,7 +25,7 @@ AC_CHECK_SIZEOF(unsigned)
|
||||||
# may modify CPPFLAGS and CFLAGS
|
# may modify CPPFLAGS and CFLAGS
|
||||||
AX_CPP_PRECOMP
|
AX_CPP_PRECOMP
|
||||||
|
|
||||||
# Compiler option for position independent code, needed whan making shared objects.
|
# Compiler option for position independent code, needed when making shared objects.
|
||||||
AX_C_PICFLAG
|
AX_C_PICFLAG
|
||||||
|
|
||||||
AC_SUBST(EXEEXT)
|
AC_SUBST(EXEEXT)
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ typedef struct t_pli_data {
|
||||||
int paramvc; /* parameter number for misctf */
|
int paramvc; /* parameter number for misctf */
|
||||||
} s_pli_data, *p_pli_data;
|
} s_pli_data, *p_pli_data;
|
||||||
|
|
||||||
static int compiletf(char *);
|
static PLI_INT32 compiletf(char *);
|
||||||
static int calltf(char *);
|
static PLI_INT32 calltf(char *);
|
||||||
static int callback(p_cb_data);
|
static PLI_INT32 callback(p_cb_data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register veriusertfs routines/wrappers. Iterate over the tfcell
|
* Register veriusertfs routines/wrappers. Iterate over the tfcell
|
||||||
|
|
@ -109,7 +109,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
||||||
tf_data.tfname = tf->tfname;
|
tf_data.tfname = tf->tfname;
|
||||||
tf_data.compiletf = compiletf;
|
tf_data.compiletf = compiletf;
|
||||||
tf_data.calltf = calltf;
|
tf_data.calltf = calltf;
|
||||||
tf_data.sizetf = tf->sizetf;
|
tf_data.sizetf = (PLI_INT32 (*)(char *))tf->sizetf;
|
||||||
tf_data.user_data = (char *)data;
|
tf_data.user_data = (char *)data;
|
||||||
|
|
||||||
if (pli_trace) {
|
if (pli_trace) {
|
||||||
|
|
@ -139,7 +139,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
||||||
* This function calls the veriusertfs checktf and sets up all the
|
* This function calls the veriusertfs checktf and sets up all the
|
||||||
* callbacks misctf requires.
|
* callbacks misctf requires.
|
||||||
*/
|
*/
|
||||||
static int compiletf(char *data)
|
static PLI_INT32 compiletf(char *data)
|
||||||
{
|
{
|
||||||
p_pli_data pli;
|
p_pli_data pli;
|
||||||
p_tfcell tf;
|
p_tfcell tf;
|
||||||
|
|
@ -221,7 +221,7 @@ static int compiletf(char *data)
|
||||||
/*
|
/*
|
||||||
* This function is the wrapper for the veriusertfs calltf routine.
|
* This function is the wrapper for the veriusertfs calltf routine.
|
||||||
*/
|
*/
|
||||||
static int calltf(char *data)
|
static PLI_INT32 calltf(char *data)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
p_pli_data pli;
|
p_pli_data pli;
|
||||||
|
|
@ -249,7 +249,7 @@ static int calltf(char *data)
|
||||||
*/
|
*/
|
||||||
extern int async_misctf_enable;
|
extern int async_misctf_enable;
|
||||||
|
|
||||||
static int callback(p_cb_data data)
|
static PLI_INT32 callback(p_cb_data data)
|
||||||
{
|
{
|
||||||
p_pli_data pli;
|
p_pli_data pli;
|
||||||
p_tfcell tf;
|
p_tfcell tf;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: load_module.cc,v 1.12 2003/06/05 04:31:09 steve Exp $"
|
#ident "$Id: load_module.cc,v 1.12.2.1 2005/03/22 15:53:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
# include <cstdlib>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The module library items are maps of key names to file name within
|
* The module library items are maps of key names to file name within
|
||||||
|
|
@ -88,7 +90,7 @@ bool load_module(const char*type)
|
||||||
cerr << "Executing: " << cmdline << endl;
|
cerr << "Executing: " << cmdline << endl;
|
||||||
|
|
||||||
pform_parse(path, file);
|
pform_parse(path, file);
|
||||||
fclose(file);
|
pclose(file);
|
||||||
free(cmdline);
|
free(cmdline);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -193,6 +195,9 @@ int build_library_index(const char*path, bool key_case_sensitive)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: load_module.cc,v $
|
* $Log: load_module.cc,v $
|
||||||
|
* Revision 1.12.2.1 2005/03/22 15:53:12 steve
|
||||||
|
* popen must be matched by pclose.
|
||||||
|
*
|
||||||
* Revision 1.12 2003/06/05 04:31:09 steve
|
* Revision 1.12 2003/06/05 04:31:09 steve
|
||||||
* INclude missing assert.h in load_module.
|
* INclude missing assert.h in load_module.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
|
|
||||||
|
Icarus Verilog for Mac OS X
|
||||||
|
|
||||||
|
NOTE: Icarus Verilog version 0.8 is known to compile "out of the
|
||||||
|
box" on MacOSX 10.3. OSX 10.3 users need only the developer tools
|
||||||
|
included with new systems or available for free download from
|
||||||
|
Apple. Install Xcode and skip directly to step #3.
|
||||||
|
|
||||||
This file describes the procedure to build and install Icarus Verilog
|
This file describes the procedure to build and install Icarus Verilog
|
||||||
on Mac OS X. I assume that you have experience with Unix and
|
on Mac OS X. I assume that you have experience with Unix and
|
||||||
Terminal.app and a basic knowledge of how to download, compile and
|
Terminal.app and a basic knowledge of how to download, compile and
|
||||||
|
|
|
||||||
41
main.cc
41
main.cc
|
|
@ -19,7 +19,7 @@ const char COPYRIGHT[] =
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: main.cc,v 1.86 2004/10/04 01:10:53 steve Exp $"
|
#ident "$Id: main.cc,v 1.86.2.3 2006/06/12 00:16:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -59,6 +59,7 @@ const char NOTICE[] =
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "target.h"
|
# include "target.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
|
# include "version.h"
|
||||||
|
|
||||||
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
|
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
|
||||||
extern "C" int getopt(int argc, char*argv[], const char*fmt);
|
extern "C" int getopt(int argc, char*argv[], const char*fmt);
|
||||||
|
|
@ -75,8 +76,6 @@ extern "C" const char*optarg;
|
||||||
/* Count errors detected in flag processing. */
|
/* Count errors detected in flag processing. */
|
||||||
unsigned flag_errors = 0;
|
unsigned flag_errors = 0;
|
||||||
|
|
||||||
const char VERSION[] = "$Name: $";
|
|
||||||
|
|
||||||
const char*basedir = ".";
|
const char*basedir = ".";
|
||||||
|
|
||||||
const char*target = "null";
|
const char*target = "null";
|
||||||
|
|
@ -103,6 +102,7 @@ FILE *depend_file = NULL;
|
||||||
bool warn_implicit = false;
|
bool warn_implicit = false;
|
||||||
bool warn_timescale = false;
|
bool warn_timescale = false;
|
||||||
bool warn_portbinding = false;
|
bool warn_portbinding = false;
|
||||||
|
bool warn_unused = false;
|
||||||
|
|
||||||
bool error_implicit = false;
|
bool error_implicit = false;
|
||||||
|
|
||||||
|
|
@ -112,6 +112,9 @@ bool error_implicit = false;
|
||||||
bool debug_scopes = false;
|
bool debug_scopes = false;
|
||||||
bool debug_eval_tree = false;
|
bool debug_eval_tree = false;
|
||||||
bool debug_elaborate = false;
|
bool debug_elaborate = false;
|
||||||
|
bool debug_synth = false;
|
||||||
|
bool debug_cprop = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verbose messages enabled.
|
* Verbose messages enabled.
|
||||||
*/
|
*/
|
||||||
|
|
@ -132,6 +135,11 @@ const bool CASE_SENSITIVE = false;
|
||||||
const bool CASE_SENSITIVE = true;
|
const bool CASE_SENSITIVE = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Are we doing synthesis?
|
||||||
|
*/
|
||||||
|
bool synthesis = false;
|
||||||
|
|
||||||
extern void cprop(Design*des);
|
extern void cprop(Design*des);
|
||||||
extern void synth(Design*des);
|
extern void synth(Design*des);
|
||||||
extern void synth2(Design*des);
|
extern void synth2(Design*des);
|
||||||
|
|
@ -314,6 +322,12 @@ static void read_iconfig_file(const char*ipath)
|
||||||
} else if (strcmp(cp,"elaborate") == 0) {
|
} else if (strcmp(cp,"elaborate") == 0) {
|
||||||
debug_elaborate = true;
|
debug_elaborate = true;
|
||||||
cerr << "debug: Enable elaborate debug" << endl;
|
cerr << "debug: Enable elaborate debug" << endl;
|
||||||
|
} else if (strcmp(cp,"synth") == 0) {
|
||||||
|
debug_synth = true;
|
||||||
|
cerr << "debug: Enable synthesis debug" << endl;
|
||||||
|
} else if (strcmp(cp,"cprop") == 0) {
|
||||||
|
debug_cprop = true;
|
||||||
|
cerr << "debug: Enable cprop debug" << endl;
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -325,6 +339,9 @@ static void read_iconfig_file(const char*ipath)
|
||||||
parm_to_flagmap(parm);
|
parm_to_flagmap(parm);
|
||||||
|
|
||||||
} else if (strcmp(buf,"functor") == 0) {
|
} else if (strcmp(buf,"functor") == 0) {
|
||||||
|
if (strncmp(cp, "synth", 5) == 0) {
|
||||||
|
synthesis = true; // We are doing synthesis.
|
||||||
|
}
|
||||||
net_func tmp = name_to_net_func(cp);
|
net_func tmp = name_to_net_func(cp);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
cerr << "No such design transform function ``"
|
cerr << "No such design transform function ``"
|
||||||
|
|
@ -376,6 +393,9 @@ static void read_iconfig_file(const char*ipath)
|
||||||
case 't':
|
case 't':
|
||||||
warn_timescale = true;
|
warn_timescale = true;
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
warn_unused = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -483,7 +503,7 @@ int main(int argc, char*argv[])
|
||||||
# endif
|
# endif
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
cout << "Icarus Verilog version " << VERSION << endl;
|
cout << "Icarus Verilog version " << VERSION << endl << endl;
|
||||||
cout << COPYRIGHT << endl;
|
cout << COPYRIGHT << endl;
|
||||||
cout << endl << NOTICE << endl;
|
cout << endl << NOTICE << endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -496,8 +516,8 @@ int main(int argc, char*argv[])
|
||||||
return flag_errors;
|
return flag_errors;
|
||||||
|
|
||||||
if (help_flag) {
|
if (help_flag) {
|
||||||
cout << "Icarus Verilog version " << VERSION << endl <<
|
cout << "Icarus Verilog version " << VERSION << endl << endl <<
|
||||||
"usage: ivl <options> <file>\n"
|
"Usage: ivl <options> <file>\n"
|
||||||
"options:\n"
|
"options:\n"
|
||||||
"\t-C <name> Config file from driver.\n"
|
"\t-C <name> Config file from driver.\n"
|
||||||
"\t-h Print usage information, and exit.\n"
|
"\t-h Print usage information, and exit.\n"
|
||||||
|
|
@ -744,6 +764,15 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: main.cc,v $
|
* $Log: main.cc,v $
|
||||||
|
* Revision 1.86.2.3 2006/06/12 00:16:53 steve
|
||||||
|
* Add support for -Wunused warnings.
|
||||||
|
*
|
||||||
|
* Revision 1.86.2.2 2006/04/23 04:25:45 steve
|
||||||
|
* Add cprop debugging.
|
||||||
|
*
|
||||||
|
* Revision 1.86.2.1 2006/04/01 01:37:24 steve
|
||||||
|
* Add synth debug flag
|
||||||
|
*
|
||||||
* Revision 1.86 2004/10/04 01:10:53 steve
|
* Revision 1.86 2004/10/04 01:10:53 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
217
mingw.txt
217
mingw.txt
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
MINGW PORT OF ICARUS VERILOG
|
MINGW PORT OF ICARUS VERILOG
|
||||||
|
|
||||||
Copyright 2003 Stephen Williams <steve@icarus.com>
|
Copyright 2006 Stephen Williams <steve@icarus.com>
|
||||||
|
|
||||||
|
|
||||||
Icarus Verilog source can be compiled with the mingw C/C++ compilers
|
Icarus Verilog source can be compiled with the mingw C/C++ compilers
|
||||||
|
|
@ -12,13 +12,13 @@ or without Cygwin, so this is the preferred Windows distribution form.
|
||||||
The configure scripts automatically detect that the compilers in use
|
The configure scripts automatically detect that the compilers in use
|
||||||
are the mingw compilers and will configure the Makefiles appropriately.
|
are the mingw compilers and will configure the Makefiles appropriately.
|
||||||
|
|
||||||
However, the mingw tools do not include all the other tools around the
|
The mingw patch doesn't contain tools beyond the compiler, but there
|
||||||
compiler, including the shell interpreter for the configure script,
|
is the "msys" package that the makers of Mingw publish that has enough
|
||||||
bison, flex, gperf, etc. Therefore, you still need Cygwin to compile
|
extra tools to get most everything else working. There are a few extra
|
||||||
Icarus Verilog, even if you don't need the Cygwin compilers. There are
|
packages needed beyond mingw and msys, and the following instructions
|
||||||
also a few precompiled library prerequisites that you need.
|
explain how to get them and install them.
|
||||||
|
|
||||||
* Some Preliminary Comments
|
* Some Preliminary Comments -- PLEASE READ ME --
|
||||||
|
|
||||||
The Windows port of Icarus Verilog is the most difficult of all the
|
The Windows port of Icarus Verilog is the most difficult of all the
|
||||||
ports. The Windows system off the shelf is completely stripped, devoid
|
ports. The Windows system off the shelf is completely stripped, devoid
|
||||||
|
|
@ -26,7 +26,15 @@ of any support for software development. Everything needed to compile
|
||||||
Icarus Verilog must be collected from various sources and stitched
|
Icarus Verilog must be collected from various sources and stitched
|
||||||
together by hand. Normal human beings with a basic understanding of
|
together by hand. Normal human beings with a basic understanding of
|
||||||
software development can do this, but some patience (and access to the
|
software development can do this, but some patience (and access to the
|
||||||
Internet) is required. You may choose to print these instructions.
|
Internet) is required. You may choose to print these instructions. FOR
|
||||||
|
BEST RESULTS, FOLLOW THESE INSTRUCTIONS CAREFULLY.
|
||||||
|
|
||||||
|
NOTE that if you have Cygwin installed, it is best to not use a cygwin
|
||||||
|
window to do the build, as the Cygwin tools will intermix with the
|
||||||
|
mingw tools such that it is hard to be sure you are using the right
|
||||||
|
compiler. Thus, it is recommended that these steps be *not* done in a
|
||||||
|
Cygwin window. Use an MSYS window instead, and be careful that your
|
||||||
|
msys/mingw tools are not masked by paths that point to Cygwin binaries.
|
||||||
|
|
||||||
I have no plans to intentionally support MSVC++ compilation. Don't ask.
|
I have no plans to intentionally support MSVC++ compilation. Don't ask.
|
||||||
|
|
||||||
|
|
@ -36,13 +44,15 @@ This is a brief list of prerequisite packages, along with the URL
|
||||||
where each can be found. In most cases, the specific version is not
|
where each can be found. In most cases, the specific version is not
|
||||||
critical, but these are the versions I use.
|
critical, but these are the versions I use.
|
||||||
|
|
||||||
Cygwin <http://cygwin.com>
|
msys-1.0 <http://www.mingw/org>
|
||||||
Mingw32-2.0.0 <http://www.mingw.org>
|
msysDTK-1.0 <http://www.mingw.org>
|
||||||
|
Mingw32-5.x <http://www.mingw.org>
|
||||||
readline-4.2-20010727.zip <http://mingwrep.sourceforge.net>
|
readline-4.2-20010727.zip <http://mingwrep.sourceforge.net>
|
||||||
bzip2-1.0.2-bin.zip <http://gnuwin32.sourceforge.net>
|
bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
|
||||||
zlib-1.1.4-bin.zip <http://gnuwin32.sourceforge.net>
|
zlib-1.2.3 <http://gnuwin32.sourceforge.net>
|
||||||
bzip2-1.0.2-lib.zip <http://gnuwin32.sourceforge.net>
|
gperf-3.0.1 <http://gnuwin32.sourceforge.net>
|
||||||
zlib-1.1.4-lib.zip <http://gnuwin32.sourceforge.net>
|
bison-2.1 <http://gnuwin32.sourceforge.net>
|
||||||
|
flex-2.5.4a <http://gnuwin32.sourceforge.net>
|
||||||
|
|
||||||
The above table lists the packages required. It is convenient to
|
The above table lists the packages required. It is convenient to
|
||||||
install them in the above order. Many of these packages are also
|
install them in the above order. Many of these packages are also
|
||||||
|
|
@ -55,59 +65,38 @@ installation of Icarus Verilog is complete. These are only needed to
|
||||||
build the compiler. The Mingw32 package can be used to compile VPI
|
build the compiler. The Mingw32 package can be used to compile VPI
|
||||||
modules if you choose.
|
modules if you choose.
|
||||||
|
|
||||||
* Install Cygwin
|
* Install MSYS and msysDTK
|
||||||
|
|
||||||
So, step 1 is "Download and Install Cygwin." See the web page
|
The msys package is available from the mingw download site. This is
|
||||||
http://www.cygwin.com for instructions and the files to do
|
not the compiler but a collection of *nix tools ported to Windows and
|
||||||
this. Cygwin *is* a kool package, and is worth having anyhow. There is
|
wrapped in a convenient installer. The msys package is all the various
|
||||||
a convenient setup program that you download first. You execute the
|
basic tools (shells, file utils, etc) and the msysDTK is extra
|
||||||
setup program, and that prompts you to select the package you want.
|
developer tools other then the compiler.
|
||||||
|
|
||||||
You need in particular the Cygwin base, bison (see notes) flex, make
|
Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are
|
||||||
and gperf. If you are compiling from CVS, you also need cvs, rcs and
|
self-installing packages. Install msys first, and then msysDTC. Most
|
||||||
automake packages. You will also need tar and gunzip, but these are
|
likely, you want to install them in c:/msys. (The msysDTK is installed
|
||||||
hard to not install. I recommend installing the "which" package as
|
in the same location, as it is an add-on.)
|
||||||
well. Beyond the basics, be sure to install these Cygwin packages:
|
|
||||||
|
|
||||||
bison (*not* 1.875. See Notes.)
|
This install should be easy and reliable.
|
||||||
flex
|
|
||||||
ghostscript (makes the documentation)
|
|
||||||
gperf
|
|
||||||
gzip
|
|
||||||
make
|
|
||||||
strip
|
|
||||||
tar (tar and gunzip for unpacking the source)
|
|
||||||
unzip (For unpacking zip compressed packages.)
|
|
||||||
which
|
|
||||||
|
|
||||||
NOTES:
|
The installation will leave an "msys" icon on your desktop and in the
|
||||||
bison-1.875 is broken, it generates invalid C/C++ code. You
|
mingw sub-menu of your Start menu. This icon brings up a shell window
|
||||||
don't want that version for anything you do. If you have that
|
(a command line) that has paths all set up for executing msys and
|
||||||
version (use "bison -V" to check the version) then use the
|
mingw commands. This is what you will want to use while executing
|
||||||
Cygwin setup program to get a different version. I've downgraded
|
commands below.
|
||||||
to 1.75 and couldn't be happier. In fact, a whole host of insane
|
|
||||||
bison bugs can be avoided that way.
|
|
||||||
|
|
||||||
There is a mingw32 runtime package included in the Cygwin
|
|
||||||
distribution. You do *not* need that, as you will be getting
|
|
||||||
everything from the mingw32 distribution itself.
|
|
||||||
|
|
||||||
Other then the install of mingw32, most of the remaining steps are
|
|
||||||
best done in a Cygwin window. When you installed Cygwin, a start menu
|
|
||||||
entry was created to allow you to start up the Cygwin window. I'll use
|
|
||||||
the string "$ " to represent a command prompt in this window, because
|
|
||||||
that is the usual bash prompt.
|
|
||||||
|
|
||||||
* Install Mingw32
|
* Install Mingw32
|
||||||
|
|
||||||
The obvious step 2, then, is install the mingw compilers. These can be
|
The obvious step 2, then, is install the mingw compilers. These can be
|
||||||
found at the web page <http://www.mingw.org>. The Mingw-2.x.x version
|
found at the web page <http://www.mingw.org>. The Mingw-5.x.x package
|
||||||
comes prepackaged in a convenient, Windows style, installer. I
|
is a convenient remote installer. Download this program and run
|
||||||
recommend you download this package instead of picking and choosing
|
it. The installer will ask wich components you want to install. You
|
||||||
bits.
|
need only the base C compiler and the C++ compiler. (You may install
|
||||||
|
other languages if you wish.)
|
||||||
|
|
||||||
When I install Mingw32 (using the installer) I typically set a
|
When I install Mingw32 (using the installer) I typically set a
|
||||||
destination directory of d:\mingw-2.0.0 or the like. You will be using
|
destination directory of d:\mingw or the like. You will be using
|
||||||
that path later.
|
that path later.
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
|
|
@ -115,6 +104,10 @@ that path later.
|
||||||
need Mingw32, even if you are using a precompiled binary. VPI
|
need Mingw32, even if you are using a precompiled binary. VPI
|
||||||
modules only require Mingw32, and none of the other libraries.
|
modules only require Mingw32, and none of the other libraries.
|
||||||
|
|
||||||
|
Finally, as part of installing the mingw32 compilers, remember to add
|
||||||
|
the mingw/bin directory to your path. You will need that to be able to
|
||||||
|
find the compilers later.
|
||||||
|
|
||||||
* Install Mingw32 Packages
|
* Install Mingw32 Packages
|
||||||
|
|
||||||
There is a collection of precompiled libraries and add-on packages
|
There is a collection of precompiled libraries and add-on packages
|
||||||
|
|
@ -123,86 +116,94 @@ with simplified Windows installers, but they are pretty easy to
|
||||||
install by hand. Icarus Verilog uses the readline-4.2 package from
|
install by hand. Icarus Verilog uses the readline-4.2 package from
|
||||||
that collection.
|
that collection.
|
||||||
|
|
||||||
Since I installed Mingw32 in d:\mingw-2.0.0, I also created a
|
Since I installed Mingw32 in c:\mingw, I also created a
|
||||||
Mingw-packages directory called d:\mingw-packages. The install, then,
|
Mingw-packages directory called c:\mingw-packages. The install, then,
|
||||||
is as easy as this:
|
is as easy as this:
|
||||||
|
|
||||||
<cygwin shell>
|
<msys shell>
|
||||||
$ cd d:/mingw-packages
|
$ cd c:/mingw-packages
|
||||||
$ unzip readline-4.2-20010727.zip
|
$ unzip readline-4.2-20010727.zip
|
||||||
[lots of inflating...]
|
[lots of inflating...]
|
||||||
|
|
||||||
|
There is no need to adjust your execution path for this package as we
|
||||||
|
are only using a library out of here. However, do remember the
|
||||||
|
directory name, as you will need it later.
|
||||||
|
|
||||||
Done. On to the next packages.
|
Done. On to the next packages.
|
||||||
|
|
||||||
* Install GnuWin32 Packages
|
* Install GnuWin32 Packages
|
||||||
|
|
||||||
The GnuWin32 project is a collections of open source programs and
|
The GnuWin32 project is a collections of open source programs and
|
||||||
libraries ported to Windows. These also work well with the Mingw
|
libraries ported to Windows. These also work well with the Mingw
|
||||||
compiler, and in fact Icarus Verilog uses a few libraries from this
|
compiler, and in fact Icarus Verilog uses a few pieces from this
|
||||||
collection.
|
collection.
|
||||||
|
|
||||||
You will need these gnuwin32 packages to compile Icarus Verilog:
|
You will need these gnuwin32 packages to compile Icarus Verilog:
|
||||||
|
|
||||||
<http://gnuwin32.sourceforge.net>
|
<http://gnuwin32.sourceforge.net>
|
||||||
bzip2-1.0.2-lib.zip
|
bzip2-1.0.3.exe
|
||||||
bzip2-1.0.2-bin.zip
|
zlib-1.2.3.exe
|
||||||
zlib-1.1.4-lib.zip
|
gperf-3.0.1.exe
|
||||||
zlib-1.1.4-bin.zip
|
bison-2.1.exe
|
||||||
|
flex-2.5.4a.exe
|
||||||
|
|
||||||
I suggest creating a common directory for holding all your gnuwin32
|
I suggest creating a common directory for holding all your gnuwin32
|
||||||
packages. I use D:\gnuwin32.
|
packages. I use C:\gnuwin32. The download page at the gnuwin32 site
|
||||||
|
has a "setup" link for each of these packages. Click the setup to
|
||||||
|
download the installer for each of the desired programes, then execute
|
||||||
|
the downloaded .exe files to invoke the installer. Install into the
|
||||||
|
c:\gunwin32 directory.
|
||||||
|
|
||||||
After downloading these packages, put the .zip files in your gnuwin32
|
NOTES:
|
||||||
directory and install them like so:
|
You need the binaries and the developer files, but you do not
|
||||||
|
need the source to these packages. The installer gives you the
|
||||||
|
choice.
|
||||||
|
|
||||||
<cygwin shell>
|
After you are done installing the gnuwin32 tools, you should add the
|
||||||
$ cd d:/gnuwin32
|
c:\gnuwin32\bin directory (assuming you installed in c:\gnuwin32) to
|
||||||
$ unzip bzip2-1.0.2-bin.zip
|
your Windows path. The msys shell will pick up your Windows path.
|
||||||
[lots of inflating...]
|
|
||||||
$ unzip bzip2-1.0.2-lib.zip
|
|
||||||
[lots of inflating...]
|
|
||||||
$ unzip zlib-1.1.4-bin.zip
|
|
||||||
[lots of inflating...]
|
|
||||||
$ unzip zlib-1.1.4-lib.zip
|
|
||||||
[lots of inflating...]
|
|
||||||
|
|
||||||
Done.
|
|
||||||
|
|
||||||
* Unpack Icarus Verilog source
|
* Unpack Icarus Verilog source
|
||||||
|
|
||||||
Unpack the compressed tar file (.tar.gz) of the source with a command
|
Unpack the compressed tar file (.tar.gz) of the source with a command
|
||||||
like this:
|
like this:
|
||||||
|
|
||||||
$ gunzip -d verilog-20030303.tar.gz | tar xvf -
|
$ gunzip -d verilog-xxxxxxxx.tar.gz | tar xvf -
|
||||||
|
|
||||||
This will create a directory "verilog-20030303" that contains all the
|
This will create a directory "verilog-xxxxxxxx" that contains all the
|
||||||
source for Icarus Verilog. Descend into that directory, as that is
|
source for Icarus Verilog. Descend into that directory, as that is
|
||||||
where we will work from now on.
|
where we will work from now on.
|
||||||
|
|
||||||
$ cd verilog-20030303
|
$ cd verilog-xxxxxxxx
|
||||||
|
|
||||||
NOTE:
|
NOTES:
|
||||||
The exact name of the file will vary according to the
|
The exact name of the file will vary according to the
|
||||||
snapshot. The 20030303 name is only an example.
|
snapshot. The 20030303 name is only an example.
|
||||||
|
|
||||||
* Select the mingw compilers
|
Unpack the source into a directory that has no spaces. The
|
||||||
|
makefiles included in the source get confused by white space in
|
||||||
|
directory names.
|
||||||
|
|
||||||
In your cygwin window, if you type "which c++" you might get the
|
* Preconfigure Icarus Verilog (Not normally needed)
|
||||||
response path "/usr/bin/c++" which is the cygwin compiler. This is not
|
|
||||||
the one we want to use, however. Tell the shell where the mingw
|
|
||||||
compilers are by setting the search path like so:
|
|
||||||
|
|
||||||
$ PATH=/cygdrive/d/mingw-2.0.0/bin:$PATH
|
Under certain cases, you may need to "preconfigure" the Icarus Verilog
|
||||||
|
source tree. You should only need to do this if you are getting the
|
||||||
|
Icarus Verilog source tree from CVS, or you are using an existing
|
||||||
|
source tree that you've patched to cause configure.in files to change.
|
||||||
|
|
||||||
This assumes that you installed mingw in D:\mingw-2.0.0. The actual
|
NOTE: If you are building from a fresh, bundled source tree that
|
||||||
programs are in the bin directory under the root. After this command,
|
you downloaded from an FTP site, then SKIP THIS STEP. Go on to
|
||||||
check that you are now getting the right compilers with this "which"
|
the "Configure Icarus Verilog" step below.
|
||||||
command:
|
|
||||||
|
|
||||||
$ which c++
|
First, remove any autom4te.cache directories that may exist in your
|
||||||
/cygdrive/d/mingw-2.0.0/bin/c++
|
source tree. These can make a mess of autoconf runs. Then, generate
|
||||||
|
configure scripts with this command:
|
||||||
|
|
||||||
Good!
|
$ sh autoconf.sh
|
||||||
|
|
||||||
|
This script will run the "autoconf" command (part of the msysDTK) to
|
||||||
|
generate all the necessary "configure" scripts. This will take a few
|
||||||
|
minutes. This should go smoothly.
|
||||||
|
|
||||||
* Configure Icarus Verilog
|
* Configure Icarus Verilog
|
||||||
|
|
||||||
|
|
@ -215,10 +216,10 @@ without white space.
|
||||||
Now, configure the source to make the makefiles and configuration
|
Now, configure the source to make the makefiles and configuration
|
||||||
details. Run these commands:
|
details. Run these commands:
|
||||||
|
|
||||||
$ CPPFLAGS="-Id:/gnuwin32/include -Id:/mingw-packages/include"
|
$ CPPFLAGS="-Ic:/gnuwin32/include -Ic:/mingw-packages/include"
|
||||||
$ LDFLAGS="-Ld:/gnuwin32/lib -Ld:/mingw-packages/include"
|
$ LDFLAGS="-Lc:/gnuwin32/lib -Lc:/mingw-packages/lib"
|
||||||
$ export CPPFLAGS LDFLAGS
|
$ export CPPFLAGS LDFLAGS
|
||||||
$ ./configure --prefix=d:/iverilog
|
$ ./configure --prefix=c:/iverilog
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
The CPPFLAGS and LDFLAGS variables tell configure where
|
The CPPFLAGS and LDFLAGS variables tell configure where
|
||||||
|
|
@ -267,10 +268,10 @@ directory you chose) and away you go.
|
||||||
You may find that you need to put some of the prerequisite DLLs into
|
You may find that you need to put some of the prerequisite DLLs into
|
||||||
the d:\iverilog\bin directory. These include:
|
the d:\iverilog\bin directory. These include:
|
||||||
|
|
||||||
d:\mingw-2.0.0\bin\mingw10.dll
|
c:\mingw\bin\mingw10.dll
|
||||||
d:\mingw-packages\bin\libreadline.dll
|
c:\mingw-packages\bin\libreadline.dll
|
||||||
d:\gnuwin32\bin\bzip2.dll
|
c:\gnuwin32\bin\bzip2.dll
|
||||||
d:\gnuwin32\bin\zlib.dll
|
c:\gnuwin32\bin\zlib.dll
|
||||||
|
|
||||||
If you already have these in your Windows path (i.e. your system32
|
If you already have these in your Windows path (i.e. your system32
|
||||||
directory) then you do not need to copy them into the iverilog
|
directory) then you do not need to copy them into the iverilog
|
||||||
|
|
@ -279,14 +280,14 @@ files.
|
||||||
|
|
||||||
* Running Icarus Verilog
|
* Running Icarus Verilog
|
||||||
|
|
||||||
Finally, put the D:\iverilog\bin directory in your Windows path, and
|
Finally, put the C:\iverilog\bin directory in your Windows path, and
|
||||||
you should be able to run the iverilog and vvp commands to your
|
you should be able to run the iverilog and vvp commands to your
|
||||||
heart's content.
|
heart's content.
|
||||||
|
|
||||||
Currently, the iverilog.exe uses the path to itself to locate the
|
Currently, the iverilog.exe uses the path to itself to locate the
|
||||||
libraries and modules associated with itself. In other words, if you
|
libraries and modules associated with itself. In other words, if you
|
||||||
execute the D:\iverilog\bin\iverilog.exe program, it will locate its
|
execute the C:\iverilog\bin\iverilog.exe program, it will locate its
|
||||||
subparts in the D:\iverilog directory and subdirectories below
|
subparts in the C:\iverilog directory and subdirectories below
|
||||||
that. This means you can move the Icarus Verilog installation by
|
that. This means you can move the Icarus Verilog installation by
|
||||||
simply moving the root directory and all its contents.
|
simply moving the root directory and all its contents.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_assign.cc,v 1.18 2004/08/28 15:08:31 steve Exp $"
|
#ident "$Id: net_assign.cc,v 1.18.2.3 2006/05/02 02:00:15 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -45,6 +45,7 @@ NetAssign_::NetAssign_(NetNet*s)
|
||||||
lwid_ = sig_->pin_count();
|
lwid_ = sig_->pin_count();
|
||||||
sig_->incr_lref();
|
sig_->incr_lref();
|
||||||
more = 0;
|
more = 0;
|
||||||
|
mem_lref_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign_::NetAssign_(NetMemory*s)
|
NetAssign_::NetAssign_(NetMemory*s)
|
||||||
|
|
@ -53,6 +54,7 @@ NetAssign_::NetAssign_(NetMemory*s)
|
||||||
loff_ = 0;
|
loff_ = 0;
|
||||||
lwid_ = mem_->width();
|
lwid_ = mem_->width();
|
||||||
more = 0;
|
more = 0;
|
||||||
|
mem_lref_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign_::NetAssign_(NetVariable*s)
|
NetAssign_::NetAssign_(NetVariable*s)
|
||||||
|
|
@ -61,6 +63,7 @@ NetAssign_::NetAssign_(NetVariable*s)
|
||||||
loff_ = 0;
|
loff_ = 0;
|
||||||
lwid_ = 0;
|
lwid_ = 0;
|
||||||
more = 0;
|
more = 0;
|
||||||
|
mem_lref_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign_::~NetAssign_()
|
NetAssign_::~NetAssign_()
|
||||||
|
|
@ -71,6 +74,14 @@ NetAssign_::~NetAssign_()
|
||||||
sig_->type(NetNet::WIRE);
|
sig_->type(NetNet::WIRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mem_) {
|
||||||
|
NetNet*exp = mem_->reg_from_explode();
|
||||||
|
if (exp && mem_lref_) {
|
||||||
|
exp->decr_lref();
|
||||||
|
if (turn_sig_to_wire_on_release_ && exp->peek_lref() == 0)
|
||||||
|
exp->type(NetNet::WIRE);
|
||||||
|
}
|
||||||
|
}
|
||||||
assert( more == 0 );
|
assert( more == 0 );
|
||||||
if (bmux_) delete bmux_;
|
if (bmux_) delete bmux_;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +122,10 @@ perm_string NetAssign_::name() const
|
||||||
|
|
||||||
NetNet* NetAssign_::sig() const
|
NetNet* NetAssign_::sig() const
|
||||||
{
|
{
|
||||||
return sig_;
|
if (mem_)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return sig_;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetMemory* NetAssign_::mem() const
|
NetMemory* NetAssign_::mem() const
|
||||||
|
|
@ -124,6 +138,16 @@ NetVariable* NetAssign_::var() const
|
||||||
return var_;
|
return var_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetAssign_::incr_mem_lref()
|
||||||
|
{
|
||||||
|
if (! mem_lref_) {
|
||||||
|
assert(mem_);
|
||||||
|
NetNet*exp = mem_->reg_from_explode();
|
||||||
|
assert(exp);
|
||||||
|
exp->incr_lref();
|
||||||
|
mem_lref_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NetAssign_::set_part(unsigned lo, unsigned lw)
|
void NetAssign_::set_part(unsigned lo, unsigned lw)
|
||||||
{
|
{
|
||||||
|
|
@ -261,6 +285,15 @@ NetAssignNB::~NetAssignNB()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_assign.cc,v $
|
* $Log: net_assign.cc,v $
|
||||||
|
* Revision 1.18.2.3 2006/05/02 02:00:15 steve
|
||||||
|
* Fix uninitialized mem_lref_ member.
|
||||||
|
*
|
||||||
|
* Revision 1.18.2.2 2006/04/16 19:26:38 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.18.2.1 2006/03/12 07:34:17 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
* Revision 1.18 2004/08/28 15:08:31 steve
|
* Revision 1.18 2004/08/28 15:08:31 steve
|
||||||
* Do not change reg to wire in NetAssign_ unless synthesizing.
|
* Do not change reg to wire in NetAssign_ unless synthesizing.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_design.cc,v 1.45 2004/10/04 01:10:54 steve Exp $"
|
#ident "$Id: net_design.cc,v 1.45.2.1 2006/10/04 00:34:45 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
Design:: Design()
|
Design:: Design()
|
||||||
: errors(0), nodes_(0), procs_(0), lcounter_(0)
|
: errors(0), nodes_(0), procs_(0), lcounter_(0)
|
||||||
|
|
@ -279,7 +280,7 @@ void NetScope::run_defparams(Design*des)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flag = targ_scope->replace_parameter(perm_name, val);
|
bool flag = targ_scope->replace_parameter(perm_name, val->dup_expr());
|
||||||
if (! flag) {
|
if (! flag) {
|
||||||
cerr << val->get_line() << ": warning: parameter "
|
cerr << val->get_line() << ": warning: parameter "
|
||||||
<< perm_name << " not found in "
|
<< perm_name << " not found in "
|
||||||
|
|
@ -396,6 +397,7 @@ void NetScope::evaluate_parameters(Design*des)
|
||||||
<< ": internal error: "
|
<< ": internal error: "
|
||||||
"unable to evaluate real parameter values: " <<
|
"unable to evaluate real parameter values: " <<
|
||||||
*expr << endl;
|
*expr << endl;
|
||||||
|
cerr << "FYI: V0.8 cannot evaluate constant real expressions." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -422,10 +424,6 @@ void NetScope::evaluate_parameters(Design*des)
|
||||||
assert(nexpr);
|
assert(nexpr);
|
||||||
delete expr;
|
delete expr;
|
||||||
(*cur).second.expr = nexpr;
|
(*cur).second.expr = nexpr;
|
||||||
|
|
||||||
// Set the signedness flag.
|
|
||||||
(*cur).second.expr
|
|
||||||
->cast_signed( (*cur).second.signed_flag );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -438,7 +436,9 @@ void NetScope::evaluate_parameters(Design*des)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the parameter has range information, then make
|
/* If the parameter has range information, then make
|
||||||
sure the value is set right. */
|
sure the value is set right. Note that if the
|
||||||
|
parameter doesn't have an explicit range, then it
|
||||||
|
will get the signedness from the expression itself. */
|
||||||
if (range_flag) {
|
if (range_flag) {
|
||||||
unsigned long wid = (msb >= lsb)? msb - lsb : lsb - msb;
|
unsigned long wid = (msb >= lsb)? msb - lsb : lsb - msb;
|
||||||
wid += 1;
|
wid += 1;
|
||||||
|
|
@ -618,6 +618,9 @@ void Design::delete_process(NetProcTop*top)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_design.cc,v $
|
* $Log: net_design.cc,v $
|
||||||
|
* Revision 1.45.2.1 2006/10/04 00:34:45 steve
|
||||||
|
* Fix a dangling reference to NetEParam objects in defparams.
|
||||||
|
*
|
||||||
* Revision 1.45 2004/10/04 01:10:54 steve
|
* Revision 1.45 2004/10/04 01:10:54 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
192
net_link.cc
192
net_link.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_link.cc,v 1.14 2004/02/18 17:11:56 steve Exp $"
|
#ident "$Id: net_link.cc,v 1.14.2.6 2006/08/23 04:09:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
# include <string>
|
# include <string>
|
||||||
|
# include <cstring>
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
#ifdef HAVE_MALLOC_H
|
#ifdef HAVE_MALLOC_H
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
|
|
@ -40,30 +41,33 @@ void connect(Nexus*l, Link&r)
|
||||||
if (l == r.nexus_)
|
if (l == r.nexus_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
Nexus*tmp = r.nexus_;
|
Nexus*tmp = r.nexus_;
|
||||||
|
|
||||||
while (Link*cur = tmp->list_) {
|
while (Link*cur = tmp->list_) {
|
||||||
tmp->list_ = cur->next_;
|
tmp->list_ = cur->next_;
|
||||||
cur->nexus_ = 0;
|
cur->nexus_ = 0;
|
||||||
cur->next_ = 0;
|
cur->next_ = 0;
|
||||||
|
cur->prev_ = 0;
|
||||||
l->relink(cur);
|
l->relink(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
l->driven_ = Nexus::NO_GUESS;
|
|
||||||
|
|
||||||
assert(tmp->list_ == 0);
|
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(Link&l, Link&r)
|
void connect(Link&l, Link&r)
|
||||||
{
|
{
|
||||||
assert(&l != &r);
|
assert(&l != &r);
|
||||||
connect(l.nexus_, r);
|
if (r.is_linked() && !l.is_linked())
|
||||||
|
connect(r.nexus_, l);
|
||||||
|
else if (r.nexus_->list_len_ > l.nexus_->list_len_)
|
||||||
|
connect(r.nexus_, l);
|
||||||
|
else
|
||||||
|
connect(l.nexus_, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link::Link()
|
Link::Link()
|
||||||
: dir_(PASSIVE), drive0_(STRONG), drive1_(STRONG), init_(verinum::Vx),
|
: dir_(PASSIVE), drive0_(STRONG), drive1_(STRONG), init_(verinum::Vx),
|
||||||
inst_(0), next_(0), nexus_(0)
|
inst_(0), next_(0), prev_(0), nexus_(0)
|
||||||
{
|
{
|
||||||
(new Nexus()) -> relink(this);
|
(new Nexus()) -> relink(this);
|
||||||
}
|
}
|
||||||
|
|
@ -215,6 +219,7 @@ Nexus::Nexus()
|
||||||
{
|
{
|
||||||
name_ = 0;
|
name_ = 0;
|
||||||
list_ = 0;
|
list_ = 0;
|
||||||
|
list_len_ = 0;
|
||||||
driven_ = NO_GUESS;
|
driven_ = NO_GUESS;
|
||||||
t_cookie_ = 0;
|
t_cookie_ = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -241,6 +246,18 @@ verinum::V Nexus::get_init() const
|
||||||
return verinum::Vz;
|
return verinum::Vz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Nexus::is_driven() const
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (Link*cur = list_ ; cur ; cur = cur->next_) {
|
||||||
|
if (cur->get_dir() == Link::OUTPUT)
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void Nexus::unlink(Link*that)
|
void Nexus::unlink(Link*that)
|
||||||
{
|
{
|
||||||
if (name_) {
|
if (name_) {
|
||||||
|
|
@ -254,22 +271,32 @@ void Nexus::unlink(Link*that)
|
||||||
driven_ = NO_GUESS;
|
driven_ = NO_GUESS;
|
||||||
|
|
||||||
assert(that);
|
assert(that);
|
||||||
|
assert(that->nexus_ == this);
|
||||||
if (list_ == that) {
|
if (list_ == that) {
|
||||||
|
assert(that->prev_ == 0);
|
||||||
|
// Move the second item the front of the list.
|
||||||
list_ = that->next_;
|
list_ = that->next_;
|
||||||
|
if (list_)
|
||||||
|
list_->prev_ = 0;
|
||||||
|
list_len_ -= 1;
|
||||||
|
// Clear the pointers for the link.
|
||||||
that->next_ = 0;
|
that->next_ = 0;
|
||||||
|
that->prev_ = 0;
|
||||||
that->nexus_ = 0;
|
that->nexus_ = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Link*cur = list_;
|
|
||||||
while (cur->next_ != that) {
|
Link*cur = that->prev_;
|
||||||
assert(cur->next_);
|
assert(cur->nexus_ == this);
|
||||||
cur = cur->next_;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur->next_ = that->next_;
|
cur->next_ = that->next_;
|
||||||
|
if (cur->next_)
|
||||||
|
cur->next_->prev_ = cur;
|
||||||
that->nexus_ = 0;
|
that->nexus_ = 0;
|
||||||
that->next_ = 0;
|
that->next_ = 0;
|
||||||
|
that->prev_ = 0;
|
||||||
|
list_len_ -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nexus::relink(Link*that)
|
void Nexus::relink(Link*that)
|
||||||
|
|
@ -287,8 +314,13 @@ void Nexus::relink(Link*that)
|
||||||
assert(that->nexus_ == 0);
|
assert(that->nexus_ == 0);
|
||||||
assert(that->next_ == 0);
|
assert(that->next_ == 0);
|
||||||
that->next_ = list_;
|
that->next_ = list_;
|
||||||
|
that->prev_ = 0;
|
||||||
|
if (that->next_)
|
||||||
|
that->next_->prev_ = that;
|
||||||
|
|
||||||
that->nexus_ = this;
|
that->nexus_ = this;
|
||||||
list_ = that;
|
list_ = that;
|
||||||
|
list_len_ += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Link* Nexus::first_nlink()
|
Link* Nexus::first_nlink()
|
||||||
|
|
@ -360,8 +392,9 @@ const char* Nexus::name() const
|
||||||
obj->name() << " pin " << pin << "(" <<
|
obj->name() << " pin " << pin << "(" <<
|
||||||
lnk->get_name() << "<" << lnk->get_inst() << ">)"
|
lnk->get_name() << "<" << lnk->get_inst() << ">)"
|
||||||
" type=" << typeid(*obj).name() << "?" << endl;
|
" type=" << typeid(*obj).name() << "?" << endl;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sig);
|
assert(sig);
|
||||||
ostringstream tmp;
|
ostringstream tmp;
|
||||||
tmp << sig->name();
|
tmp << sig->name();
|
||||||
|
|
@ -378,6 +411,7 @@ const char* Nexus::name() const
|
||||||
NexusSet::NexusSet()
|
NexusSet::NexusSet()
|
||||||
{
|
{
|
||||||
items_ = 0;
|
items_ = 0;
|
||||||
|
index_ = 0;
|
||||||
nitems_ = 0;
|
nitems_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,8 +420,11 @@ NexusSet::~NexusSet()
|
||||||
if (nitems_ > 0) {
|
if (nitems_ > 0) {
|
||||||
assert(items_ != 0);
|
assert(items_ != 0);
|
||||||
delete[] items_;
|
delete[] items_;
|
||||||
|
assert(index_ != 0);
|
||||||
|
delete[] index_;
|
||||||
} else {
|
} else {
|
||||||
assert(items_ == 0);
|
assert(items_ == 0);
|
||||||
|
assert(index_ == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,25 +433,44 @@ unsigned NexusSet::count() const
|
||||||
return nitems_;
|
return nitems_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the Nexus to the nexus set at the *end* of the array. This
|
||||||
|
* preserves order, which is used in a few cases by the
|
||||||
|
* synthesizer. But for efficiency, also create a sorted index.
|
||||||
|
*/
|
||||||
void NexusSet::add(Nexus*that)
|
void NexusSet::add(Nexus*that)
|
||||||
{
|
{
|
||||||
|
/* Handle the special case that the set is empty. */
|
||||||
if (nitems_ == 0) {
|
if (nitems_ == 0) {
|
||||||
assert(items_ == 0);
|
assert(items_ == 0);
|
||||||
|
assert(index_ == 0);
|
||||||
items_ = (Nexus**)malloc(sizeof(Nexus*));
|
items_ = (Nexus**)malloc(sizeof(Nexus*));
|
||||||
items_[0] = that;
|
items_[0] = that;
|
||||||
|
index_ = (unsigned*)malloc(sizeof(unsigned));
|
||||||
|
index_[0] = 0;
|
||||||
nitems_ = 1;
|
nitems_ = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ptr = bsearch_(that);
|
unsigned ptr = bsearch_(that);
|
||||||
if ((ptr < nitems_) && (items_[ptr] == that))
|
if (ptr < nitems_ && items_[index_[ptr]] == that) {
|
||||||
|
assert(items_[index_[ptr]] == that);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
items_ = (Nexus**)realloc(items_, (nitems_+1) * sizeof(Nexus*));
|
items_ = (Nexus**) realloc(items_, (nitems_+1) * sizeof(Nexus*));
|
||||||
for (unsigned idx = nitems_ ; idx > ptr ; idx -= 1)
|
index_ = (unsigned*)realloc(index_, (nitems_+1) * sizeof(unsigned));
|
||||||
items_[idx] = items_[idx-1];
|
|
||||||
|
items_[nitems_] = that;
|
||||||
|
|
||||||
|
unsigned dest = nitems_;
|
||||||
|
for (unsigned idx = ptr ; idx < nitems_ ; idx += 1) {
|
||||||
|
unsigned tmp = index_[idx];
|
||||||
|
index_[idx] = dest;
|
||||||
|
dest = tmp;
|
||||||
|
}
|
||||||
|
index_[nitems_] = dest;
|
||||||
|
|
||||||
items_[ptr] = that;
|
|
||||||
nitems_ += 1;
|
nitems_ += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -430,20 +486,31 @@ void NexusSet::rem(Nexus*that)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned ptr = bsearch_(that);
|
unsigned ptr = bsearch_(that);
|
||||||
if ((ptr >= nitems_) || (items_[ptr] != that))
|
if (ptr >= nitems_ || items_[index_[ptr]] != that)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (nitems_ == 1) {
|
if (nitems_ == 1) {
|
||||||
free(items_);
|
free(items_);
|
||||||
|
free(index_);
|
||||||
items_ = 0;
|
items_ = 0;
|
||||||
|
index_ = 0;
|
||||||
nitems_ = 0;
|
nitems_ = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned idx = ptr ; idx < (nitems_-1) ; idx += 1)
|
unsigned index_ptr = index_[ptr];
|
||||||
|
for (unsigned idx = index_ptr ; idx < (nitems_-1) ; idx += 1)
|
||||||
items_[idx] = items_[idx+1];
|
items_[idx] = items_[idx+1];
|
||||||
|
|
||||||
items_ = (Nexus**)realloc(items_, (nitems_-1) * sizeof(Nexus*));
|
for (unsigned idx = ptr ; idx < (nitems_-1) ; idx += 1)
|
||||||
|
index_[idx] = index_[idx+1];
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < (nitems_-1) ; idx += 1)
|
||||||
|
if (index_[idx] > index_ptr)
|
||||||
|
index_[idx] -= 1;
|
||||||
|
|
||||||
|
items_ = (Nexus**) realloc(items_, (nitems_-1) * sizeof(Nexus*));
|
||||||
|
index_ = (unsigned*)realloc(index_, (nitems_-1) * sizeof(unsigned));
|
||||||
nitems_ -= 1;
|
nitems_ -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -459,16 +526,37 @@ Nexus* NexusSet::operator[] (unsigned idx) const
|
||||||
return items_[idx];
|
return items_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method uses binary search to locate the item in the list of
|
||||||
|
* nexus pointers. If the item is in the set, then this method returns
|
||||||
|
* the index where it exists in the *index* array. If the item is not
|
||||||
|
* in the set, the index points to where in the array the item should go.
|
||||||
|
*/
|
||||||
unsigned NexusSet::bsearch_(Nexus*that) const
|
unsigned NexusSet::bsearch_(Nexus*that) const
|
||||||
{
|
{
|
||||||
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
|
|
||||||
if (items_[idx] < that)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return idx;
|
unsigned low = 0, hig = nitems_;
|
||||||
|
|
||||||
|
while (low < hig) {
|
||||||
|
unsigned mid = (low + hig) / 2;
|
||||||
|
if (mid == hig) mid -= 1;
|
||||||
|
assert(mid >= low);
|
||||||
|
assert(mid < hig);
|
||||||
|
|
||||||
|
if (items_[index_[mid]] == that) {
|
||||||
|
return mid;
|
||||||
|
|
||||||
|
} else if (items_[index_[mid]] > that) {
|
||||||
|
hig = mid;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
low = mid+1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nitems_;
|
assert(low == hig);
|
||||||
|
assert(low == nitems_ || items_[index_[low]] >= that);
|
||||||
|
return low;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NexusSet::contains(const NexusSet&that) const
|
bool NexusSet::contains(const NexusSet&that) const
|
||||||
|
|
@ -477,7 +565,7 @@ bool NexusSet::contains(const NexusSet&that) const
|
||||||
unsigned where = bsearch_(that[idx]);
|
unsigned where = bsearch_(that[idx]);
|
||||||
if (where == nitems_)
|
if (where == nitems_)
|
||||||
return false;
|
return false;
|
||||||
if (items_[where] != that[idx])
|
if (items_[index_[where]] != that[idx])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -490,7 +578,7 @@ bool NexusSet::intersect(const NexusSet&that) const
|
||||||
unsigned where = bsearch_(that[idx]);
|
unsigned where = bsearch_(that[idx]);
|
||||||
if (where == nitems_)
|
if (where == nitems_)
|
||||||
continue;
|
continue;
|
||||||
if (items_[where] == that[idx])
|
if (items_[index_[where]] == that[idx])
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,6 +587,24 @@ bool NexusSet::intersect(const NexusSet&that) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_link.cc,v $
|
* $Log: net_link.cc,v $
|
||||||
|
* Revision 1.14.2.6 2006/08/23 04:09:14 steve
|
||||||
|
* missing sig diagnostics.
|
||||||
|
*
|
||||||
|
* Revision 1.14.2.5 2006/08/15 03:41:24 steve
|
||||||
|
* Improve performance of unlink of heavily connected nexa.
|
||||||
|
*
|
||||||
|
* Revision 1.14.2.4 2006/08/08 02:17:48 steve
|
||||||
|
* Improved nexus management performance.
|
||||||
|
*
|
||||||
|
* Revision 1.14.2.3 2006/07/23 19:42:33 steve
|
||||||
|
* Handle statement output override better in blocks.
|
||||||
|
*
|
||||||
|
* Revision 1.14.2.2 2006/01/27 02:05:46 steve
|
||||||
|
* Speed up processing of connect when one side is empty.
|
||||||
|
*
|
||||||
|
* Revision 1.14.2.1 2005/09/25 23:30:31 steve
|
||||||
|
* More predictable ordering of items in NexusSet.
|
||||||
|
*
|
||||||
* Revision 1.14 2004/02/18 17:11:56 steve
|
* Revision 1.14 2004/02/18 17:11:56 steve
|
||||||
* Use perm_strings for named langiage items.
|
* Use perm_strings for named langiage items.
|
||||||
*
|
*
|
||||||
|
|
@ -523,35 +629,5 @@ bool NexusSet::intersect(const NexusSet&that) const
|
||||||
* Revision 1.7 2002/06/24 01:49:39 steve
|
* Revision 1.7 2002/06/24 01:49:39 steve
|
||||||
* Make link_drive_constant cache its results in
|
* Make link_drive_constant cache its results in
|
||||||
* the Nexus, to improve cprop performance.
|
* the Nexus, to improve cprop performance.
|
||||||
*
|
|
||||||
* Revision 1.6 2002/04/21 04:59:08 steve
|
|
||||||
* Add support for conbinational events by finding
|
|
||||||
* the inputs to expressions and some statements.
|
|
||||||
* Get case and assignment statements working.
|
|
||||||
*
|
|
||||||
* Revision 1.5 2001/07/25 03:10:49 steve
|
|
||||||
* Create a config.h.in file to hold all the config
|
|
||||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
|
||||||
*
|
|
||||||
* Revision 1.4 2000/10/06 23:46:50 steve
|
|
||||||
* ivl_target updates, including more complete
|
|
||||||
* handling of ivl_nexus_t objects. Much reduced
|
|
||||||
* dependencies on pointers to netlist objects.
|
|
||||||
*
|
|
||||||
* Revision 1.3 2000/08/26 00:54:03 steve
|
|
||||||
* Get at gate information for ivl_target interface.
|
|
||||||
*
|
|
||||||
* Revision 1.2 2000/07/14 06:12:57 steve
|
|
||||||
* Move inital value handling from NetNet to Nexus
|
|
||||||
* objects. This allows better propogation of inital
|
|
||||||
* values.
|
|
||||||
*
|
|
||||||
* Clean up constant propagation a bit to account
|
|
||||||
* for regs that are not really values.
|
|
||||||
*
|
|
||||||
* Revision 1.1 2000/06/25 19:59:42 steve
|
|
||||||
* Redesign Links to include the Nexus class that
|
|
||||||
* carries properties of the connected set of links.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
163
net_nex_input.cc
163
net_nex_input.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_nex_input.cc,v 1.12 2004/09/04 04:24:15 steve Exp $"
|
#ident "$Id: net_nex_input.cc,v 1.12.2.1 2006/05/21 21:58:47 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
|
||||||
NexusSet* NetExpr::nex_input()
|
NexusSet* NetExpr::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
cerr << get_line()
|
cerr << get_line()
|
||||||
<< ": internal error: nex_input not implemented: "
|
<< ": internal error: nex_input not implemented: "
|
||||||
|
|
@ -37,7 +37,7 @@ NexusSet* NetExpr::nex_input()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetProc::nex_input()
|
NexusSet* NetProc::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
cerr << get_line()
|
cerr << get_line()
|
||||||
<< ": internal error: NetProc::nex_input not implemented"
|
<< ": internal error: NetProc::nex_input not implemented"
|
||||||
|
|
@ -45,29 +45,34 @@ NexusSet* NetProc::nex_input()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEBinary::nex_input()
|
NexusSet* NetEBinary::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = left_->nex_input();
|
NexusSet*result = left_->nex_input(rem_out);
|
||||||
NexusSet*tmp = right_->nex_input();
|
NexusSet*tmp = right_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEBitSel::nex_input()
|
NexusSet* NetEBitSel::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = sig_->nex_input();
|
NexusSet*result = sig_->nex_input(rem_out);
|
||||||
NexusSet*tmp = idx_->nex_input();
|
NexusSet*tmp = idx_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEConcat::nex_input()
|
NexusSet* NetEConcat::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = parms_[0]->nex_input();
|
if (parms_[0] == NULL) return NULL;
|
||||||
|
NexusSet*result = parms_[0]->nex_input(rem_out);
|
||||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||||
NexusSet*tmp = parms_[idx]->nex_input();
|
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
delete result;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -77,19 +82,19 @@ NexusSet* NetEConcat::nex_input()
|
||||||
/*
|
/*
|
||||||
* A constant has not inputs, so always return an empty set.
|
* A constant has not inputs, so always return an empty set.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetEConst::nex_input()
|
NexusSet* NetEConst::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetECReal::nex_input()
|
NexusSet* NetECReal::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEMemory::nex_input()
|
NexusSet* NetEMemory::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = idx_->nex_input();
|
NexusSet*result = idx_->nex_input(rem_out);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,74 +102,79 @@ NexusSet* NetEMemory::nex_input()
|
||||||
* A parameter by definition has no inputs. It represents a constant
|
* A parameter by definition has no inputs. It represents a constant
|
||||||
* value, even if that value is a constant expression.
|
* value, even if that value is a constant expression.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetEParam::nex_input()
|
NexusSet* NetEParam::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEEvent::nex_input()
|
NexusSet* NetEEvent::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEScope::nex_input()
|
NexusSet* NetEScope::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetESelect::nex_input()
|
NexusSet* NetESelect::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = base_? base_->nex_input() : new NexusSet();
|
NexusSet*result = base_? base_->nex_input(rem_out) : new NexusSet();
|
||||||
NexusSet*tmp = expr_->nex_input();
|
NexusSet*tmp = expr_->nex_input(rem_out);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
delete result;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetESFunc::nex_input()
|
NexusSet* NetESFunc::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
if (nparms_ == 0)
|
if (nparms_ == 0)
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
|
|
||||||
NexusSet*result = parms_[0]->nex_input();
|
NexusSet*result = parms_[0]->nex_input(rem_out);
|
||||||
for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) {
|
for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) {
|
||||||
NexusSet*tmp = parms_[idx]->nex_input();
|
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetESignal::nex_input()
|
NexusSet* NetESignal::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = new NexusSet;
|
NexusSet*result = new NexusSet;
|
||||||
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
assert(msi_ <= net_->pin_count());
|
||||||
|
for (unsigned idx = lsi_ ; idx <= msi_ ; idx += 1)
|
||||||
result->add(net_->pin(idx).nexus());
|
result->add(net_->pin(idx).nexus());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetETernary::nex_input()
|
NexusSet* NetETernary::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*tmp;
|
NexusSet*tmp;
|
||||||
NexusSet*result = cond_->nex_input();
|
NexusSet*result = cond_->nex_input(rem_out);
|
||||||
|
|
||||||
tmp = true_val_->nex_input();
|
tmp = true_val_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
tmp = false_val_->nex_input();
|
tmp = false_val_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEUFunc::nex_input()
|
NexusSet* NetEUFunc::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = new NexusSet;
|
NexusSet*result = new NexusSet;
|
||||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||||
NexusSet*tmp = parms_[idx]->nex_input();
|
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -172,33 +182,33 @@ NexusSet* NetEUFunc::nex_input()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEUnary::nex_input()
|
NexusSet* NetEUnary::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return expr_->nex_input();
|
return expr_->nex_input(rem_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetEVariable::nex_input()
|
NexusSet* NetEVariable::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetAssign_::nex_input()
|
NexusSet* NetAssign_::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
if (bmux_ == 0)
|
if (bmux_ == 0)
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
else
|
else
|
||||||
return bmux_->nex_input();
|
return bmux_->nex_input(rem_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetAssignBase::nex_input()
|
NexusSet* NetAssignBase::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = rval_->nex_input();
|
NexusSet*result = rval_->nex_input(rem_out);
|
||||||
|
|
||||||
/* It is possible that the lval_ can hav nex_input values. In
|
/* It is possible that the lval_ can hav nex_input values. In
|
||||||
particular, index expressions are statement inputs as well,
|
particular, index expressions are statement inputs as well,
|
||||||
so should be addressed here. */
|
so should be addressed here. */
|
||||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||||
NexusSet*tmp = cur->nex_input();
|
NexusSet*tmp = cur->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +233,7 @@ NexusSet* NetAssignBase::nex_input()
|
||||||
* In this example, "t" should not be in the input set because it is
|
* In this example, "t" should not be in the input set because it is
|
||||||
* used by the sequence as a temporary value.
|
* used by the sequence as a temporary value.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetBlock::nex_input()
|
NexusSet* NetBlock::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
if (last_ == 0)
|
if (last_ == 0)
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
|
|
@ -243,24 +253,24 @@ NexusSet* NetBlock::nex_input()
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* Get the inputs for the current statement. */
|
/* Get the inputs for the current statement. */
|
||||||
NexusSet*tmp = cur->nex_input();
|
NexusSet*tmp = cur->nex_input(rem_out);
|
||||||
|
|
||||||
/* Remove from the input set those bits that are outputs
|
/* Add the current input set to the accumulated input set. */
|
||||||
from previous statements. They aren't really inputs
|
|
||||||
to the block, just internal intermediate values. */
|
|
||||||
tmp->rem(*prev);
|
|
||||||
|
|
||||||
/* Add the corrected set to the accumulated input set. */
|
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
||||||
/* Add the current outputs to the accumulated output
|
/* Add the current outputs to the accumulated output set,
|
||||||
set, for processing of later statements. */
|
so they can be removed from the input set below. */
|
||||||
cur->nex_output(*prev);
|
cur->nex_output(*prev);
|
||||||
|
|
||||||
cur = cur->next_;
|
cur = cur->next_;
|
||||||
} while (cur != last_->next_);
|
} while (cur != last_->next_);
|
||||||
|
|
||||||
|
/* Remove from the input set those bits that are outputs
|
||||||
|
from other statements. They aren't really inputs
|
||||||
|
to the block, just internal intermediate values. */
|
||||||
|
if (rem_out) result->rem(*prev);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,9 +279,9 @@ NexusSet* NetBlock::nex_input()
|
||||||
* the inputs to all the guards, and the inputs to all the guarded
|
* the inputs to all the guards, and the inputs to all the guarded
|
||||||
* statements.
|
* statements.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetCase::nex_input()
|
NexusSet* NetCase::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = expr_->nex_input();
|
NexusSet*result = expr_->nex_input(rem_out);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -281,7 +291,7 @@ NexusSet* NetCase::nex_input()
|
||||||
if (items_[idx].statement == 0)
|
if (items_[idx].statement == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
NexusSet*tmp = items_[idx].statement->nex_input();
|
NexusSet*tmp = items_[idx].statement->nex_input(rem_out);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
@ -290,7 +300,7 @@ NexusSet* NetCase::nex_input()
|
||||||
case is special and is identified by a null
|
case is special and is identified by a null
|
||||||
guard. The default guard obviously has no input. */
|
guard. The default guard obviously has no input. */
|
||||||
if (items_[idx].guard) {
|
if (items_[idx].guard) {
|
||||||
tmp = items_[idx].guard->nex_input();
|
tmp = items_[idx].guard->nex_input(rem_out);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
@ -300,24 +310,24 @@ NexusSet* NetCase::nex_input()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetCAssign::nex_input()
|
NexusSet* NetCAssign::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
cerr << get_line() << ": internal warning: NetCAssign::nex_input()"
|
cerr << get_line() << ": internal warning: NetCAssign::nex_input()"
|
||||||
<< " not implemented." << endl;
|
<< " not implemented." << endl;
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetCondit::nex_input()
|
NexusSet* NetCondit::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = expr_->nex_input();
|
NexusSet*result = expr_->nex_input(rem_out);
|
||||||
if (if_ != 0) {
|
if (if_ != 0) {
|
||||||
NexusSet*tmp = if_->nex_input();
|
NexusSet*tmp = if_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (else_ != 0) {
|
if (else_ != 0) {
|
||||||
NexusSet*tmp = else_->nex_input();
|
NexusSet*tmp = else_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -325,16 +335,16 @@ NexusSet* NetCondit::nex_input()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetForce::nex_input()
|
NexusSet* NetForce::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
cerr << get_line() << ": internal warning: NetForce::nex_input()"
|
cerr << get_line() << ": internal warning: NetForce::nex_input()"
|
||||||
<< " not implemented." << endl;
|
<< " not implemented." << endl;
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetForever::nex_input()
|
NexusSet* NetForever::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = statement_->nex_input();
|
NexusSet*result = statement_->nex_input(rem_out);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,29 +357,29 @@ NexusSet* NetForever::nex_input()
|
||||||
* include the input set of the <expr> because it does not affect the
|
* include the input set of the <expr> because it does not affect the
|
||||||
* result.
|
* result.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetPDelay::nex_input()
|
NexusSet* NetPDelay::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = statement_->nex_input();
|
NexusSet*result = statement_->nex_input(rem_out);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetRepeat::nex_input()
|
NexusSet* NetRepeat::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = statement_->nex_input();
|
NexusSet*result = statement_->nex_input(rem_out);
|
||||||
NexusSet*tmp = expr_->nex_input();
|
NexusSet*tmp = expr_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetSTask::nex_input()
|
NexusSet* NetSTask::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
if (parms_.count() == 0)
|
if (parms_.count() == 0)
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
|
|
||||||
NexusSet*result = parms_[0]->nex_input();
|
NexusSet*result = parms_[0]->nex_input(rem_out);
|
||||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||||
NexusSet*tmp = parms_[idx]->nex_input();
|
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -382,15 +392,15 @@ NexusSet* NetSTask::nex_input()
|
||||||
* parameters to consider, because the compiler already removed them
|
* parameters to consider, because the compiler already removed them
|
||||||
* and converted them to blocking assignments.
|
* and converted them to blocking assignments.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetUTask::nex_input()
|
NexusSet* NetUTask::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
return new NexusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetWhile::nex_input()
|
NexusSet* NetWhile::nex_input(bool rem_out)
|
||||||
{
|
{
|
||||||
NexusSet*result = proc_->nex_input();
|
NexusSet*result = proc_->nex_input(rem_out);
|
||||||
NexusSet*tmp = cond_->nex_input();
|
NexusSet*tmp = cond_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -398,6 +408,9 @@ NexusSet* NetWhile::nex_input()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_nex_input.cc,v $
|
* $Log: net_nex_input.cc,v $
|
||||||
|
* Revision 1.12.2.1 2006/05/21 21:58:47 steve
|
||||||
|
* NetESignal input is only selected bits.
|
||||||
|
*
|
||||||
* Revision 1.12 2004/09/04 04:24:15 steve
|
* Revision 1.12 2004/09/04 04:24:15 steve
|
||||||
* PR1026: assignment statements can have sensitivities in the l-values.
|
* PR1026: assignment statements can have sensitivities in the l-values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_nex_output.cc,v 1.11 2004/09/16 03:17:33 steve Exp $"
|
#ident "$Id: net_nex_output.cc,v 1.11.2.8 2006/08/08 02:17:48 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -47,10 +47,55 @@ void NetAssignBase::nex_output(NexusSet&out)
|
||||||
{
|
{
|
||||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||||
if (NetNet*lsig = cur->sig()) {
|
if (NetNet*lsig = cur->sig()) {
|
||||||
|
|
||||||
|
if (cur->bmux()) {
|
||||||
|
for (unsigned idx = 0; idx < lsig->pin_count(); idx += 1) {
|
||||||
|
out.add(lsig->pin(idx).nexus());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle l-value signals. We don't need to worry
|
||||||
|
here about whether there is a bmux, because the
|
||||||
|
synthesizer will detect that mux and create a
|
||||||
|
decoder between the expression and the signal. */
|
||||||
for (unsigned idx = 0 ; idx < cur->lwidth() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < cur->lwidth() ; idx += 1) {
|
||||||
unsigned off = cur->get_loff() + idx;
|
unsigned off = cur->get_loff() + idx;
|
||||||
out.add(lsig->pin(off).nexus());
|
out.add(lsig->pin(off).nexus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (NetMemory*lmem = cur->mem()) {
|
||||||
|
|
||||||
|
/* Memories here are treated as a bunch of reg
|
||||||
|
devices. Use the explode_to_reg method to get
|
||||||
|
access to the FF version of the memory and use
|
||||||
|
that in our l-value management. */
|
||||||
|
NetNet*tmp = lmem->explode_to_reg();
|
||||||
|
|
||||||
|
if (NetEConst*ae = dynamic_cast<NetEConst*>(cur->bmux())) {
|
||||||
|
/* The address is constant, so simply
|
||||||
|
connect to the right pins and we are
|
||||||
|
done. */
|
||||||
|
long adr_s = ae->value().as_long();
|
||||||
|
unsigned adr = lmem->index_to_address(adr_s) * lmem->width();
|
||||||
|
|
||||||
|
if (adr >= lmem->count()*lmem->width()) {
|
||||||
|
/* Skip assignments with constant
|
||||||
|
addresses that are outside the
|
||||||
|
range of memories. */
|
||||||
|
} else {
|
||||||
|
for (unsigned idx=0; idx<cur->lwidth(); idx += 1)
|
||||||
|
out.add(tmp->pin(adr+idx).nexus());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Put all the bits of the memory into the
|
||||||
|
set. The synthesis will generate a
|
||||||
|
decoder to handle this. */
|
||||||
|
for (unsigned idx = 0; idx < tmp->pin_count(); idx+=1)
|
||||||
|
out.add(tmp->pin(idx).nexus());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Quoting from netlist.h comments for class NetMemory:
|
/* Quoting from netlist.h comments for class NetMemory:
|
||||||
* "This is not a node because memory objects can only be
|
* "This is not a node because memory objects can only be
|
||||||
|
|
@ -69,11 +114,11 @@ void NetBlock::nex_output(NexusSet&out)
|
||||||
if (last_ == 0)
|
if (last_ == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NetProc*cur = last_;
|
NetProc*cur = last_->next_;
|
||||||
do {
|
do {
|
||||||
cur = cur->next_;
|
|
||||||
cur->nex_output(out);
|
cur->nex_output(out);
|
||||||
} while (cur != last_);
|
cur = cur->next_;
|
||||||
|
} while (cur != last_->next_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetCase::nex_output(NexusSet&out)
|
void NetCase::nex_output(NexusSet&out)
|
||||||
|
|
@ -114,6 +159,15 @@ void NetSTask::nex_output(NexusSet&out)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Consider a task call to not have any outputs. This is not quite
|
||||||
|
* right, we should be listing as outputs all the output ports, but for
|
||||||
|
* the purposes that this method is used, this will do for now.
|
||||||
|
*/
|
||||||
|
void NetUTask::nex_output(NexusSet&out)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void NetWhile::nex_output(NexusSet&out)
|
void NetWhile::nex_output(NexusSet&out)
|
||||||
{
|
{
|
||||||
if (proc_ != 0)
|
if (proc_ != 0)
|
||||||
|
|
@ -122,6 +176,30 @@ void NetWhile::nex_output(NexusSet&out)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_nex_output.cc,v $
|
* $Log: net_nex_output.cc,v $
|
||||||
|
* Revision 1.11.2.8 2006/08/08 02:17:48 steve
|
||||||
|
* Improved nexus management performance.
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.7 2006/06/02 23:42:48 steve
|
||||||
|
* Compilation warnings.
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.6 2006/06/01 03:01:48 steve
|
||||||
|
* Handle condit clauses with unassigned outputs.
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.5 2006/05/18 01:47:12 steve
|
||||||
|
* Fix synthesis of l-value bit select in block.
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.4 2006/05/05 01:56:36 steve
|
||||||
|
* Handle memory assignments out of range during synthesis
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.3 2006/04/16 19:26:38 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.2 2006/03/12 07:34:17 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.11.2.1 2006/01/18 01:23:23 steve
|
||||||
|
* Rework l-value handling to allow for more l-value type flexibility.
|
||||||
|
*
|
||||||
* Revision 1.11 2004/09/16 03:17:33 steve
|
* Revision 1.11 2004/09/16 03:17:33 steve
|
||||||
* net_output handles l-value concatenations.
|
* net_output handles l-value concatenations.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: net_scope.cc,v 1.33 2004/10/04 01:10:54 steve Exp $"
|
#ident "$Id: net_scope.cc,v 1.33.2.1 2005/02/19 16:39:31 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The NetScope class keeps a scope tree organized. Each node of the
|
* The NetScope class keeps a scope tree organized. Each node of the
|
||||||
|
|
@ -194,7 +195,7 @@ const NetFuncDef* NetScope::func_def() const
|
||||||
void NetScope::set_module_name(perm_string n)
|
void NetScope::set_module_name(perm_string n)
|
||||||
{
|
{
|
||||||
assert(type_ == MODULE);
|
assert(type_ == MODULE);
|
||||||
module_name_ = n; /* NOTE: n mus have been permallocated. */
|
module_name_ = n; /* NOTE: n must have been permallocated. */
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string NetScope::module_name() const
|
perm_string NetScope::module_name() const
|
||||||
|
|
@ -467,6 +468,9 @@ string NetScope::local_hsymbol()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_scope.cc,v $
|
* $Log: net_scope.cc,v $
|
||||||
|
* Revision 1.33.2.1 2005/02/19 16:39:31 steve
|
||||||
|
* Spellig fixes.
|
||||||
|
*
|
||||||
* Revision 1.33 2004/10/04 01:10:54 steve
|
* Revision 1.33 2004/10/04 01:10:54 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
271
netlist.cc
271
netlist.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netlist.cc,v 1.226 2004/10/04 01:10:54 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.226.2.7 2006/04/23 04:26:14 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -229,7 +229,7 @@ NetNode::~NetNode()
|
||||||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||||
: NetObj(s, n, npins), sig_next_(0), sig_prev_(0),
|
: NetObj(s, n, npins), sig_next_(0), sig_prev_(0),
|
||||||
type_(t), port_type_(NOT_A_PORT), signed_(false), msb_(npins-1), lsb_(0),
|
type_(t), port_type_(NOT_A_PORT), signed_(false), msb_(npins-1), lsb_(0),
|
||||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
local_flag_(false), eref_count_(0), lref_count_(0), mref_(0)
|
||||||
{
|
{
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
|
@ -270,7 +270,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, long ms, long ls)
|
||||||
: NetObj(s, n, ((ms>ls)?ms-ls:ls-ms) + 1),
|
: NetObj(s, n, ((ms>ls)?ms-ls:ls-ms) + 1),
|
||||||
sig_next_(0), sig_prev_(0), type_(t),
|
sig_next_(0), sig_prev_(0), type_(t),
|
||||||
port_type_(NOT_A_PORT), signed_(false), msb_(ms), lsb_(ls),
|
port_type_(NOT_A_PORT), signed_(false), msb_(ms), lsb_(ls),
|
||||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
local_flag_(false), eref_count_(0), lref_count_(0), mref_(0)
|
||||||
{
|
{
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
|
@ -322,6 +322,14 @@ NetNet::~NetNet()
|
||||||
dump_net(cerr, 4);
|
dump_net(cerr, 4);
|
||||||
}
|
}
|
||||||
assert(lref_count_ == 0);
|
assert(lref_count_ == 0);
|
||||||
|
if (mref_ != 0) {
|
||||||
|
cerr << get_line() << ": internal error: attempt to delete "
|
||||||
|
<< "signal ``" << name() << "'' which has "
|
||||||
|
<< "memory explode references." << endl;
|
||||||
|
dump_net(cerr, 4);
|
||||||
|
}
|
||||||
|
assert(mref_ == 0);
|
||||||
|
|
||||||
if (scope())
|
if (scope())
|
||||||
scope()->rem_signal(this);
|
scope()->rem_signal(this);
|
||||||
|
|
||||||
|
|
@ -462,6 +470,23 @@ unsigned NetNet::get_refs() const
|
||||||
return lref_count_ + eref_count_;
|
return lref_count_ + eref_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetNet::mref(NetMemory*mem)
|
||||||
|
{
|
||||||
|
assert(mref_ == 0);
|
||||||
|
assert(mem != 0);
|
||||||
|
mref_ = mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetMemory*NetNet::mref()
|
||||||
|
{
|
||||||
|
return mref_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetMemory* NetNet::mref() const
|
||||||
|
{
|
||||||
|
return mref_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NetSubnet::NetSubnet(NetNet*sig, unsigned off, unsigned wid)
|
NetSubnet::NetSubnet(NetNet*sig, unsigned off, unsigned wid)
|
||||||
: NetNet(sig->scope(), sig->scope()->local_symbol(), sig->type(), wid)
|
: NetNet(sig->scope(), sig->scope()->local_symbol(), sig->type(), wid)
|
||||||
|
|
@ -533,6 +558,8 @@ const NetScope* NetProcTop::scope() const
|
||||||
NetFF::NetFF(NetScope*s, perm_string n, unsigned wid)
|
NetFF::NetFF(NetScope*s, perm_string n, unsigned wid)
|
||||||
: NetNode(s, n, 8 + 2*wid)
|
: NetNode(s, n, 8 + 2*wid)
|
||||||
{
|
{
|
||||||
|
demux_ = 0;
|
||||||
|
|
||||||
pin_Clock().set_dir(Link::INPUT);
|
pin_Clock().set_dir(Link::INPUT);
|
||||||
pin_Clock().set_name(perm_string::literal("Clock"), 0);
|
pin_Clock().set_name(perm_string::literal("Clock"), 0);
|
||||||
pin_Enable().set_dir(Link::INPUT);
|
pin_Enable().set_dir(Link::INPUT);
|
||||||
|
|
@ -684,6 +711,118 @@ const verinum& NetFF::sset_value() const
|
||||||
return sset_value_;
|
return sset_value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned NetDecode::width() const
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned NetDecode::awidth() const
|
||||||
|
{
|
||||||
|
return pin_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
NetDemux::NetDemux(NetScope*s, perm_string name,
|
||||||
|
unsigned bus_width, unsigned address_width, unsigned size)
|
||||||
|
: NetNode(s, name, bus_width*2+address_width+bus_width/size)
|
||||||
|
{
|
||||||
|
width_ = bus_width;
|
||||||
|
awidth_ = address_width;
|
||||||
|
size_ = size;
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
|
||||||
|
pin_Q(idx).set_dir(Link::OUTPUT);
|
||||||
|
pin_Q(idx).set_name(perm_string::literal("Q"), idx);
|
||||||
|
}
|
||||||
|
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
|
||||||
|
pin_Data(idx).set_dir(Link::INPUT);
|
||||||
|
pin_Data(idx).set_name(perm_string::literal("Data"), idx);
|
||||||
|
}
|
||||||
|
for (unsigned idx = 0 ; idx < awidth_ ; idx += 1) {
|
||||||
|
pin_Address(idx).set_dir(Link::INPUT);
|
||||||
|
pin_Address(idx).set_name(perm_string::literal("Address"), idx);
|
||||||
|
}
|
||||||
|
for (unsigned idx = 0 ; idx < width_/size_ ; idx += 1) {
|
||||||
|
pin_WriteData(idx).set_dir(Link::INPUT);
|
||||||
|
pin_WriteData(idx).set_name(perm_string::literal("Writedata"), idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetDemux::~NetDemux()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned NetDemux::width() const
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned NetDemux::awidth() const
|
||||||
|
{
|
||||||
|
return awidth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned NetDemux::size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetDemux::pin_Q(unsigned idx)
|
||||||
|
{
|
||||||
|
assert(idx < width_);
|
||||||
|
return pin(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link& NetDemux::pin_Q(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < width_);
|
||||||
|
return pin(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetDemux::pin_Data(unsigned idx)
|
||||||
|
{
|
||||||
|
assert(idx < width_);
|
||||||
|
return pin(width_+idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link& NetDemux::pin_Data(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < width_);
|
||||||
|
return pin(width_+idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetDemux::pin_Address(unsigned idx)
|
||||||
|
{
|
||||||
|
assert(idx < awidth_);
|
||||||
|
return pin(width_+width_+idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link& NetDemux::pin_Address(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < awidth_);
|
||||||
|
return pin(width_+width_+idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetDemux::pin_WriteData(unsigned idx)
|
||||||
|
{
|
||||||
|
assert(idx < width_/size_);
|
||||||
|
return pin(width_+width_+awidth_+idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link& NetDemux::pin_WriteData(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < width_/size_);
|
||||||
|
return pin(width_+width_+awidth_+idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetDecode* NetFF::get_demux()
|
||||||
|
{
|
||||||
|
return demux_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetDecode* NetFF::get_demux() const
|
||||||
|
{
|
||||||
|
return demux_;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The NetAddSub class represents an LPM_ADD_SUB device. The pinout is
|
* The NetAddSub class represents an LPM_ADD_SUB device. The pinout is
|
||||||
|
|
@ -1060,6 +1199,40 @@ const Link& NetCompare::pin_DataB(unsigned idx) const
|
||||||
return pin(8+width_+idx);
|
return pin(8+width_+idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetDecode::NetDecode(NetScope*s, perm_string name, NetFF*mem,
|
||||||
|
unsigned awid, unsigned word_width)
|
||||||
|
: NetNode(s, name, awid)
|
||||||
|
{
|
||||||
|
width_ = word_width;
|
||||||
|
assert( mem->width() % width_ == 0 );
|
||||||
|
|
||||||
|
ff_ = mem;
|
||||||
|
ff_->demux_ = this;
|
||||||
|
make_pins_(awid);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetDecode::~NetDecode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetDecode::make_pins_(unsigned awid)
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0 ; idx < awid ; idx += 1) {
|
||||||
|
pin(idx).set_dir(Link::INPUT);
|
||||||
|
pin(idx).set_name(perm_string::literal("Address"), idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Link& NetDecode::pin_Address(unsigned idx)
|
||||||
|
{
|
||||||
|
return pin(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link& NetDecode::pin_Address(unsigned idx) const
|
||||||
|
{
|
||||||
|
return pin(idx);
|
||||||
|
}
|
||||||
|
|
||||||
NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr,
|
NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr,
|
||||||
unsigned wa, unsigned wb)
|
unsigned wa, unsigned wb)
|
||||||
: NetNode(sc, n, wr+wa+wb),
|
: NetNode(sc, n, wr+wa+wb),
|
||||||
|
|
@ -1385,10 +1558,7 @@ const Link& NetMux::pin_Data(unsigned w, unsigned s) const
|
||||||
return pin(2+width_+swidth_+s*width_+w);
|
return pin(2+width_+swidth_+s*width_+w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetRamDq::make_pins_(unsigned wid)
|
||||||
NetRamDq::NetRamDq(NetScope*s, perm_string n, NetMemory*mem, unsigned awid)
|
|
||||||
: NetNode(s, n, 3+2*mem->width()+awid),
|
|
||||||
mem_(mem), awidth_(awid)
|
|
||||||
{
|
{
|
||||||
pin(0).set_dir(Link::INPUT); pin(0).set_name(perm_string::literal("InClock"), 0);
|
pin(0).set_dir(Link::INPUT); pin(0).set_name(perm_string::literal("InClock"), 0);
|
||||||
pin(1).set_dir(Link::INPUT); pin(1).set_name(perm_string::literal("OutClock"), 0);
|
pin(1).set_dir(Link::INPUT); pin(1).set_name(perm_string::literal("OutClock"), 0);
|
||||||
|
|
@ -1399,39 +1569,49 @@ NetRamDq::NetRamDq(NetScope*s, perm_string n, NetMemory*mem, unsigned awid)
|
||||||
pin(3+idx).set_name(perm_string::literal("Address"), idx);
|
pin(3+idx).set_name(perm_string::literal("Address"), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < width() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||||
pin(3+awidth_+idx).set_dir(Link::INPUT);
|
pin(3+awidth_+idx).set_dir(Link::INPUT);
|
||||||
pin(3+awidth_+idx).set_name(perm_string::literal("Data"), idx);
|
pin(3+awidth_+idx).set_name(perm_string::literal("Data"), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < width() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||||
pin(3+awidth_+width()+idx).set_dir(Link::OUTPUT);
|
pin(3+awidth_+wid+idx).set_dir(Link::OUTPUT);
|
||||||
pin(3+awidth_+width()+idx).set_name(perm_string::literal("Q"), idx);
|
pin(3+awidth_+wid+idx).set_name(perm_string::literal("Q"), idx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetRamDq::NetRamDq(NetScope*s, perm_string n, NetMemory*mem, unsigned awid)
|
||||||
|
: NetNode(s, n, 3+2*mem->width()+awid),
|
||||||
|
mem_(mem), awidth_(awid)
|
||||||
|
{
|
||||||
|
make_pins_(mem->width());
|
||||||
next_ = mem_->ram_list_;
|
next_ = mem_->ram_list_;
|
||||||
mem_->ram_list_ = this;
|
mem_->ram_list_ = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetRamDq::~NetRamDq()
|
NetRamDq::~NetRamDq()
|
||||||
{
|
{
|
||||||
if (mem_->ram_list_ == this) {
|
if (mem_) {
|
||||||
mem_->ram_list_ = next_;
|
if (mem_->ram_list_ == this) {
|
||||||
|
mem_->ram_list_ = next_;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
NetRamDq*cur = mem_->ram_list_;
|
NetRamDq*cur = mem_->ram_list_;
|
||||||
while (cur->next_ != this) {
|
while (cur->next_ != this) {
|
||||||
assert(cur->next_);
|
assert(cur->next_);
|
||||||
cur = cur->next_;
|
cur = cur->next_;
|
||||||
|
}
|
||||||
|
assert(cur->next_ == this);
|
||||||
|
cur->next_ = next_;
|
||||||
}
|
}
|
||||||
assert(cur->next_ == this);
|
|
||||||
cur->next_ = next_;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NetRamDq::width() const
|
unsigned NetRamDq::width() const
|
||||||
{
|
{
|
||||||
return mem_->width();
|
if (mem_) return mem_->width();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NetRamDq::awidth() const
|
unsigned NetRamDq::awidth() const
|
||||||
|
|
@ -1441,7 +1621,13 @@ unsigned NetRamDq::awidth() const
|
||||||
|
|
||||||
unsigned NetRamDq::size() const
|
unsigned NetRamDq::size() const
|
||||||
{
|
{
|
||||||
return mem_->count();
|
if (mem_) return mem_->count();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetMemory* NetRamDq::mem()
|
||||||
|
{
|
||||||
|
return mem_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NetMemory* NetRamDq::mem() const
|
const NetMemory* NetRamDq::mem() const
|
||||||
|
|
@ -2003,6 +2189,7 @@ NetMemory::NetMemory(NetScope*sc, perm_string n, long w, long s, long e)
|
||||||
: width_(w), idxh_(s), idxl_(e), ram_list_(0), scope_(sc)
|
: width_(w), idxh_(s), idxl_(e), ram_list_(0), scope_(sc)
|
||||||
{
|
{
|
||||||
name_ = n;
|
name_ = n;
|
||||||
|
explode_ = 0;
|
||||||
scope_->add_memory(this);
|
scope_->add_memory(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2033,7 +2220,26 @@ unsigned NetMemory::index_to_address(long idx) const
|
||||||
return idx - idxl_;
|
return idx - idxl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet* NetMemory::explode_to_reg()
|
||||||
|
{
|
||||||
|
if (explode_)
|
||||||
|
return explode_;
|
||||||
|
|
||||||
|
explode_ = new NetNet(scope_, name_, NetNet::REG, count()*width_);
|
||||||
|
explode_->mref(this);
|
||||||
|
//explode_->incr_lref();
|
||||||
|
return explode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet* NetMemory::reg_from_explode()
|
||||||
|
{
|
||||||
|
return explode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetNet* NetMemory::reg_from_explode() const
|
||||||
|
{
|
||||||
|
return explode_;
|
||||||
|
}
|
||||||
|
|
||||||
NetEMemory* NetEMemory::dup_expr() const
|
NetEMemory* NetEMemory::dup_expr() const
|
||||||
{
|
{
|
||||||
|
|
@ -2281,6 +2487,27 @@ const NetProc*NetTaskDef::proc() const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.226.2.7 2006/04/23 04:26:14 steve
|
||||||
|
* Constant propagate addresses through NetRamDq read ports.
|
||||||
|
*
|
||||||
|
* Revision 1.226.2.6 2006/04/16 19:26:38 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.226.2.5 2006/03/26 23:09:22 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.226.2.4 2006/03/16 05:40:18 steve
|
||||||
|
* Fix crash when memory exploding doesnot work
|
||||||
|
*
|
||||||
|
* Revision 1.226.2.3 2006/03/12 07:34:17 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.226.2.2 2006/02/19 00:11:32 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
|
* Revision 1.226.2.1 2006/01/18 01:23:23 steve
|
||||||
|
* Rework l-value handling to allow for more l-value type flexibility.
|
||||||
|
*
|
||||||
* Revision 1.226 2004/10/04 01:10:54 steve
|
* Revision 1.226 2004/10/04 01:10:54 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
390
netlist.h
390
netlist.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netlist.h,v 1.321 2004/10/04 01:10:54 steve Exp $"
|
#ident "$Id: netlist.h,v 1.321.2.25 2007/05/30 17:48:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -48,6 +48,7 @@ class ostream;
|
||||||
class Design;
|
class Design;
|
||||||
class Link;
|
class Link;
|
||||||
class Nexus;
|
class Nexus;
|
||||||
|
class NetMemory;
|
||||||
class NetNode;
|
class NetNode;
|
||||||
class NetProc;
|
class NetProc;
|
||||||
class NetProcTop;
|
class NetProcTop;
|
||||||
|
|
@ -58,12 +59,22 @@ class NetEvProbe;
|
||||||
class NetExpr;
|
class NetExpr;
|
||||||
class NetESignal;
|
class NetESignal;
|
||||||
class NetEVariable;
|
class NetEVariable;
|
||||||
|
class NetFF;
|
||||||
class NetFuncDef;
|
class NetFuncDef;
|
||||||
|
|
||||||
|
class NetRamDq;
|
||||||
|
class NetEvTrig;
|
||||||
|
class NetEvWait;
|
||||||
|
|
||||||
struct target;
|
struct target;
|
||||||
struct functor_t;
|
struct functor_t;
|
||||||
|
|
||||||
|
struct sync_accounting_cell {
|
||||||
|
NetProc*proc;
|
||||||
|
NetFF*ff;
|
||||||
|
unsigned pin;
|
||||||
|
};
|
||||||
|
|
||||||
/* =========
|
/* =========
|
||||||
* A NetObj is anything that has any kind of behavior in the
|
* A NetObj is anything that has any kind of behavior in the
|
||||||
* netlist. Nodes can be gates, registers, etc. and are linked
|
* netlist. Nodes can be gates, registers, etc. and are linked
|
||||||
|
|
@ -86,7 +97,6 @@ struct functor_t;
|
||||||
*/
|
*/
|
||||||
class NetObj : public Attrib, public virtual LineInfo {
|
class NetObj : public Attrib, public virtual LineInfo {
|
||||||
|
|
||||||
public:
|
|
||||||
public:
|
public:
|
||||||
// The name of the object must be a permallocated string. A
|
// The name of the object must be a permallocated string. A
|
||||||
// lex_strings string, for example.
|
// lex_strings string, for example.
|
||||||
|
|
@ -215,7 +225,7 @@ class Link {
|
||||||
unsigned inst_;
|
unsigned inst_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Link *next_;
|
Link *next_, *prev_;
|
||||||
Nexus*nexus_;
|
Nexus*nexus_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
|
|
@ -253,6 +263,9 @@ class Nexus {
|
||||||
Link*first_nlink();
|
Link*first_nlink();
|
||||||
const Link* first_nlink()const;
|
const Link* first_nlink()const;
|
||||||
|
|
||||||
|
/* Return the number of drivers, or 0 if undriven. */
|
||||||
|
int is_driven() const;
|
||||||
|
|
||||||
/* This method returns true if all the possible drivers of
|
/* This method returns true if all the possible drivers of
|
||||||
this nexus are constant. It will also return true if there
|
this nexus are constant. It will also return true if there
|
||||||
are no drivers at all. */
|
are no drivers at all. */
|
||||||
|
|
@ -267,6 +280,7 @@ class Nexus {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Link*list_;
|
Link*list_;
|
||||||
|
int list_len_;
|
||||||
void unlink(Link*);
|
void unlink(Link*);
|
||||||
void relink(Link*);
|
void relink(Link*);
|
||||||
|
|
||||||
|
|
@ -307,6 +321,7 @@ class NexusSet {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Nexus**items_;
|
Nexus**items_;
|
||||||
|
unsigned*index_;
|
||||||
unsigned nitems_;
|
unsigned nitems_;
|
||||||
|
|
||||||
unsigned bsearch_(Nexus*that) const;
|
unsigned bsearch_(Nexus*that) const;
|
||||||
|
|
@ -424,6 +439,11 @@ class NetNet : public NetObj {
|
||||||
|
|
||||||
unsigned get_refs() const;
|
unsigned get_refs() const;
|
||||||
|
|
||||||
|
/* This may be and explode of a memory. */
|
||||||
|
void mref(NetMemory*ref);
|
||||||
|
NetMemory*mref();
|
||||||
|
const NetMemory*mref() const;
|
||||||
|
|
||||||
virtual void dump_net(ostream&, unsigned) const;
|
virtual void dump_net(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -448,6 +468,7 @@ class NetNet : public NetObj {
|
||||||
bool local_flag_;
|
bool local_flag_;
|
||||||
unsigned eref_count_;
|
unsigned eref_count_;
|
||||||
unsigned lref_count_;
|
unsigned lref_count_;
|
||||||
|
NetMemory*mref_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -581,6 +602,87 @@ class NetCompare : public NetNode {
|
||||||
bool signed_flag_;
|
bool signed_flag_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A decoder takes an address input and activates (high) the single
|
||||||
|
* Q bit that is addressed. This can be used, for example, to
|
||||||
|
* generate an enable for a FF from an array of FFs.
|
||||||
|
*/
|
||||||
|
class NetDecode : public NetNode {
|
||||||
|
|
||||||
|
public:
|
||||||
|
NetDecode(NetScope*s, perm_string name, NetFF*mem,
|
||||||
|
unsigned awid, unsigned word_width);
|
||||||
|
~NetDecode();
|
||||||
|
|
||||||
|
// This is the width of the word. The width of the NetFF mem
|
||||||
|
// is an even multiple of this.
|
||||||
|
unsigned width() const;
|
||||||
|
// This is the width of the address. The address value for the
|
||||||
|
// base of a word is the address * width().
|
||||||
|
unsigned awidth() const;
|
||||||
|
|
||||||
|
const NetFF*ff() const;
|
||||||
|
|
||||||
|
Link& pin_Address(unsigned idx);
|
||||||
|
|
||||||
|
const Link& pin_Address(unsigned idx) const;
|
||||||
|
const Link& pin_Q(unsigned idx) const;
|
||||||
|
|
||||||
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
|
virtual bool emit_node(struct target_t*) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned width_;
|
||||||
|
NetFF* ff_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void make_pins_(unsigned awid);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The NetDemux is similar to the NetDecode, except that it is
|
||||||
|
* combinational. The inputs are an address, Data, and WriteData.
|
||||||
|
* The Q output is the same as the Data input, except for the bit that
|
||||||
|
* is addressed by the address input, which gets WriteData instead.
|
||||||
|
*/
|
||||||
|
class NetDemux : public NetNode {
|
||||||
|
|
||||||
|
public:
|
||||||
|
NetDemux(NetScope*s, perm_string name,
|
||||||
|
unsigned bus_width, unsigned address_width,
|
||||||
|
unsigned size);
|
||||||
|
~NetDemux();
|
||||||
|
|
||||||
|
// This is the width of the bus that passes through the
|
||||||
|
// device. The address addresses into this width.
|
||||||
|
unsigned width() const;
|
||||||
|
// This is the width of the address. The address value for the
|
||||||
|
// base of a word is the address * width().
|
||||||
|
unsigned awidth() const;
|
||||||
|
// This is the number of words in the width that can be
|
||||||
|
// addressed. This implies (by division) the width of a word.
|
||||||
|
unsigned size() const;
|
||||||
|
|
||||||
|
Link& pin_Address(unsigned idx);
|
||||||
|
Link& pin_Data(unsigned idx);
|
||||||
|
Link& pin_Q(unsigned idx);
|
||||||
|
Link& pin_WriteData(unsigned idx);
|
||||||
|
|
||||||
|
const Link& pin_Address(unsigned idx) const;
|
||||||
|
const Link& pin_Data(unsigned idx) const;
|
||||||
|
const Link& pin_Q(unsigned idx) const;
|
||||||
|
const Link& pin_WriteData(unsigned idx) const;
|
||||||
|
|
||||||
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
|
virtual bool emit_node(struct target_t*) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned width_, awidth_, size_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void make_pins_(unsigned wid, unsigned awid);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class represents a theoretical (though not necessarily
|
* This class represents a theoretical (though not necessarily
|
||||||
* practical) integer divider gate. This is not to represent any real
|
* practical) integer divider gate. This is not to represent any real
|
||||||
|
|
@ -703,10 +805,19 @@ class NetFF : public NetNode {
|
||||||
void sset_value(const verinum&val);
|
void sset_value(const verinum&val);
|
||||||
const verinum& sset_value() const;
|
const verinum& sset_value() const;
|
||||||
|
|
||||||
|
NetDecode* get_demux();
|
||||||
|
const NetDecode* get_demux() const;
|
||||||
|
|
||||||
virtual void dump_node(ostream&, unsigned ind) const;
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
virtual bool emit_node(struct target_t*) const;
|
virtual bool emit_node(struct target_t*) const;
|
||||||
virtual void functor_node(Design*des, functor_t*fun);
|
virtual void functor_node(Design*des, functor_t*fun);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// If there is a demux associated with this gate, the demux_
|
||||||
|
// member will point to the decoder.
|
||||||
|
friend class NetDecode;
|
||||||
|
NetDecode*demux_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
verinum aset_value_;
|
verinum aset_value_;
|
||||||
verinum sset_value_;
|
verinum sset_value_;
|
||||||
|
|
@ -735,6 +846,7 @@ class NetMemory {
|
||||||
|
|
||||||
// NetScope*scope();
|
// NetScope*scope();
|
||||||
const NetScope*scope() const { return scope_; };
|
const NetScope*scope() const { return scope_; };
|
||||||
|
NetScope*scope() { return scope_; };
|
||||||
|
|
||||||
// This is the number of memory positions.
|
// This is the number of memory positions.
|
||||||
unsigned count() const;
|
unsigned count() const;
|
||||||
|
|
@ -744,6 +856,13 @@ class NetMemory {
|
||||||
// that are not zero based.
|
// that are not zero based.
|
||||||
unsigned index_to_address(long idx) const;
|
unsigned index_to_address(long idx) const;
|
||||||
|
|
||||||
|
// This method returns a NetNet::REG that has the same number
|
||||||
|
// of bits as the memory as a whole. This is used to represent
|
||||||
|
// memories that are synthesized to individual bits.
|
||||||
|
NetNet* explode_to_reg();
|
||||||
|
NetNet* reg_from_explode();
|
||||||
|
const NetNet* reg_from_explode() const;
|
||||||
|
|
||||||
void dump(ostream&o, unsigned lm) const;
|
void dump(ostream&o, unsigned lm) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -753,12 +872,14 @@ class NetMemory {
|
||||||
long idxl_;
|
long idxl_;
|
||||||
|
|
||||||
friend class NetRamDq;
|
friend class NetRamDq;
|
||||||
NetRamDq* ram_list_;
|
class NetRamDq* ram_list_;
|
||||||
|
|
||||||
friend class NetScope;
|
friend class NetScope;
|
||||||
NetMemory*snext_, *sprev_;
|
NetMemory*snext_, *sprev_;
|
||||||
NetScope*scope_;
|
NetScope*scope_;
|
||||||
|
|
||||||
|
NetNet*explode_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
NetMemory(const NetMemory&);
|
NetMemory(const NetMemory&);
|
||||||
NetMemory& operator= (const NetMemory&);
|
NetMemory& operator= (const NetMemory&);
|
||||||
|
|
@ -878,6 +999,8 @@ class NetRamDq : public NetNode {
|
||||||
unsigned width() const;
|
unsigned width() const;
|
||||||
unsigned awidth() const;
|
unsigned awidth() const;
|
||||||
unsigned size() const;
|
unsigned size() const;
|
||||||
|
|
||||||
|
NetMemory*mem();
|
||||||
const NetMemory*mem() const;
|
const NetMemory*mem() const;
|
||||||
|
|
||||||
Link& pin_InClock();
|
Link& pin_InClock();
|
||||||
|
|
@ -908,11 +1031,15 @@ class NetRamDq : public NetNode {
|
||||||
// that are ports to the attached memory.
|
// that are ports to the attached memory.
|
||||||
unsigned count_partners() const;
|
unsigned count_partners() const;
|
||||||
|
|
||||||
|
void functor_node(Design*des, functor_t*fun);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetMemory*mem_;
|
NetMemory*mem_;
|
||||||
NetRamDq*next_;
|
NetRamDq*next_;
|
||||||
unsigned awidth_;
|
unsigned awidth_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void make_pins_(unsigned wid);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1003,7 +1130,7 @@ class NetExpr : public LineInfo {
|
||||||
// Get the Nexus that are the input to this
|
// Get the Nexus that are the input to this
|
||||||
// expression. Normally this descends down to the reference to
|
// expression. Normally this descends down to the reference to
|
||||||
// a signal that reads from its input.
|
// a signal that reads from its input.
|
||||||
virtual NexusSet* nex_input() =0;
|
virtual NexusSet* nex_input(bool rem_out = true) =0;
|
||||||
|
|
||||||
// Return a version of myself that is structural. This is used
|
// Return a version of myself that is structural. This is used
|
||||||
// for converting expressions to gates.
|
// for converting expressions to gates.
|
||||||
|
|
@ -1044,7 +1171,7 @@ class NetEConst : public NetExpr {
|
||||||
|
|
||||||
virtual NetEConst* dup_expr() const;
|
virtual NetEConst* dup_expr() const;
|
||||||
virtual NetNet*synthesize(Design*);
|
virtual NetNet*synthesize(Design*);
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
verinum value_;
|
verinum value_;
|
||||||
|
|
@ -1096,7 +1223,7 @@ class NetECReal : public NetExpr {
|
||||||
|
|
||||||
virtual NetECReal* dup_expr() const;
|
virtual NetECReal* dup_expr() const;
|
||||||
virtual NetNet*synthesize(Design*);
|
virtual NetNet*synthesize(Design*);
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
verireal value_;
|
verireal value_;
|
||||||
|
|
@ -1315,7 +1442,7 @@ class NetUDP : public NetNode {
|
||||||
* linked into the netlist. However, elaborating a process may cause
|
* linked into the netlist. However, elaborating a process may cause
|
||||||
* special nodes to be created to handle things like events.
|
* special nodes to be created to handle things like events.
|
||||||
*/
|
*/
|
||||||
class NetProc : public virtual LineInfo {
|
class NetProc : public virtual LineInfo, public Attrib {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetProc();
|
explicit NetProc();
|
||||||
|
|
@ -1324,7 +1451,7 @@ class NetProc : public virtual LineInfo {
|
||||||
// Find the Nexa that are input by the statement. This is used
|
// Find the Nexa that are input by the statement. This is used
|
||||||
// for example by @* to find the inputs to the process for the
|
// for example by @* to find the inputs to the process for the
|
||||||
// sensitivity list.
|
// sensitivity list.
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
// Find the nexa that are set by the statement. Add the output
|
// Find the nexa that are set by the statement. Add the output
|
||||||
// values to the set passed as a parameter.
|
// values to the set passed as a parameter.
|
||||||
|
|
@ -1346,15 +1473,33 @@ class NetProc : public virtual LineInfo {
|
||||||
// process. Most process types are not.
|
// process. Most process types are not.
|
||||||
virtual bool is_synchronous();
|
virtual bool is_synchronous();
|
||||||
|
|
||||||
// synthesize as asynchronous logic, and return true.
|
// synthesize as asynchronous logic, and return true. The
|
||||||
virtual bool synth_async(Design*des, NetScope*scope,
|
// sync_flag is used to tell the async synthesizer that the
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
// output nex_map is ultimately connected to a DFF Q
|
||||||
|
// output. This can affect how cycles are handled.
|
||||||
|
|
||||||
virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
bool synth_async_noaccum(Design*des, NetScope*scope, bool sync_flag,
|
||||||
const NetNet*nex_map, NetNet*nex_out,
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out);
|
||||||
|
|
||||||
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
|
NetNet*accum_in, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
|
||||||
|
// Synthesize synchronous logic, and return true. The nex_out
|
||||||
|
// is where outputs are actually connected, and the nex_map
|
||||||
|
// maps nexa to bit positions. The ff is the initial DFF that
|
||||||
|
// was created to receive the Data inputs. The method *may*
|
||||||
|
// delete that DFF in favor of multiple smaller devices, but
|
||||||
|
// in that case it will set the ff argument to nil.
|
||||||
|
virtual bool synth_sync(Design*des, NetScope*scope,
|
||||||
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
void dump_proc_attr(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class NetBlock;
|
friend class NetBlock;
|
||||||
|
|
@ -1432,11 +1577,13 @@ class NetAssign_ {
|
||||||
// into a wire.
|
// into a wire.
|
||||||
void turn_sig_to_wire_on_release();
|
void turn_sig_to_wire_on_release();
|
||||||
|
|
||||||
|
void incr_mem_lref();
|
||||||
|
|
||||||
// It is possible that l-values can have *inputs*, as well as
|
// It is possible that l-values can have *inputs*, as well as
|
||||||
// being outputs. For example foo[idx] = ... is the l-value
|
// being outputs. For example foo[idx] = ... is the l-value
|
||||||
// (NetAssign_ object) with a foo l-value and the input
|
// (NetAssign_ object) with a foo l-value and the input
|
||||||
// expression idx.
|
// expression idx.
|
||||||
NexusSet* nex_input();
|
NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
// This pointer is for keeping simple lists.
|
// This pointer is for keeping simple lists.
|
||||||
NetAssign_* more;
|
NetAssign_* more;
|
||||||
|
|
@ -1452,6 +1599,7 @@ class NetAssign_ {
|
||||||
bool turn_sig_to_wire_on_release_;
|
bool turn_sig_to_wire_on_release_;
|
||||||
unsigned loff_;
|
unsigned loff_;
|
||||||
unsigned lwid_;
|
unsigned lwid_;
|
||||||
|
bool mem_lref_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetAssignBase : public NetProc {
|
class NetAssignBase : public NetProc {
|
||||||
|
|
@ -1474,7 +1622,7 @@ class NetAssignBase : public NetProc {
|
||||||
void set_delay(NetExpr*);
|
void set_delay(NetExpr*);
|
||||||
const NetExpr* get_delay() const;
|
const NetExpr* get_delay() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&o);
|
virtual void nex_output(NexusSet&o);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1482,13 +1630,24 @@ class NetAssignBase : public NetProc {
|
||||||
// accounts for any grouping of NetAssign_ objects that might happen.
|
// accounts for any grouping of NetAssign_ objects that might happen.
|
||||||
unsigned lwidth() const;
|
unsigned lwidth() const;
|
||||||
|
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
|
NetNet*accum_in, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
bool synth_sync(Design*des, NetScope*scope,
|
||||||
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
// This dumps all the lval structures.
|
// This dumps all the lval structures.
|
||||||
void dump_lval(ostream&) const;
|
void dump_lval(ostream&) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool synth_async_mem_sync_(Design*des, NetScope*scope,
|
||||||
|
NetAssign_*cur, NetNet*rsig, unsigned&roff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetAssign_*lval_;
|
NetAssign_*lval_;
|
||||||
NetExpr *rval_;
|
NetExpr *rval_;
|
||||||
|
|
@ -1549,11 +1708,13 @@ class NetBlock : public NetProc {
|
||||||
|
|
||||||
|
|
||||||
// synthesize as asynchronous logic, and return true.
|
// synthesize as asynchronous logic, and return true.
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out, NetNet*accum_in, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
|
||||||
bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
bool synth_sync(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out,
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
// This version of emit_recurse scans all the statements of
|
// This version of emit_recurse scans all the statements of
|
||||||
|
|
@ -1561,7 +1722,7 @@ class NetBlock : public NetProc {
|
||||||
// for sequential blocks.
|
// for sequential blocks.
|
||||||
void emit_recurse(struct target_t*) const;
|
void emit_recurse(struct target_t*) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&);
|
virtual void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
|
|
@ -1601,15 +1762,21 @@ class NetCase : public NetProc {
|
||||||
const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
|
const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
|
||||||
const NetProc*stat(unsigned idx) const { return items_[idx].statement; }
|
const NetProc*stat(unsigned idx) const { return items_[idx].statement; }
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&out);
|
virtual void nex_output(NexusSet&out);
|
||||||
|
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out, NetNet*accum_in, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool synth_async_1hot_(Design*des, NetScope*scope, bool sync_flag,
|
||||||
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out, NetNet*accum_in,
|
||||||
|
NetNet*esig, unsigned hot_items);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TYPE type_;
|
TYPE type_;
|
||||||
|
|
@ -1642,7 +1809,7 @@ class NetCAssign : public NetProc, public NetNode {
|
||||||
|
|
||||||
const Link& lval_pin(unsigned) const;
|
const Link& lval_pin(unsigned) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump_node(ostream&, unsigned ind) const;
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
|
|
@ -1682,21 +1849,30 @@ class NetCondit : public NetProc {
|
||||||
bool emit_recurse_if(struct target_t*) const;
|
bool emit_recurse_if(struct target_t*) const;
|
||||||
bool emit_recurse_else(struct target_t*) const;
|
bool emit_recurse_else(struct target_t*) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&o);
|
virtual void nex_output(NexusSet&o);
|
||||||
|
|
||||||
bool is_asynchronous();
|
bool is_asynchronous();
|
||||||
bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out, NetNet*accum, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
|
||||||
bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
bool synth_sync(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out,
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual int match_proc(struct proc_match_t*);
|
virtual int match_proc(struct proc_match_t*);
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int connect_set_clr_range_( struct sync_accounting_cell*nex_ff,
|
||||||
|
unsigned bits, NetNet*rst,
|
||||||
|
const verinum&val);
|
||||||
|
int connect_enable_range_(Design*des, NetScope*scope,
|
||||||
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
unsigned bits, NetNet*ce);
|
||||||
private:
|
private:
|
||||||
NetExpr* expr_;
|
NetExpr* expr_;
|
||||||
NetProc*if_;
|
NetProc*if_;
|
||||||
|
|
@ -1845,12 +2021,12 @@ class NetEvent : public LineInfo {
|
||||||
NetEvProbe*probes_;
|
NetEvProbe*probes_;
|
||||||
|
|
||||||
// Use these methods to list the triggers attached to me.
|
// Use these methods to list the triggers attached to me.
|
||||||
NetEvTrig* trig_;
|
class NetEvTrig* trig_;
|
||||||
|
|
||||||
// Use This member to count references by NetEvWait objects.
|
// Use This member to count references by NetEvWait objects.
|
||||||
unsigned waitref_;
|
unsigned waitref_;
|
||||||
struct wcell_ {
|
struct wcell_ {
|
||||||
NetEvWait*obj;
|
class NetEvWait*obj;
|
||||||
struct wcell_*next;
|
struct wcell_*next;
|
||||||
};
|
};
|
||||||
struct wcell_ *wlist_;
|
struct wcell_ *wlist_;
|
||||||
|
|
@ -1911,11 +2087,14 @@ class NetEvWait : public NetProc {
|
||||||
|
|
||||||
virtual void nex_output(NexusSet&out);
|
virtual void nex_output(NexusSet&out);
|
||||||
|
|
||||||
virtual bool synth_async(Design*des, NetScope*scope,
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
const NetNet*nex_map, NetNet*nex_out);
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
|
NetNet*accum_in, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
|
||||||
virtual bool synth_sync(Design*des, NetScope*scope, NetFF*ff,
|
virtual bool synth_sync(Design*des, NetScope*scope,
|
||||||
const NetNet*nex_map, NetNet*nex_out,
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out,
|
||||||
const svector<NetEvProbe*>&events);
|
const svector<NetEvProbe*>&events);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -1974,7 +2153,7 @@ class NetForce : public NetProc, public NetNode {
|
||||||
|
|
||||||
const NetNet*lval() const;
|
const NetNet*lval() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
|
|
@ -1997,7 +2176,7 @@ class NetForever : public NetProc {
|
||||||
|
|
||||||
void emit_recurse(struct target_t*) const;
|
void emit_recurse(struct target_t*) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
|
@ -2035,6 +2214,8 @@ class NetFuncDef {
|
||||||
const NetNet*return_sig() const;
|
const NetNet*return_sig() const;
|
||||||
const NetVariable*return_var() const;
|
const NetVariable*return_var() const;
|
||||||
|
|
||||||
|
NetNet* synthesize(Design*des, const svector<NetNet*>&inports_);
|
||||||
|
|
||||||
void dump(ostream&, unsigned ind) const;
|
void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -2069,7 +2250,7 @@ class NetPDelay : public NetProc {
|
||||||
unsigned long delay() const;
|
unsigned long delay() const;
|
||||||
const NetExpr*expr() const;
|
const NetExpr*expr() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&);
|
virtual void nex_output(NexusSet&);
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
|
|
@ -2095,7 +2276,7 @@ class NetRepeat : public NetProc {
|
||||||
const NetExpr*expr() const;
|
const NetExpr*expr() const;
|
||||||
void emit_recurse(struct target_t*) const;
|
void emit_recurse(struct target_t*) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
|
@ -2147,7 +2328,7 @@ class NetSTask : public NetProc {
|
||||||
|
|
||||||
const NetExpr* parm(unsigned idx) const;
|
const NetExpr* parm(unsigned idx) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&);
|
virtual void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
@ -2253,7 +2434,9 @@ class NetEUFunc : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEUFunc*dup_expr() const;
|
virtual NetEUFunc*dup_expr() const;
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
|
virtual NetNet* synthesize(Design*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetScope*func_;
|
NetScope*func_;
|
||||||
|
|
@ -2281,7 +2464,8 @@ class NetUTask : public NetProc {
|
||||||
|
|
||||||
const NetScope* task() const;
|
const NetScope* task() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
virtual void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
|
@ -2304,11 +2488,15 @@ class NetWhile : public NetProc {
|
||||||
|
|
||||||
void emit_proc_recurse(struct target_t*) const;
|
void emit_proc_recurse(struct target_t*) const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void nex_output(NexusSet&);
|
virtual void nex_output(NexusSet&);
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
virtual bool synth_async(Design*des, NetScope*scope, bool sync_flag,
|
||||||
|
struct sync_accounting_cell*nex_ff,
|
||||||
|
NetNet*nex_map, NetNet*nex_out, NetNet*accum_in, bool latch_inferred = false, NetNet *gsig = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr* cond_;
|
NetExpr* cond_;
|
||||||
NetProc*proc_;
|
NetProc*proc_;
|
||||||
|
|
@ -2336,14 +2524,14 @@ class NetProcTop : public LineInfo, public Attrib {
|
||||||
const NetScope*scope() const;
|
const NetScope*scope() const;
|
||||||
|
|
||||||
/* Return true if this process represents combinational logic. */
|
/* Return true if this process represents combinational logic. */
|
||||||
bool is_asynchronous();
|
bool is_asynchronous() const;
|
||||||
|
|
||||||
/* Create asynchronous logic from this thread and return true,
|
/* Create asynchronous logic from this thread and return true,
|
||||||
or return false if that cannot be done. */
|
or return false if that cannot be done. */
|
||||||
bool synth_async(Design*des);
|
bool synth_async(Design*des);
|
||||||
|
|
||||||
/* Return true if this process represents synchronous logic. */
|
/* Return true if this process represents synchronous logic. */
|
||||||
bool is_synchronous();
|
bool is_synchronous() const;
|
||||||
|
|
||||||
/* Create synchronous logic from this thread and return true,
|
/* Create synchronous logic from this thread and return true,
|
||||||
or return false if that cannot be done. */
|
or return false if that cannot be done. */
|
||||||
|
|
@ -2410,7 +2598,7 @@ class NetEBinary : public NetExpr {
|
||||||
virtual bool has_width() const;
|
virtual bool has_width() const;
|
||||||
|
|
||||||
virtual NetEBinary* dup_expr() const;
|
virtual NetEBinary* dup_expr() const;
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
@ -2523,7 +2711,7 @@ class NetEBComp : public NetEBinary {
|
||||||
NetEConst*eval_eqeq_();
|
NetEConst*eval_eqeq_();
|
||||||
NetEConst*eval_less_();
|
NetEConst*eval_less_();
|
||||||
NetEConst*eval_leeq_();
|
NetEConst*eval_leeq_();
|
||||||
NetEConst*eval_leeq_real_();
|
NetEConst*eval_leeq_real_(bool gt_flag, bool include_eq_flag);
|
||||||
NetEConst*eval_gt_();
|
NetEConst*eval_gt_();
|
||||||
NetEConst*eval_gteq_();
|
NetEConst*eval_gteq_();
|
||||||
NetEConst*eval_neeq_();
|
NetEConst*eval_neeq_();
|
||||||
|
|
@ -2628,7 +2816,7 @@ class NetEConcat : public NetExpr {
|
||||||
unsigned nparms() const { return parms_.count() ; }
|
unsigned nparms() const { return parms_.count() ; }
|
||||||
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
|
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual bool has_width() const;
|
virtual bool has_width() const;
|
||||||
virtual bool set_width(unsigned w);
|
virtual bool set_width(unsigned w);
|
||||||
virtual NetEConcat* dup_expr() const;
|
virtual NetEConcat* dup_expr() const;
|
||||||
|
|
@ -2661,7 +2849,7 @@ class NetEVariable : public NetExpr {
|
||||||
void dump(ostream&) const;
|
void dump(ostream&) const;
|
||||||
|
|
||||||
NetEVariable*dup_expr() const;
|
NetEVariable*dup_expr() const;
|
||||||
NexusSet* nex_input();
|
NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetVariable*var_;
|
NetVariable*var_;
|
||||||
|
|
@ -2682,7 +2870,7 @@ class NetEParam : public NetExpr {
|
||||||
NetEParam(class Design*des, NetScope*scope, perm_string name);
|
NetEParam(class Design*des, NetScope*scope, perm_string name);
|
||||||
~NetEParam();
|
~NetEParam();
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual bool set_width(unsigned w);
|
virtual bool set_width(unsigned w);
|
||||||
virtual bool has_width() const;
|
virtual bool has_width() const;
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
|
|
@ -2718,7 +2906,7 @@ class NetESelect : public NetExpr {
|
||||||
const NetExpr*sub_expr() const;
|
const NetExpr*sub_expr() const;
|
||||||
const NetExpr*select() const;
|
const NetExpr*select() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual bool set_width(unsigned w);
|
virtual bool set_width(unsigned w);
|
||||||
virtual bool has_width() const;
|
virtual bool has_width() const;
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
|
|
@ -2745,7 +2933,7 @@ class NetEEvent : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEEvent* dup_expr() const;
|
virtual NetEEvent* dup_expr() const;
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
virtual void dump(ostream&os) const;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -2768,7 +2956,7 @@ class NetEScope : public NetExpr {
|
||||||
|
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEScope* dup_expr() const;
|
virtual NetEScope* dup_expr() const;
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
virtual void dump(ostream&os) const;
|
virtual void dump(ostream&os) const;
|
||||||
|
|
||||||
|
|
@ -2796,7 +2984,7 @@ class NetESFunc : public NetExpr {
|
||||||
const NetExpr* parm(unsigned idx) const;
|
const NetExpr* parm(unsigned idx) const;
|
||||||
|
|
||||||
virtual TYPE expr_type() const;
|
virtual TYPE expr_type() const;
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual bool set_width(unsigned);
|
virtual bool set_width(unsigned);
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
|
|
@ -2834,7 +3022,7 @@ class NetETernary : public NetExpr {
|
||||||
virtual NetETernary* dup_expr() const;
|
virtual NetETernary* dup_expr() const;
|
||||||
virtual NetExpr* eval_tree();
|
virtual NetExpr* eval_tree();
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
virtual NetNet*synthesize(Design*);
|
virtual NetNet*synthesize(Design*);
|
||||||
|
|
@ -2874,7 +3062,7 @@ class NetEUnary : public NetExpr {
|
||||||
virtual NetEUnary* dup_expr() const;
|
virtual NetEUnary* dup_expr() const;
|
||||||
virtual NetEConst* eval_tree();
|
virtual NetEConst* eval_tree();
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
|
|
@ -2924,11 +3112,11 @@ class NetEMemory : public NetExpr {
|
||||||
const NetExpr* index() const;
|
const NetExpr* index() const;
|
||||||
|
|
||||||
virtual bool set_width(unsigned);
|
virtual bool set_width(unsigned);
|
||||||
|
virtual NetNet* synthesize(Design*);
|
||||||
NetExpr* eval_tree();
|
NetExpr* eval_tree();
|
||||||
virtual NetEMemory*dup_expr() const;
|
virtual NetEMemory*dup_expr() const;
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
|
|
@ -2962,7 +3150,7 @@ class NetESignal : public NetExpr {
|
||||||
|
|
||||||
virtual NetESignal* dup_expr() const;
|
virtual NetESignal* dup_expr() const;
|
||||||
NetNet* synthesize(Design*des);
|
NetNet* synthesize(Design*des);
|
||||||
NexusSet* nex_input();
|
NexusSet* nex_input(bool rem_out = true);
|
||||||
|
|
||||||
// These methods actually reference the properties of the
|
// These methods actually reference the properties of the
|
||||||
// NetNet object that I point to.
|
// NetNet object that I point to.
|
||||||
|
|
@ -3004,8 +3192,9 @@ class NetEBitSel : public NetExpr {
|
||||||
const NetNet* sig() const;
|
const NetNet* sig() const;
|
||||||
|
|
||||||
NetEBitSel* dup_expr() const;
|
NetEBitSel* dup_expr() const;
|
||||||
|
NetNet* synthesize(Design*des);
|
||||||
|
|
||||||
virtual NexusSet* nex_input();
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
||||||
|
|
@ -3357,6 +3546,81 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.321.2.25 2007/05/30 17:48:53 steve
|
||||||
|
* Support Latch synthesis (Alan Feldstein)
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.24 2006/11/26 01:54:05 steve
|
||||||
|
* Add synthesis of user defined functions.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.23 2006/08/15 03:41:24 steve
|
||||||
|
* Improve performance of unlink of heavily connected nexa.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.22 2006/08/08 02:17:48 steve
|
||||||
|
* Improved nexus management performance.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.21 2006/07/23 19:42:33 steve
|
||||||
|
* Handle statement output override better in blocks.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.20 2006/07/10 00:21:51 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.19 2006/06/23 03:49:46 steve
|
||||||
|
* synthesis of NetCondit handles partial resets.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.18 2006/06/14 03:02:54 steve
|
||||||
|
* synthesis for NetEBitSel.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.17 2006/04/23 04:26:14 steve
|
||||||
|
* Constant propagate addresses through NetRamDq read ports.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.16 2006/04/16 19:26:38 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.15 2006/04/10 03:43:39 steve
|
||||||
|
* Exploded memories accessed by constant indices.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.14 2006/03/26 23:09:23 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.13 2006/03/18 18:43:21 steve
|
||||||
|
* Better error messages when synthesis fails.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.12 2006/03/16 05:40:18 steve
|
||||||
|
* Fix crash when memory exploding doesnot work
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.11 2006/03/12 07:34:17 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.10 2006/02/19 00:11:32 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.9 2006/01/21 21:42:31 steve
|
||||||
|
* When mux has wide select but sparse choices, use 1hot translation.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.8 2006/01/18 01:23:24 steve
|
||||||
|
* Rework l-value handling to allow for more l-value type flexibility.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.7 2005/12/31 04:28:14 steve
|
||||||
|
* Fix crashes caused bu synthesis of sqrt32.v.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.6 2005/12/14 00:54:29 steve
|
||||||
|
* Account for sync vs async muxes.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.5 2005/11/13 22:28:48 steve
|
||||||
|
* Allow for block output to be set throughout the statements.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.4 2005/09/09 02:17:08 steve
|
||||||
|
* Evaluate magnitude compare with real operands.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.3 2005/08/22 01:00:41 steve
|
||||||
|
* Add support for implicit defaults in case and conditions.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.2 2005/08/13 00:45:54 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
|
* Revision 1.321.2.1 2005/07/06 22:41:34 steve
|
||||||
|
* Fix compile errors with g++-4.
|
||||||
|
*
|
||||||
* Revision 1.321 2004/10/04 01:10:54 steve
|
* Revision 1.321 2004/10/04 01:10:54 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
25
netmisc.cc
25
netmisc.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netmisc.cc,v 1.8 2004/02/20 18:53:35 steve Exp $"
|
#ident "$Id: netmisc.cc,v 1.8.2.1 2006/05/15 03:55:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -72,6 +72,26 @@ NetNet* add_to_net(Design*des, NetNet*sig, long val)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetNet* reduction_or(Design*des, NetNet*isig)
|
||||||
|
{
|
||||||
|
NetScope*scope = isig->scope();
|
||||||
|
|
||||||
|
NetLogic*olog = new NetLogic(scope, scope->local_symbol(),
|
||||||
|
isig->pin_count()+1, NetLogic::OR);
|
||||||
|
olog->set_line(*isig);
|
||||||
|
des->add_node(olog);
|
||||||
|
|
||||||
|
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||||
|
NetNet::IMPLICIT, 1);
|
||||||
|
osig->local_flag(true);
|
||||||
|
osig->set_line(*isig);
|
||||||
|
|
||||||
|
connect(olog->pin(0), osig->pin(0));
|
||||||
|
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
|
||||||
|
connect(olog->pin(1+idx), isig->pin(idx));
|
||||||
|
|
||||||
|
return osig;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
|
NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
|
||||||
{
|
{
|
||||||
|
|
@ -90,6 +110,9 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netmisc.cc,v $
|
* $Log: netmisc.cc,v $
|
||||||
|
* Revision 1.8.2.1 2006/05/15 03:55:23 steve
|
||||||
|
* Fix synthesis of expressions with land of vectors.
|
||||||
|
*
|
||||||
* Revision 1.8 2004/02/20 18:53:35 steve
|
* Revision 1.8 2004/02/20 18:53:35 steve
|
||||||
* Addtrbute keys are perm_strings.
|
* Addtrbute keys are perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
10
netmisc.h
10
netmisc.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netmisc.h,v 1.19 2004/03/07 20:04:11 steve Exp $"
|
#ident "$Id: netmisc.h,v 1.19.2.1 2006/05/15 03:55:23 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -57,6 +57,11 @@ extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
|
||||||
*/
|
*/
|
||||||
extern NetNet*add_to_net(Design*des, NetNet*sig, long val);
|
extern NetNet*add_to_net(Design*des, NetNet*sig, long val);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the reduction OR from the input signal.
|
||||||
|
*/
|
||||||
|
extern NetNet*reduction_or(Design*des, NetNet*sig);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In some cases the lval is accessible as a pointer to the head of
|
* In some cases the lval is accessible as a pointer to the head of
|
||||||
* a list of NetAssign_ objects. This function returns the width of
|
* a list of NetAssign_ objects. This function returns the width of
|
||||||
|
|
@ -75,6 +80,9 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netmisc.h,v $
|
* $Log: netmisc.h,v $
|
||||||
|
* Revision 1.19.2.1 2006/05/15 03:55:23 steve
|
||||||
|
* Fix synthesis of expressions with land of vectors.
|
||||||
|
*
|
||||||
* Revision 1.19 2004/03/07 20:04:11 steve
|
* Revision 1.19 2004/03/07 20:04:11 steve
|
||||||
* MOre thorough use of elab_and_eval function.
|
* MOre thorough use of elab_and_eval function.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
14
nodangle.cc
14
nodangle.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: nodangle.cc,v 1.21 2004/02/20 18:53:35 steve Exp $"
|
#ident "$Id: nodangle.cc,v 1.21.2.2 2006/08/23 04:08:55 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -109,6 +109,9 @@ void nodangle_f::signal(Design*des, NetNet*sig)
|
||||||
if (sig->get_refs() > 0)
|
if (sig->get_refs() > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (sig->mref())
|
||||||
|
return;
|
||||||
|
|
||||||
/* Cannot delete the ports of tasks or functions. There are
|
/* Cannot delete the ports of tasks or functions. There are
|
||||||
too many places where they are referenced. */
|
too many places where they are referenced. */
|
||||||
if ((sig->port_type() != NetNet::NOT_A_PORT)
|
if ((sig->port_type() != NetNet::NOT_A_PORT)
|
||||||
|
|
@ -160,6 +163,9 @@ void nodangle_f::signal(Design*des, NetNet*sig)
|
||||||
if (cursig == 0)
|
if (cursig == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (cursig == sig)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (cursig->local_flag())
|
if (cursig->local_flag())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -205,6 +211,12 @@ void nodangle(Design*des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: nodangle.cc,v $
|
* $Log: nodangle.cc,v $
|
||||||
|
* Revision 1.21.2.2 2006/08/23 04:08:55 steve
|
||||||
|
* Do not count self as signifincant in nodangle.
|
||||||
|
*
|
||||||
|
* Revision 1.21.2.1 2006/03/16 05:40:19 steve
|
||||||
|
* Fix crash when memory exploding doesnot work
|
||||||
|
*
|
||||||
* Revision 1.21 2004/02/20 18:53:35 steve
|
* Revision 1.21 2004/02/20 18:53:35 steve
|
||||||
* Addtrbute keys are perm_strings.
|
* Addtrbute keys are perm_strings.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
234
parse.y
234
parse.y
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: parse.y,v 1.201 2004/10/04 01:10:54 steve Exp $"
|
#ident "$Id: parse.y,v 1.201.2.8 2007/04/26 00:50:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -134,9 +134,10 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
||||||
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
||||||
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
|
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
|
||||||
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
|
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
|
||||||
%token K_edge K_else K_end K_endcase K_endfunction K_endmodule
|
%token K_edge K_edge_descriptor
|
||||||
|
%token K_else K_end K_endcase K_endfunction K_endmodule
|
||||||
%token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for
|
%token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for
|
||||||
%token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if
|
%token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if K_ifnone
|
||||||
%token K_initial K_inout K_input K_integer K_join K_large K_localparam
|
%token K_initial K_inout K_input K_integer K_join K_large K_localparam
|
||||||
%token K_macromodule
|
%token K_macromodule
|
||||||
%token K_medium K_module K_nand K_negedge K_nmos K_nor K_not K_notif0
|
%token K_medium K_module K_nand K_negedge K_nmos K_nor K_not K_notif0
|
||||||
|
|
@ -191,11 +192,11 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
||||||
%type <gate> gate_instance
|
%type <gate> gate_instance
|
||||||
%type <gates> gate_instance_list
|
%type <gates> gate_instance_list
|
||||||
|
|
||||||
%type <expr> expression expr_primary
|
%type <expr> expression expr_primary expr_mintypmax
|
||||||
%type <expr> lavalue lpvalue
|
%type <expr> lavalue lpvalue
|
||||||
%type <expr> delay_value delay_value_simple
|
%type <expr> delay_value delay_value_simple
|
||||||
%type <exprs> delay1 delay3 delay3_opt
|
%type <exprs> delay1 delay3 delay3_opt
|
||||||
%type <exprs> expression_list
|
%type <exprs> expression_list expression_list_proper
|
||||||
%type <exprs> assign assign_list
|
%type <exprs> assign assign_list
|
||||||
|
|
||||||
%type <exprs> range range_opt
|
%type <exprs> range range_opt
|
||||||
|
|
@ -287,7 +288,7 @@ attribute
|
||||||
}
|
}
|
||||||
| IDENTIFIER '=' expression
|
| IDENTIFIER '=' expression
|
||||||
{ PExpr*tmp = $3;
|
{ PExpr*tmp = $3;
|
||||||
if (!pform_expression_is_constant(tmp)) {
|
if (tmp && !pform_expression_is_constant(tmp)) {
|
||||||
yyerror(@3, "error: attribute value "
|
yyerror(@3, "error: attribute value "
|
||||||
"expression must be constant.");
|
"expression must be constant.");
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
@ -308,17 +309,14 @@ attribute
|
||||||
integers. This rule matches those declarations. The containing
|
integers. This rule matches those declarations. The containing
|
||||||
rule has presumably set up the scope. */
|
rule has presumably set up the scope. */
|
||||||
block_item_decl
|
block_item_decl
|
||||||
: attribute_list_opt K_reg signed_opt range register_variable_list ';'
|
: K_reg signed_opt range register_variable_list ';'
|
||||||
{ pform_set_net_range($5, $4, $3);
|
{ pform_set_net_range($4, $3, $2);
|
||||||
if ($1) delete $1;
|
|
||||||
}
|
}
|
||||||
| attribute_list_opt K_reg signed_opt register_variable_list ';'
|
| K_reg signed_opt register_variable_list ';'
|
||||||
{ pform_set_net_range($4, 0, $3);
|
{ pform_set_net_range($3, 0, $2);
|
||||||
if ($1) delete $1;
|
|
||||||
}
|
}
|
||||||
| attribute_list_opt K_integer register_variable_list ';'
|
| K_integer register_variable_list ';'
|
||||||
{ pform_set_reg_integer($3);
|
{ pform_set_reg_integer($2);
|
||||||
if ($1) delete $1;
|
|
||||||
}
|
}
|
||||||
| K_time register_variable_list ';'
|
| K_time register_variable_list ';'
|
||||||
{ pform_set_reg_time($2);
|
{ pform_set_reg_time($2);
|
||||||
|
|
@ -335,15 +333,13 @@ block_item_decl
|
||||||
/* Recover from errors that happen within variable lists. Use the
|
/* Recover from errors that happen within variable lists. Use the
|
||||||
trailing semi-colon to resync the parser. */
|
trailing semi-colon to resync the parser. */
|
||||||
|
|
||||||
| attribute_list_opt K_reg error ';'
|
| K_reg error ';'
|
||||||
{ yyerror(@2, "error: syntax error in reg variable list.");
|
{ yyerror(@1, "error: syntax error in reg variable list.");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
if ($1) delete $1;
|
|
||||||
}
|
}
|
||||||
| attribute_list_opt K_integer error ';'
|
| K_integer error ';'
|
||||||
{ yyerror(@2, "error: syntax error in integer variable list.");
|
{ yyerror(@1, "error: syntax error in integer variable list.");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
if ($1) delete $1;
|
|
||||||
}
|
}
|
||||||
| K_time error ';'
|
| K_time error ';'
|
||||||
{ yyerror(@1, "error: syntax error in time variable list.");
|
{ yyerror(@1, "error: syntax error in time variable list.");
|
||||||
|
|
@ -882,6 +878,30 @@ expression
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
expr_mintypmax
|
||||||
|
: expression
|
||||||
|
{ $$ = $1; }
|
||||||
|
| expression ':' expression ':' expression
|
||||||
|
{ switch (min_typ_max_flag) {
|
||||||
|
case MIN:
|
||||||
|
$$ = $1;
|
||||||
|
delete $3;
|
||||||
|
delete $5;
|
||||||
|
break;
|
||||||
|
case TYP:
|
||||||
|
delete $1;
|
||||||
|
$$ = $3;
|
||||||
|
delete $5;
|
||||||
|
break;
|
||||||
|
case MAX:
|
||||||
|
delete $1;
|
||||||
|
delete $3;
|
||||||
|
$$ = $5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/* Many contexts take a comma separated list of expressions. Null
|
/* Many contexts take a comma separated list of expressions. Null
|
||||||
expressions can happen anywhere in the list, so there are two
|
expressions can happen anywhere in the list, so there are two
|
||||||
|
|
@ -910,6 +930,19 @@ expression_list
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
expression_list_proper
|
||||||
|
: expression_list_proper ',' expression
|
||||||
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, $3);
|
||||||
|
delete $1;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| expression
|
||||||
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
||||||
|
(*tmp)[0] = $1;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
expr_primary
|
expr_primary
|
||||||
: number
|
: number
|
||||||
|
|
@ -975,12 +1008,20 @@ expr_primary
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| '(' expression ')'
|
| '(' expr_mintypmax ')'
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
| '{' expression_list '}'
|
| '{' expression_list '}'
|
||||||
{ PEConcat*tmp = new PEConcat(*$2);
|
{ PEConcat*tmp = new PEConcat(*$2);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
|
for (unsigned idx = 0 ; idx < (*$2).count() ; idx += 1) {
|
||||||
|
PExpr*ex = (*$2)[idx];
|
||||||
|
if (ex == 0) {
|
||||||
|
yyerror(@1, "error: Null arguments not allowed"
|
||||||
|
" in repeat expressions.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -990,7 +1031,6 @@ expr_primary
|
||||||
yyerror(@2, "error: Repeat expression "
|
yyerror(@2, "error: Repeat expression "
|
||||||
"must be constant.");
|
"must be constant.");
|
||||||
delete rep;
|
delete rep;
|
||||||
delete $2;
|
|
||||||
rep = 0;
|
rep = 0;
|
||||||
}
|
}
|
||||||
PEConcat*tmp = new PEConcat(*$4, rep);
|
PEConcat*tmp = new PEConcat(*$4, rep);
|
||||||
|
|
@ -1028,6 +1068,14 @@ function_item
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
yyerror(@1, "Functions may not have output ports.");
|
yyerror(@1, "Functions may not have output ports.");
|
||||||
}
|
}
|
||||||
|
| K_output K_signed range_opt list_of_identifiers ';'
|
||||||
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINPUT, true,
|
||||||
|
$3, $4,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
yyerror(@1, "Functions may not have output ports.");
|
||||||
|
}
|
||||||
| K_inout range_opt list_of_identifiers ';'
|
| K_inout range_opt list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINPUT, false,
|
= pform_make_task_ports(NetNet::PINPUT, false,
|
||||||
|
|
@ -1036,7 +1084,15 @@ function_item
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
yyerror(@1, "Functions may not have inout ports.");
|
yyerror(@1, "Functions may not have inout ports.");
|
||||||
}
|
}
|
||||||
| block_item_decl
|
| K_inout K_signed range_opt list_of_identifiers ';'
|
||||||
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINPUT, true,
|
||||||
|
$3, $4,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
yyerror(@1, "Functions may not have inout ports.");
|
||||||
|
}
|
||||||
|
| attribute_list_opt block_item_decl
|
||||||
{ $$ = 0; }
|
{ $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -1583,7 +1639,8 @@ module_item
|
||||||
/* block_item_decl rule is shared with task blocks and named
|
/* block_item_decl rule is shared with task blocks and named
|
||||||
begin/end. */
|
begin/end. */
|
||||||
|
|
||||||
| block_item_decl
|
| attribute_list_opt block_item_decl
|
||||||
|
{ ; }
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
|
@ -2265,8 +2322,11 @@ specify_item
|
||||||
| K_if '(' expression ')' specify_edge_path_decl ';'
|
| K_if '(' expression ')' specify_edge_path_decl ';'
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
| K_ifnone specify_simple_path_decl ';'
|
||||||
|
{
|
||||||
|
}
|
||||||
| K_Shold '(' spec_reference_event ',' spec_reference_event
|
| K_Shold '(' spec_reference_event ',' spec_reference_event
|
||||||
',' expression spec_notifier_opt ')' ';'
|
',' delay_value spec_notifier_opt ')' ';'
|
||||||
{ delete $7;
|
{ delete $7;
|
||||||
}
|
}
|
||||||
| K_Speriod '(' spec_reference_event ',' delay_value
|
| K_Speriod '(' spec_reference_event ',' delay_value
|
||||||
|
|
@ -2274,11 +2334,11 @@ specify_item
|
||||||
{ delete $5;
|
{ delete $5;
|
||||||
}
|
}
|
||||||
| K_Srecovery '(' spec_reference_event ',' spec_reference_event
|
| K_Srecovery '(' spec_reference_event ',' spec_reference_event
|
||||||
',' expression spec_notifier_opt ')' ';'
|
',' delay_value spec_notifier_opt ')' ';'
|
||||||
{ delete $7;
|
{ delete $7;
|
||||||
}
|
}
|
||||||
| K_Ssetup '(' spec_reference_event ',' spec_reference_event
|
| K_Ssetup '(' spec_reference_event ',' spec_reference_event
|
||||||
',' expression spec_notifier_opt ')' ';'
|
',' delay_value spec_notifier_opt ')' ';'
|
||||||
{ delete $7;
|
{ delete $7;
|
||||||
}
|
}
|
||||||
| K_Ssetuphold '(' spec_reference_event ',' spec_reference_event
|
| K_Ssetuphold '(' spec_reference_event ',' spec_reference_event
|
||||||
|
|
@ -2296,14 +2356,18 @@ specify_item
|
||||||
{ delete $5;
|
{ delete $5;
|
||||||
delete $7;
|
delete $7;
|
||||||
}
|
}
|
||||||
| K_Swidth '(' spec_reference_event ',' expression ')' ';'
|
| K_Swidth '(' spec_reference_event ',' delay_value ')' ';'
|
||||||
{ delete $5;
|
{ delete $5;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
specify_delay_value_list
|
specify_delay_value_list
|
||||||
: delay_value { }
|
: delay_value
|
||||||
| specify_delay_value_list ',' delay_value { }
|
{ delete $1;
|
||||||
|
}
|
||||||
|
| specify_delay_value_list ',' delay_value
|
||||||
|
{ delete $3;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
specify_item_list
|
specify_item_list
|
||||||
|
|
@ -2316,15 +2380,19 @@ specify_edge_path_decl
|
||||||
| specify_edge_path '=' delay_value_simple
|
| specify_edge_path '=' delay_value_simple
|
||||||
;
|
;
|
||||||
|
|
||||||
|
specify_edge_operator
|
||||||
|
: K_posedge
|
||||||
|
| K_negedge
|
||||||
|
;
|
||||||
|
|
||||||
|
/* The first two rules are not in development. */
|
||||||
specify_edge_path
|
specify_edge_path
|
||||||
: '(' K_posedge specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
|
: '(' specify_edge_operator specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
|
||||||
| '(' K_posedge specify_path_identifiers spec_polarity K_EG '(' expr_primary polarity_operator expression ')' ')'
|
| '(' specify_edge_operator specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
|
||||||
| '(' K_posedge specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
|
| '(' specify_path_identifiers spec_polarity K_EG '(' specify_path_identifiers polarity_operator expression ')' ')'
|
||||||
| '(' K_posedge specify_path_identifiers spec_polarity K_SG '(' expr_primary polarity_operator expression ')' ')'
|
| '(' specify_edge_operator specify_path_identifiers spec_polarity K_EG '(' specify_path_identifiers polarity_operator expression ')' ')'
|
||||||
| '(' K_negedge specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
|
| '(' specify_path_identifiers spec_polarity K_SG '(' specify_path_identifiers polarity_operator expression ')' ')'
|
||||||
| '(' K_negedge specify_path_identifiers spec_polarity K_EG '(' expr_primary polarity_operator expression ')' ')'
|
| '(' specify_edge_operator specify_path_identifiers spec_polarity K_SG '(' specify_path_identifiers polarity_operator expression ')' ')'
|
||||||
| '(' K_negedge specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
|
|
||||||
| '(' K_negedge specify_path_identifiers spec_polarity K_SG '(' expr_primary polarity_operator expression ')' ')'
|
|
||||||
;
|
;
|
||||||
|
|
||||||
polarity_operator
|
polarity_operator
|
||||||
|
|
@ -2436,6 +2504,12 @@ spec_reference_event
|
||||||
{ delete $2;
|
{ delete $2;
|
||||||
delete $4;
|
delete $4;
|
||||||
}
|
}
|
||||||
|
| K_edge '[' edge_descriptor_list ']' expr_primary
|
||||||
|
{ delete $5; }
|
||||||
|
| K_edge '[' edge_descriptor_list ']' expr_primary K_TAND expression
|
||||||
|
{ delete $5;
|
||||||
|
delete $7;
|
||||||
|
}
|
||||||
| expr_primary K_TAND expression
|
| expr_primary K_TAND expression
|
||||||
{ delete $1;
|
{ delete $1;
|
||||||
delete $3;
|
delete $3;
|
||||||
|
|
@ -2444,6 +2518,11 @@ spec_reference_event
|
||||||
{ delete $1; }
|
{ delete $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
edge_descriptor_list
|
||||||
|
: edge_descriptor_list ',' K_edge_descriptor
|
||||||
|
| K_edge_descriptor
|
||||||
|
;
|
||||||
|
|
||||||
spec_notifier_opt
|
spec_notifier_opt
|
||||||
: /* empty */
|
: /* empty */
|
||||||
{ }
|
{ }
|
||||||
|
|
@ -2458,7 +2537,10 @@ spec_notifier
|
||||||
| spec_notifier ','
|
| spec_notifier ','
|
||||||
{ }
|
{ }
|
||||||
| spec_notifier ',' identifier
|
| spec_notifier ',' identifier
|
||||||
{ delete $3;
|
{ delete $3; }
|
||||||
|
| spec_notifier ',' identifier '[' expr_primary ']'
|
||||||
|
{ delete $3;
|
||||||
|
delete $5;
|
||||||
}
|
}
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{ delete $1; }
|
{ delete $1; }
|
||||||
|
|
@ -2541,9 +2623,9 @@ statement
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_begin error K_end
|
/* | K_begin error K_end
|
||||||
{ yyerrok; }
|
{ yyerrok; }
|
||||||
|
*/
|
||||||
/* fork-join blocks are very similar to begin-end blocks. In fact,
|
/* fork-join blocks are very similar to begin-end blocks. In fact,
|
||||||
from the parser's perspective there is no real difference. All we
|
from the parser's perspective there is no real difference. All we
|
||||||
need to do is remember that this is a parallel block so that the
|
need to do is remember that this is a parallel block so that the
|
||||||
|
|
@ -2690,28 +2772,34 @@ statement
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| event_control statement_opt
|
| event_control attribute_list_opt statement_opt
|
||||||
{ PEventStatement*tmp = $1;
|
{ PEventStatement*tmp = $1;
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
yyerror(@1, "error: Invalid event control.");
|
yyerror(@1, "error: Invalid event control.");
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
} else {
|
} else {
|
||||||
tmp->set_statement($2);
|
pform_attach_attributes($3, $2);
|
||||||
|
tmp->set_statement($3);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
if ($2) delete $2;
|
||||||
}
|
}
|
||||||
| '@' '*' statement_opt
|
| '@' '*' attribute_list_opt statement_opt
|
||||||
{ PEventStatement*tmp = new PEventStatement;
|
{ PEventStatement*tmp = new PEventStatement;
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
tmp->set_statement($3);
|
pform_attach_attributes($4, $3);
|
||||||
|
tmp->set_statement($4);
|
||||||
|
if ($3) delete $3;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| '@' '(' '*' ')' statement_opt
|
| '@' '(' '*' ')' attribute_list_opt statement_opt
|
||||||
{ PEventStatement*tmp = new PEventStatement;
|
{ PEventStatement*tmp = new PEventStatement;
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
tmp->set_statement($5);
|
pform_attach_attributes($6, $5);
|
||||||
|
tmp->set_statement($6);
|
||||||
|
if ($5) delete $5;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| lpvalue '=' expression ';'
|
| lpvalue '=' expression ';'
|
||||||
|
|
@ -2796,7 +2884,7 @@ statement
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| identifier '(' expression_list ')' ';'
|
| identifier '(' expression_list_proper ')' ';'
|
||||||
{ PCallTask*tmp = new PCallTask(*$1, *$3);
|
{ PCallTask*tmp = new PCallTask(*$1, *$3);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
|
|
@ -2804,6 +2892,19 @@ statement
|
||||||
delete $3;
|
delete $3;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTE: The standard doesn't really support an empty argument list
|
||||||
|
between parentheses, but it seems natural, and people commonly
|
||||||
|
want it. So accept it explicitly. */
|
||||||
|
|
||||||
|
| identifier '(' ')' ';'
|
||||||
|
{ svector<PExpr*>pt (0);
|
||||||
|
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||||
|
tmp->set_file(@1.text);
|
||||||
|
tmp->set_lineno(@1.first_line);
|
||||||
|
delete $1;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| identifier ';'
|
| identifier ';'
|
||||||
{ svector<PExpr*>pt (0);
|
{ svector<PExpr*>pt (0);
|
||||||
PCallTask*tmp = new PCallTask(*$1, pt);
|
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||||
|
|
@ -2820,14 +2921,18 @@ statement
|
||||||
;
|
;
|
||||||
|
|
||||||
statement_list
|
statement_list
|
||||||
: statement_list statement
|
: statement_list attribute_list_opt statement
|
||||||
{ svector<Statement*>*tmp = new svector<Statement*>(*$1, $2);
|
{ pform_attach_attributes($3, $2);
|
||||||
|
svector<Statement*>*tmp = new svector<Statement*>(*$1, $3);
|
||||||
delete $1;
|
delete $1;
|
||||||
|
if ($2) delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| statement
|
| attribute_list_opt statement
|
||||||
{ svector<Statement*>*tmp = new svector<Statement*>(1);
|
{ pform_attach_attributes($2, $1);
|
||||||
(*tmp)[0] = $1;
|
svector<Statement*>*tmp = new svector<Statement*>(1);
|
||||||
|
(*tmp)[0] = $2;
|
||||||
|
if ($1) delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -2848,6 +2953,13 @@ task_item
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| K_input K_signed range_opt list_of_identifiers ';'
|
||||||
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINPUT, true,
|
||||||
|
$3, $4,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| K_output range_opt list_of_identifiers ';'
|
| K_output range_opt list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::POUTPUT, false,
|
= pform_make_task_ports(NetNet::POUTPUT, false,
|
||||||
|
|
@ -2855,6 +2967,13 @@ task_item
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| K_output K_signed range_opt list_of_identifiers ';'
|
||||||
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::POUTPUT, true,
|
||||||
|
$3, $4,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| K_inout range_opt list_of_identifiers ';'
|
| K_inout range_opt list_of_identifiers ';'
|
||||||
{ svector<PWire*>*tmp
|
{ svector<PWire*>*tmp
|
||||||
= pform_make_task_ports(NetNet::PINOUT, false,
|
= pform_make_task_ports(NetNet::PINOUT, false,
|
||||||
|
|
@ -2862,6 +2981,13 @@ task_item
|
||||||
@1.text, @1.first_line);
|
@1.text, @1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| K_inout K_signed range_opt list_of_identifiers ';'
|
||||||
|
{ svector<PWire*>*tmp
|
||||||
|
= pform_make_task_ports(NetNet::PINOUT, true,
|
||||||
|
$3, $4,
|
||||||
|
@1.text, @1.first_line);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
task_item_list
|
task_item_list
|
||||||
|
|
|
||||||
11
parse_api.h
11
parse_api.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: parse_api.h,v 1.3 2004/02/18 17:11:57 steve Exp $"
|
#ident "$Id: parse_api.h,v 1.3.2.1 2005/08/13 00:45:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
@ -35,8 +35,8 @@ class PUdp;
|
||||||
* Verilog source into pform for elaboration. The parser adds modules
|
* Verilog source into pform for elaboration. The parser adds modules
|
||||||
* to these maps as it compiles modules in the verilog source.
|
* to these maps as it compiles modules in the verilog source.
|
||||||
*/
|
*/
|
||||||
extern map<perm_string,Module*> pform_modules;
|
extern std::map<perm_string,Module*> pform_modules;
|
||||||
extern map<perm_string,PUdp*> pform_primitives;
|
extern std::map<perm_string,PUdp*> pform_primitives;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code actually invokes the parser to make modules. The first
|
* This code actually invokes the parser to make modules. The first
|
||||||
|
|
@ -47,10 +47,13 @@ extern map<perm_string,PUdp*> pform_primitives;
|
||||||
*/
|
*/
|
||||||
extern int pform_parse(const char*path, FILE*file =0);
|
extern int pform_parse(const char*path, FILE*file =0);
|
||||||
|
|
||||||
extern string vl_file;
|
extern std::string vl_file;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: parse_api.h,v $
|
* $Log: parse_api.h,v $
|
||||||
|
* Revision 1.3.2.1 2005/08/13 00:45:54 steve
|
||||||
|
* Fix compilation warnings/errors with newer compilers.
|
||||||
|
*
|
||||||
* Revision 1.3 2004/02/18 17:11:57 steve
|
* Revision 1.3 2004/02/18 17:11:57 steve
|
||||||
* Use perm_strings for named langiage items.
|
* Use perm_strings for named langiage items.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
18
pform.cc
18
pform.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform.cc,v 1.129 2004/10/04 01:10:55 steve Exp $"
|
#ident "$Id: pform.cc,v 1.129.2.1 2006/07/10 00:21:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -203,6 +203,19 @@ verinum* pform_verinum_with_size(verinum*siz, verinum*val,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pform_attach_attributes(Statement*obj, svector<named_pexpr_t*>*attr)
|
||||||
|
{
|
||||||
|
if (obj == 0)
|
||||||
|
return;
|
||||||
|
if (attr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
|
||||||
|
named_pexpr_t*tmp = (*attr)[idx];
|
||||||
|
obj->attributes[tmp->name] = tmp->parm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pform_startmodule(const char*name, const char*file, unsigned lineno,
|
void pform_startmodule(const char*name, const char*file, unsigned lineno,
|
||||||
svector<named_pexpr_t*>*attr)
|
svector<named_pexpr_t*>*attr)
|
||||||
{
|
{
|
||||||
|
|
@ -1597,6 +1610,9 @@ int pform_parse(const char*path, FILE*file)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.cc,v $
|
* $Log: pform.cc,v $
|
||||||
|
* Revision 1.129.2.1 2006/07/10 00:21:53 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
* Revision 1.129 2004/10/04 01:10:55 steve
|
* Revision 1.129 2004/10/04 01:10:55 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
9
pform.h
9
pform.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform.h,v 1.81 2004/08/26 04:02:04 steve Exp $"
|
#ident "$Id: pform.h,v 1.81.2.1 2006/07/10 00:21:53 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -37,6 +37,8 @@
|
||||||
# include <string>
|
# include <string>
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
# include <cstring>
|
||||||
|
# include <cstdlib>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These classes implement the parsed form (P-form for short) of the
|
* These classes implement the parsed form (P-form for short) of the
|
||||||
|
|
@ -219,6 +221,8 @@ extern void pform_set_attrib(perm_string name, perm_string key,
|
||||||
extern void pform_set_type_attrib(perm_string name, const string&key,
|
extern void pform_set_type_attrib(perm_string name, const string&key,
|
||||||
char*value);
|
char*value);
|
||||||
|
|
||||||
|
extern void pform_attach_attributes(Statement*obj, svector<named_pexpr_t*>*attr);
|
||||||
|
|
||||||
extern void pform_set_parameter(perm_string name,
|
extern void pform_set_parameter(perm_string name,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
|
|
@ -298,6 +302,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform.h,v $
|
* $Log: pform.h,v $
|
||||||
|
* Revision 1.81.2.1 2006/07/10 00:21:53 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
* Revision 1.81 2004/08/26 04:02:04 steve
|
* Revision 1.81 2004/08/26 04:02:04 steve
|
||||||
* Add support for localparam ranges.
|
* Add support for localparam ranges.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform_dump.cc,v 1.88 2004/10/04 01:10:55 steve Exp $"
|
#ident "$Id: pform_dump.cc,v 1.88.2.1 2006/07/10 00:21:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -360,10 +360,14 @@ void PGModule::dump(ostream&out) const
|
||||||
out << " " << type_ << " ";
|
out << " " << type_ << " ";
|
||||||
|
|
||||||
// If parameters are overridden by order, dump them.
|
// If parameters are overridden by order, dump them.
|
||||||
if (overrides_) {
|
if (overrides_ && overrides_->count() > 0) {
|
||||||
assert(parms_ == 0);
|
assert(parms_ == 0);
|
||||||
out << "#(";
|
out << "#(";
|
||||||
out << *((*overrides_)[0]);
|
|
||||||
|
if ((*overrides_)[0] == 0)
|
||||||
|
out << "<nil>";
|
||||||
|
else
|
||||||
|
out << *((*overrides_)[0]);
|
||||||
for (unsigned idx = 1 ; idx < overrides_->count() ; idx += 1) {
|
for (unsigned idx = 1 ; idx < overrides_->count() ; idx += 1) {
|
||||||
out << "," << *((*overrides_)[idx]);
|
out << "," << *((*overrides_)[idx]);
|
||||||
}
|
}
|
||||||
|
|
@ -418,6 +422,19 @@ void Statement::dump(ostream&out, unsigned ind) const
|
||||||
out << setw(ind) << "";
|
out << setw(ind) << "";
|
||||||
out << "/* " << get_line() << ": " << typeid(*this).name()
|
out << "/* " << get_line() << ": " << typeid(*this).name()
|
||||||
<< " */ ;" << endl;
|
<< " */ ;" << endl;
|
||||||
|
dump_attributes(out, ind+2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::dump_attributes(ostream&out, unsigned ind) const
|
||||||
|
{
|
||||||
|
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
|
||||||
|
; idx != attributes.end()
|
||||||
|
; idx ++) {
|
||||||
|
out << setw(ind) << "" << "(* " << (*idx).first;
|
||||||
|
if ((*idx).second)
|
||||||
|
out << " = " << *(*idx).second;
|
||||||
|
out << " *)" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PAssign::dump(ostream&out, unsigned ind) const
|
void PAssign::dump(ostream&out, unsigned ind) const
|
||||||
|
|
@ -487,6 +504,8 @@ void PCase::dump(ostream&out, unsigned ind) const
|
||||||
}
|
}
|
||||||
out << " (" << *expr_ << ") /* " << get_line() << " */" << endl;
|
out << " (" << *expr_ << ") /* " << get_line() << " */" << endl;
|
||||||
|
|
||||||
|
dump_attributes(out, ind+2);
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
|
||||||
PCase::Item*cur = (*items_)[idx];
|
PCase::Item*cur = (*items_)[idx];
|
||||||
|
|
||||||
|
|
@ -909,6 +928,9 @@ void PUdp::dump(ostream&out) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform_dump.cc,v $
|
* $Log: pform_dump.cc,v $
|
||||||
|
* Revision 1.88.2.1 2006/07/10 00:21:54 steve
|
||||||
|
* Add support for full_case attribute.
|
||||||
|
*
|
||||||
* Revision 1.88 2004/10/04 01:10:55 steve
|
* Revision 1.88 2004/10/04 01:10:55 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
# This is a debug conf file that the scripts/devel-stub.sh script uses
|
||||||
|
# to control the ivl core. The contents of this file are normally written
|
||||||
|
# to a temporary file by the driver program, but for devel purposes, where
|
||||||
|
# the driver program is not used, this config substitutes.
|
||||||
|
#
|
||||||
|
# NOTE: DO NOT INSTALL THIS FILE!
|
||||||
|
#
|
||||||
|
iwidth:32
|
||||||
|
sys_func:vpi/system.sft
|
||||||
|
warnings:implicit
|
||||||
|
debug:eval_tree
|
||||||
|
debug:elaborate
|
||||||
|
debug:scope
|
||||||
|
debug:synth
|
||||||
|
debug:cprop
|
||||||
|
out:a.out
|
||||||
|
ivlpp:./ivlpp/ivlpp -D__ICARUS__ -L -Pfoo.pp
|
||||||
|
sys_func:scripts/devel-stub.sft
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
# This is an example function table.
|
||||||
|
$realtime vpiSysFuncReal
|
||||||
|
|
||||||
|
$verywide vpiSysFuncSized 128 signed
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
# This is a little developer convenience script to run the ivl core program
|
||||||
|
# in place with the stub target. It runs the ivl core verbose, with diagnostic
|
||||||
|
# output files enable, and without the driver program or preprocessor.
|
||||||
|
# It is useful only for development of the ivl core program.
|
||||||
|
#
|
||||||
|
# Run this script in the source directory for the ivl core program so that
|
||||||
|
# the patch to the other components is correct.
|
||||||
|
#
|
||||||
|
# NOTE: DO NOT INSTALL THIS FILE.
|
||||||
|
|
||||||
|
./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl
|
||||||
|
|
||||||
|
echo "*** ivl command completed, rc=$?"
|
||||||
14
set_width.cc
14
set_width.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: set_width.cc,v 1.34 2003/08/28 04:11:19 steve Exp $"
|
#ident "$Id: set_width.cc,v 1.34.2.1 2005/03/05 01:36:16 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -167,12 +167,13 @@ bool NetEBDiv::set_width(unsigned w)
|
||||||
return w == expr_width();
|
return w == expr_width();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The logical binary operators do not care what the widths of their
|
||||||
|
* operands are, the output is always 1 bit. The operands are
|
||||||
|
* self-determined, so a set_width is stopped here.
|
||||||
|
*/
|
||||||
bool NetEBLogic::set_width(unsigned w)
|
bool NetEBLogic::set_width(unsigned w)
|
||||||
{
|
{
|
||||||
bool flag;
|
|
||||||
flag = left_->set_width(right_->expr_width());
|
|
||||||
if (!flag)
|
|
||||||
flag = right_->set_width(left_->expr_width());
|
|
||||||
return (w == 1);
|
return (w == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,6 +412,9 @@ bool NetEUReduce::set_width(unsigned w)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: set_width.cc,v $
|
* $Log: set_width.cc,v $
|
||||||
|
* Revision 1.34.2.1 2005/03/05 01:36:16 steve
|
||||||
|
* Fix set_width to allow binary logical operands to be self determined.
|
||||||
|
*
|
||||||
* Revision 1.34 2003/08/28 04:11:19 steve
|
* Revision 1.34 2003/08/28 04:11:19 steve
|
||||||
* Spelling patch.
|
* Spelling patch.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# $Id: README-solaris_pkg.txt,v 1.2 2004/10/04 01:10:56 steve Exp $
|
# $Id: README-solaris_pkg.txt,v 1.2.2.1 2007/02/26 19:51:39 steve Exp $
|
||||||
|
|
||||||
Notes about the solaris package.
|
Notes about the solaris package.
|
||||||
|
|
||||||
I. Installing a prebuild solaris package
|
I. Installing a prebuilt solaris package
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
To install the solaris package do the following as root on your machine:
|
To install the solaris package do the following as root on your machine:
|
||||||
|
|
@ -24,10 +24,10 @@ To install the solaris package do the following as root on your machine:
|
||||||
this will install the package. The package will be registered under the
|
this will install the package. The package will be registered under the
|
||||||
name "IVLver"
|
name "IVLver"
|
||||||
|
|
||||||
II. Deinstalling the solaris package
|
II. Uninstalling the solaris package
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
To deinstall an installed solaris package do the following as root on your machine:
|
To uninstall an installed solaris package do the following as root on your machine:
|
||||||
|
|
||||||
pkgrm IVLver
|
pkgrm IVLver
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
PKG="IVLver"
|
PKG="IVLver"
|
||||||
NAME="verilog"
|
NAME="verilog"
|
||||||
ARCH="sparc"
|
ARCH="sparc"
|
||||||
VERSION="0.7"
|
VERSION="0.8"
|
||||||
CATEGORY="application"
|
CATEGORY="application"
|
||||||
VENDOR="Icarus.com"
|
VENDOR="Icarus.com"
|
||||||
EMAIL="steve@icarus.com"
|
EMAIL="steve@icarus.com"
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ f none bin/iverilog 0755 bin bin
|
||||||
f none bin/iverilog-vpi 0755 bin bin
|
f none bin/iverilog-vpi 0755 bin bin
|
||||||
f none bin/vvp 0755 bin bin
|
f none bin/vvp 0755 bin bin
|
||||||
d none include 0755 bin bin
|
d none include 0755 bin bin
|
||||||
|
f none include/_pli_types.h 0644 bin bin
|
||||||
f none include/acc_user.h 0644 bin bin
|
f none include/acc_user.h 0644 bin bin
|
||||||
f none include/ivl_target.h 0644 bin bin
|
f none include/ivl_target.h 0644 bin bin
|
||||||
f none include/veriuser.h 0644 bin bin
|
f none include/veriuser.h 0644 bin bin
|
||||||
|
|
@ -11,12 +12,21 @@ f none include/vpi_user.h 0644 bin bin
|
||||||
d none lib 0755 bin bin
|
d none lib 0755 bin bin
|
||||||
d none lib/ivl 0755 bin bin
|
d none lib/ivl 0755 bin bin
|
||||||
f none lib/ivl/fpga.tgt 0644 bin bin
|
f none lib/ivl/fpga.tgt 0644 bin bin
|
||||||
|
f none lib/ivl/fpga.conf 0644 bin bin
|
||||||
|
f none lib/ivl/fpga-s.conf 0644 bin bin
|
||||||
f none lib/ivl/iverilog.conf 0644 bin bin
|
f none lib/ivl/iverilog.conf 0644 bin bin
|
||||||
f none lib/ivl/ivl 0755 bin bin
|
f none lib/ivl/ivl 0755 bin bin
|
||||||
f none lib/ivl/ivlpp 0755 bin bin
|
f none lib/ivl/ivlpp 0755 bin bin
|
||||||
f none lib/ivl/null.tgt 0644 bin bin
|
f none lib/ivl/null.tgt 0644 bin bin
|
||||||
|
f none lib/ivl/null.conf 0644 bin bin
|
||||||
|
f none lib/ivl/null-s.conf 0644 bin bin
|
||||||
f none lib/ivl/system.vpi 0644 bin bin
|
f none lib/ivl/system.vpi 0644 bin bin
|
||||||
|
f none lib/ivl/system.sft 0644 bin bin
|
||||||
f none lib/ivl/vvp.tgt 0644 bin bin
|
f none lib/ivl/vvp.tgt 0644 bin bin
|
||||||
|
f none lib/ivl/vvp.conf 0644 bin bin
|
||||||
|
f none lib/ivl/vvp-s.conf 0644 bin bin
|
||||||
|
f none lib/ivl/xnf.conf 0644 bin bin
|
||||||
|
f none lib/ivl/xnf-s.conf 0644 bin bin
|
||||||
f none lib/libveriuser.a 0644 bin bin
|
f none lib/libveriuser.a 0644 bin bin
|
||||||
f none lib/libvpi.a 0644 bin bin
|
f none lib/libvpi.a 0644 bin bin
|
||||||
d none man 0755 bin bin
|
d none man 0755 bin bin
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: svector.h,v 1.9 2003/07/23 02:35:44 steve Exp $"
|
#ident "$Id: svector.h,v 1.9.2.1 2005/06/14 15:33:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -101,14 +101,17 @@ template <class TYPE> class svector {
|
||||||
* Override the implementation of the above template for the string
|
* Override the implementation of the above template for the string
|
||||||
* type parameter. The initialization to nil works different here.
|
* type parameter. The initialization to nil works different here.
|
||||||
*/
|
*/
|
||||||
inline svector<string>::svector<string>(unsigned size)
|
template <> inline svector<std::string>::svector(unsigned size)
|
||||||
: nitems_(size), items_(new string[size])
|
: nitems_(size), items_(new std::string[size])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: svector.h,v $
|
* $Log: svector.h,v $
|
||||||
|
* Revision 1.9.2.1 2005/06/14 15:33:54 steve
|
||||||
|
* Fix gcc4 build issues.
|
||||||
|
*
|
||||||
* Revision 1.9 2003/07/23 02:35:44 steve
|
* Revision 1.9 2003/07/23 02:35:44 steve
|
||||||
* Inline the svector<string> constructor.
|
* Inline the svector<string> constructor.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
7
sync.cc
7
sync.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: sync.cc,v 1.3 2002/09/24 00:58:35 steve Exp $"
|
#ident "$Id: sync.cc,v 1.3.2.1 2007/05/30 17:48:54 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -57,7 +57,7 @@ bool NetEvWait::is_synchronous()
|
||||||
return true; //statement_->is_asynchronous();
|
return true; //statement_->is_asynchronous();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetProcTop::is_synchronous()
|
bool NetProcTop::is_synchronous() const
|
||||||
{
|
{
|
||||||
if (type_ == NetProcTop::KINITIAL)
|
if (type_ == NetProcTop::KINITIAL)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -67,6 +67,9 @@ bool NetProcTop::is_synchronous()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: sync.cc,v $
|
* $Log: sync.cc,v $
|
||||||
|
* Revision 1.3.2.1 2007/05/30 17:48:54 steve
|
||||||
|
* Support Latch synthesis (Alan Feldstein)
|
||||||
|
*
|
||||||
* Revision 1.3 2002/09/24 00:58:35 steve
|
* Revision 1.3 2002/09/24 00:58:35 steve
|
||||||
* More detailed check of process edge events.
|
* More detailed check of process edge events.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
# include <cstdlib>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Manage the information about system functions. This information is
|
* Manage the information about system functions. This information is
|
||||||
|
|
|
||||||
139
t-dll-api.cc
139
t-dll-api.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: t-dll-api.cc,v 1.108 2004/10/04 01:10:55 steve Exp $"
|
#ident "$Id: t-dll-api.cc,v 1.108.2.5 2006/04/16 19:26:40 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -28,6 +28,9 @@
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
using std::invalid_argument;
|
||||||
|
|
||||||
/* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
|
/* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
|
||||||
|
|
||||||
extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key)
|
extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key)
|
||||||
|
|
@ -481,6 +484,7 @@ extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
return 0UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -620,6 +624,19 @@ extern "C" const char* ivl_udp_name(ivl_udp_t net)
|
||||||
return net->name;
|
return net->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" unsigned ivl_lpm_attr_cnt(ivl_lpm_t net)
|
||||||
|
{
|
||||||
|
return net->nattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" ivl_attribute_t ivl_lpm_attr_val(ivl_lpm_t net, unsigned idx)
|
||||||
|
{
|
||||||
|
if (idx >= net->nattr)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return net->attr + idx;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" const char* ivl_lpm_basename(ivl_lpm_t net)
|
extern "C" const char* ivl_lpm_basename(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
return net->name;
|
return net->name;
|
||||||
|
|
@ -686,6 +703,21 @@ extern "C" ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" ivl_nexus_t ivl_lpm_gate( ivl_lpm_t netPtr )
|
||||||
|
{
|
||||||
|
assert( netPtr );
|
||||||
|
|
||||||
|
switch ( netPtr->type )
|
||||||
|
{
|
||||||
|
case IVL_LPM_LATCH:
|
||||||
|
return netPtr->u_.latch.gatePtr;
|
||||||
|
default:
|
||||||
|
assert( false );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net)
|
extern "C" ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
assert(net);
|
assert(net);
|
||||||
|
|
@ -752,6 +784,10 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
||||||
assert(idx < net->u_.arith.width);
|
assert(idx < net->u_.arith.width);
|
||||||
return net->u_.arith.a[idx];
|
return net->u_.arith.a[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
assert(idx < net->u_.demux.width);
|
||||||
|
return net->u_.demux.d[idx];
|
||||||
|
|
||||||
case IVL_LPM_SHIFTL:
|
case IVL_LPM_SHIFTL:
|
||||||
case IVL_LPM_SHIFTR:
|
case IVL_LPM_SHIFTR:
|
||||||
assert(idx < net->u_.shift.width);
|
assert(idx < net->u_.shift.width);
|
||||||
|
|
@ -765,6 +801,20 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
||||||
else
|
else
|
||||||
return net->u_.ff.d.pins[idx];
|
return net->u_.ff.d.pins[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_LATCH:
|
||||||
|
|
||||||
|
if( idx >= net->u_.latch.width )
|
||||||
|
{
|
||||||
|
throw invalid_argument( "idx too high" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( net->u_.latch.width != 1U )
|
||||||
|
{
|
||||||
|
throw invalid_argument( "Only 1-wide latches are currently supported." );
|
||||||
|
}
|
||||||
|
|
||||||
|
return net->u_.latch.dataPtr;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -788,6 +838,10 @@ extern "C" ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx)
|
||||||
assert(idx < net->u_.arith.width);
|
assert(idx < net->u_.arith.width);
|
||||||
return net->u_.arith.b[idx];
|
return net->u_.arith.b[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
assert(idx < net->u_.demux.width/net->u_.demux.size);
|
||||||
|
return net->u_.demux.bit_in[idx];
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -813,6 +867,22 @@ extern "C" ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx)
|
||||||
return net->u_.ufunc.pins[base+idx];
|
return net->u_.ufunc.pins[base+idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case IVL_LPM_RAM:
|
||||||
|
if (net->u_.ff.a.mem == 0) {
|
||||||
|
// This is an exploded RAM, so we use sdx and idx
|
||||||
|
// to address a nexa into the exploded ram.
|
||||||
|
if (sdx >= net->u_.ff.scnt)
|
||||||
|
return 0;
|
||||||
|
if (idx >= net->u_.ff.width)
|
||||||
|
return 0;
|
||||||
|
unsigned adr = sdx * net->u_.ff.width + idx;
|
||||||
|
return net->u_.ff.d.pins[adr];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Normal RAM port does not have data2 nexa
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -833,6 +903,18 @@ extern "C" unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" ivl_lpm_t ivl_lpm_decode(ivl_lpm_t net)
|
||||||
|
{
|
||||||
|
assert(net);
|
||||||
|
switch (net->type) {
|
||||||
|
case IVL_LPM_FF:
|
||||||
|
return net->u_.ff.a.decode;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function returns the hierarchical name for the LPM device. The
|
* This function returns the hierarchical name for the LPM device. The
|
||||||
* name needs to be built up from the scope name and the lpm base
|
* name needs to be built up from the scope name and the lpm base
|
||||||
|
|
@ -891,6 +973,20 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
|
||||||
else
|
else
|
||||||
return net->u_.ff.q.pins[idx];
|
return net->u_.ff.q.pins[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_LATCH:
|
||||||
|
|
||||||
|
if ( idx >= net->u_.latch.width )
|
||||||
|
{
|
||||||
|
throw invalid_argument( "idx too high" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( net->u_.latch.width != 1U )
|
||||||
|
{
|
||||||
|
throw invalid_argument( "Only 1-wide latches are currently supported." );
|
||||||
|
}
|
||||||
|
|
||||||
|
return net->u_.latch.qPtr;
|
||||||
|
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
assert(idx < net->u_.mux.width);
|
assert(idx < net->u_.mux.width);
|
||||||
if (net->u_.mux.width == 1)
|
if (net->u_.mux.width == 1)
|
||||||
|
|
@ -898,6 +994,10 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
|
||||||
else
|
else
|
||||||
return net->u_.mux.q.pins[idx];
|
return net->u_.mux.q.pins[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
assert(idx < net->u_.demux.width);
|
||||||
|
return net->u_.demux.q[idx];
|
||||||
|
|
||||||
case IVL_LPM_SHIFTL:
|
case IVL_LPM_SHIFTL:
|
||||||
case IVL_LPM_SHIFTR:
|
case IVL_LPM_SHIFTR:
|
||||||
assert(idx < net->u_.shift.width);
|
assert(idx < net->u_.shift.width);
|
||||||
|
|
@ -929,6 +1029,7 @@ extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx)
|
||||||
else
|
else
|
||||||
return net->u_.ff.s.pins[idx];
|
return net->u_.ff.s.pins[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_DECODE:
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
assert(idx < net->u_.mux.swid);
|
assert(idx < net->u_.mux.swid);
|
||||||
if (net->u_.mux.swid == 1)
|
if (net->u_.mux.swid == 1)
|
||||||
|
|
@ -936,6 +1037,10 @@ extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx)
|
||||||
else
|
else
|
||||||
return net->u_.mux.s.pins[idx];
|
return net->u_.mux.s.pins[idx];
|
||||||
|
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
assert(idx < net->u_.demux.awid);
|
||||||
|
return net->u_.demux.a[idx];
|
||||||
|
|
||||||
case IVL_LPM_SHIFTL:
|
case IVL_LPM_SHIFTL:
|
||||||
case IVL_LPM_SHIFTR:
|
case IVL_LPM_SHIFTR:
|
||||||
assert(idx < net->u_.shift.select);
|
assert(idx < net->u_.shift.select);
|
||||||
|
|
@ -952,8 +1057,11 @@ extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
|
||||||
switch (net->type) {
|
switch (net->type) {
|
||||||
case IVL_LPM_RAM:
|
case IVL_LPM_RAM:
|
||||||
return net->u_.ff.swid;
|
return net->u_.ff.swid;
|
||||||
|
case IVL_LPM_DECODE:
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
return net->u_.mux.swid;
|
return net->u_.mux.swid;
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
return net->u_.demux.awid;
|
||||||
case IVL_LPM_SHIFTL:
|
case IVL_LPM_SHIFTL:
|
||||||
case IVL_LPM_SHIFTR:
|
case IVL_LPM_SHIFTR:
|
||||||
return net->u_.shift.select;
|
return net->u_.shift.select;
|
||||||
|
|
@ -970,6 +1078,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
||||||
case IVL_LPM_FF:
|
case IVL_LPM_FF:
|
||||||
case IVL_LPM_RAM:
|
case IVL_LPM_RAM:
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
return 0;
|
return 0;
|
||||||
case IVL_LPM_ADD:
|
case IVL_LPM_ADD:
|
||||||
case IVL_LPM_CMP_EQ:
|
case IVL_LPM_CMP_EQ:
|
||||||
|
|
@ -984,7 +1093,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
||||||
case IVL_LPM_SHIFTL:
|
case IVL_LPM_SHIFTL:
|
||||||
case IVL_LPM_SHIFTR:
|
case IVL_LPM_SHIFTR:
|
||||||
return net->u_.shift.signed_flag;
|
return net->u_.shift.signed_flag;
|
||||||
return 0;
|
case IVL_LPM_DECODE:
|
||||||
case IVL_LPM_UFUNC:
|
case IVL_LPM_UFUNC:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
|
@ -996,8 +1105,12 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
||||||
extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
|
extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
|
||||||
{
|
{
|
||||||
switch (net->type) {
|
switch (net->type) {
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
return net->u_.demux.size;
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
return net->u_.mux.size;
|
return net->u_.mux.size;
|
||||||
|
case IVL_LPM_RAM:
|
||||||
|
return net->u_.ff.scnt;
|
||||||
case IVL_LPM_UFUNC:
|
case IVL_LPM_UFUNC:
|
||||||
return net->u_.ufunc.ports - 1;
|
return net->u_.ufunc.ports - 1;
|
||||||
default:
|
default:
|
||||||
|
|
@ -1018,8 +1131,13 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
|
||||||
case IVL_LPM_FF:
|
case IVL_LPM_FF:
|
||||||
case IVL_LPM_RAM:
|
case IVL_LPM_RAM:
|
||||||
return net->u_.ff.width;
|
return net->u_.ff.width;
|
||||||
|
case IVL_LPM_LATCH:
|
||||||
|
return net->u_.latch.width;
|
||||||
|
case IVL_LPM_DECODE:
|
||||||
case IVL_LPM_MUX:
|
case IVL_LPM_MUX:
|
||||||
return net->u_.mux.width;
|
return net->u_.mux.width;
|
||||||
|
case IVL_LPM_DEMUX:
|
||||||
|
return net->u_.demux.width;
|
||||||
case IVL_LPM_ADD:
|
case IVL_LPM_ADD:
|
||||||
case IVL_LPM_CMP_EQ:
|
case IVL_LPM_CMP_EQ:
|
||||||
case IVL_LPM_CMP_GE:
|
case IVL_LPM_CMP_GE:
|
||||||
|
|
@ -1046,7 +1164,7 @@ extern "C" ivl_memory_t ivl_lpm_memory(ivl_lpm_t net)
|
||||||
assert(net);
|
assert(net);
|
||||||
switch (net->type) {
|
switch (net->type) {
|
||||||
case IVL_LPM_RAM:
|
case IVL_LPM_RAM:
|
||||||
return net->u_.ff.mem;
|
return net->u_.ff.a.mem;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1935,6 +2053,21 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll-api.cc,v $
|
* $Log: t-dll-api.cc,v $
|
||||||
|
* Revision 1.108.2.5 2006/04/16 19:26:40 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.108.2.4 2006/03/26 23:09:24 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.108.2.3 2006/03/12 07:34:19 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.108.2.2 2006/02/25 05:03:29 steve
|
||||||
|
* Add support for negedge FFs by using attributes.
|
||||||
|
*
|
||||||
|
* Revision 1.108.2.1 2006/02/19 00:11:33 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
* Revision 1.108 2004/10/04 01:10:55 steve
|
* Revision 1.108 2004/10/04 01:10:55 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: t-dll-expr.cc,v 1.39 2004/06/17 16:06:19 steve Exp $"
|
#ident "$Id: t-dll-expr.cc,v 1.39.2.2 2006/09/15 23:56:05 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -30,7 +30,8 @@
|
||||||
#ifdef HAVE_MALLOC_H
|
#ifdef HAVE_MALLOC_H
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
# include <stdlib.h>
|
# include <cstdlib>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a little convenience function for converting a NetExpr
|
* This is a little convenience function for converting a NetExpr
|
||||||
|
|
@ -222,12 +223,73 @@ void dll_target::expr_memory(const NetEMemory*net)
|
||||||
ivl_expr_t cur = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
ivl_expr_t cur = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||||
assert(cur);
|
assert(cur);
|
||||||
|
|
||||||
cur->type_ = IVL_EX_MEMORY;
|
const NetMemory*mem = net->memory();
|
||||||
cur->value_ = IVL_VT_VECTOR;
|
|
||||||
cur->width_= net->expr_width();
|
if (const NetNet*reg = mem->reg_from_explode()) {
|
||||||
cur->signed_ = net->has_sign()? 1 : 0;
|
|
||||||
cur->u_.memory_.mem_ = find_memory(des_, net->memory());
|
if (expr_ == 0) {
|
||||||
cur->u_.memory_.idx_ = expr_;
|
// If there is no index expression for the
|
||||||
|
// exploded memory, then replace it with the
|
||||||
|
// entire exploded reg.
|
||||||
|
cur->type_ = IVL_EX_SIGNAL;
|
||||||
|
cur->value_ = IVL_VT_VECTOR;
|
||||||
|
cur->width_= reg->pin_count();
|
||||||
|
cur->signed_ = net->has_sign()? 1 : 0;
|
||||||
|
cur->u_.signal_.sig = find_signal(des_, reg);
|
||||||
|
cur->u_.signal_.lsi = 0;
|
||||||
|
cur->u_.signal_.msi = cur->width_ - 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cur->type_ = IVL_EX_SELECT;
|
||||||
|
cur->value_ = IVL_VT_VECTOR;
|
||||||
|
cur->width_ = net->expr_width();
|
||||||
|
cur->signed_ = net->has_sign()? 1 : 0;
|
||||||
|
|
||||||
|
// Create an expression form of the exploded
|
||||||
|
// memory. This is what the select will apply to.
|
||||||
|
ivl_expr_t sig = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||||
|
sig->type_ = IVL_EX_SIGNAL;
|
||||||
|
sig->value_ = IVL_VT_VECTOR;
|
||||||
|
sig->width_ = reg->pin_count();
|
||||||
|
sig->signed_ = 0;
|
||||||
|
sig->u_.signal_.sig = find_signal(des_, reg);
|
||||||
|
assert(sig->u_.signal_.sig);
|
||||||
|
sig->u_.signal_.lsi = 0;
|
||||||
|
sig->u_.signal_.msi = reg->pin_count()-1;
|
||||||
|
cur->u_.binary_.lef_ = sig;
|
||||||
|
|
||||||
|
// Create an expression of the address calculation.
|
||||||
|
cur->u_.binary_.rig_ = expr_;
|
||||||
|
|
||||||
|
if (cur->width_ > 1) {
|
||||||
|
ivl_expr_t mul = (ivl_expr_t)calloc(2, sizeof(struct ivl_expr_s));
|
||||||
|
ivl_expr_t fac = mul+1;
|
||||||
|
|
||||||
|
fac->type_ = IVL_EX_ULONG;
|
||||||
|
fac->value_ = IVL_VT_VECTOR;
|
||||||
|
fac->width_ = 8*sizeof(cur->width_);
|
||||||
|
fac->signed_= 0;
|
||||||
|
fac->u_.ulong_.value = cur->width_;
|
||||||
|
|
||||||
|
mul->type_ = IVL_EX_BINARY;
|
||||||
|
mul->value_ = IVL_VT_VECTOR;
|
||||||
|
mul->width_ = fac->width_;
|
||||||
|
mul->signed_= 0;
|
||||||
|
mul->u_.binary_.op_ = '*';
|
||||||
|
mul->u_.binary_.lef_ = cur->u_.binary_.rig_;
|
||||||
|
mul->u_.binary_.rig_ = fac;
|
||||||
|
cur->u_.binary_.rig_ = mul;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cur->type_ = IVL_EX_MEMORY;
|
||||||
|
cur->value_ = IVL_VT_VECTOR;
|
||||||
|
cur->width_= net->expr_width();
|
||||||
|
cur->signed_ = net->has_sign()? 1 : 0;
|
||||||
|
cur->u_.memory_.mem_ = find_memory(des_, net->memory());
|
||||||
|
cur->u_.memory_.idx_ = expr_;
|
||||||
|
}
|
||||||
|
|
||||||
expr_ = cur;
|
expr_ = cur;
|
||||||
}
|
}
|
||||||
|
|
@ -604,6 +666,12 @@ void dll_target::expr_variable(const NetEVariable*net)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll-expr.cc,v $
|
* $Log: t-dll-expr.cc,v $
|
||||||
|
* Revision 1.39.2.2 2006/09/15 23:56:05 steve
|
||||||
|
* Special handling of exploded memory arguments.
|
||||||
|
*
|
||||||
|
* Revision 1.39.2.1 2006/03/12 07:34:19 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
* Revision 1.39 2004/06/17 16:06:19 steve
|
* Revision 1.39 2004/06/17 16:06:19 steve
|
||||||
* Help system function signedness survive elaboration.
|
* Help system function signedness survive elaboration.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@
|
||||||
#ifdef HAVE_MALLOC_H
|
#ifdef HAVE_MALLOC_H
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
# include <stdlib.h>
|
# include <cstdlib>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
|
|
||||||
bool dll_target::process(const NetProcTop*net)
|
bool dll_target::process(const NetProcTop*net)
|
||||||
|
|
|
||||||
253
t-dll.cc
253
t-dll.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: t-dll.cc,v 1.131 2004/10/04 01:10:55 steve Exp $"
|
#ident "$Id: t-dll.cc,v 1.131.2.8 2006/07/23 19:42:35 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -31,7 +31,11 @@
|
||||||
#ifdef HAVE_MALLOC_H
|
#ifdef HAVE_MALLOC_H
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
# include <stdlib.h>
|
# include <cstdlib>
|
||||||
|
# include <cstring>
|
||||||
|
|
||||||
|
#include <new> // standard operator new
|
||||||
|
using std::bad_alloc;
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
|
|
||||||
|
|
@ -940,6 +944,8 @@ void dll_target::net_case_cmp(const NetCaseCmp*net)
|
||||||
obj->delay[1] = net->fall_time();
|
obj->delay[1] = net->fall_time();
|
||||||
obj->delay[2] = net->decay_time();
|
obj->delay[2] = net->decay_time();
|
||||||
|
|
||||||
|
logic_attributes(obj,net);
|
||||||
|
|
||||||
scope_add_logic(scope, obj);
|
scope_add_logic(scope, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -965,6 +971,8 @@ bool dll_target::net_function(const NetUserFunc*net)
|
||||||
obj->type = IVL_LPM_UFUNC;
|
obj->type = IVL_LPM_UFUNC;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
||||||
/* Get the definition of the function and save it. */
|
/* Get the definition of the function and save it. */
|
||||||
|
|
@ -1104,9 +1112,11 @@ void dll_target::lpm_add_sub(const NetAddSub*net)
|
||||||
obj->type = IVL_LPM_SUB;
|
obj->type = IVL_LPM_SUB;
|
||||||
else
|
else
|
||||||
obj->type = IVL_LPM_ADD;
|
obj->type = IVL_LPM_ADD;
|
||||||
obj->name = net->name(); // NetAddSub names are permallocated.
|
obj->name = net->name(); // NetAddSub names are permallocated
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
||||||
obj->u_.arith.signed_flag = 0;
|
obj->u_.arith.signed_flag = 0;
|
||||||
|
|
@ -1176,6 +1186,8 @@ void dll_target::lpm_clshift(const NetCLShift*net)
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_SHIFTL;
|
obj->type = IVL_LPM_SHIFTL;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
@ -1243,6 +1255,8 @@ void dll_target::lpm_clshift(const NetCLShift*net)
|
||||||
void dll_target::lpm_compare(const NetCompare*net)
|
void dll_target::lpm_compare(const NetCompare*net)
|
||||||
{
|
{
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
obj->name = net->name(); // NetCompare names are permallocated
|
obj->name = net->name(); // NetCompare names are permallocated
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
|
|
@ -1357,6 +1371,8 @@ void dll_target::lpm_divide(const NetDivide*net)
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_DIVIDE;
|
obj->type = IVL_LPM_DIVIDE;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
@ -1427,6 +1443,8 @@ void dll_target::lpm_modulo(const NetModulo*net)
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_MOD;
|
obj->type = IVL_LPM_MOD;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
@ -1489,16 +1507,131 @@ void dll_target::lpm_modulo(const NetModulo*net)
|
||||||
scope_add_lpm(obj->scope, obj);
|
scope_add_lpm(obj->scope, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dll_target::lpm_decode(const NetDecode*net)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivl_lpm_t dll_target::lpm_decode_ff_(const NetDecode*net)
|
||||||
|
{
|
||||||
|
if (net == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
|
obj->type = IVL_LPM_DECODE;
|
||||||
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
|
obj->scope = find_scope(des_, net->scope());
|
||||||
|
|
||||||
|
obj->u_.mux.swid = net->awidth();
|
||||||
|
obj->u_.mux.size = 0;
|
||||||
|
obj->u_.mux.width = net->width();
|
||||||
|
obj->u_.mux.d = 0;
|
||||||
|
|
||||||
|
if (obj->u_.mux.swid > 1) {
|
||||||
|
obj->u_.mux.s.pins = new ivl_nexus_t[obj->u_.mux.swid];
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < obj->u_.mux.swid ; idx += 1) {
|
||||||
|
const Nexus*nex = net->pin_Address(idx).nexus();
|
||||||
|
assert(nex->t_cookie());
|
||||||
|
obj->u_.mux.s.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
nexus_lpm_add(obj->u_.mux.s.pins[idx], obj, idx,
|
||||||
|
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(obj->u_.mux.swid == 1);
|
||||||
|
const Nexus*nex = net->pin_Address(0).nexus();
|
||||||
|
assert(nex->t_cookie());
|
||||||
|
obj->u_.mux.s.pin = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
nexus_lpm_add(obj->u_.mux.s.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope_add_lpm(obj->scope, obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dll_target::lpm_demux(const NetDemux*net)
|
||||||
|
{
|
||||||
|
unsigned idx;
|
||||||
|
unsigned width = net->width();
|
||||||
|
unsigned awid = net->awidth();
|
||||||
|
unsigned size = net->size();
|
||||||
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
|
obj->type = IVL_LPM_DEMUX;
|
||||||
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
|
obj->scope = find_scope(des_, net->scope());
|
||||||
|
assert(obj->scope);
|
||||||
|
|
||||||
|
obj->u_.demux.width = width;
|
||||||
|
obj->u_.demux.awid = awid;
|
||||||
|
obj->u_.demux.size = net->size();
|
||||||
|
|
||||||
|
ivl_nexus_t*tmp = new ivl_nexus_t [2*width + awid + width/size];
|
||||||
|
obj->u_.demux.q = tmp;
|
||||||
|
obj->u_.demux.d = tmp + width;
|
||||||
|
obj->u_.demux.a = tmp + 2*width;
|
||||||
|
obj->u_.demux.bit_in = tmp + 2*width + awid;
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
const Nexus*nex = net->pin_Q(idx).nexus();
|
||||||
|
obj->u_.demux.q[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
|
||||||
|
/* It is possible, but unlikely, that the Q is unused. */
|
||||||
|
if (obj->u_.demux.q[idx])
|
||||||
|
nexus_lpm_add(obj->u_.demux.q[idx], obj, idx,
|
||||||
|
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
const Nexus*nex = net->pin_Data(idx).nexus();
|
||||||
|
assert(nex->t_cookie());
|
||||||
|
obj->u_.demux.d[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
nexus_lpm_add(obj->u_.demux.d[idx], obj, idx,
|
||||||
|
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < awid ; idx += 1) {
|
||||||
|
const Nexus*nex = net->pin_Address(idx).nexus();
|
||||||
|
assert(nex->t_cookie());
|
||||||
|
obj->u_.demux.a[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
nexus_lpm_add(obj->u_.demux.a[idx], obj, idx,
|
||||||
|
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0 ; idx < width/size ; idx += 1) {
|
||||||
|
const Nexus*nex = net->pin_WriteData(idx).nexus();
|
||||||
|
assert(nex->t_cookie());
|
||||||
|
obj->u_.demux.bit_in[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
nexus_lpm_add(obj->u_.demux.bit_in[idx], obj, 0,
|
||||||
|
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->nattr = net->attr_cnt();
|
||||||
|
obj->attr = fill_in_attributes(net);
|
||||||
|
|
||||||
|
scope_add_lpm(obj->scope, obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void dll_target::lpm_ff(const NetFF*net)
|
void dll_target::lpm_ff(const NetFF*net)
|
||||||
{
|
{
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_FF;
|
obj->type = IVL_LPM_FF;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
|
obj->u_.ff.a.decode = lpm_decode_ff_(net->get_demux());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
||||||
obj->u_.ff.width = net->width();
|
obj->u_.ff.width = net->width();
|
||||||
|
|
||||||
|
obj->nattr = net->attr_cnt();
|
||||||
|
obj->attr = fill_in_attributes(net);
|
||||||
|
|
||||||
scope_add_lpm(obj->scope, obj);
|
scope_add_lpm(obj->scope, obj);
|
||||||
|
|
||||||
const Nexus*nex;
|
const Nexus*nex;
|
||||||
|
|
@ -1605,18 +1738,52 @@ void dll_target::lpm_ff(const NetFF*net)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dll_target::lpm_latch( const NetLatch *latchPtr )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ivl_lpm_s *objPtr = new ivl_lpm_s;
|
||||||
|
objPtr->type = IVL_LPM_LATCH;
|
||||||
|
objPtr->name = latchPtr->name();
|
||||||
|
objPtr->scope = find_scope( des_, latchPtr->scope() );
|
||||||
|
assert( objPtr->scope ); // C++ programmers prefer using exceptions rather than assertions.
|
||||||
|
|
||||||
|
objPtr->u_.latch.width = latchPtr->width();
|
||||||
|
|
||||||
|
objPtr->nattr = latchPtr->attr_cnt();
|
||||||
|
objPtr->attr = fill_in_attributes( latchPtr );
|
||||||
|
|
||||||
|
scope_add_lpm( objPtr->scope, objPtr );
|
||||||
|
|
||||||
|
// Set the gate signal to point to the nexus, and the nexus to point back to this device.
|
||||||
|
const Nexus *const nexPtr = latchPtr->pin_Gate().nexus();
|
||||||
|
}
|
||||||
|
catch ( bad_alloc &memoryAllocationException )
|
||||||
|
{
|
||||||
|
cerr << "Exception occurred: " << memoryAllocationException.what() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end function lpm_latch
|
||||||
|
|
||||||
void dll_target::lpm_ram_dq(const NetRamDq*net)
|
void dll_target::lpm_ram_dq(const NetRamDq*net)
|
||||||
{
|
{
|
||||||
|
ivl_memory_t mem = find_memory(des_, net->mem());
|
||||||
|
assert(mem);
|
||||||
|
|
||||||
|
const NetNet*ereg = net->mem()->reg_from_explode();
|
||||||
|
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_RAM;
|
obj->type = IVL_LPM_RAM;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
obj->u_.ff.mem = find_memory(des_, net->mem());
|
obj->attr = 0;
|
||||||
assert(obj->u_.ff.mem);
|
obj->nattr = 0;
|
||||||
|
obj->u_.ff.a.mem = ereg? 0 : mem;
|
||||||
obj->scope = find_scope(des_, net->mem()->scope());
|
obj->scope = find_scope(des_, net->mem()->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
||||||
obj->u_.ff.width = net->width();
|
obj->u_.ff.width = net->width();
|
||||||
obj->u_.ff.swid = net->awidth();
|
obj->u_.ff.swid = net->awidth();
|
||||||
|
obj->u_.ff.scnt = net->mem()->count();
|
||||||
|
|
||||||
scope_add_lpm(obj->scope, obj);
|
scope_add_lpm(obj->scope, obj);
|
||||||
|
|
||||||
|
|
@ -1626,6 +1793,7 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
|
||||||
// the clock input.
|
// the clock input.
|
||||||
|
|
||||||
bool has_write_port = net->pin_InClock().is_linked();
|
bool has_write_port = net->pin_InClock().is_linked();
|
||||||
|
assert( ereg? !has_write_port : 1 );
|
||||||
|
|
||||||
// Connect the write clock and write enable
|
// Connect the write clock and write enable
|
||||||
|
|
||||||
|
|
@ -1717,6 +1885,21 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
|
||||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ereg) {
|
||||||
|
unsigned count = obj->u_.ff.width * obj->u_.ff.scnt;
|
||||||
|
assert(ereg->pin_count() == count);
|
||||||
|
|
||||||
|
obj->u_.ff.d.pins = new ivl_nexus_t [count];
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < count ; idx += 1) {
|
||||||
|
nex = ereg->pin(idx).nexus();
|
||||||
|
assert(nex->t_cookie());
|
||||||
|
obj->u_.ff.d.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
|
nexus_lpm_add(obj->u_.ff.d.pins[idx], obj, 0,
|
||||||
|
IVL_DR_HiZ, IVL_DR_HiZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dll_target::lpm_mult(const NetMult*net)
|
void dll_target::lpm_mult(const NetMult*net)
|
||||||
|
|
@ -1724,6 +1907,8 @@ void dll_target::lpm_mult(const NetMult*net)
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_MULT;
|
obj->type = IVL_LPM_MULT;
|
||||||
obj->name = net->name();
|
obj->name = net->name();
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
assert(net->scope());
|
assert(net->scope());
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
@ -1803,7 +1988,9 @@ void dll_target::lpm_mux(const NetMux*net)
|
||||||
{
|
{
|
||||||
ivl_lpm_t obj = new struct ivl_lpm_s;
|
ivl_lpm_t obj = new struct ivl_lpm_s;
|
||||||
obj->type = IVL_LPM_MUX;
|
obj->type = IVL_LPM_MUX;
|
||||||
obj->name = net->name(); // The NetMux perallocates its name.
|
obj->name = net->name(); // NetMux names are permallocated
|
||||||
|
obj->attr = 0;
|
||||||
|
obj->nattr = 0;
|
||||||
obj->scope = find_scope(des_, net->scope());
|
obj->scope = find_scope(des_, net->scope());
|
||||||
assert(obj->scope);
|
assert(obj->scope);
|
||||||
|
|
||||||
|
|
@ -1828,10 +2015,34 @@ void dll_target::lpm_mux(const NetMux*net)
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < obj->u_.mux.width ; idx += 1) {
|
for (unsigned idx = 0 ; idx < obj->u_.mux.width ; idx += 1) {
|
||||||
nex = net->pin_Result(idx).nexus();
|
nex = net->pin_Result(idx).nexus();
|
||||||
assert(nex->t_cookie());
|
#if 0
|
||||||
|
if (! nex->t_cookie()) {
|
||||||
|
cerr << net->get_line() << ": internal error: "
|
||||||
|
<< "broken mux. name=" << net->name()
|
||||||
|
<< ", width=" << obj->u_.mux.width
|
||||||
|
<< ", swid=" << obj->u_.mux.swid << endl;
|
||||||
|
for (unsigned tmp = 0; tmp < obj->u_.mux.width; tmp += 1) {
|
||||||
|
const Nexus*tmpn = net->pin_Result(tmp).nexus();
|
||||||
|
if (tmpn->t_cookie() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cerr << net->get_line() << ": XXXX "
|
||||||
|
<< "Result(" << tmp << ") : "
|
||||||
|
<< tmpn->name() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
obj->u_.mux.q.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
obj->u_.mux.q.pins[idx] = (ivl_nexus_t) nex->t_cookie();
|
||||||
nexus_lpm_add(obj->u_.mux.q.pins[idx], obj, 0,
|
|
||||||
IVL_DR_STRONG, IVL_DR_STRONG);
|
/* It is possible (although unlikely) that the
|
||||||
|
result bit of the mux is not used. This can
|
||||||
|
happen, for example, if the output is
|
||||||
|
overridden in the HDL. In that case, skip
|
||||||
|
it. But if the bit is used, then add it to the
|
||||||
|
nexus. */
|
||||||
|
if (obj->u_.mux.q.pins[idx])
|
||||||
|
nexus_lpm_add(obj->u_.mux.q.pins[idx], obj, 0,
|
||||||
|
IVL_DR_STRONG, IVL_DR_STRONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2180,6 +2391,30 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll.cc,v $
|
* $Log: t-dll.cc,v $
|
||||||
|
* Revision 1.131.2.8 2006/07/23 19:42:35 steve
|
||||||
|
* Handle statement output override better in blocks.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.7 2006/04/16 19:26:40 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.6 2006/03/26 23:09:24 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.5 2006/03/12 07:34:19 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.4 2006/02/25 05:03:29 steve
|
||||||
|
* Add support for negedge FFs by using attributes.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.3 2006/02/19 00:11:34 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.2 2006/01/21 21:42:33 steve
|
||||||
|
* When mux has wide select but sparse choices, use 1hot translation.
|
||||||
|
*
|
||||||
|
* Revision 1.131.2.1 2005/02/19 16:39:31 steve
|
||||||
|
* Spellig fixes.
|
||||||
|
*
|
||||||
* Revision 1.131 2004/10/04 01:10:55 steve
|
* Revision 1.131 2004/10/04 01:10:55 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
47
t-dll.h
47
t-dll.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: t-dll.h,v 1.115 2004/10/04 01:10:56 steve Exp $"
|
#ident "$Id: t-dll.h,v 1.115.2.5 2006/04/16 19:26:40 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "target.h"
|
# include "target.h"
|
||||||
|
|
@ -76,8 +76,11 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||||
void lpm_add_sub(const NetAddSub*);
|
void lpm_add_sub(const NetAddSub*);
|
||||||
void lpm_clshift(const NetCLShift*);
|
void lpm_clshift(const NetCLShift*);
|
||||||
void lpm_compare(const NetCompare*);
|
void lpm_compare(const NetCompare*);
|
||||||
|
bool lpm_decode(const NetDecode*);
|
||||||
|
bool lpm_demux(const NetDemux*);
|
||||||
void lpm_divide(const NetDivide*);
|
void lpm_divide(const NetDivide*);
|
||||||
void lpm_ff(const NetFF*);
|
void lpm_ff(const NetFF*);
|
||||||
|
void lpm_latch( const NetLatch * );
|
||||||
void lpm_modulo(const NetModulo*);
|
void lpm_modulo(const NetModulo*);
|
||||||
void lpm_mult(const NetMult*);
|
void lpm_mult(const NetMult*);
|
||||||
void lpm_mux(const NetMux*);
|
void lpm_mux(const NetMux*);
|
||||||
|
|
@ -162,6 +165,8 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||||
|
|
||||||
void add_root(ivl_design_s &des_, const NetScope *s);
|
void add_root(ivl_design_s &des_, const NetScope *s);
|
||||||
|
|
||||||
|
ivl_lpm_t lpm_decode_ff_(const NetDecode*);
|
||||||
|
|
||||||
void sub_off_from_expr_(long);
|
void sub_off_from_expr_(long);
|
||||||
void mul_expr_by_const_(long);
|
void mul_expr_by_const_(long);
|
||||||
|
|
||||||
|
|
@ -290,10 +295,14 @@ struct ivl_lpm_s {
|
||||||
ivl_scope_t scope;
|
ivl_scope_t scope;
|
||||||
perm_string name;
|
perm_string name;
|
||||||
|
|
||||||
|
struct ivl_attribute_s*attr;
|
||||||
|
unsigned nattr;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct ivl_lpm_ff_s {
|
struct ivl_lpm_ff_s {
|
||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned swid; // ram only
|
unsigned swid; // ram only
|
||||||
|
unsigned scnt;
|
||||||
ivl_nexus_t clk;
|
ivl_nexus_t clk;
|
||||||
ivl_nexus_t we;
|
ivl_nexus_t we;
|
||||||
ivl_nexus_t aclr;
|
ivl_nexus_t aclr;
|
||||||
|
|
@ -312,11 +321,22 @@ struct ivl_lpm_s {
|
||||||
ivl_nexus_t*pins;
|
ivl_nexus_t*pins;
|
||||||
ivl_nexus_t pin;
|
ivl_nexus_t pin;
|
||||||
} s;
|
} s;
|
||||||
ivl_memory_t mem; // ram only
|
union {
|
||||||
|
ivl_memory_t mem; // ram only
|
||||||
|
ivl_lpm_t decode; // FF only
|
||||||
|
} a;
|
||||||
ivl_expr_t aset_value;
|
ivl_expr_t aset_value;
|
||||||
ivl_expr_t sset_value;
|
ivl_expr_t sset_value;
|
||||||
} ff;
|
} ff;
|
||||||
|
|
||||||
|
struct ivl_lpm_latch_s
|
||||||
|
{
|
||||||
|
unsigned width;
|
||||||
|
ivl_nexus_s *gatePtr;
|
||||||
|
ivl_nexus_s *qPtr;
|
||||||
|
ivl_nexus_s *dataPtr;
|
||||||
|
} latch;
|
||||||
|
|
||||||
struct ivl_lpm_mux_s {
|
struct ivl_lpm_mux_s {
|
||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
|
@ -332,6 +352,14 @@ struct ivl_lpm_s {
|
||||||
} s;
|
} s;
|
||||||
} mux;
|
} mux;
|
||||||
|
|
||||||
|
struct ivl_lpm_demux_s {
|
||||||
|
unsigned width;
|
||||||
|
unsigned awid;
|
||||||
|
unsigned size;
|
||||||
|
ivl_nexus_t*bit_in;
|
||||||
|
ivl_nexus_t *q,*d,*a;
|
||||||
|
} demux;
|
||||||
|
|
||||||
struct ivl_lpm_shift_s {
|
struct ivl_lpm_shift_s {
|
||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned select;
|
unsigned select;
|
||||||
|
|
@ -684,6 +712,21 @@ struct ivl_variable_s {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll.h,v $
|
* $Log: t-dll.h,v $
|
||||||
|
* Revision 1.115.2.5 2006/04/16 19:26:40 steve
|
||||||
|
* Fix handling of exploded memories with partial or missing resets.
|
||||||
|
*
|
||||||
|
* Revision 1.115.2.4 2006/03/26 23:09:25 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.115.2.3 2006/03/12 07:34:19 steve
|
||||||
|
* Fix the memsynth1 case.
|
||||||
|
*
|
||||||
|
* Revision 1.115.2.2 2006/02/25 05:03:30 steve
|
||||||
|
* Add support for negedge FFs by using attributes.
|
||||||
|
*
|
||||||
|
* Revision 1.115.2.1 2006/02/19 00:11:34 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
* Revision 1.115 2004/10/04 01:10:56 steve
|
* Revision 1.115 2004/10/04 01:10:56 steve
|
||||||
* Clean up spurious trailing white space.
|
* Clean up spurious trailing white space.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
27
target.cc
27
target.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: target.cc,v 1.69 2004/05/31 23:34:39 steve Exp $"
|
#ident "$Id: target.cc,v 1.69.2.2 2006/03/26 23:09:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -101,6 +101,20 @@ void target_t::lpm_compare(const NetCompare*)
|
||||||
"Unhandled NetCompare." << endl;
|
"Unhandled NetCompare." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool target_t::lpm_decode(const NetDecode*)
|
||||||
|
{
|
||||||
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
|
"Unhandled NetDecode." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool target_t::lpm_demux(const NetDemux*)
|
||||||
|
{
|
||||||
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
|
"Unhandled NetDemux." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void target_t::lpm_divide(const NetDivide*)
|
void target_t::lpm_divide(const NetDivide*)
|
||||||
{
|
{
|
||||||
cerr << "target (" << typeid(*this).name() << "): "
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
|
|
@ -119,6 +133,11 @@ void target_t::lpm_ff(const NetFF*)
|
||||||
"Unhandled NetFF." << endl;
|
"Unhandled NetFF." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void target_t::lpm_latch( const NetLatch * )
|
||||||
|
{
|
||||||
|
cerr << "target (" << typeid( *this ).name() << "): Unhandled NetLatch." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
void target_t::lpm_mult(const NetMult*)
|
void target_t::lpm_mult(const NetMult*)
|
||||||
{
|
{
|
||||||
cerr << "target (" << typeid(*this).name() << "): "
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
|
|
@ -420,6 +439,12 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: target.cc,v $
|
* $Log: target.cc,v $
|
||||||
|
* Revision 1.69.2.2 2006/03/26 23:09:25 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.69.2.1 2006/02/19 00:11:34 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
* Revision 1.69 2004/05/31 23:34:39 steve
|
* Revision 1.69 2004/05/31 23:34:39 steve
|
||||||
* Rewire/generalize parsing an elaboration of
|
* Rewire/generalize parsing an elaboration of
|
||||||
* function return values to allow for better
|
* function return values to allow for better
|
||||||
|
|
|
||||||
12
target.h
12
target.h
|
|
@ -19,10 +19,11 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: target.h,v 1.65 2004/05/31 23:34:39 steve Exp $"
|
#ident "$Id: target.h,v 1.65.2.2 2006/03/26 23:09:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
#include "NetLatch.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This header file describes the types and constants used to describe
|
* This header file describes the types and constants used to describe
|
||||||
|
|
@ -79,9 +80,12 @@ struct target_t {
|
||||||
virtual void lpm_add_sub(const NetAddSub*);
|
virtual void lpm_add_sub(const NetAddSub*);
|
||||||
virtual void lpm_clshift(const NetCLShift*);
|
virtual void lpm_clshift(const NetCLShift*);
|
||||||
virtual void lpm_compare(const NetCompare*);
|
virtual void lpm_compare(const NetCompare*);
|
||||||
|
virtual bool lpm_decode(const NetDecode*);
|
||||||
|
virtual bool lpm_demux(const NetDemux*);
|
||||||
virtual void lpm_divide(const NetDivide*);
|
virtual void lpm_divide(const NetDivide*);
|
||||||
virtual void lpm_modulo(const NetModulo*);
|
virtual void lpm_modulo(const NetModulo*);
|
||||||
virtual void lpm_ff(const NetFF*);
|
virtual void lpm_ff(const NetFF*);
|
||||||
|
virtual void lpm_latch( const NetLatch * );
|
||||||
virtual void lpm_mult(const NetMult*);
|
virtual void lpm_mult(const NetMult*);
|
||||||
virtual void lpm_mux(const NetMux*);
|
virtual void lpm_mux(const NetMux*);
|
||||||
virtual void lpm_ram_dq(const NetRamDq*);
|
virtual void lpm_ram_dq(const NetRamDq*);
|
||||||
|
|
@ -170,6 +174,12 @@ extern const struct target *target_table[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: target.h,v $
|
* $Log: target.h,v $
|
||||||
|
* Revision 1.65.2.2 2006/03/26 23:09:25 steve
|
||||||
|
* Handle asynchronous demux/bit replacements.
|
||||||
|
*
|
||||||
|
* Revision 1.65.2.1 2006/02/19 00:11:34 steve
|
||||||
|
* Handle synthesis of FF vectors with l-value decoder.
|
||||||
|
*
|
||||||
* Revision 1.65 2004/05/31 23:34:39 steve
|
* Revision 1.65 2004/05/31 23:34:39 steve
|
||||||
* Rewire/generalize parsing an elaboration of
|
* Rewire/generalize parsing an elaboration of
|
||||||
* function return values to allow for better
|
* function return values to allow for better
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
configure
|
||||||
|
Makefile
|
||||||
|
edif.tgt
|
||||||
|
dep
|
||||||
|
config.status
|
||||||
|
config.log
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
The tgt-edif files are licensed differently from the rest of Icarus
|
||||||
|
Verilog. These files are:
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
Copyright (c) 2005 Stephen Williams
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. The name of the author may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
The purpose of the different license here is to allow licensees to use
|
||||||
|
these files to make EDIF based code generators that use these common
|
||||||
|
functions without statically linking to GPL files from elsewhere
|
||||||
|
within Icarus Verilog.
|
||||||
|
|
||||||
|
As a reminder, while this more relaxed license is here to allow
|
||||||
|
entities to make closed source (binary) code generators, this is not
|
||||||
|
intended to effect the GPL standing of the rest of Icarus Verilog
|
||||||
|
source. THIS RELAXED LICENSE APPLIES ONLY TO FILES SPECIFICALLY MARKED
|
||||||
|
WITH THIS NEW LICENSE. Furthermore, all rights remain reserved. Note
|
||||||
|
specifically the requirement for you to reproduce notices in your
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2005 Stephen Williams
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# 3. The name of the author may not be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
#ident "$Id: Makefile.in,v 1.1.2.3 2006/05/08 04:33:36 steve Exp $"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
suffix = @install_suffix@
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
mandir = @mandir@
|
||||||
|
|
||||||
|
VPATH = $(srcdir)
|
||||||
|
|
||||||
|
bindir = @bindir@
|
||||||
|
libdir = @libdir@
|
||||||
|
includedir = $(prefix)/include
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
MAN = @MAN@
|
||||||
|
PS2pdf = @ps2pdf@
|
||||||
|
|
||||||
|
CPPFLAGS = @ident_support@ -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||||
|
CFLAGS = -Wall @CFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
|
all: dep edif.tgt
|
||||||
|
|
||||||
|
dep:
|
||||||
|
mkdir dep
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||||
|
mv $*.d dep
|
||||||
|
|
||||||
|
D = d-lpm.o d-virtex.o xilinx.o
|
||||||
|
O = edif.o device.o target.o gates.o generic.o $D
|
||||||
|
|
||||||
|
ifeq (@WIN32@,yes)
|
||||||
|
TGTLDFLAGS=-L.. -livl
|
||||||
|
TGTDEPLIBS=../libivl.a
|
||||||
|
else
|
||||||
|
TGTLDFLAGS=
|
||||||
|
TGTDEPLIBS=
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
edif.tgt: tables.o libedif_tgt.a $(TGTDEPLIBS)
|
||||||
|
$(CC) @shared@ -o $@ tables.o libedif_tgt.a $(TGTLDFLAGS)
|
||||||
|
|
||||||
|
libedif_tgt.a: $O
|
||||||
|
rm -f libedif_tgt.a
|
||||||
|
ar cqv libedif_tgt.a $O
|
||||||
|
$(RANLIB) libedif_tgt.a
|
||||||
|
|
||||||
|
iverilog-edif.ps: $(srcdir)/iverilog-edif.man
|
||||||
|
$(MAN) -t $(srcdir)/iverilog-edif.man > iverilog-edif.ps
|
||||||
|
|
||||||
|
iverilog-edif.pdf: iverilog-edif.ps
|
||||||
|
$(PS2PDF) iverilog-edif.ps iverilog-edif.pdf
|
||||||
|
|
||||||
|
|
||||||
|
Makefile: Makefile.in config.status
|
||||||
|
./config.status
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o dep edif.tgt
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile config.status config.log config.cache
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
|
check: all
|
||||||
|
|
||||||
|
ifeq (@WIN32@,yes)
|
||||||
|
ifeq ($(MAN),none)
|
||||||
|
INSTALL_DOC =
|
||||||
|
else
|
||||||
|
ifeq ($(PS2PDF),none)
|
||||||
|
#INSTALL_DOC = $(mandir)/man1/iverilog-edif.1
|
||||||
|
else
|
||||||
|
#INSTALL_DOC = $(prefix)/iverilog-edif.pdf $(mandir)/man1/iverilog-edif.1
|
||||||
|
#all: iverilog-edif.pdf
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
#INSTALL_DOC = $(prefix)/iverilog-edif.pdf $(mandir)/man1/iverilog-edif.1
|
||||||
|
#INSTALL_DOCDIR = $(mandir)/man1
|
||||||
|
endif
|
||||||
|
|
||||||
|
install: all installdirs $(libdir)/ivl$(suffix)/edif.tgt $(INSTALL_DOC) $(libdir)/ivl$(suffix)/edif.conf $(libdir)/ivl$(suffix)/edif-s.conf
|
||||||
|
|
||||||
|
$(libdir)/ivl$(suffix)/edif.tgt: ./edif.tgt
|
||||||
|
$(INSTALL_PROGRAM) ./edif.tgt $(libdir)/ivl$(suffix)/edif.tgt
|
||||||
|
|
||||||
|
$(libdir)/ivl$(suffix)/edif.conf: $(srcdir)/edif.conf
|
||||||
|
$(INSTALL_DATA) $(srcdir)/edif.conf $(libdir)/ivl$(suffix)/edif.conf
|
||||||
|
|
||||||
|
$(libdir)/ivl$(suffix)/edif-s.conf: $(srcdir)/edif-s.conf
|
||||||
|
$(INSTALL_DATA) $(srcdir)/edif-s.conf $(libdir)/ivl$(suffix)/edif-s.conf
|
||||||
|
|
||||||
|
|
||||||
|
$(mandir)/man1/iverilog-edif$(suffix).1: $(srcdir)/iverilog-edif.man
|
||||||
|
$(INSTALL_DATA) $(srcdir)/iverilog-edif.man $(mandir)/man1/iverilog-edif$(suffix).1
|
||||||
|
|
||||||
|
$(prefix)/iverilog-edif$(suffix).pdf: iverilog-edif.pdf
|
||||||
|
$(INSTALL_DATA) iverilog-edif.pdf $(prefix)/iverilog-edif$(suffix).pdf
|
||||||
|
|
||||||
|
installdirs: ../mkinstalldirs
|
||||||
|
$(srcdir)/../mkinstalldirs $(libdir)/ivl$(suffix)
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f $(libdir)/ivl$(suffix)/edif.tgt
|
||||||
|
rm -f $(INSTALL_DOC)
|
||||||
|
rm -f $(libdir)/ivl$(suffix)/edif-s.conf
|
||||||
|
rm -f $(libdir)/ivl$(suffix)/edif.conf
|
||||||
|
|
||||||
|
-include $(patsubst %.o, dep/%.d, $O)
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
AC_INIT(edif.conf)
|
||||||
|
|
||||||
|
dnl Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_CHECK_PROGS(MAN,man,none)
|
||||||
|
AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
|
||||||
|
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
# $host
|
||||||
|
|
||||||
|
AX_ENABLE_SUFFIX
|
||||||
|
|
||||||
|
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||||
|
AX_WIN32
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(malloc.h)
|
||||||
|
|
||||||
|
# may modify CPPFLAGS and CFLAGS
|
||||||
|
AX_CPP_PRECOMP
|
||||||
|
|
||||||
|
# Compiler option for position independent code, needed when making shared objects.
|
||||||
|
AX_C_PICFLAG
|
||||||
|
|
||||||
|
# linker options when building a shared library
|
||||||
|
AX_LD_SHAREDLIB_OPTS
|
||||||
|
|
||||||
|
AX_CPP_IDENT
|
||||||
|
|
||||||
|
AC_OUTPUT(Makefile)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue