Compare commits
239 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
a08de693d4 | |
|
|
37837f3904 | |
|
|
daa01a05d8 | |
|
|
9cd7a22dbe | |
|
|
f733030b41 | |
|
|
99f7d1197c | |
|
|
7817e479a4 | |
|
|
0c97cabe18 | |
|
|
e56c142dff | |
|
|
7e06a87b8e | |
|
|
0c3eef4c41 | |
|
|
3b22be5507 | |
|
|
287b19f22d | |
|
|
8de7fc6161 | |
|
|
663ab34ae7 | |
|
|
b5c819051b | |
|
|
fdbc212349 | |
|
|
d35d542b9e | |
|
|
8139551908 | |
|
|
021ae6c08f | |
|
|
b8b1bc4a36 | |
|
|
327cdc77a3 | |
|
|
a8e1643ae9 | |
|
|
02a986b35d | |
|
|
8759eaf720 | |
|
|
daff9ed30d | |
|
|
e4a319cfe2 | |
|
|
3d5c6c6f30 | |
|
|
c44ce66a87 | |
|
|
ce8a84db3c | |
|
|
33c852d2b4 | |
|
|
1eb593e8ad | |
|
|
8ef7344ea5 | |
|
|
5479aaf721 | |
|
|
b85b2d8a26 | |
|
|
8b7ffa1a17 | |
|
|
9b6e9f5832 | |
|
|
ab926ccee4 | |
|
|
3351004945 | |
|
|
7684814593 | |
|
|
3f29f96695 | |
|
|
7210061f2c | |
|
|
2396faac39 | |
|
|
c7126c3c1f | |
|
|
14bc857c54 | |
|
|
f49f3f56cf | |
|
|
c89ae29bf2 | |
|
|
d570437a17 | |
|
|
0cc8285a01 | |
|
|
d090fd7a17 | |
|
|
09cdf5268e | |
|
|
c1f750ff98 | |
|
|
c7414f79b0 | |
|
|
95eec69102 | |
|
|
23ea74a126 | |
|
|
70f15b472f | |
|
|
73d9a37020 | |
|
|
13921f0c0c | |
|
|
29f5c882eb | |
|
|
98c3391acb | |
|
|
f5728c4a39 | |
|
|
cca3b0ed5a | |
|
|
391ef78d42 | |
|
|
ab5b9271f3 | |
|
|
7eb4825435 | |
|
|
58511ab212 | |
|
|
b3ca7e1774 | |
|
|
5e8e59484b | |
|
|
517b4e3248 | |
|
|
a6fdb4b6e6 | |
|
|
ad786a2aa3 | |
|
|
e92c4638ed | |
|
|
fd4b849091 | |
|
|
98e5e36f03 | |
|
|
1a0d475907 | |
|
|
807a66f0a2 | |
|
|
92e7587320 | |
|
|
04be3a6323 | |
|
|
d2a900d187 | |
|
|
eb9d79ec61 | |
|
|
e8dada7337 | |
|
|
3dfc1d5097 | |
|
|
6bbf97a05d | |
|
|
e7815c3984 | |
|
|
fb01245501 | |
|
|
d0a45ffe9d | |
|
|
9c624a2403 | |
|
|
4d4a693248 | |
|
|
1872652019 | |
|
|
d68fea3f58 | |
|
|
b0e2185ade | |
|
|
6aaf2f84a8 | |
|
|
7ad50f4454 | |
|
|
19b0d5b7c9 | |
|
|
ae87aff745 | |
|
|
9c09394785 | |
|
|
3f8f81568a | |
|
|
bb5d30ead5 | |
|
|
4e77abca44 | |
|
|
902ae19bbf | |
|
|
5587e42e2e | |
|
|
f8f363a0b6 | |
|
|
f34485d415 | |
|
|
df177e9e14 | |
|
|
5d4c8d616a | |
|
|
72c02a8285 | |
|
|
043c86ba02 | |
|
|
b9d0783ad9 | |
|
|
047ee137ed | |
|
|
ef814a9ef4 | |
|
|
fa0ecb3761 | |
|
|
f2a81cf660 | |
|
|
e1b4d531a1 | |
|
|
a418995988 | |
|
|
8c36e20fd4 | |
|
|
2c982a6edb | |
|
|
a298bfb22a | |
|
|
cce61d7134 | |
|
|
aad5443a36 | |
|
|
f5f104f8a6 | |
|
|
b7ff68c3f4 | |
|
|
69986a5bc7 | |
|
|
c0f4b0374a | |
|
|
817b1ef3d4 | |
|
|
f9774758a3 | |
|
|
eb2fed7015 | |
|
|
5af47cda12 | |
|
|
0aad444bbf | |
|
|
e63c75d1a3 | |
|
|
a5b0872016 | |
|
|
f6b9db1c78 | |
|
|
597097eaef | |
|
|
47512e351f | |
|
|
506c09f5f8 | |
|
|
693fb93962 | |
|
|
8ca5926db9 | |
|
|
7acafd128f | |
|
|
d0a12f5b14 | |
|
|
8964a175f8 | |
|
|
97d70f9069 | |
|
|
0dc0fbf78d | |
|
|
786b3a0ca9 | |
|
|
24a60ce6af | |
|
|
4c640f67cb | |
|
|
cfe68fe6b4 | |
|
|
78149e9d15 | |
|
|
bbe037bf9f | |
|
|
d3bf6be7b2 | |
|
|
6146a98278 | |
|
|
63c7285113 | |
|
|
79e0203280 | |
|
|
ad419dfbe4 | |
|
|
75d71fe312 | |
|
|
5a30355faf | |
|
|
623e897e55 | |
|
|
0bb6360ac7 | |
|
|
4b850e1e74 | |
|
|
8ce807a263 | |
|
|
cc9524bd89 | |
|
|
13e07d6b7c | |
|
|
bbf11b830b | |
|
|
d345fb7654 | |
|
|
3186e3dc54 | |
|
|
d4d50fd97d | |
|
|
3337c9d51a | |
|
|
dfda202f14 | |
|
|
5ca440dc1c | |
|
|
96908e2fc5 | |
|
|
9f07e3c16e | |
|
|
3ae3e34732 | |
|
|
372efd8c30 | |
|
|
ac7f55f22a | |
|
|
b74736c784 | |
|
|
7988ef04d8 | |
|
|
61214108fe | |
|
|
356a19c918 | |
|
|
f1c5b58845 | |
|
|
fad37da1dc | |
|
|
80f74d0d24 | |
|
|
d25f689f55 | |
|
|
42618741d9 | |
|
|
9bcfc8ab6d | |
|
|
de75e71152 | |
|
|
5f8f7bc6fc | |
|
|
f7fb754ee8 | |
|
|
e59a6b8df7 | |
|
|
f149a30045 | |
|
|
ddaba5b017 | |
|
|
dff535923f | |
|
|
d66471c449 | |
|
|
b16e3ab59e | |
|
|
d7b76e9390 | |
|
|
6f692e7984 | |
|
|
dfe7279488 | |
|
|
b9ea0036de | |
|
|
fc24624fa2 | |
|
|
cca3d5907c | |
|
|
ec809c9137 | |
|
|
682e54841c | |
|
|
7d2734c9cc | |
|
|
74df582c73 | |
|
|
10b8055a38 | |
|
|
95848eb2f8 | |
|
|
efc3bbd29e | |
|
|
c56f21a20c | |
|
|
17210d5423 | |
|
|
b1af2f8535 | |
|
|
aa28430832 | |
|
|
ceea5d568c | |
|
|
710ad582ed | |
|
|
183137b60c | |
|
|
9c7c719cac | |
|
|
2f3061c158 | |
|
|
af08ff64c7 | |
|
|
036c176e8b | |
|
|
327e8d0ec0 | |
|
|
cfb45e56e2 | |
|
|
809044cbf8 | |
|
|
2a53255445 | |
|
|
4205752bb0 | |
|
|
d237e35076 | |
|
|
90f37fe3cb | |
|
|
4be2f61b53 | |
|
|
f8aa9073ac | |
|
|
9ea20d6677 | |
|
|
9fec1f7e45 | |
|
|
c47ea0721c | |
|
|
ef12137931 | |
|
|
0e8a12eebf | |
|
|
9473e823ed | |
|
|
c75f9db315 | |
|
|
1d31a91b4f | |
|
|
b795d8c1d8 | |
|
|
5ec7731e04 | |
|
|
bb29e1d588 | |
|
|
74fd1865cb | |
|
|
b40b6fb50d | |
|
|
19b68f6332 | |
|
|
c96e4da9e4 |
|
|
@ -18,6 +18,7 @@ config.h
|
|||
/tgt-vvp/vvp_config.h
|
||||
/tgt-vhdl/vhdl_config.h
|
||||
/vpi/vpi_config.h
|
||||
stamp-*-h
|
||||
/version.h
|
||||
/version_tag.h
|
||||
|
||||
|
|
@ -61,6 +62,11 @@ dep
|
|||
# Program created files
|
||||
/vvp/tables.cc
|
||||
|
||||
/iverilog-vpi.man
|
||||
/driver-vpi/res.rc
|
||||
/driver/iverilog.man
|
||||
/vvp/vvp.man
|
||||
|
||||
# The executables.
|
||||
*.exe
|
||||
/driver/iverilog
|
||||
|
|
|
|||
4
Attrib.h
4
Attrib.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __Attrib_H
|
||||
#define __Attrib_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -30,7 +30,7 @@ class Attrib {
|
|||
|
||||
public:
|
||||
Attrib();
|
||||
~Attrib();
|
||||
virtual ~Attrib();
|
||||
|
||||
const verinum&attribute(perm_string key) const;
|
||||
void attribute(perm_string key, const verinum&value);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __LineInfo_H
|
||||
#define __LineInfo_H
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -36,7 +36,7 @@ using namespace std;
|
|||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
~LineInfo();
|
||||
virtual ~LineInfo();
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
string get_fileline() const;
|
||||
|
|
|
|||
124
Makefile.in
124
Makefile.in
|
|
@ -40,10 +40,19 @@ datarootdir = @datarootdir@
|
|||
|
||||
SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl driver
|
||||
# Only run distclean for these driectories.
|
||||
# Only run distclean for these directories.
|
||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||
|
||||
VPATH = $(srcdir)
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
NOTUSED += driver-vpi
|
||||
endif
|
||||
|
||||
# To get the version headers to build correctly we only want to look
|
||||
# for C++ files in the source directory. All other files will require
|
||||
# an explicit $(srcdir).
|
||||
vpath %.cc $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
|
|
@ -55,6 +64,7 @@ mandir = @mandir@
|
|||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
HOSTCC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
|
|
@ -71,44 +81,57 @@ CXXFLAGS = -Wall @CXXFLAGS@
|
|||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
|
||||
all: dep config.h _pli_types.h version.h ivl@EXEEXT@
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@MINGW32@,yes)
|
||||
all: dep dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
dosify.exe: $(srcdir)/dosify.c
|
||||
$(CC) -o dosify.exe $(srcdir)/dosify.c
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@install_suffix@,)
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
else
|
||||
# On Windows if we have a suffix we must run the vvp part of
|
||||
# the test with a suffix since it was built/linked that way.
|
||||
ln vvp/vvp.exe vvp/vvp$(suffix).exe
|
||||
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
rm vvp/vvp$(suffix).exe
|
||||
endif
|
||||
else
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
endif
|
||||
|
||||
clean:
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
ifeq (@MINGW32@,no)
|
||||
(cd driver-vpi ; $(MAKE) $@)
|
||||
endif
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f *.o parse.cc parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps parse.output
|
||||
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
|
||||
rm -rf dep
|
||||
rm -f version.exe
|
||||
|
||||
distclean: clean
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
ifeq (@MINGW32@,no)
|
||||
(cd driver-vpi ; $(MAKE) $@)
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
rm -f stamp-config-h config.h
|
||||
rm -f stamp-_pli_types-h _pli_types.h
|
||||
ifneq (@srcdir@,.)
|
||||
rm -f version.h version_tag.h check.conf
|
||||
rmdir $(SUBDIRS) $(NOTUSED)
|
||||
endif
|
||||
for dir in $(NOTUSED); do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f Makefile config.status config.log config.cache config.h
|
||||
rm -f _pli_types.h
|
||||
rm -rf autom4te.cache
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
|
||||
|
|
@ -134,12 +157,22 @@ $(FF) $(TT)
|
|||
Makefile: $(srcdir)/Makefile.in config.status
|
||||
./config.status --file=$@
|
||||
|
||||
config.h: $(srcdir)/config.h.in
|
||||
./config.status --header=$@
|
||||
stamp-config-h: $(srcdir)/config.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status config.h
|
||||
config.h: stamp-config-h
|
||||
|
||||
_pli_types.h: $(srcdir)/_pli_types.h.in
|
||||
./config.status --header=$@
|
||||
stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status _pli_types.h
|
||||
_pli_types.h: stamp-_pli_types-h
|
||||
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
|
||||
cd $(srcdir) && autoconf
|
||||
|
||||
config.status: $(srcdir)/configure
|
||||
./config.status --recheck
|
||||
./config.status
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
# Under Windows (mingw) I need to make the ivl.exe in two steps.
|
||||
|
|
@ -156,12 +189,10 @@ ivl@EXEEXT@: $O
|
|||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
ifeq (@MINGW32@,no)
|
||||
all: dep iverilog-vpi
|
||||
|
||||
iverilog-vpi: iverilog-vpi.sh Makefile
|
||||
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);' \
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
|
|
@ -172,13 +203,18 @@ iverilog-vpi: iverilog-vpi.sh Makefile
|
|||
chmod +x $@
|
||||
endif
|
||||
|
||||
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
|
||||
$(HOSTCC) -Wall -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.cc
|
||||
%.o: %.cc config.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
# Here are some explicit dependencies needed to get things going.
|
||||
main.o: main.cc version_tag.h
|
||||
|
||||
lexor.o: lexor.cc parse.h
|
||||
|
||||
|
|
@ -196,20 +232,19 @@ lexor.cc: $(srcdir)/lexor.lex
|
|||
|
||||
lexor_keyword.o: lexor_keyword.cc parse.h
|
||||
|
||||
lexor_keyword.cc: lexor_keyword.gperf
|
||||
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-4,$$ -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
|
||||
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
|
||||
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
|
||||
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
|
||||
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
|
||||
|
||||
iverilog-vpi.ps: iverilog-vpi.man
|
||||
$(MAN) -t iverilog-vpi.man > iverilog-vpi.ps
|
||||
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
# The version.h header file is the concatenation of a relatively static
|
||||
# base version and the detailed version tag.
|
||||
version.h: $(srcdir)/version_base.in version_tag.h
|
||||
cat $(srcdir)/version_base.in version_tag.h > version.h
|
||||
|
||||
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
|
||||
# version.h file in the source tree (included in snapshots and releases), and
|
||||
# finally use nothing.
|
||||
|
|
@ -223,15 +258,16 @@ endif
|
|||
version_tag.h version:
|
||||
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
|
||||
echo "Using git-describe for VERSION_TAG"; \
|
||||
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
|
||||
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
|
||||
tag=`$(GIT) --git-dir $(srcdir)/.git describe`; \
|
||||
tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"$$tag\"\n#endif\n"`; \
|
||||
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
|
||||
elif test -r $(srcdir)/version_tag.h; then \
|
||||
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
|
||||
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
|
||||
else \
|
||||
echo "Using empty VERSION_TAG"; \
|
||||
echo '#define VERSION_TAG ""' > version_tag.h; \
|
||||
tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"\"\n#endif\n"`; \
|
||||
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
|
||||
fi
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
|
|
@ -258,7 +294,7 @@ WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
|
|||
endif
|
||||
|
||||
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
||||
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
|
||||
|
|
@ -287,8 +323,8 @@ $(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
|||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
|
||||
|
||||
$(mandir)/man1/iverilog-vpi$(suffix).1: $(srcdir)/iverilog-vpi.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
|
||||
$(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
|
||||
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
|
||||
|
||||
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
|
||||
|
|
@ -303,7 +339,7 @@ installdirs: $(srcdir)/mkinstalldirs
|
|||
"$(DESTDIR)$(mandir)/man1"
|
||||
|
||||
uninstall:
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
|
||||
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
|
||||
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -29,7 +29,10 @@ Module::Module(perm_string n)
|
|||
: PScope(n)
|
||||
{
|
||||
library_flag = false;
|
||||
is_cell = false;
|
||||
uc_drive = UCD_NONE;
|
||||
default_nettype = NetNet::NONE;
|
||||
timescale_warn_done = false;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
|
|
|
|||
9
Module.h
9
Module.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -74,6 +74,11 @@ class Module : public PScope, public LineInfo {
|
|||
other effect. */
|
||||
bool library_flag;
|
||||
|
||||
bool is_cell;
|
||||
|
||||
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
|
||||
UCDriveType uc_drive;
|
||||
|
||||
NetNet::Type default_nettype;
|
||||
|
||||
/* specparams are simpler then other params, in that they have
|
||||
|
|
@ -105,6 +110,8 @@ class Module : public PScope, public LineInfo {
|
|||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
bool time_from_timescale;
|
||||
bool timescale_warn_done;
|
||||
|
||||
/* Task definitions within this module */
|
||||
map<perm_string,PTask*> tasks;
|
||||
|
|
|
|||
53
PDelays.cc
53
PDelays.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -26,6 +26,11 @@
|
|||
# include "verinum.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
bool dly_used_no_timescale = false;
|
||||
bool dly_used_timescale = false;
|
||||
bool display_ts_dly_warning = true;
|
||||
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
|
|
@ -60,12 +65,28 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
|||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
|
||||
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
||||
{
|
||||
|
||||
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
|
||||
bool tmp_flag = false;
|
||||
expr->test_width(des, scope, 0, 0, tmp_type, tmp_flag);
|
||||
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
|
||||
eval_expr(dex);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
units, and return an adjusted value. */
|
||||
|
|
@ -119,6 +140,20 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
|
|||
return expr;
|
||||
}
|
||||
|
||||
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
|
||||
{
|
||||
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
|
||||
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
|
||||
if (c_rise && c_fall) {
|
||||
if (c_rise->value() < c_fall->value()) return rise;
|
||||
else return fall;
|
||||
}
|
||||
|
||||
cerr << fall->get_fileline() << ": sorry: can not calculate the "
|
||||
<< "decay time from " << *rise << " and " << *fall << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
|
|
@ -140,14 +175,14 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
|||
|
||||
if (delay_[2]) {
|
||||
decay_time = calculate_val(des, scope, delay_[2]);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, scope, decay_time);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, scope,
|
||||
decay_time);
|
||||
|
||||
} else {
|
||||
if (rise_time < fall_time)
|
||||
decay_time = rise_time;
|
||||
else
|
||||
decay_time = fall_time;
|
||||
// If this is zero then we need to do the min()
|
||||
// at run time.
|
||||
decay_time = calc_decay_time(rise_time, fall_time);
|
||||
}
|
||||
} else {
|
||||
assert(delay_[2] == 0);
|
||||
|
|
|
|||
7
PExpr.h
7
PExpr.h
|
|
@ -183,7 +183,6 @@ class PEConcat : public PExpr {
|
|||
std::valarray<unsigned>tested_widths_;
|
||||
|
||||
PExpr*repeat_;
|
||||
NetExpr*repeat_expr_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -339,6 +338,12 @@ class PEIdent : public PExpr {
|
|||
NetScope*found,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb) const;
|
||||
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb) const;
|
||||
NetExpr*elaborate_expr_net(Design*des,
|
||||
NetScope*scope,
|
||||
NetNet*net,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006,2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -55,6 +55,7 @@ void PGenerate::probe_for_direct_nesting_(void)
|
|||
if (localparams.size() > 0) return;
|
||||
if (events.size() > 0) return;
|
||||
if (wires.size() > 0) return;
|
||||
if (genvars.size() > 0) return;
|
||||
if (behaviors.size() > 0) return;
|
||||
if (analog_behaviors.size() > 0) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __PGenerate_H
|
||||
#define __PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -87,6 +87,9 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
map<perm_string,PTask*> tasks;
|
||||
map<perm_string,PFunction*>funcs;
|
||||
|
||||
// genvars declared within this scheme.
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
list<PGenerate*> generate_schemes;
|
||||
PGenerate*parent;
|
||||
|
|
@ -109,8 +112,8 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
bool generate_scope_case_(Design*des, NetScope*container);
|
||||
bool generate_scope_nblock_(Design*des, NetScope*container);
|
||||
|
||||
// Call probe during elaborate_scope to calulate the
|
||||
// directed_nested_ flag. It is OK to store the direct_nested_
|
||||
// Call probe during elaborate_scope to calculate the
|
||||
// direct_nested_ flag. It is OK to store the direct_nested_
|
||||
// information here because "direct nested" is a property of
|
||||
// the lexical generate code.
|
||||
void probe_for_direct_nesting_(void);
|
||||
|
|
|
|||
16
PWire.cc
16
PWire.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -29,8 +29,8 @@ PWire::PWire(perm_string n,
|
|||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
port_msb_(0), port_lsb_(0), port_set_(false),
|
||||
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
|
||||
lidx_(0), ridx_(0), discipline_(0)
|
||||
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
|
|
@ -135,7 +135,12 @@ bool PWire::get_isint() const
|
|||
return isint_;
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||
bool PWire::get_scalar() const
|
||||
{
|
||||
return is_scalar_;
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
|
||||
{
|
||||
switch (type) {
|
||||
case SR_PORT:
|
||||
|
|
@ -147,6 +152,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
|||
port_msb_ = m;
|
||||
port_lsb_ = l;
|
||||
port_set_ = true;
|
||||
is_scalar_ = is_scalar;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -159,6 +165,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
|||
net_msb_ = m;
|
||||
net_lsb_ = l;
|
||||
net_set_ = true;
|
||||
is_scalar_ = is_scalar;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -181,6 +188,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
|||
net_msb_ = m;
|
||||
net_lsb_ = l;
|
||||
net_set_ = true;
|
||||
is_scalar_ = is_scalar;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
6
PWire.h
6
PWire.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __PWire_H
|
||||
#define __PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -70,11 +70,12 @@ class PWire : public LineInfo {
|
|||
void set_signed(bool flag);
|
||||
bool get_signed() const;
|
||||
bool get_isint() const;
|
||||
bool get_scalar() const;
|
||||
|
||||
bool set_data_type(ivl_variable_type_t dt);
|
||||
ivl_variable_type_t get_data_type() const;
|
||||
|
||||
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
|
||||
void set_range(PExpr*msb, PExpr*lsb, PWSRType type, bool is_scalar);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
|
|
@ -104,6 +105,7 @@ class PWire : public LineInfo {
|
|||
PExpr*net_msb_;
|
||||
PExpr*net_lsb_;
|
||||
bool net_set_;
|
||||
bool is_scalar_;
|
||||
unsigned error_cnt_;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -25,6 +25,11 @@
|
|||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
static char **string_pool = NULL;
|
||||
static unsigned string_pool_count = 0;
|
||||
#endif
|
||||
|
||||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
|
|
@ -46,6 +51,12 @@ const char* StringHeap::add(const char*text)
|
|||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
if (rem < (len+1)) {
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char **) realloc(string_pool,
|
||||
string_pool_count*sizeof(char **));
|
||||
string_pool[string_pool_count-1] = cell_base_;
|
||||
#endif
|
||||
cell_ptr_ = 0;
|
||||
cell_count_ += 1;
|
||||
assert(cell_base_ != 0);
|
||||
|
|
@ -80,6 +91,22 @@ StringHeapLex::~StringHeapLex()
|
|||
{
|
||||
}
|
||||
|
||||
void StringHeapLex::cleanup()
|
||||
{
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
|
||||
free(string_pool[idx]);
|
||||
}
|
||||
free(string_pool);
|
||||
string_pool = NULL;
|
||||
string_pool_count = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
|
||||
hash_table_[idx] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned StringHeapLex::add_hit_count() const
|
||||
{
|
||||
return hit_count_;
|
||||
|
|
@ -175,4 +202,3 @@ bool operator < (perm_string a, perm_string b)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -104,6 +104,7 @@ class StringHeapLex : private StringHeap {
|
|||
|
||||
unsigned add_count() const;
|
||||
unsigned add_hit_count() const;
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
enum { HASH_SIZE = 4096 };
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
# 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=no])
|
||||
[AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
|
||||
[Use/set the installation command suffix])],
|
||||
[true],[enable_suffix=no])
|
||||
if test X$enable_suffix = Xyes; then
|
||||
install_suffix='-0.9'
|
||||
elif test X$enable_suffix = Xno; then
|
||||
|
|
@ -214,3 +216,17 @@ case "${host}" in
|
|||
;;
|
||||
esac
|
||||
])# AX_CPP_PRECOMP
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp file name are based on the header name.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[
|
||||
_config_header=$1
|
||||
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
|
||||
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
|
||||
]) #_AC_AM_CONFIG_HEADER_HOOK
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ dep:
|
|||
O = cadpli.o
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
../config.status --file=$@
|
||||
cd ..; ./config.status --file=cadpli/$@
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@MINGW32@,yes)
|
||||
|
|
@ -71,7 +71,7 @@ cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
|||
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep cadpli.vpl bin32
|
||||
rm -rf *.o dep cadpli.vpl
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
CADENCE PLI1 MODULES
|
||||
|
||||
Copyright 2003 Stephen Williams
|
||||
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
|
||||
|
||||
With the cadpli module, Icarus Verilog is able to load PLI1
|
||||
applications that were compiled and linked to be dynamic loaded by
|
||||
|
|
@ -34,15 +33,3 @@ the +loadpli1= argument to Verilog-XL.
|
|||
The integration from this point is seamless. The PLI application
|
||||
hardly knows that it is being invoked by Icarus Verilog instead of
|
||||
Verilog-XL, so operates as it would otherwise.
|
||||
|
||||
$Log: cadpli.txt,v $
|
||||
Revision 1.2 2003/02/17 00:01:25 steve
|
||||
Use a variant of ivl_dlfcn to do dynamic loading
|
||||
from within the cadpli module.
|
||||
|
||||
Change the +cadpli flag to -cadpli, to keep the
|
||||
plusargs namespace clear.
|
||||
|
||||
Revision 1.1 2003/02/16 02:44:47 steve
|
||||
Add the cadpli HOWTO.
|
||||
|
||||
|
|
|
|||
30
compiler.h
30
compiler.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -36,6 +36,12 @@
|
|||
*/
|
||||
extern unsigned integer_width;
|
||||
|
||||
/*
|
||||
* This is the maximum number of recursive module loops allowed within
|
||||
* a generate block.
|
||||
*/
|
||||
extern unsigned recursive_mod_limit;
|
||||
|
||||
/* The TIME_WIDTH is the width of time variables. */
|
||||
#ifndef TIME_WIDTH
|
||||
# define TIME_WIDTH 64
|
||||
|
|
@ -76,9 +82,17 @@ extern bool warn_timescale;
|
|||
/* Warn about legal but questionable module port bindings. */
|
||||
extern bool warn_portbinding;
|
||||
|
||||
/* Warn about constant out of bound selects. */
|
||||
extern bool warn_ob_select;
|
||||
|
||||
/* Warn about structures that may have infinite loops. */
|
||||
extern bool warn_inf_loop;
|
||||
|
||||
/* Warn about always @* statements where a part or word select causes
|
||||
sensitivity to an entire vector or array. */
|
||||
extern bool warn_sens_entire_vec;
|
||||
extern bool warn_sens_entire_arr;
|
||||
|
||||
/* This is true if verbose output is requested. */
|
||||
extern bool verbose_flag;
|
||||
|
||||
|
|
@ -89,6 +103,12 @@ extern bool debug_elab_pexpr;
|
|||
extern bool debug_synth2;
|
||||
extern bool debug_optimizer;
|
||||
|
||||
/* Possibly temporary flag to control virtualization of pin arrays */
|
||||
extern bool disable_virtual_pins;
|
||||
|
||||
/* Limit to size of devirtualized arrays */
|
||||
extern unsigned long array_size_limit;
|
||||
|
||||
/* Path to a directory useful for finding subcomponents. */
|
||||
extern const char*basedir;
|
||||
|
||||
|
|
@ -101,9 +121,10 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
|
|||
specific language features. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001 = 2,
|
||||
GN_VER2005 = 3,
|
||||
GN_DEFAULT = 3
|
||||
GN_VER2001_NOCONFIG = 2,
|
||||
GN_VER2001 = 3,
|
||||
GN_VER2005 = 4,
|
||||
GN_DEFAULT = 4
|
||||
};
|
||||
|
||||
extern generation_t generation_flag;
|
||||
|
|
@ -189,5 +210,6 @@ struct sfunc_return_type {
|
|||
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
extern void cleanup_sys_func_table();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -50,4 +50,10 @@
|
|||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define this if you want to compile vvp with memory freeing and
|
||||
* special valgrind hooks for the memory pools.
|
||||
*/
|
||||
# undef CHECK_WITH_VALGRIND
|
||||
|
||||
#endif /* __config_H */
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2002-07-03'
|
||||
timestamp='2009-04-17'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
|
|
@ -21,14 +22,15 @@ timestamp='2002-07-03'
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
|
|
@ -70,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
|
@ -83,11 +85,11 @@ Try \`$me --help' for more information."
|
|||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
--time-stamp | --time* | -t )
|
||||
echo "$timestamp" ; exit 0 ;;
|
||||
echo "$timestamp" ; exit ;;
|
||||
--version | -v )
|
||||
echo "$version" ; exit 0 ;;
|
||||
echo "$version" ; exit ;;
|
||||
--help | --h* | -h )
|
||||
echo "$usage"; exit 0 ;;
|
||||
echo "$usage"; exit ;;
|
||||
-- ) # Stop option processing
|
||||
shift; break ;;
|
||||
- ) # Use stdin as input.
|
||||
|
|
@ -99,7 +101,7 @@ while test $# -gt 0 ; do
|
|||
*local*)
|
||||
# First pass through any local machine types.
|
||||
echo $1
|
||||
exit 0;;
|
||||
exit ;;
|
||||
|
||||
* )
|
||||
break ;;
|
||||
|
|
@ -118,7 +120,10 @@ esac
|
|||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
|
|
@ -144,7 +149,7 @@ case $os in
|
|||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis)
|
||||
-apple | -axis | -knuth | -cray)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
|
|
@ -169,6 +174,10 @@ case $os in
|
|||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
-sco6)
|
||||
os=-sco5v6
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco5)
|
||||
os=-sco3.2v5
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
|
|
@ -185,6 +194,10 @@ case $os in
|
|||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco5v6*)
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco*)
|
||||
os=-sco3.2v2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
|
|
@ -228,40 +241,57 @@ case $basic_machine in
|
|||
| a29k \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| fido | fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| ip2k | iq2000 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64octeon | mips64octeonel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64r5900 | mips64r5900el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nios | nios2 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic80 | tron \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xscale | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
|
|
@ -271,6 +301,9 @@ case $basic_machine in
|
|||
;;
|
||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
||||
;;
|
||||
ms1)
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
|
|
@ -290,48 +323,67 @@ case $basic_machine in
|
|||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c54x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| avr-* | avr32-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* \
|
||||
| m32r-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64octeon-* | mips64octeonel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64r5900-* | mips64r5900el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mips64vr5900-* | mips64vr5900el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nios-* | nios2-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
| xtensa-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
| z8k-* | z80-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
|
|
@ -349,6 +401,9 @@ case $basic_machine in
|
|||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
basic_machine=m68010-adobe
|
||||
os=-scout
|
||||
|
|
@ -363,6 +418,12 @@ case $basic_machine in
|
|||
basic_machine=a29k-none
|
||||
os=-bsd
|
||||
;;
|
||||
amd64)
|
||||
basic_machine=x86_64-pc
|
||||
;;
|
||||
amd64-*)
|
||||
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
amdahl)
|
||||
basic_machine=580-amdahl
|
||||
os=-sysv
|
||||
|
|
@ -386,6 +447,10 @@ case $basic_machine in
|
|||
basic_machine=m68k-apollo
|
||||
os=-bsd
|
||||
;;
|
||||
aros)
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
|
|
@ -394,10 +459,22 @@ case $basic_machine in
|
|||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
blackfin)
|
||||
basic_machine=bfin-unknown
|
||||
os=-linux
|
||||
;;
|
||||
blackfin-*)
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
|
|
@ -422,12 +499,27 @@ case $basic_machine in
|
|||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
craynv)
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
basic_machine=m68k-crds
|
||||
;;
|
||||
crisv32 | crisv32-* | etraxfs*)
|
||||
basic_machine=crisv32-axis
|
||||
;;
|
||||
cris | cris-* | etrax*)
|
||||
basic_machine=cris-axis
|
||||
;;
|
||||
crx)
|
||||
basic_machine=crx-unknown
|
||||
os=-elf
|
||||
;;
|
||||
da30 | da30-*)
|
||||
basic_machine=m68k-da30
|
||||
;;
|
||||
|
|
@ -450,6 +542,14 @@ case $basic_machine in
|
|||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dicos)
|
||||
basic_machine=i686-pc
|
||||
os=-dicos
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
;;
|
||||
dpx20 | dpx20-*)
|
||||
basic_machine=rs6000-bull
|
||||
os=-bosx
|
||||
|
|
@ -600,6 +700,14 @@ case $basic_machine in
|
|||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
;;
|
||||
m68knommu-*)
|
||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
|
|
@ -615,6 +723,10 @@ case $basic_machine in
|
|||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
basic_machine=arm-unknown
|
||||
os=-mingw32ce
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
|
|
@ -628,10 +740,6 @@ case $basic_machine in
|
|||
mips3*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||
;;
|
||||
mmix*)
|
||||
basic_machine=mmix-knuth
|
||||
os=-mmixware
|
||||
;;
|
||||
monitor)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
|
|
@ -644,6 +752,9 @@ case $basic_machine in
|
|||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
;;
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
|
|
@ -719,9 +830,12 @@ case $basic_machine in
|
|||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
or32 | or32-*)
|
||||
openrisc | openrisc-*)
|
||||
basic_machine=or32-unknown
|
||||
os=-coff
|
||||
;;
|
||||
os400)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-os400
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
|
|
@ -739,55 +853,75 @@ case $basic_machine in
|
|||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
parisc)
|
||||
basic_machine=hppa-unknown
|
||||
os=-linux
|
||||
;;
|
||||
parisc-*)
|
||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
pbb)
|
||||
basic_machine=m68k-tti
|
||||
;;
|
||||
pc532 | pc532-*)
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pc98)
|
||||
basic_machine=i386-pc
|
||||
;;
|
||||
pc98-*)
|
||||
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6 | 6x86 | athlon)
|
||||
pentiumpro | p6 | 6x86 | athlon | athlon_*)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentiumii | pentium2)
|
||||
pentiumii | pentium2 | pentiumiii | pentium3)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentium4)
|
||||
basic_machine=i786-pc
|
||||
;;
|
||||
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumpro-* | p6-* | 6x86-* | athlon-*)
|
||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumii-* | pentium2-*)
|
||||
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
|
||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentium4-*)
|
||||
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pn)
|
||||
basic_machine=pn-gould
|
||||
;;
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64) basic_machine=powerpc64-unknown
|
||||
;;
|
||||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
|
|
@ -798,6 +932,10 @@ case $basic_machine in
|
|||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rom68k)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
|
|
@ -818,6 +956,20 @@ case $basic_machine in
|
|||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
sb1)
|
||||
basic_machine=mipsisa64sb1-unknown
|
||||
;;
|
||||
sb1el)
|
||||
basic_machine=mipsisa64sb1el-unknown
|
||||
;;
|
||||
sde)
|
||||
basic_machine=mipsisa32-sde
|
||||
os=-elf
|
||||
;;
|
||||
sei)
|
||||
basic_machine=mips-sei
|
||||
os=-seiux
|
||||
;;
|
||||
sequent)
|
||||
basic_machine=i386-sequent
|
||||
;;
|
||||
|
|
@ -825,6 +977,12 @@ case $basic_machine in
|
|||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sh5el)
|
||||
basic_machine=sh5le-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparclite-wrs | simso-wrs)
|
||||
basic_machine=sparclite-wrs
|
||||
os=-vxworks
|
||||
|
|
@ -883,7 +1041,7 @@ case $basic_machine in
|
|||
sun386 | sun386i | roadrunner)
|
||||
basic_machine=i386-sun
|
||||
;;
|
||||
sv1)
|
||||
sv1)
|
||||
basic_machine=sv1-cray
|
||||
os=-unicos
|
||||
;;
|
||||
|
|
@ -891,10 +1049,6 @@ case $basic_machine in
|
|||
basic_machine=i386-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
t3d)
|
||||
basic_machine=alpha-cray
|
||||
os=-unicos
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=alphaev5-cray
|
||||
os=-unicos
|
||||
|
|
@ -907,6 +1061,18 @@ case $basic_machine in
|
|||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic55x | c55x*)
|
||||
basic_machine=tic55x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic6x | c6x*)
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
|
|
@ -920,6 +1086,10 @@ case $basic_machine in
|
|||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
tpf)
|
||||
basic_machine=s390x-ibm
|
||||
os=-tpf
|
||||
;;
|
||||
udi29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
|
|
@ -941,8 +1111,8 @@ case $basic_machine in
|
|||
os=-vms
|
||||
;;
|
||||
vpp*|vx|vx-*)
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
vxworks960)
|
||||
basic_machine=i960-wrs
|
||||
os=-vxworks
|
||||
|
|
@ -963,11 +1133,11 @@ case $basic_machine in
|
|||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
windows32)
|
||||
basic_machine=i386-pc
|
||||
os=-windows32-msvcrt
|
||||
xbox)
|
||||
basic_machine=i686-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
xps | xps100)
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
ymp)
|
||||
|
|
@ -978,6 +1148,10 @@ case $basic_machine in
|
|||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
;;
|
||||
z80-*-coff)
|
||||
basic_machine=z80-unknown
|
||||
os=-sim
|
||||
;;
|
||||
none)
|
||||
basic_machine=none-none
|
||||
os=-none
|
||||
|
|
@ -997,6 +1171,9 @@ case $basic_machine in
|
|||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
mmix)
|
||||
basic_machine=mmix-knuth
|
||||
;;
|
||||
rs6000)
|
||||
basic_machine=rs6000-ibm
|
||||
;;
|
||||
|
|
@ -1013,16 +1190,13 @@ case $basic_machine in
|
|||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
|
||||
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
cydra)
|
||||
basic_machine=cydra-cydrome
|
||||
;;
|
||||
orion)
|
||||
|
|
@ -1037,10 +1211,6 @@ case $basic_machine in
|
|||
pmac | pmac-mpw)
|
||||
basic_machine=powerpc-apple
|
||||
;;
|
||||
c4x*)
|
||||
basic_machine=c4x-none
|
||||
os=-coff
|
||||
;;
|
||||
*-unknown)
|
||||
# Make sure to match an already-canonicalized machine name.
|
||||
;;
|
||||
|
|
@ -1092,22 +1262,28 @@ case $os in
|
|||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -kopensolaris* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* \
|
||||
| -aos* | -aros* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
|
|
@ -1119,16 +1295,24 @@ case $os in
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
-nto-qnx*)
|
||||
;;
|
||||
-nto*)
|
||||
os=-nto-qnx
|
||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
|
||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
||||
;;
|
||||
-mac*)
|
||||
os=`echo $os | sed -e 's|mac|macos|'`
|
||||
;;
|
||||
-linux-dietlibc)
|
||||
os=-linux-dietlibc
|
||||
;;
|
||||
-linux*)
|
||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||
;;
|
||||
-sunos5*)
|
||||
os=`echo $os | sed -e 's|sunos5|solaris2|'`
|
||||
;;
|
||||
|
|
@ -1138,6 +1322,9 @@ case $os in
|
|||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
os=-wince
|
||||
;;
|
||||
|
|
@ -1159,6 +1346,9 @@ case $os in
|
|||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-syllable*)
|
||||
os=-syllable
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
|
|
@ -1169,7 +1359,7 @@ case $os in
|
|||
os=-rtmk-nova
|
||||
;;
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk*)
|
||||
os=-nsk
|
||||
|
|
@ -1181,6 +1371,9 @@ case $os in
|
|||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
os=-sysv3
|
||||
;;
|
||||
|
|
@ -1208,8 +1401,20 @@ case $os in
|
|||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
;;
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
|
|
@ -1233,6 +1438,12 @@ else
|
|||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
os=-riscix1.2
|
||||
;;
|
||||
|
|
@ -1242,11 +1453,14 @@ case $basic_machine in
|
|||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
;;
|
||||
pdp11-*)
|
||||
pdp11-*)
|
||||
os=-none
|
||||
;;
|
||||
*-dec | vax-*)
|
||||
|
|
@ -1267,6 +1481,9 @@ case $basic_machine in
|
|||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
os=-elf
|
||||
;;
|
||||
|
|
@ -1285,9 +1502,15 @@ case $basic_machine in
|
|||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
*-haiku)
|
||||
os=-haiku
|
||||
;;
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
os=-proelf
|
||||
;;
|
||||
|
|
@ -1339,19 +1562,19 @@ case $basic_machine in
|
|||
*-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
*-gould)
|
||||
*-gould)
|
||||
os=-sysv
|
||||
;;
|
||||
*-highlevel)
|
||||
*-highlevel)
|
||||
os=-bsd
|
||||
;;
|
||||
*-encore)
|
||||
os=-bsd
|
||||
;;
|
||||
*-sgi)
|
||||
*-sgi)
|
||||
os=-irix
|
||||
;;
|
||||
*-siemens)
|
||||
*-siemens)
|
||||
os=-sysv4
|
||||
;;
|
||||
*-masscomp)
|
||||
|
|
@ -1420,9 +1643,15 @@ case $basic_machine in
|
|||
-mvs* | -opened*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-os400*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-tpf*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
|
|
@ -1447,7 +1676,7 @@ case $basic_machine in
|
|||
esac
|
||||
|
||||
echo $basic_machine$os
|
||||
exit 0
|
||||
exit
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
|
|
|
|||
58
configure.in
58
configure.in
|
|
@ -11,6 +11,13 @@ AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
|
|||
AC_CANONICAL_HOST
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
|
||||
# If you must use an older version then comment out the following two
|
||||
# lines, but be warned that there could be issues with finding the
|
||||
# nan(), etc. functions. It is really best to upgrade to a supported
|
||||
# version of autoconf.
|
||||
AC_PREREQ([2.60])
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
|
@ -79,12 +86,17 @@ AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
|
|||
fi
|
||||
AC_SUBST(HAVE_LIBBZ2)
|
||||
|
||||
# The lxt/lxt2 files from GTKWave use these...
|
||||
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_FSEEKO
|
||||
|
||||
# valgrind checks
|
||||
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind],
|
||||
AC_ARG_WITH([valgrind], [AC_HELP_STRING([--with-valgrind],
|
||||
[Add valgrind hooks])],
|
||||
[], [check_valgrind=yes])
|
||||
|
||||
AS_IF([test "x$check_valgrind" == xyes],
|
||||
AS_IF([test "x$check_valgrind" = xyes],
|
||||
[AC_MSG_NOTICE([Not using valgrind hooks])],
|
||||
[AC_CHECK_HEADER([valgrind/memcheck.h],
|
||||
[AC_DEFINE([CHECK_WITH_VALGRIND], [1],
|
||||
|
|
@ -156,7 +168,41 @@ AC_SUBST(file64_support)
|
|||
|
||||
# Check that these functions exist. They are mostly C99
|
||||
# functions that older compilers may not yet support.
|
||||
AC_CHECK_FUNCS(lround nan fmin fmax fopen64)
|
||||
AC_CHECK_FUNCS(fopen64)
|
||||
# The following math functions may be defined in the math library so look
|
||||
# in the default libraries first and then look in -lm for them. On some
|
||||
# systems we may need to use the compiler in C99 mode to get a definition.
|
||||
# We requested C99 mode earlier with AC_PROG_CC_C99.
|
||||
AC_SEARCH_LIBS([lround], [m], [AC_DEFINE([HAVE_LROUND], [1])])
|
||||
AC_SEARCH_LIBS([llround], [m], [AC_DEFINE([HAVE_LLROUND], [1])])
|
||||
AC_SEARCH_LIBS([nan], [m], [AC_DEFINE([HAVE_NAN], [1])])
|
||||
AC_SEARCH_LIBS([fmin], [m], [AC_DEFINE([HAVE_FMIN], [1])])
|
||||
AC_SEARCH_LIBS([fmax], [m], [AC_DEFINE([HAVE_FMAX], [1])])
|
||||
|
||||
# Check to see if an unsigned long and uint64_t are the same from
|
||||
# a compiler perspective. We can not just check that they are the
|
||||
# same size since unsigned long and unsigned long long are not the
|
||||
# same from an overloading perspective even though they could be
|
||||
# the same size on some 64 bit machines. The result from this test
|
||||
# is only used if inttypes.h is available, so if the test fails for
|
||||
# that reason we don't care.
|
||||
AC_LANG(C++)
|
||||
AC_MSG_CHECKING(if uint64_t and unsigned long are identical)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "inttypes.h"
|
||||
static bool check(unsigned long val)
|
||||
{
|
||||
return val != 0;
|
||||
}
|
||||
static bool check(uint64_t val)
|
||||
{
|
||||
return val != 0;
|
||||
}]], [[unsigned long ulval = 1;
|
||||
bool result = check(ulval);
|
||||
uint64_t uival = 1;
|
||||
result &= check(uival);
|
||||
return !result;]])],
|
||||
[AC_MSG_RESULT(no)],
|
||||
[AC_DEFINE([UINT64_T_AND_ULONG_SAME], [1]) AC_MSG_RESULT(yes)])
|
||||
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
|
@ -181,21 +227,21 @@ AX_C_UNDERSCORES_TRAILING
|
|||
#######################
|
||||
|
||||
AC_MSG_CHECKING(for sanity of prefix)
|
||||
if test X`echo "$prefix" | wc -w` != X1
|
||||
if test `echo "$prefix" | wc -w` != 1
|
||||
then
|
||||
AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AC_MSG_CHECKING(for sanity of exec_prefix)
|
||||
if test X`echo "$exec_prefix" | wc -w` != X1
|
||||
if test `echo "$exec_prefix" | wc -w` != 1
|
||||
then
|
||||
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AC_MSG_CHECKING(for sanity of libdir)
|
||||
if test X`echo "$libdir" | wc -w` != X1
|
||||
if test `echo "$libdir" | wc -w` != 1
|
||||
then
|
||||
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
|
||||
fi
|
||||
|
|
|
|||
4
cprop.cc
4
cprop.cc
|
|
@ -823,6 +823,10 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
|||
|
||||
/* If the select input is constant, then replace with a BUFZ */
|
||||
bool flag = obj->pin_Sel().nexus()->drivers_constant();
|
||||
/* Note that this cannot be constant if there are assignments
|
||||
to this nexus. (Assignments include "force" to nets.) */
|
||||
flag &= !obj->pin_Sel().nexus()->assign_lval();
|
||||
|
||||
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
|
||||
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
|
||||
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -208,8 +208,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
|||
o << " scope=" << scope_path(scope());
|
||||
o << " #(" << rise_time() << "," << fall_time() << ","
|
||||
<< decay_time() << ") vector_width=" << vector_width()
|
||||
<< " pin_count=" << pin_count()
|
||||
<< " init=";
|
||||
<< " pin_count=" << pin_count();
|
||||
if (pins_are_virtual()) {
|
||||
o << " pins_are_virtual" << endl;
|
||||
return;
|
||||
}
|
||||
o << " init=";
|
||||
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
|
||||
o << pin(idx-1).get_init();
|
||||
|
||||
|
|
@ -1073,29 +1077,11 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
|
|||
void NetScope::dump(ostream&o) const
|
||||
{
|
||||
/* This is a constructed hierarchical name. */
|
||||
o << scope_path(this);
|
||||
o << scope_path(this) << " ";
|
||||
|
||||
switch (type_) {
|
||||
case BEGIN_END:
|
||||
o << " sequential block";
|
||||
break;
|
||||
case FORK_JOIN:
|
||||
o << " parallel block";
|
||||
break;
|
||||
case FUNC:
|
||||
o << " function";
|
||||
break;
|
||||
case MODULE:
|
||||
o << " module <" << (module_name_? module_name_.str() : "") << ">";
|
||||
break;
|
||||
case TASK:
|
||||
o << " task";
|
||||
break;
|
||||
case GENBLOCK:
|
||||
o << " generate block";
|
||||
break;
|
||||
}
|
||||
print_type(o);
|
||||
if (is_auto()) o << " (automatic)";
|
||||
if (is_cell()) o << " (cell)";
|
||||
o << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||
|
|
|
|||
28
dosify.c
28
dosify.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is a simple program to make a dosified copy of the
|
||||
|
|
@ -51,6 +48,7 @@ int main(int argc, char*argv[])
|
|||
ofile = fopen(argv[2], "wb");
|
||||
if (ofile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
|
||||
fclose(ifile);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
@ -64,25 +62,7 @@ int main(int argc, char*argv[])
|
|||
pr = ch;
|
||||
}
|
||||
|
||||
fclose(ifile);
|
||||
fclose(ofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dosify.c,v $
|
||||
* Revision 1.5 2003/07/15 16:17:47 steve
|
||||
* Fix spelling of ifdef.
|
||||
*
|
||||
* Revision 1.4 2003/07/15 03:49:22 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.1 2001/08/03 17:06:47 steve
|
||||
* Add install of examples for Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -50,20 +50,20 @@ all: iverilog-vpi@EXEEXT@
|
|||
check: all
|
||||
|
||||
clean:
|
||||
rm -f *.o config.h iverilog-vpi@EXEEXT@
|
||||
rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
../config.status --file=$@
|
||||
cd ..; ./config.status --file=driver-vpi/$@
|
||||
|
||||
O = main.o res.o
|
||||
|
||||
iverilog-vpi@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
main.o: main.c config.h
|
||||
main.o: $(srcdir)/main.c config.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||
|
||||
|
||||
|
|
@ -74,6 +74,10 @@ config.h: $(srcdir)/config.h.in Makefile
|
|||
-e 's;@SHARED@;@shared@;' $< > $@
|
||||
|
||||
# Windows specific...
|
||||
res.rc: $(srcdir)/res.rc.in ../version.exe
|
||||
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,0'`';' \
|
||||
$(srcdir)/res.rc.in > $@
|
||||
|
||||
res.o: res.rc
|
||||
windres -i res.rc -o res.o
|
||||
#
|
||||
|
|
|
|||
|
|
@ -413,11 +413,18 @@ static void checkMingwDir(char *root)
|
|||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
char *path, *comp, *cp;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
|
||||
append(&path,"bin\\");
|
||||
/* Get just the compiler name (the first word) */
|
||||
comp = strdup(IVERILOG_VPI_CC);
|
||||
cp = strchr(comp, ' ');
|
||||
if (cp != NULL) *cp = '\0';
|
||||
append(&path, comp);
|
||||
append(&path,".exe");
|
||||
free(comp);
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
|
@ -511,16 +518,16 @@ static void setup_ivl_environment()
|
|||
}
|
||||
|
||||
/* Build up the CFLAGS option string */
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I");
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\iverilog" IVERILOG_SUFFIX);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the LDFLAGS option string */
|
||||
assign(&gstr.pLDLIBS,"-L");
|
||||
assign(&gstr.pLDLIBS,"-L\"");
|
||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pLDLIBS);
|
||||
append(&gstr.pLDLIBS,"\\lib " IVERILOG_VPI_LDLIBS);
|
||||
append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
|
||||
}
|
||||
|
||||
/* compile source modules */
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ LANGUAGE 9, 4
|
|||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 2002,11,13,0
|
||||
PRODUCTVERSION 0,7,0,0
|
||||
PRODUCTVERSION @PRODUCTVERSION@
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x2L
|
||||
FILEOS 0x40004L
|
||||
|
|
@ -28,7 +28,7 @@ BEGIN
|
|||
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
|
||||
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
|
||||
VALUE "ProductName", "Icarus Verilog\0"
|
||||
VALUE "ProductVersion", "0, 7, 0, 0\0"
|
||||
VALUE "ProductVersion", "@PRODUCTVERSION@\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
@ -45,21 +45,20 @@ CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
|
|||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: dep iverilog@EXEEXT@
|
||||
all: dep iverilog@EXEEXT@ iverilog.man
|
||||
|
||||
check: all
|
||||
|
||||
clean:
|
||||
rm -f *.o lexor.c parse.c parse.h parse.output
|
||||
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
|
||||
rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
|
||||
rm -rf dep
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
../config.status --file=$@
|
||||
cd ..; ./config.status --file=driver/$@
|
||||
|
||||
O = main.o substit.o cflexor.o cfparse.o
|
||||
|
||||
|
|
@ -79,14 +78,18 @@ dep:
|
|||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
main.o: main.c globals.h ../version.h Makefile
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
mv $*.d dep
|
||||
|
||||
cflexor.o: cflexor.c cfparse.h
|
||||
|
||||
iverilog.ps: $(srcdir)/iverilog.man
|
||||
$(MAN) -t $(srcdir)/iverilog.man > iverilog.ps
|
||||
iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
|
||||
../version.exe `head -1 $(srcdir)/iverilog.man.in`'\n' > $@
|
||||
tail -n +2 $(srcdir)/iverilog.man.in >> $@
|
||||
|
||||
iverilog.ps: iverilog.man
|
||||
$(MAN) -t iverilog.man > iverilog.ps
|
||||
|
||||
iverilog.pdf: iverilog.ps
|
||||
$(PS2PDF) iverilog.ps iverilog.pdf
|
||||
|
|
@ -113,8 +116,8 @@ install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
|
|||
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
|
||||
|
||||
$(mandir)/man1/iverilog$(suffix).1: $(srcdir)/iverilog.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
|
||||
$(mandir)/man1/iverilog$(suffix).1: iverilog.man
|
||||
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
|
||||
|
||||
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf
|
||||
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -21,9 +21,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
# include "cfparse_misc.h"
|
||||
|
|
@ -236,3 +233,17 @@ void cfreset(FILE*fd, const char*path)
|
|||
current_file = strdup(path);
|
||||
cflloc.first_line = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_lexor()
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
%{
|
||||
/*
|
||||
* Copyright (c) 20001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -17,10 +17,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include "cfparse_misc.h"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __cfparse_misc_H
|
||||
#define __cfparse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001 Picture Elements, Inc.
|
||||
* Copyright (c) 2001-2009 Picture Elements, Inc.
|
||||
* Stephen Williams (steve@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -38,6 +38,7 @@ int cflex(void);
|
|||
int cferror(const char *);
|
||||
int cfparse(void);
|
||||
void switch_to_command_file(const char *);
|
||||
void destroy_lexor();
|
||||
char *current_file;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __globals_H
|
||||
#define __globals_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -21,31 +21,6 @@
|
|||
|
||||
# include <stddef.h>
|
||||
|
||||
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
|
||||
extern const char*base;
|
||||
|
||||
/* This is the path to the iconfig file sent to ivl. */
|
||||
extern char* iconfig_path;
|
||||
extern char* iconfig_common_path;
|
||||
|
||||
/* This is the optional -M<dependfile> value, if one was supplied. */
|
||||
extern const char*depfile;
|
||||
|
||||
/* This is the optional -N<path> value, if one was supplied. */
|
||||
extern const char*npath;
|
||||
|
||||
/* This is the name of the output file that the user selected. */
|
||||
extern const char*opath;
|
||||
|
||||
/* This pointer is set if there were -s<value> parameters. */
|
||||
extern char*start;
|
||||
|
||||
/* This flag is true if the -S flag was used on the command line. */
|
||||
extern int synth_flag;
|
||||
|
||||
/* This is the name of the selected target. */
|
||||
extern const char*targ;
|
||||
|
||||
/* This is the integer-width argument that will be passed to ivl. */
|
||||
extern unsigned integer_width;
|
||||
|
||||
|
|
@ -66,13 +41,4 @@ extern void process_include_dir(const char*name);
|
|||
/* Add a new -D define. */
|
||||
extern void process_define(const char*name);
|
||||
|
||||
/* -v */
|
||||
extern int verbose_flag;
|
||||
|
||||
extern char warning_flags[];
|
||||
|
||||
/* -y and -Y flags from the command line. */
|
||||
extern char* library_flags;
|
||||
extern char* library_flags2;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
.TH iverilog 1 "February 4th, 2009" "" "Version 0.9.devel"
|
||||
.TH iverilog 1 "October 28th, 2009" "" "Version %M.%m.%n %E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-dname] [-g1995|-g2001|-g2005|-g<feature>]
|
||||
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
|
||||
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]] [\-pflag=value]
|
||||
[\-dname] [\-g1995|\-g2001|\-g2005|\-g<feature>]
|
||||
[\-Iincludedir] [\-mmodule] [\-Mfile] [\-Nfile] [\-ooutputfilename]
|
||||
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
|
|
@ -18,14 +18,13 @@ simulation, and \fIfpga\fP for synthesis. Other target
|
|||
types are added as code generators are implemented.
|
||||
|
||||
.SH OPTIONS
|
||||
.l
|
||||
\fIiverilog\fP accepts the following options:
|
||||
.TP 8
|
||||
.B -B\fIbase\fP
|
||||
The \fIiverilog\fP program uses external programs and configuration
|
||||
files to preprocess and compile the Verilog source. Normally, the path
|
||||
used to locate these tools is built into the \fIiverilog\fP
|
||||
program. However, the \fB-B\fP switch allows the user to select a
|
||||
program. However, the \fB\-B\fP switch allows the user to select a
|
||||
different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
|
|
@ -44,7 +43,7 @@ Verilog source.
|
|||
Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
.TP 8
|
||||
.B -d\fIname\fP
|
||||
Activate a class of compiler debugging messages. The \fB-d\fP switch may
|
||||
Activate a class of compiler debugging messages. The \fB\-d\fP switch may
|
||||
be used as often as necessary to activate all the desired messages.
|
||||
Supported names are scopes, eval_tree, elaborate, and synth2;
|
||||
any other names are ignored.
|
||||
|
|
@ -55,17 +54,18 @@ is the Verilog input, but with file inclusions and macro references
|
|||
expanded and removed. This is useful, for example, to preprocess
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -g1995\fI|\fP-g2001\fI|\fP-g2005
|
||||
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005
|
||||
Select the Verilog language \fIgeneration\fP to support in the
|
||||
compiler. This selects between \fIIEEE1364-1995\fP,
|
||||
\fIIEEE1364-2001\fP(2), or \fIIEEE1364-2005\fP. Normally,
|
||||
compiler. This selects between \fIIEEE1364\-1995\fP,
|
||||
\fIIEEE1364\-2001\fP, or \fIIEEE1364\-2005\fP. Normally,
|
||||
Icarus Verilog defaults to the latest known generation of the
|
||||
language. This flag is most useful to restrict the language to a set
|
||||
supported by tools of specific generations, for compatibility with
|
||||
other tools.
|
||||
.TP 8
|
||||
.B -gverilog-ams\fI|-fP-gno-verilog-ams
|
||||
Enable or disable (default) support for Verilog-AMS.
|
||||
.B -gverilog-ams\fI|\fP-gno-verilog-ams
|
||||
Enable or disable (default) support for Verilog\-AMS.
|
||||
Very little Verilog\-AMS specific functionality is currently supported.
|
||||
.TP 8
|
||||
.B -gspecify\fI|\fP-gno-specify
|
||||
Enable or disable (default) specify block support. When enabled,
|
||||
|
|
@ -100,7 +100,7 @@ The standards requires that a vectored port have matching ranges for its
|
|||
port declaration as well as any net/register declaration. It was common
|
||||
practice in the past to only specify the range for the net/register
|
||||
declaration and some tools still allow this. By default any mismatch is
|
||||
reported as a error. Using \fI-gno-io-range-error\fP will produce a
|
||||
reported as a error. Using \fB\-gno\-io\-range\-error\fP will produce a
|
||||
warning instead of a fatal error for the case of a vectored net/register
|
||||
and a scalar port declaration.
|
||||
.TP 8
|
||||
|
|
@ -110,13 +110,13 @@ expression changes value, the entire expression is re-evaluated. By
|
|||
default, parts of the expression that do not depend on the changed
|
||||
input value(s) are not re-evaluated. If an expression contains a call
|
||||
to a function that doesn't depend solely on its input values or that
|
||||
has side effects, the resulting behaviour will differ from that
|
||||
required by the standard. Using \fI-gstrict-ca-eval\fP will force
|
||||
standard compliant behaviour (with some loss in performance).
|
||||
has side effects, the resulting behavior will differ from that
|
||||
required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
|
||||
standard compliant behavior (with some loss in performance).
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
for Verilog include files. The \fB-I\fP switch may be used many times
|
||||
for Verilog include files. The \fB\-I\fP switch may be used many times
|
||||
to specify several directories to search, the directories are searched
|
||||
in the order they appear on the command line.
|
||||
.TP 8
|
||||
|
|
@ -145,7 +145,7 @@ Place output in the file \fIfilename\fP. If no output file name is
|
|||
specified, \fIiverilog\fP uses the default name \fBa.out\fP.
|
||||
.TP 8
|
||||
.B -p\fIflag=value\fP
|
||||
Assign a value to a target specific flag. The \fB-p\fP switch may be
|
||||
Assign a value to a target specific flag. The \fB\-p\fP switch may be
|
||||
used as often as necessary to specify all the desired flags. The flags
|
||||
that are used depend on the target that is selected, and are described
|
||||
in target specific documentation. Flags that are not used are ignored.
|
||||
|
|
@ -153,15 +153,15 @@ in target specific documentation. Flags that are not used are ignored.
|
|||
.B -S
|
||||
Synthesize. Normally, if the target can accept behavioral
|
||||
descriptions the compiler will leave processes in behavioral
|
||||
form. The \fB-S\fP switch causes the compiler to perform synthesis
|
||||
form. The \fB\-S\fP switch causes the compiler to perform synthesis
|
||||
even if it is not necessary for the target. If the target type is a
|
||||
netlist format, the \fB-S\fP switch is unnecessary and has no effect.
|
||||
netlist format, the \fB\-S\fP switch is unnecessary and has no effect.
|
||||
.TP 8
|
||||
.B -s \fItopmodule\fP
|
||||
Specify the top level module to elaborate. Icarus Verilog will by default
|
||||
choose modules that are not instantiated in any other modules, but
|
||||
sometimes that is not sufficient, or instantiates too many modules. If
|
||||
the user specifies one or more root modules with \fB-s\fP flags, then
|
||||
the user specifies one or more root modules with \fB\-s\fP flags, then
|
||||
they will be used as root modules instead.
|
||||
.TP 8
|
||||
.B -T\fImin|typ|max\fP
|
||||
|
|
@ -191,13 +191,18 @@ Print the version of the compiler, and exit.
|
|||
.B -W\fIclass\fP
|
||||
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
|
||||
section below for descriptions of the different warning groups. If
|
||||
multiple \fB-W\fP switches are used, the warning set is the union of
|
||||
multiple \fB\-W\fP switches are used, the warning set is the union of
|
||||
all the requested classes.
|
||||
.TP 8
|
||||
.B -y\fIlibdir\fP
|
||||
Append the directory to the library module search path. When the
|
||||
compiler finds an undefined module, it looks in these directories for
|
||||
files with the right name.
|
||||
.TP 8
|
||||
.B -Y\fIsuffix\fP
|
||||
Add suffix to the list of accepted file name suffixes used when
|
||||
searching a library for cells. The list defaults to the single
|
||||
entry \fI.v\fP.
|
||||
|
||||
.SH MODULE LIBRARIES
|
||||
|
||||
|
|
@ -216,7 +221,7 @@ library or in the main design.
|
|||
.SH TARGETS
|
||||
|
||||
The Icarus Verilog compiler supports a variety of targets, for
|
||||
different purposes, and the \fB-t\fP switch is used to select the
|
||||
different purposes, and the \fB\-t\fP switch is used to select the
|
||||
desired target.
|
||||
|
||||
.TP 8
|
||||
|
|
@ -234,7 +239,7 @@ This is a synthesis target that supports a variety of fpga devices,
|
|||
mostly by EDIF format output. The Icarus Verilog fpga code generator
|
||||
can generate complete designs or EDIF macros that can in turn be
|
||||
imported into larger designs by other tools. The \fBfpga\fP target
|
||||
implies the synthesis \fB-S\fP flag.
|
||||
implies the synthesis \fB\-S\fP flag.
|
||||
.TP 8
|
||||
.B vhdl
|
||||
This target produces a VHDL translation of the Verilog netlist. The
|
||||
|
|
@ -243,14 +248,15 @@ the modules in the Verilog source code. Note that only a subset of
|
|||
the Verilog language is supported. See the wiki for more information.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
These are the types of warnings that can be selected by the \fB-W\fP
|
||||
These are the types of warnings that can be selected by the \fB\-W\fP
|
||||
switch. All the warning types (other than \fBall\fP) can also be
|
||||
prefixed with \fBno-\fP to turn off that warning. This is most useful
|
||||
after a \fB-Wall\fP argument to suppress isolated warning types.
|
||||
prefixed with \fBno\-\fP to turn off that warning. This is most useful
|
||||
after a \fB\-Wall\fP argument to suppress isolated warning types.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
This enables all supported warning categories.
|
||||
This enables the implicit, portbind, select\-range, timescale, and
|
||||
sensitivity\-entire\-array warning categories.
|
||||
|
||||
.TP 8
|
||||
.B implicit
|
||||
|
|
@ -264,6 +270,12 @@ This enables warnings for ports of module instantiations that are not
|
|||
connected but probably should be. Dangling input ports, for example,
|
||||
will generate a warning.
|
||||
|
||||
.TP 8
|
||||
.B select-range
|
||||
This enables warnings for constant out of bound selects. This includes
|
||||
partial or fully out of bound selects as well as a select containing
|
||||
a 'bx or 'bz in the index.
|
||||
|
||||
.TP 8
|
||||
.B timescale
|
||||
This enables warnings for inconsistent use of the timescale
|
||||
|
|
@ -276,7 +288,7 @@ and dependent on compilation order.
|
|||
.B infloop
|
||||
This enables warnings for \fRalways\fP statements that may have runtime
|
||||
infinite loops (has paths with no or zero delay). This class of warnings
|
||||
is not included in \fB-Wall\fP and hence does not have a \fBno-\fP variant.
|
||||
is not included in \fB\-Wall\fP and hence does not have a \fBno\-\fP variant.
|
||||
A fatal error message will always be printed when the compiler can
|
||||
determine that there will definitely be an infinite loop (all paths have
|
||||
no or zero delay).
|
||||
|
|
@ -287,6 +299,22 @@ verified. It is expected that many of the warnings will be false
|
|||
positives, since the code treats the value of all variables and signals
|
||||
as indeterminate.
|
||||
|
||||
.TP 8
|
||||
.B sensitivity-entire-vector
|
||||
This enables warnings for when a part select within an "always @*"
|
||||
statement results in the entire vector being added to the implicit
|
||||
sensitivity list. Although this behaviour is prescribed by the IEEE
|
||||
standard, it is not what might be expected and can have performance
|
||||
implications if the vector is large.
|
||||
|
||||
.TP 8
|
||||
.B sensitivity-entire-array
|
||||
This enables warnings for when a word select within an "always @*"
|
||||
statement results in the entire array being added to the implicit
|
||||
sensitivity list. Although this behaviour is prescribed by the IEEE
|
||||
standard, it is not what might be expected and can have performance
|
||||
implications if the array is large.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||
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
|
||||
|
|
@ -328,14 +356,14 @@ character. Variables are substituted in file names.
|
|||
|
||||
.TP 8
|
||||
.B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP
|
||||
A \fB-c\fP or \fB-f\fP token prefixes a command file, exactly like it
|
||||
A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it
|
||||
does on the command line. The cmdfile may be on the same line or the
|
||||
next non-comment line.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB-y\fP token prefixes a library directory in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB-y\fP
|
||||
A \fB\-y\fP token prefixes a library directory in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB\-y\fP
|
||||
flag may be on the same line or the next non-comment line.
|
||||
|
||||
Variables in the \fIlibdir\fP are substituted.
|
||||
|
|
@ -343,7 +371,7 @@ Variables in the \fIlibdir\fP are substituted.
|
|||
.TP 8
|
||||
.B +incdir+\fIincludedir\fP
|
||||
The \fB+incdir+\fP token in command files gives directories to search
|
||||
for include files in much the same way that \fB-I\fP flags work on the
|
||||
for include files in much the same way that \fB\-I\fP flags work on the
|
||||
command line. The difference is that multiple \fI+includedir\fP
|
||||
directories are valid parameters to a single \fB+incdir+\fP token,
|
||||
although you may also have multiple \fB+incdir+\fP lines.
|
||||
|
|
@ -354,12 +382,12 @@ Variables in the \fIincludedir\fP are substituted.
|
|||
.B +libext+\fIext\fP
|
||||
The \fB+libext\fP token in command files fives file extensions to try
|
||||
when looking for a library file. This is useful in conjunction with
|
||||
\fB-y\fP flags to list suffixes to try in each directory before moving
|
||||
\fB\-y\fP flags to list suffixes to try in each directory before moving
|
||||
on to the next library directory.
|
||||
|
||||
.TP 8
|
||||
.B +libdir+\fIdir\fP
|
||||
This is another way to specify library directories. See the -y flag.
|
||||
This is another way to specify library directories. See the \-y flag.
|
||||
|
||||
.TP 8
|
||||
.B +libdir-nocase+\fIdir\fP
|
||||
|
|
@ -371,19 +399,19 @@ letters are correct. For example, "foo" matches "Foo.v" but not
|
|||
|
||||
.TP 8
|
||||
.B +define+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+define+\fP token is the same as the \fB-D\fP option on the
|
||||
The \fB+define+\fP token is the same as the \fB\-D\fP option on the
|
||||
command line. The value part of the token is optional.
|
||||
|
||||
.TP 8
|
||||
.B +toupper-filename\fP
|
||||
.B +toupper-filename
|
||||
This token causes file names after this in the command file to be
|
||||
translated to uppercase. This helps with situations where a directory
|
||||
has passed through a DOS machine, and in the process the file names
|
||||
become munged.
|
||||
|
||||
.TP 8
|
||||
.B +tolower-filename\fP
|
||||
This is similar to the \fB+toupper-filename\fP hack described above.
|
||||
.B +tolower-filename
|
||||
This is similar to the \fB+toupper\-filename\fP hack described above.
|
||||
|
||||
.TP 8
|
||||
.B +integer-width+\fIvalue\fP
|
||||
|
|
@ -394,7 +422,8 @@ integer value.
|
|||
.SH "VARIABLES IN COMMAND FILES"
|
||||
|
||||
In certain cases, iverilog supports variables in command files. These
|
||||
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
|
||||
are strings of the form "$(\fIvarname\fP)" or "${\fIvarname\fP}", where
|
||||
\fIvarname\fP is the
|
||||
name of the environment variable to read. The entire string is
|
||||
replaced with the contents of that variable. Variables are only
|
||||
substituted in contexts that explicitly support them, including file
|
||||
|
|
@ -407,12 +436,12 @@ from preprocessor defines elsewhere in the file or the command line.
|
|||
|
||||
The following macros are predefined by the compiler:
|
||||
.TP 8
|
||||
.B __ICARUS__ = 1\fP
|
||||
This is defined always when compiling with Icarus Verilog.
|
||||
.B __ICARUS__ = 1
|
||||
This is always defined when compiling with Icarus Verilog.
|
||||
|
||||
.TP 8
|
||||
.B __VAMS_ENABLE__ = 1\fp
|
||||
This is defined if Verilog-AMS is enabled.
|
||||
.B __VAMS_ENABLE__ = 1
|
||||
This is defined if Verilog\-AMS is enabled.
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
|
|
@ -424,11 +453,11 @@ To compile hello.v to an executable file called a.out:
|
|||
|
||||
To compile hello.v to an executable file called hello:
|
||||
|
||||
iverilog -o hello hello.v
|
||||
iverilog \-o hello hello.v
|
||||
|
||||
To compile and run explicitly using the vvp runtime:
|
||||
|
||||
iverilog -ohello.vvp -tvvp hello.v
|
||||
iverilog \-ohello.vvp \-tvvp hello.v
|
||||
|
||||
.SH "AUTHOR"
|
||||
.nf
|
||||
|
|
@ -443,7 +472,7 @@ Tips on using, debugging, and developing the compiler can be found at
|
|||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002-2008 Stephen Williams
|
||||
Copyright \(co 2002\-2009 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
147
driver/main.c
147
driver/main.c
|
|
@ -18,7 +18,8 @@
|
|||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include "version.h"
|
||||
# include "version_base.h"
|
||||
# include "version_tag.h"
|
||||
|
||||
const char NOTICE[] =
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
|
|
@ -146,8 +147,7 @@ FILE*iconfig_file = 0;
|
|||
|
||||
char*compiled_defines_path = 0;
|
||||
|
||||
static char iconfig_common_path_buf[4096] = "";
|
||||
char*iconfig_common_path = iconfig_common_path_buf;
|
||||
static char iconfig_common_path[4096] = "";
|
||||
|
||||
int synth_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
|
|
@ -230,6 +230,23 @@ static FILE*fopen_safe(const char*path)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/*
|
||||
* The MinGW version of getenv() returns the path with a forward
|
||||
* slash. This should be converted to a back slash to keep every
|
||||
* thing in the code using a back slash. This function wraps the
|
||||
* code for this in one place. The conversion can not be done
|
||||
* directly on the getenv() result since it is const char*.
|
||||
*/
|
||||
static void convert_to_MS_path(char *path)
|
||||
{
|
||||
char *t;
|
||||
for (t = path; *t; t++) {
|
||||
if (*t == '/') *t = '\\';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char*my_tempfile(const char*str, FILE**fout)
|
||||
{
|
||||
FILE*file;
|
||||
|
|
@ -258,7 +275,11 @@ static const char*my_tempfile(const char*str, FILE**fout)
|
|||
file = NULL;
|
||||
while ((retry > 0) && (file == NULL)) {
|
||||
unsigned code = rand();
|
||||
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
|
||||
snprintf(pathbuf, sizeof pathbuf, "%s%c%s%04x",
|
||||
tmpdir, sep, str, code);
|
||||
#ifdef __MINGW32__
|
||||
convert_to_MS_path(pathbuf);
|
||||
#endif
|
||||
file = fopen_safe(pathbuf);
|
||||
retry -= 1;
|
||||
}
|
||||
|
|
@ -281,7 +302,7 @@ static int t_version_only(void)
|
|||
}
|
||||
|
||||
fflush(0);
|
||||
snprintf(tmp, sizeof tmp, "%s%civl -V -C%s -C%s", pbase, sep,
|
||||
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
|
||||
iconfig_path, iconfig_common_path);
|
||||
rc = system(tmp);
|
||||
if (rc != 0) {
|
||||
|
|
@ -302,8 +323,8 @@ static int t_version_only(void)
|
|||
|
||||
static void build_preprocess_command(int e_flag)
|
||||
{
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F%s -f%s -p%s ",
|
||||
pbase,sep, verbose_flag?" -v":"",
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
|
||||
pbase, sep, verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", defines_path, source_path,
|
||||
compiled_defines_path);
|
||||
}
|
||||
|
|
@ -321,7 +342,7 @@ static int t_preprocess_only(void)
|
|||
strcpy(cmd, tmp);
|
||||
|
||||
if (strcmp(opath,"-") != 0) {
|
||||
snprintf(tmp, sizeof tmp, " > %s", opath);
|
||||
snprintf(tmp, sizeof tmp, " > \"%s\"", opath);
|
||||
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += strlen(tmp);
|
||||
|
|
@ -374,14 +395,12 @@ static int t_compile()
|
|||
char*cmd = malloc(ncmd + 1);
|
||||
strcpy(cmd, tmp);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
unsigned ncmd_start = ncmd;
|
||||
#else
|
||||
#ifndef __MINGW32__
|
||||
int rtn;
|
||||
#endif
|
||||
|
||||
/* Build the ivl command and pipe it to the preprocessor. */
|
||||
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
|
||||
snprintf(tmp, sizeof tmp, " | %s%civl", base, sep);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
|
@ -396,35 +415,25 @@ static int t_compile()
|
|||
}
|
||||
|
||||
if (npath != 0) {
|
||||
snprintf(tmp, sizeof tmp, " -N%s", npath);
|
||||
snprintf(tmp, sizeof tmp, " -N\"%s\"", npath);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path);
|
||||
snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path);
|
||||
snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{
|
||||
char *t;
|
||||
for (t = cmd+ncmd_start; *t; t++)
|
||||
{
|
||||
if (*t == '/') *t = '\\';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (verbose_flag)
|
||||
printf("translate: %s\n", cmd);
|
||||
|
|
@ -469,13 +478,18 @@ static void process_warning_switch(const char*name)
|
|||
if (strcmp(name,"all") == 0) {
|
||||
process_warning_switch("implicit");
|
||||
process_warning_switch("portbind");
|
||||
process_warning_switch("select-range");
|
||||
process_warning_switch("timescale");
|
||||
process_warning_switch("sensitivity-entire-array");
|
||||
} else if (strcmp(name,"implicit") == 0) {
|
||||
if (! strchr(warning_flags, 'i'))
|
||||
strcat(warning_flags, "i");
|
||||
} else if (strcmp(name,"portbind") == 0) {
|
||||
if (! strchr(warning_flags, 'p'))
|
||||
strcat(warning_flags, "p");
|
||||
} else if (strcmp(name,"select-range") == 0) {
|
||||
if (! strchr(warning_flags, 's'))
|
||||
strcat(warning_flags, "s");
|
||||
} else if (strcmp(name,"timescale") == 0) {
|
||||
if (! strchr(warning_flags, 't'))
|
||||
strcat(warning_flags, "t");
|
||||
|
|
@ -484,6 +498,12 @@ static void process_warning_switch(const char*name)
|
|||
} else if (strcmp(name,"infloop") == 0) {
|
||||
if (! strchr(warning_flags, 'l'))
|
||||
strcat(warning_flags, "l");
|
||||
} else if (strcmp(name,"sensitivity-entire-vector") == 0) {
|
||||
if (! strchr(warning_flags, 'v'))
|
||||
strcat(warning_flags, "v");
|
||||
} else if (strcmp(name,"sensitivity-entire-array") == 0) {
|
||||
if (! strchr(warning_flags, 'a'))
|
||||
strcat(warning_flags, "a");
|
||||
} else if (strcmp(name,"no-implicit") == 0) {
|
||||
char*cp = strchr(warning_flags, 'i');
|
||||
if (cp) while (*cp) {
|
||||
|
|
@ -496,12 +516,30 @@ static void process_warning_switch(const char*name)
|
|||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-select-range") == 0) {
|
||||
char*cp = strchr(warning_flags, 's');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-timescale") == 0) {
|
||||
char*cp = strchr(warning_flags, 't');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-sensitivity-entire-vector") == 0) {
|
||||
char*cp = strchr(warning_flags, 'v');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-sensitivity-entire-array") == 0) {
|
||||
char*cp = strchr(warning_flags, 'a');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -557,6 +595,9 @@ int process_generation(const char*name)
|
|||
else if (strcmp(name,"2001") == 0)
|
||||
generation = "2001";
|
||||
|
||||
else if (strcmp(name,"2001-noconfig") == 0)
|
||||
generation = "2001-noconfig";
|
||||
|
||||
else if (strcmp(name,"2005") == 0)
|
||||
generation = "2005";
|
||||
|
||||
|
|
@ -670,31 +711,31 @@ int main(int argc, char **argv)
|
|||
int opt, idx;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{ char * s;
|
||||
char basepath[1024];
|
||||
GetModuleFileName(NULL,basepath,1024);
|
||||
/* Calculate the ivl_root from the path to the command. This
|
||||
is necessary because of the installation process on
|
||||
Windows. Mostly, it is those darn drive letters, but oh
|
||||
well. We know the command path is formed like this:
|
||||
|
||||
/* Calculate the ivl_root from the path to the command. This
|
||||
is necessary because of the installation process in
|
||||
Windows. Mostly, it is those darn drive letters, but oh
|
||||
well. We know the command path is formed like this:
|
||||
D:\iverilog\bin\iverilog.exe
|
||||
|
||||
D:\iverilog\bin\iverilog.exe
|
||||
The module path in a Windows installation is the path:
|
||||
|
||||
The IVL_ROOT in a Windows installation is the path:
|
||||
D:\iverilog\lib\ivl$(suffix)
|
||||
|
||||
D:\iverilog\lib\ivl
|
||||
|
||||
so we chop the file name and the last directory by
|
||||
turning the last two \ characters to null. Then we append
|
||||
the lib\ivl to finish. */
|
||||
|
||||
strncpy(ivl_root, basepath, MAXSIZE);
|
||||
so we chop the file name and the last directory by
|
||||
turning the last two \ characters to null. Then we append
|
||||
the lib\ivl$(suffix) to finish. */
|
||||
{ char *s;
|
||||
char basepath[4096], tmp[4096];
|
||||
GetModuleFileName(NULL, tmp, sizeof tmp);
|
||||
/* Convert to a short name to remove any embedded spaces. */
|
||||
GetShortPathName(tmp, basepath, sizeof basepath);
|
||||
strncpy(ivl_root, basepath, MAXSIZE);
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s) *s = 0;
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s) *s = 0;
|
||||
strcat(ivl_root, "\\lib\\ivl");
|
||||
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
|
||||
|
||||
base = ivl_root;
|
||||
}
|
||||
|
|
@ -866,6 +907,20 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case '?':
|
||||
default:
|
||||
fclose(source_file);
|
||||
remove(source_path);
|
||||
free(source_path);
|
||||
fclose(defines_file);
|
||||
remove(defines_path);
|
||||
free(defines_path);
|
||||
fclose(iconfig_file);
|
||||
remove(iconfig_path);
|
||||
free(iconfig_path);
|
||||
remove(compiled_defines_path);
|
||||
free(compiled_defines_path);
|
||||
while( (command_filename = get_cmd_file()) ) {
|
||||
free(command_filename);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -880,8 +935,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Make a common conf file path to reflect the target. */
|
||||
sprintf(iconfig_common_path, "%s%c%s%s.conf",
|
||||
base,sep, targ, synth_flag? "-s" : "");
|
||||
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
|
||||
base, sep, targ, synth_flag? "-s" : "");
|
||||
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
|
|
@ -937,7 +992,9 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
free(command_filename);
|
||||
fclose(fp);
|
||||
}
|
||||
destroy_lexor();
|
||||
|
||||
if (depfile) {
|
||||
fprintf(defines_file, "M:%s\n", depfile);
|
||||
|
|
@ -986,7 +1043,7 @@ int main(int argc, char **argv)
|
|||
/* Write the preprocessor command needed to preprocess a
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s -P%s\n",
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
|
||||
pbase, sep, defines_path, compiled_defines_path);
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,12 +16,10 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
|
@ -35,13 +33,13 @@ char* substitutions(const char*str)
|
|||
|
||||
while (*str) {
|
||||
|
||||
if ((str[0] == '$') && (str[1] == '(')) {
|
||||
/* If I find a $(x) string in the source, replace
|
||||
if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) {
|
||||
/* If I find a $(x) or ${x} string in the source, replace
|
||||
it in the destination with the contents of the
|
||||
environment variable x. */
|
||||
char*name;
|
||||
char*value;
|
||||
const char*ep = strchr(str, ')');
|
||||
const char*ep = strchr(str, (str[1]=='(') ? ')' : '}');
|
||||
str += 2;
|
||||
|
||||
name = malloc(ep-str+1);
|
||||
|
|
@ -51,9 +49,13 @@ char* substitutions(const char*str)
|
|||
str = ep + 1;
|
||||
|
||||
value = getenv(name);
|
||||
free(name);
|
||||
if (value == 0)
|
||||
fprintf(stderr, "Warning: environment variable "
|
||||
"\"%s\" not found during command file "
|
||||
"processing.\n", name);
|
||||
free(name);
|
||||
continue;
|
||||
free(name);
|
||||
|
||||
if (strlen(value) >= (nbuf - (cp-buf))) {
|
||||
size_t old_size = cp - buf;
|
||||
|
|
@ -92,24 +94,3 @@ char* substitutions(const char*str)
|
|||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: substit.c,v $
|
||||
* Revision 1.5 2003/12/19 01:27:10 steve
|
||||
* Fix various unsigned compare warnings.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.2 2002/06/25 01:33:01 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.1 2002/06/23 20:10:51 steve
|
||||
* Variable substitution in command files.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
467
elab_expr.cc
467
elab_expr.cc
|
|
@ -419,10 +419,8 @@ NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des,
|
|||
// If either of the arguments is unsigned, then process both
|
||||
// of them as unsigned. This only impacts the padding that is
|
||||
// done to get the operands to the expr_wid.
|
||||
if (! lp->has_sign())
|
||||
rp->cast_signed(false);
|
||||
if (! rp->has_sign())
|
||||
lp->cast_signed(false);
|
||||
if (! lp->has_sign()) rp->cast_signed(false);
|
||||
if (! rp->has_sign()) lp->cast_signed(false);
|
||||
|
||||
if (expr_wid > 0) {
|
||||
if (type_is_vectorable(lp->expr_type()))
|
||||
|
|
@ -453,6 +451,12 @@ NetExpr* PEBinary::elaborate_expr_base_div_(Design*des,
|
|||
}
|
||||
}
|
||||
|
||||
// If either of the arguments is unsigned, then process both
|
||||
// of them as unsigned. This only impacts the padding that is
|
||||
// done to get the operands to the expr_wid.
|
||||
if (! lp->has_sign()) rp->cast_signed(false);
|
||||
if (! rp->has_sign()) lp->cast_signed(false);
|
||||
|
||||
/* The original elaboration of the left and right expressions
|
||||
already tried to elaborate to the expr_wid. If the
|
||||
expressions are not that width by now, then they need to be
|
||||
|
|
@ -643,13 +647,13 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
|
|||
}
|
||||
|
||||
if (NetEConst*rpc = dynamic_cast<NetEConst*> (rp)) {
|
||||
long shift = rpc->value().as_long();
|
||||
unsigned long shift = rpc->value().as_ulong();
|
||||
|
||||
// Special case: The shift is the size of the entire
|
||||
// left operand, and the shift is unsigned. Elaborate as
|
||||
// a constant-0.
|
||||
if ((op_=='r' || (lp->has_sign()==false))
|
||||
&& shift >= (long)lp->expr_width()) {
|
||||
if ((op_=='r' || (lp->has_sign()==false)) &&
|
||||
shift >= lp->expr_width()) {
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
|
|
@ -666,7 +670,11 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
|
|||
// Special case: the shift is the size of the entire
|
||||
// left operand, and the shift is signed. Elaborate as a
|
||||
// replication of the top bit of the left expression.
|
||||
if (shift >= (long)lp->expr_width()) {
|
||||
//
|
||||
// The above test assures us that op_ == 'R' && the left
|
||||
// argument is signed when the shift is greater than the
|
||||
// expression width.
|
||||
if (shift >= lp->expr_width()) {
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
|
|
@ -685,34 +693,10 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
// Special case: shift is negative (so do a left shift)
|
||||
// and is greater then the output width. Replace the
|
||||
// expression with a constant-0.
|
||||
if (shift < 0 && (0-shift) >= use_wid) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Value signed-right-shifted " << shift
|
||||
<< " beyond width of " << use_wid
|
||||
<< "." << endl;
|
||||
|
||||
tmp = make_const_0(use_wid);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_assert(*this, shift >= 0);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Value signed-right-shifted " << shift
|
||||
<< " beyond width of " << lp->expr_width()
|
||||
<< ". shift=" << shift
|
||||
<< ", expr_wid=" << expr_wid
|
||||
<< ", expr=" << *lp << endl;
|
||||
|
||||
// If this is lossless, then pad the left expression
|
||||
// enough to cover the right shift.
|
||||
if (expr_wid == -2 && use_wid+shift > (long)lp->expr_width()) {
|
||||
if (expr_wid == -2 && use_wid+shift > lp->expr_width()) {
|
||||
lp->cast_signed(lp->has_sign() && op_=='R');
|
||||
lp = pad_to_width(lp, use_wid + shift, *this);
|
||||
}
|
||||
|
||||
|
|
@ -1504,6 +1488,12 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
|||
def->port(idx)->data_type(),
|
||||
def->port(idx)->vector_width(),
|
||||
tmp);
|
||||
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (parms[idx])) {
|
||||
cerr << evt->get_fileline() << ": error: An event '"
|
||||
<< evt->event()->name() << "' can not be a user "
|
||||
"function argument." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug:"
|
||||
<< " function " << path_
|
||||
|
|
@ -1574,8 +1564,8 @@ unsigned PEConcat::test_width(Design*des, NetScope*scope,
|
|||
// Try to evaluate the repeat expression now, so
|
||||
// that we can give the caller an accurate
|
||||
// expression width.
|
||||
repeat_expr_ = elab_and_eval(des, scope, repeat_, -1);
|
||||
if (NetEConst*tmp_c = dynamic_cast<NetEConst*> (repeat_expr_)) {
|
||||
NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
if (NetEConst*tmp_c = dynamic_cast<NetEConst*> (tmp)) {
|
||||
repeat_count = tmp_c->value().as_ulong();
|
||||
|
||||
} else {
|
||||
|
|
@ -1615,25 +1605,13 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count. */
|
||||
if (repeat_) {
|
||||
NetExpr*tmp;
|
||||
if (repeat_expr_ == 0) {
|
||||
// If the expression has not yet been elaborated,
|
||||
// then try now.
|
||||
need_constant_expr = true;
|
||||
tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
need_constant_expr = false;
|
||||
assert(tmp);
|
||||
} else {
|
||||
// If it has been elaborated, make sure it is
|
||||
// fully evaluated.
|
||||
tmp = repeat_expr_;
|
||||
need_constant_expr = true;
|
||||
eval_expr(tmp);
|
||||
need_constant_expr = false;
|
||||
}
|
||||
need_constant_expr = true;
|
||||
NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
need_constant_expr = false;
|
||||
assert(tmp);
|
||||
|
||||
if (tmp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << tmp->get_fileline() << ": error: concatenation "
|
||||
cerr << tmp->get_fileline() << ": error: Concatenation "
|
||||
<< "repeat expression can not be REAL." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -1643,7 +1621,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
if (rep == 0) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
"Concatenation repeat expression cannot be evaluated."
|
||||
<< endl;
|
||||
cerr << get_fileline() << ": : The expression is: "
|
||||
<< *tmp << endl;
|
||||
|
|
@ -1702,18 +1680,20 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (! ex->has_width()) {
|
||||
cerr << ex->get_fileline() << ": error: "
|
||||
<< "concatenation operand has indefinite width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (ex->expr_type() == IVL_VT_REAL) {
|
||||
cerr << ex->get_fileline() << ": error: "
|
||||
<< "concatenation operand can not be REAL: "
|
||||
<< *ex << endl;
|
||||
<< "Concatenation operand can not be real: "
|
||||
<< *parms_[idx] << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! ex->has_width()) {
|
||||
cerr << ex->get_fileline() << ": error: "
|
||||
<< "Concatenation operand \"" << *parms_[idx]
|
||||
<< "\" has indefinite width." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
wid_sum += ex->expr_width();
|
||||
|
|
@ -1727,6 +1707,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
<< "have zero width in this context." << endl;
|
||||
des->errors += 1;
|
||||
concat_depth -= 1;
|
||||
delete tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1748,7 +1729,7 @@ unsigned PEFNumber::test_width(Design*des, NetScope*scope,
|
|||
{
|
||||
expr_type_ = IVL_VT_REAL;
|
||||
expr_width_ = 1;
|
||||
unsized_flag = true;
|
||||
unsized_flag = false;
|
||||
|
||||
expr_type__ = expr_type_;
|
||||
return 1;
|
||||
|
|
@ -1790,7 +1771,9 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
|||
two bit select expressions, and both must be
|
||||
constant. Evaluate them and pass the results back to
|
||||
the caller. */
|
||||
need_constant_expr = true;
|
||||
NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, lsb_wid);
|
||||
need_constant_expr = false;
|
||||
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
|
||||
if (lsb_c == 0) {
|
||||
cerr << index_tail.lsb->get_fileline() << ": error: "
|
||||
|
|
@ -1808,7 +1791,9 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
|
|||
lsb = lsb_c->value().as_long();
|
||||
}
|
||||
|
||||
need_constant_expr = true;
|
||||
NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, msb_wid);
|
||||
need_constant_expr = false;
|
||||
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
|
||||
if (msb_c == 0) {
|
||||
cerr << index_tail.msb->get_fileline() << ": error: "
|
||||
|
|
@ -1845,7 +1830,9 @@ bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
|
|||
/* Calculate the width expression (in the lsb_ position)
|
||||
first. If the expression is not constant, error but guess 1
|
||||
so we can keep going and find more errors. */
|
||||
need_constant_expr = true;
|
||||
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
||||
|
||||
if (wid_c == 0) {
|
||||
|
|
@ -1943,7 +1930,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
if (!name_tail.index.empty()) {
|
||||
probe_index_expr_width(des, scope, name_tail);
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
use_sel = index_tail.sel;
|
||||
// Skip full array word net selects.
|
||||
if (!net || (name_tail.index.size() > net->array_dimensions())) {
|
||||
use_sel = index_tail.sel;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned use_width = UINT_MAX;
|
||||
|
|
@ -2214,12 +2204,12 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
static verinum param_part_select_bits(const verinum&par_val, long wid,
|
||||
long lsv, long par_lsv)
|
||||
long lsv)
|
||||
{
|
||||
verinum result (verinum::Vx, wid, true);
|
||||
|
||||
for (long idx = 0 ; idx < wid ; idx += 1) {
|
||||
long off = idx + lsv - par_lsv;
|
||||
long off = idx + lsv;
|
||||
if (off < 0)
|
||||
result.set(idx, verinum::Vx);
|
||||
else if (off < (long)par_val.len())
|
||||
|
|
@ -2234,7 +2224,7 @@ static verinum param_part_select_bits(const verinum&par_val, long wid,
|
|||
|
||||
// If the input is a string, and the part select is working on
|
||||
// byte boundaries, then make the result into a string.
|
||||
if (par_val.is_string() && (labs(lsv-par_lsv)%8 == 0) && (wid%8 == 0))
|
||||
if (par_val.is_string() && (labs(lsv)%8 == 0) && (wid%8 == 0))
|
||||
return result.as_string();
|
||||
|
||||
return result;
|
||||
|
|
@ -2259,7 +2249,7 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
|
|||
|
||||
if (! parts_defined_flag) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Part select of paramter "
|
||||
cerr << get_fileline() << ": debug: Part select of parameter "
|
||||
<< "has x/z bits, so resorting to 'bx result." << endl;
|
||||
|
||||
long wid = 1 + labs(par_msv-par_lsv);
|
||||
|
|
@ -2290,28 +2280,56 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
|
|||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||
ivl_assert(*this, par_ex);
|
||||
|
||||
verinum result = param_part_select_bits(par_ex->value(), wid, lsv, par_lsv);
|
||||
verinum result = param_part_select_bits(par_ex->value(), wid, lsv-par_lsv);
|
||||
NetEConst*result_ex = new NetEConst(result);
|
||||
result_ex->set_line(*this);
|
||||
|
||||
return result_ex;
|
||||
}
|
||||
|
||||
static void warn_param_ob(long par_msv, long par_lsv, bool defined,
|
||||
long par_base, unsigned long wid, long pwid,
|
||||
const LineInfo *info, perm_string name, bool up)
|
||||
{
|
||||
long par_max;
|
||||
|
||||
if (defined) {
|
||||
if (par_msv < par_lsv) par_max = par_lsv-par_msv;
|
||||
else par_max = par_msv-par_lsv;
|
||||
} else {
|
||||
if (pwid < 0) par_max = integer_width;
|
||||
else par_max = pwid;
|
||||
}
|
||||
|
||||
/* Is this a select before the start of the parameter? */
|
||||
if (par_base < 0) {
|
||||
cerr << info->get_fileline() << ": warning: " << name << "["
|
||||
<< par_base;
|
||||
if (up) cerr << "+:";
|
||||
else cerr << "-:";
|
||||
cerr << wid << "] is selecting before vector." << endl;
|
||||
}
|
||||
|
||||
/* Is this a select after the end of the parameter? */
|
||||
if (par_base + (long)wid - 1 > par_max) {
|
||||
cerr << info->get_fileline() << ": warning: " << name << "["
|
||||
<< par_base << "+:" << wid << "] is selecting after vector."
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb) const
|
||||
{
|
||||
|
||||
long par_msv, par_lsv;
|
||||
bool flag = calculate_param_range_(des, scope, par_msb, par_msv, par_lsb, par_lsv);
|
||||
if (!flag)
|
||||
return 0;
|
||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
||||
par_lsb, par_lsv)) return 0;
|
||||
|
||||
NetExpr*base = calculate_up_do_base_(des, scope);
|
||||
if (base == 0)
|
||||
return 0;
|
||||
if (base == 0) return 0;
|
||||
|
||||
unsigned long wid = 0;
|
||||
calculate_up_do_width_(des, scope, wid);
|
||||
|
|
@ -2327,22 +2345,139 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
|||
// Handle the special case that the base is constant. In this
|
||||
// case, just precalculate the entire constant result.
|
||||
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
|
||||
if (! base_c->value().is_defined()) {
|
||||
NetEConst *ex;
|
||||
ex = new NetEConst(verinum(verinum::Vx, wid, true));
|
||||
ex->set_line(*this);
|
||||
if (warn_ob_select) {
|
||||
perm_string name = peek_tail_name(path_);
|
||||
cerr << get_fileline() << ": warning: " << name
|
||||
<< "['bx+:" << wid
|
||||
<< "] is always outside vector." << endl;
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
long lsv = base_c->value().as_long();
|
||||
long par_base = par_lsv;
|
||||
|
||||
// Watch out for reversed bit numbering. We're making
|
||||
// the part select from LSB to MSB.
|
||||
if (par_msv < par_lsv)
|
||||
lsv = lsv - wid + 1;
|
||||
if (par_msv < par_lsv) {
|
||||
par_base = lsv;
|
||||
lsv = par_lsv - wid + 1;
|
||||
}
|
||||
|
||||
if (warn_ob_select) {
|
||||
bool defined = true;
|
||||
// Check to see if the parameter has a defined range.
|
||||
if (par_msb == 0) {
|
||||
assert(par_lsb == 0);
|
||||
defined = false;
|
||||
}
|
||||
// Get the parameter values width.
|
||||
long pwid = -1;
|
||||
if (par_ex->has_width()) pwid = par_ex->expr_width()-1;
|
||||
perm_string name = peek_tail_name(path_);
|
||||
warn_param_ob(par_msv, par_lsv, defined, lsv-par_base, wid,
|
||||
pwid, this, name, true);
|
||||
}
|
||||
verinum result = param_part_select_bits(par_ex->value(), wid,
|
||||
lsv, par_lsv);
|
||||
lsv-par_base);
|
||||
NetEConst*result_ex = new NetEConst(result);
|
||||
result_ex->set_line(*this);
|
||||
return result_ex;
|
||||
}
|
||||
|
||||
if ((par_msv < par_lsv) && (wid>1))
|
||||
base = make_add_expr(base, 1-(long)wid);
|
||||
if (par_msv >= par_lsv) {
|
||||
if (par_lsv != 0) base = make_add_expr(base, -par_lsv);
|
||||
} else {
|
||||
base = make_sub_expr(par_lsv-wid+1, base);
|
||||
}
|
||||
|
||||
NetExpr*tmp = par->dup_expr();
|
||||
tmp = new NetESelect(tmp, base, wid);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb) const
|
||||
{
|
||||
long par_msv, par_lsv;
|
||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
||||
par_lsb, par_lsv)) return 0;
|
||||
|
||||
NetExpr*base = calculate_up_do_base_(des, scope);
|
||||
if (base == 0) return 0;
|
||||
|
||||
unsigned long wid = 0;
|
||||
calculate_up_do_width_(des, scope, wid);
|
||||
|
||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||
ivl_assert(*this, par_ex);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Calculate part select "
|
||||
<< "[" << *base << "-:" << wid << "] from range "
|
||||
<< "[" << par_msv << ":" << par_lsv << "]." << endl;
|
||||
|
||||
// Handle the special case that the base is constant. In this
|
||||
// case, just precalculate the entire constant result.
|
||||
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
|
||||
if (! base_c->value().is_defined()) {
|
||||
NetEConst *ex;
|
||||
ex = new NetEConst(verinum(verinum::Vx, wid, true));
|
||||
ex->set_line(*this);
|
||||
if (warn_ob_select) {
|
||||
perm_string name = peek_tail_name(path_);
|
||||
cerr << get_fileline() << ": warning: " << name
|
||||
<< "['bx-:" << wid
|
||||
<< "] is always outside vector." << endl;
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
long lsv = base_c->value().as_long();
|
||||
long par_base = par_lsv + wid - 1;
|
||||
|
||||
// Watch out for reversed bit numbering. We're making
|
||||
// the part select from LSB to MSB.
|
||||
if (par_msv < par_lsv) {
|
||||
par_base = lsv;
|
||||
lsv = par_lsv;
|
||||
}
|
||||
|
||||
if (warn_ob_select) {
|
||||
bool defined = true;
|
||||
// Check to see if the parameter has a defined range.
|
||||
if (par_msb == 0) {
|
||||
assert(par_lsb == 0);
|
||||
defined = false;
|
||||
}
|
||||
// Get the parameter values width.
|
||||
long pwid = -1;
|
||||
if (par_ex->has_width()) pwid = par_ex->expr_width()-1;
|
||||
perm_string name = peek_tail_name(path_);
|
||||
warn_param_ob(par_msv, par_lsv, defined, lsv-par_base, wid,
|
||||
pwid, this, name, false);
|
||||
}
|
||||
|
||||
verinum result = param_part_select_bits(par_ex->value(), wid,
|
||||
lsv-par_base);
|
||||
NetEConst*result_ex = new NetEConst(result);
|
||||
result_ex->set_line(*this);
|
||||
return result_ex;
|
||||
}
|
||||
|
||||
if (par_msv >= par_lsv) {
|
||||
if (long offset = par_lsv+wid-1) {
|
||||
base = make_add_expr(base, -offset);
|
||||
}
|
||||
} else {
|
||||
base = make_sub_expr(par_lsv, base);
|
||||
}
|
||||
|
||||
NetExpr*tmp = par->dup_expr();
|
||||
tmp = new NetESelect(tmp, base, wid);
|
||||
|
|
@ -2368,6 +2503,15 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
if (!name_tail.index.empty())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
if (par->expr_type() == IVL_VT_REAL &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
perm_string name = peek_tail_name(path_);
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of real parameter: " << name << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE TO SELF: This is the way I want to see this code
|
||||
// structured. This closely follows the structure of the
|
||||
// elaborate_expr_net_ code, which splits all the various
|
||||
|
|
@ -2380,47 +2524,16 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
return elaborate_expr_param_idx_up_(des, scope, par, found_in,
|
||||
par_msb, par_lsb);
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO)
|
||||
return elaborate_expr_param_idx_do_(des, scope, par, found_in,
|
||||
par_msb, par_lsb);
|
||||
|
||||
// NOTE TO SELF (continued): The code below should be
|
||||
// rewritten in the above format, as I get to it.
|
||||
|
||||
NetExpr*tmp = par->dup_expr();
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO) {
|
||||
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb);
|
||||
ivl_assert(*this, index_tail.lsb);
|
||||
|
||||
/* Get and evaluate the width of the index
|
||||
select. This must be constant. */
|
||||
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
|
||||
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
|
||||
if (wid_ec == 0) {
|
||||
cerr << index_tail.lsb->get_fileline() << ": error: "
|
||||
<< "Second expression of indexed part select "
|
||||
<< "most be constant." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned wid = wid_ec->value().as_ulong();
|
||||
|
||||
NetExpr*idx_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
if (idx_ex == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1) {
|
||||
idx_ex = make_add_expr(idx_ex, 1-(long)wid);
|
||||
}
|
||||
|
||||
|
||||
/* Wrap the param expression with a part select. */
|
||||
tmp = new NetESelect(tmp, idx_ex, wid);
|
||||
|
||||
|
||||
} else if (use_sel == index_component_t::SEL_BIT) {
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb);
|
||||
|
|
@ -2603,6 +2716,9 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
|||
// Special case: The index is out of range, so the value
|
||||
// of this expression is a 'bx vector the width of a word.
|
||||
if (!net->array_index_is_valid(addr)) {
|
||||
cerr << get_fileline() << ": warning: returning 'bx for out "
|
||||
"of bounds array access " << net->name()
|
||||
<< "[" << addr << "]." << endl;
|
||||
NetEConst*resx = make_const_x(net->vector_width());
|
||||
resx->set_line(*this);
|
||||
delete word_index;
|
||||
|
|
@ -2638,6 +2754,18 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
|||
if (name_tail.index.size() > 1)
|
||||
word_sel = name_tail.index.back().sel;
|
||||
|
||||
if (net->get_scalar() &&
|
||||
word_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (res->expr_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << net->name()
|
||||
<<"[" << *word_index << "]" << endl;
|
||||
des->errors += 1;
|
||||
delete res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (word_sel == index_component_t::SEL_PART)
|
||||
return elaborate_expr_net_part_(des, scope, res, found_in);
|
||||
|
||||
|
|
@ -2651,6 +2779,7 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
|
|||
return elaborate_expr_net_bit_(des, scope, res, found_in);
|
||||
|
||||
ivl_assert(*this, word_sel == index_component_t::SEL_NONE);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -2745,15 +2874,47 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
|||
if (net->sig()->sb_to_idx(lsv) == 0 &&
|
||||
wid == net->vector_width()) {
|
||||
delete base;
|
||||
net->cast_signed(false);
|
||||
return net;
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
if (net->msi() < net->lsi()) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
// Otherwise, make a part select that covers the right
|
||||
// range.
|
||||
ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv)));
|
||||
ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv) +
|
||||
offset));
|
||||
if (warn_ob_select) {
|
||||
long rel_base = net->sig()->sb_to_idx(lsv) + offset;
|
||||
if (rel_base < 0) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< net->name();
|
||||
if (net->word_index()) cerr << "[]";
|
||||
cerr << "[" << lsv << "+:" << wid
|
||||
<< "] is selecting before vector." << endl;
|
||||
}
|
||||
if (rel_base + wid > net->vector_width()) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< net->name();
|
||||
if (net->word_index()) cerr << "[]";
|
||||
cerr << "[" << lsv << "+:" << wid
|
||||
<< "] is selecting after vector." << endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Return 'bx for an undefined base.
|
||||
ex = new NetEConst(verinum(verinum::Vx, 1, false));
|
||||
ex = new NetEConst(verinum(verinum::Vx, wid, true));
|
||||
ex->set_line(*this);
|
||||
delete base;
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: " << net->name();
|
||||
if (net->word_index()) cerr << "[]";
|
||||
cerr << "['bx+:" << wid
|
||||
<< "] is always outside vector." << endl;
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
NetESelect*ss = new NetESelect(net, ex, wid);
|
||||
ss->set_line(*this);
|
||||
|
|
@ -2764,11 +2925,9 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
|||
|
||||
if (net->msi() > net->lsi()) {
|
||||
if (long offset = net->lsi())
|
||||
base = make_add_expr(base, 0-offset);
|
||||
base = make_add_expr(base, -offset);
|
||||
} else {
|
||||
long vwid = net->lsi() - net->msi() + 1;
|
||||
long offset = net->msi();
|
||||
base = make_sub_expr(vwid-offset-wid, base);
|
||||
base = make_sub_expr(net->lsi()-wid+1, base);
|
||||
}
|
||||
|
||||
NetESelect*ss = new NetESelect(net, base, wid);
|
||||
|
|
@ -2807,15 +2966,47 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
|||
if (net->sig()->sb_to_idx(lsv) == (signed) (wid-1) &&
|
||||
wid == net->vector_width()) {
|
||||
delete base;
|
||||
net->cast_signed(false);
|
||||
return net;
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
if (net->msi() > net->lsi()) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
// Otherwise, make a part select that covers the right
|
||||
// range.
|
||||
ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv)-wid+1));
|
||||
ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv) +
|
||||
offset));
|
||||
if (warn_ob_select) {
|
||||
long rel_base = net->sig()->sb_to_idx(lsv) + offset;
|
||||
if (rel_base < 0) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< net->name();
|
||||
if (net->word_index()) cerr << "[]";
|
||||
cerr << "[" << lsv << "+:" << wid
|
||||
<< "] is selecting before vector." << endl;
|
||||
}
|
||||
if (rel_base + wid > net->vector_width()) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< net->name();
|
||||
if (net->word_index()) cerr << "[]";
|
||||
cerr << "[" << lsv << "-:" << wid
|
||||
<< "] is selecting after vector." << endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Return 'bx for an undefined base.
|
||||
ex = new NetEConst(verinum(verinum::Vx, 1, false));
|
||||
ex = new NetEConst(verinum(verinum::Vx, wid, true));
|
||||
ex->set_line(*this);
|
||||
delete base;
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: " << net->name();
|
||||
if (net->word_index()) cerr << "[]";
|
||||
cerr << "['bx-:" << wid
|
||||
<< "] is always outside vector." << endl;
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
NetESelect*ss = new NetESelect(net, ex, wid);
|
||||
ss->set_line(*this);
|
||||
|
|
@ -2824,16 +3015,19 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
|||
return ss;
|
||||
}
|
||||
|
||||
long offset = net->lsi();
|
||||
NetExpr*base_adjusted = wid > 1
|
||||
? make_add_expr(base,1-(long)wid-offset)
|
||||
: (offset == 0? base : make_add_expr(base, 0-offset));
|
||||
NetESelect*ss = new NetESelect(net, base_adjusted, wid);
|
||||
if (net->msi() > net->lsi()) {
|
||||
if (long offset = net->lsi()+wid-1)
|
||||
base = make_add_expr(base, -offset);
|
||||
} else {
|
||||
base = make_sub_expr(net->lsi(), base);
|
||||
}
|
||||
|
||||
NetESelect*ss = new NetESelect(net, base, wid);
|
||||
ss->set_line(*this);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Elaborate part "
|
||||
<< "select base="<< *base_adjusted << ", wid="<< wid << endl;
|
||||
<< "select base="<< *base << ", wid="<< wid << endl;
|
||||
}
|
||||
|
||||
return ss;
|
||||
|
|
@ -2932,6 +3126,16 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
|||
if (! path_.back().index.empty())
|
||||
use_sel = path_.back().index.back().sel;
|
||||
|
||||
if (net->get_scalar() &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (node->expr_type() == IVL_VT_REAL) cerr << "real: ";
|
||||
else cerr << "scalar: ";
|
||||
cerr << net->name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If this is a part select of a signal, then make a new
|
||||
// temporary signal that is connected to just the
|
||||
// selected bits. The lsb_ and msb_ expressions are from
|
||||
|
|
@ -3213,6 +3417,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
|
|||
fal = pad_to_width(fal, use_wid, *this);
|
||||
|
||||
NetETernary*res = new NetETernary(con, tru, fal);
|
||||
res->cast_signed(tru->has_sign() && fal->has_sign());
|
||||
res->set_line(*this);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
148
elab_lval.cc
148
elab_lval.cc
|
|
@ -118,17 +118,20 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
|
|||
|
||||
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
|
||||
|
||||
if (tmp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << parms_[idx]->get_fileline() << ": error: "
|
||||
<< "concatenation operand can not be real: "
|
||||
<< *parms_[idx] << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the l-value doesn't elaborate, the error was
|
||||
already detected and printed. We just skip it and let
|
||||
the compiler catch more errors. */
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
|
||||
assert(tmp);
|
||||
|
||||
if (tmp == 0) continue;
|
||||
|
||||
/* Link the new l-value to the previous one. */
|
||||
|
||||
NetAssign_*last = tmp;
|
||||
while (last->more)
|
||||
last = last->more;
|
||||
|
|
@ -195,6 +198,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
if (reg->array_dimensions() > 0)
|
||||
return elaborate_lval_net_word_(des, scope, reg);
|
||||
|
||||
// This must be after the array word elaboration above!
|
||||
if (reg->get_scalar() &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (reg->data_type() == IVL_VT_REAL) cerr << "real: ";
|
||||
else cerr << "scalar: ";
|
||||
cerr << reg->name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_sel == index_component_t::SEL_PART) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_part_(des, scope, lv);
|
||||
|
|
@ -243,13 +257,11 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
ivl_assert(*this, index_head.msb != 0);
|
||||
ivl_assert(*this, index_head.lsb == 0);
|
||||
|
||||
// These are not used, but they need to have a default value.
|
||||
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
|
||||
// This not used, but it needs to have a default value.
|
||||
bool unsized_flag_tmp = false;
|
||||
index_head.msb->test_width(des, scope,
|
||||
reg->vector_width(), reg->vector_width(),
|
||||
expr_type_tmp,
|
||||
unsized_flag_tmp);
|
||||
index_head.msb->test_width(des, scope, integer_width, integer_width,
|
||||
expr_type_tmp, unsized_flag_tmp);
|
||||
|
||||
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
|
||||
|
||||
|
|
@ -289,6 +301,20 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
if (name_tail.index.size() > 1)
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
if (reg->get_scalar() &&
|
||||
use_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
if (reg->data_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << reg->name()
|
||||
<< "[" << *word << "]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_sel == index_component_t::SEL_BIT)
|
||||
elaborate_lval_net_bit_(des, scope, lv);
|
||||
|
||||
if (use_sel == index_component_t::SEL_PART)
|
||||
elaborate_lval_net_part_(des, scope, lv);
|
||||
|
||||
|
|
@ -310,16 +336,14 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
|
||||
NetNet*reg = lv->sig();
|
||||
|
||||
// These are not used, but they need to have a default value.
|
||||
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
|
||||
// This not used, but it needs to have a default value.
|
||||
bool unsized_flag_tmp = false;
|
||||
index_tail.msb->test_width(des, scope,
|
||||
lv->lwidth(), lv->lwidth(),
|
||||
expr_type_tmp,
|
||||
unsized_flag_tmp);
|
||||
index_tail.msb->test_width(des, scope, integer_width, integer_width,
|
||||
expr_type_tmp, unsized_flag_tmp);
|
||||
|
||||
|
||||
// Bit selects have a single select expression. Evaluate the
|
||||
// Bit selects have a single select expression. Evaluate the
|
||||
// constant value and treat it as a part select with a bit
|
||||
// width of 1.
|
||||
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
|
@ -444,24 +468,88 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
unsigned long wid;
|
||||
calculate_up_do_width_(des, scope, wid);
|
||||
|
||||
// These are not used, but they need to have a default value.
|
||||
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
|
||||
// This not used, but it needs to have a default value.
|
||||
bool unsized_flag_tmp = false;
|
||||
index_tail.msb->test_width(des, scope,
|
||||
wid, wid,
|
||||
expr_type_tmp,
|
||||
unsized_flag_tmp);
|
||||
index_tail.msb->test_width(des, scope, integer_width, integer_width,
|
||||
expr_type_tmp, unsized_flag_tmp);
|
||||
|
||||
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
||||
/* Correct the mux for the range of the vector. */
|
||||
if (reg->msb() < reg->lsb())
|
||||
base = make_sub_expr(reg->lsb(), base);
|
||||
else if (reg->lsb() != 0)
|
||||
base = make_add_expr(base, - reg->lsb());
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
|
||||
base = make_add_expr(base, 1-(long)wid);
|
||||
// Handle the special case that the base is constant. For this
|
||||
// case we can reduce the expression.
|
||||
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
|
||||
// For the undefined case just let the constant pass and
|
||||
// we will handle it in the code generator.
|
||||
if (base_c->value().is_defined()) {
|
||||
long lsv = base_c->value().as_long();
|
||||
long offset = 0;
|
||||
if (((reg->msb() < reg->lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_UP) ||
|
||||
((reg->msb() > reg->lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_DO)) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
delete base;
|
||||
long rel_base = reg->sb_to_idx(lsv) + offset;
|
||||
/* If we cover the entire lvalue just skip the select. */
|
||||
if (rel_base == 0 && wid == reg->vector_width()) return true;
|
||||
base = new NetEConst(verinum(rel_base));
|
||||
if (warn_ob_select) {
|
||||
if (rel_base < 0) {
|
||||
cerr << get_fileline() << ": warning: " << reg->name();
|
||||
if (reg->array_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << lsv;
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is selecting before vector." << endl;
|
||||
}
|
||||
if (rel_base + wid > reg->vector_width()) {
|
||||
cerr << get_fileline() << ": warning: " << reg->name();
|
||||
if (reg->array_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << lsv;
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is selecting after vector." << endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: " << reg->name();
|
||||
if (reg->array_dimensions() > 0) cerr << "[]";
|
||||
cerr << "['bx";
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is always outside vector." << endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Correct the mux for the range of the vector. */
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
if (reg->msb() > reg->lsb()) {
|
||||
if (long offset = reg->lsb())
|
||||
base = make_add_expr(base, -offset);
|
||||
} else {
|
||||
base = make_sub_expr(reg->lsb()-wid+1, base);
|
||||
}
|
||||
} else {
|
||||
// This is assumed to be a SEL_IDX_DO.
|
||||
if (reg->msb() > reg->lsb()) {
|
||||
if (long offset = reg->lsb()+wid-1)
|
||||
base = make_add_expr(base, -offset);
|
||||
} else {
|
||||
base = make_sub_expr(reg->lsb(), base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_elaborate)
|
||||
|
|
|
|||
110
elab_net.cc
110
elab_net.cc
|
|
@ -72,10 +72,16 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
} else {
|
||||
nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
|
||||
}
|
||||
if (nets[idx] == 0)
|
||||
|
||||
if (nets[idx] == 0) errors += 1;
|
||||
else if (nets[idx]->data_type() == IVL_VT_REAL) {
|
||||
cerr << parms_[idx]->get_fileline() << ": error: "
|
||||
<< "concatenation operand can no be real: "
|
||||
<< *parms_[idx] << endl;
|
||||
errors += 1;
|
||||
else
|
||||
width += nets[idx]->vector_width();
|
||||
continue;
|
||||
} else width += nets[idx]->vector_width();
|
||||
|
||||
}
|
||||
|
||||
/* If any of the sub expressions failed to elaborate, then
|
||||
|
|
@ -173,7 +179,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
|
|||
assert(nettype != NetNet::NONE);
|
||||
|
||||
NetNet*sig = new NetNet(scope, peek_tail_name(path_),
|
||||
NetNet::IMPLICIT, 1);
|
||||
nettype, 1);
|
||||
sig->set_line(*this);
|
||||
/* Implicit nets are always scalar logic. */
|
||||
sig->data_type(IVL_VT_LOGIC);
|
||||
|
|
@ -220,7 +226,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
|
||||
case index_component_t::SEL_IDX_DO:
|
||||
case index_component_t::SEL_IDX_UP: {
|
||||
need_constant_expr = true;
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||
if (!tmp) {
|
||||
cerr << get_fileline() << ": error: indexed part select of "
|
||||
|
|
@ -230,15 +238,33 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
return 0;
|
||||
}
|
||||
|
||||
long midx_val = tmp->value().as_long();
|
||||
midx = sig->sb_to_idx(midx_val);
|
||||
delete tmp_ex;
|
||||
|
||||
/* The width (a constant) is calculated here. */
|
||||
unsigned long wid = 0;
|
||||
bool flag = calculate_up_do_width_(des, scope, wid);
|
||||
if (! flag)
|
||||
if (! flag) return false;
|
||||
|
||||
/* We have an undefined index and that is out of range. */
|
||||
if (! tmp->value().is_defined()) {
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< sig->name();
|
||||
if (sig->array_dimensions() > 0) cerr << "[]";
|
||||
cerr << "['bx";
|
||||
if (index_tail.sel ==
|
||||
index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is always outside vector."
|
||||
<< endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
long midx_val = tmp->value().as_long();
|
||||
midx = sig->sb_to_idx(midx_val);
|
||||
delete tmp_ex;
|
||||
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP)
|
||||
lidx = sig->sb_to_idx(midx_val+wid-1);
|
||||
|
|
@ -252,9 +278,19 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
}
|
||||
|
||||
/* Warn about an indexed part select that is out of range. */
|
||||
if (midx >= (long)sig->vector_width() || lidx < 0) {
|
||||
cerr << get_fileline() << ": warning: Indexed part "
|
||||
"select " << sig->name();
|
||||
if (warn_ob_select && (lidx < 0)) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->array_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is selecting before vector." << endl;
|
||||
}
|
||||
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->array_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
|
|
@ -264,7 +300,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is out of range." << endl;
|
||||
cerr << wid << "] is selecting after vector." << endl;
|
||||
}
|
||||
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
|
|
@ -415,7 +451,10 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
// Default part select is the entire word.
|
||||
unsigned midx = sig->vector_width()-1, lidx = 0;
|
||||
// The default word select is the first.
|
||||
unsigned widx = 0;
|
||||
long widx = 0;
|
||||
// The widx_val is the word select as entered in the source
|
||||
// code. It's used for error messages.
|
||||
long widx_val = 0;
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
|
|
@ -437,7 +476,15 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
}
|
||||
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||
|
||||
// These are not used, but they need to have a default value.
|
||||
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
|
||||
bool unsized_flag_tmp = false;
|
||||
index_head.msb->test_width(des, scope,
|
||||
integer_width, integer_width,
|
||||
expr_type_tmp, unsized_flag_tmp);
|
||||
need_constant_expr = true;
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||
if (!tmp) {
|
||||
cerr << get_fileline() << ": error: array " << sig->name()
|
||||
|
|
@ -446,8 +493,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
long widx_val = tmp->value().as_long();
|
||||
widx = sig->array_index_to_address(widx_val);
|
||||
widx_val = tmp->value().as_long();
|
||||
if (sig->array_index_is_valid(widx_val))
|
||||
widx = sig->array_index_to_address(widx_val);
|
||||
else
|
||||
widx = -1;
|
||||
delete tmp_ex;
|
||||
|
||||
if (debug_elaborate)
|
||||
|
|
@ -456,6 +506,17 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
|
||||
/* The array has a part/bit select at the end. */
|
||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of ";
|
||||
if (sig->data_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << sig->name()
|
||||
<< "[" << widx_val << "]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long midx_tmp, lidx_tmp;
|
||||
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
||||
return 0;
|
||||
|
|
@ -471,6 +532,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
lidx = lidx_tmp;
|
||||
}
|
||||
} else if (!name_tail.index.empty()) {
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of ";
|
||||
if (sig->data_type() == IVL_VT_REAL) cerr << "real: ";
|
||||
else cerr << "scalar: ";
|
||||
cerr << sig->name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long midx_tmp, lidx_tmp;
|
||||
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
||||
return 0;
|
||||
|
|
@ -489,7 +560,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
unsigned subnet_wid = midx-lidx+1;
|
||||
|
||||
if (sig->pin_count() > 1) {
|
||||
assert(widx < sig->pin_count());
|
||||
if (widx < 0 || widx >= (long) sig->pin_count()) {
|
||||
cerr << get_fileline() << ": warning: ignoring out of "
|
||||
"bounds l-value array access "
|
||||
<< sig->name() << "[" << widx_val << "]." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
sig->type(), sig->vector_width());
|
||||
|
|
|
|||
|
|
@ -150,11 +150,19 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
|||
/* Elaborate all the operands and attach them to the concat
|
||||
node. Use the elaborate_pexpr method instead of the
|
||||
elaborate_expr method. */
|
||||
bool fail = false;
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
|
||||
if (ex == 0) continue;
|
||||
|
||||
if (ex->expr_type() == IVL_VT_REAL) {
|
||||
cerr << ex->get_fileline() << ": error: concatenation "
|
||||
<< "operand can not be real: " << *ex << endl;
|
||||
des->errors += 1;
|
||||
fail = true;
|
||||
continue;
|
||||
}
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (dynamic_cast<NetEParam*>(ex)) {
|
||||
|
|
@ -167,13 +175,18 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
|||
<< "concatenation has indefinite width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
delete tmp;
|
||||
return 0;
|
||||
fail = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp->set(idx, ex);
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
delete tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
@ -194,6 +207,14 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
|||
name_component_t name_tail = path_.back();
|
||||
oldpath.pop_back();
|
||||
|
||||
if (path_.size() > 1) {
|
||||
cerr << get_fileline() << ": error: parameter r-value expression "
|
||||
"does not support hierarchical references `" << path_
|
||||
<< "`." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path_.size() > 0) {
|
||||
list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
|
||||
|
|
@ -216,8 +237,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
|||
ivl_assert(*this, pscope);
|
||||
}
|
||||
if (ex == 0) {
|
||||
cerr << get_fileline() << ": error: identifier ``" << name_tail.name <<
|
||||
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
|
||||
cerr << get_fileline() << ": error: identifier `"
|
||||
<< name_tail.name << "` is not a parameter in "
|
||||
<< scope_path(scope)<< "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
453
elab_scope.cc
453
elab_scope.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -174,6 +174,15 @@ static void elaborate_scope_parameters_(Design*des, NetScope*scope,
|
|||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
// A parameter can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: parameter and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||
}
|
||||
}
|
||||
|
|
@ -184,6 +193,15 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope,
|
|||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
// A localparam can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: localparam and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +216,7 @@ static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
|||
if (val == 0) {
|
||||
cerr << loc.get_fileline() << ": internal error: "
|
||||
<< "Missing expression in parameter replacement for "
|
||||
<< (*cur).first;
|
||||
<< (*cur).first << endl;;
|
||||
}
|
||||
assert(val);
|
||||
if (debug_scopes) {
|
||||
|
|
@ -238,13 +256,38 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
|||
; cur != tasks.end() ; cur ++ ) {
|
||||
|
||||
hname_t use_name( (*cur).first );
|
||||
if (scope->child(use_name)) {
|
||||
cerr << loc.get_fileline() << ": error: task/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
// A task can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
cerr << cur->second->get_fileline() << ": error: task and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// A task can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: task and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A task can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
|
||||
ex_lsb);
|
||||
if (parm) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: task and parameter in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, use_name,
|
||||
NetScope::TASK);
|
||||
task_scope->is_auto((*cur).second->is_auto());
|
||||
|
|
@ -268,13 +311,39 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
|||
; cur != funcs.end() ; cur ++ ) {
|
||||
|
||||
hname_t use_name( (*cur).first );
|
||||
if (scope->child(use_name)) {
|
||||
cerr << loc.get_fileline() << ": error: function/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
// A function can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// A function can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A function can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
|
||||
ex_lsb);
|
||||
if (parm) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and parameter in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetScope*func_scope = new NetScope(scope, use_name,
|
||||
NetScope::FUNC);
|
||||
func_scope->is_auto((*cur).second->is_auto());
|
||||
|
|
@ -328,6 +397,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
<< scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
// Add the genvars to the scope.
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
|
||||
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
|
||||
scope->add_genvar((*cur).first, (*cur).second);
|
||||
}
|
||||
|
||||
// Generate all the parameters that this instance of this
|
||||
// module introduces to the design. This loop elaborates the
|
||||
// parameters, but doesn't evaluate references to
|
||||
|
|
@ -446,6 +521,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
||||
scope->is_cell(is_cell);
|
||||
|
||||
return des->errors == 0;
|
||||
}
|
||||
|
||||
|
|
@ -486,8 +563,16 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
{
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
|
||||
// MISSING CODE!
|
||||
NetScope*scope = container;
|
||||
while (scope && !scope->find_genvar(loop_index))
|
||||
scope = scope->parent();
|
||||
if (!scope) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're going to need a genvar...
|
||||
int genvar;
|
||||
|
|
@ -496,7 +581,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
// use) the genvar itself, so we can evaluate this expression
|
||||
// the same way any other parameter value is evaluated.
|
||||
probe_expr_width(des, container, loop_init);
|
||||
need_constant_expr = true;
|
||||
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
|
||||
if (init == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
|
|
@ -505,19 +592,53 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Since we will be adding the genvar value as a local parameter
|
||||
// to each instances scope. We need to make sure a parameter does
|
||||
// not already exist.
|
||||
const NetExpr*tmsb;
|
||||
const NetExpr*tlsb;
|
||||
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb);
|
||||
if (texpr != 0) {
|
||||
cerr << get_fileline() << ": error: Cannot have a genvar "
|
||||
<< "and parameter with the same name: " << loop_index << endl;
|
||||
// Check the generate block name.
|
||||
|
||||
// A generate "loop" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(hname_t(scope_name));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a parameter.
|
||||
const NetExpr*tmsb;
|
||||
const NetExpr*tlsb;
|
||||
const NetExpr*texpr = container->get_parameter(scope_name, tmsb, tlsb);
|
||||
if (texpr != 0) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// These have all been checked so we just need to skip the actual
|
||||
// generation for these name conflicts. Not skipping these two will
|
||||
// cause the compiler to have problems (assert, inf. loop, etc.).
|
||||
if (container->get_parameter(loop_index, tmsb, tlsb)) return false;
|
||||
if (container->find_event(loop_index)) return false;
|
||||
|
||||
genvar = init->value().as_long();
|
||||
delete init_ex;
|
||||
|
||||
|
|
@ -526,7 +647,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
container->genvar_tmp = loop_index;
|
||||
container->genvar_tmp_val = genvar;
|
||||
probe_expr_width(des, container, loop_test);
|
||||
need_constant_expr = true;
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
||||
if (test == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
|
|
@ -541,13 +664,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
// container. The format of using [] is part of the
|
||||
// Verilog standard.
|
||||
hname_t use_name (scope_name, genvar);
|
||||
if (container->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Create generated scope " << use_name << endl;
|
||||
|
|
@ -579,7 +696,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
|
||||
// Calculate the step for the loop variable.
|
||||
probe_expr_width(des, container, loop_step);
|
||||
need_constant_expr = true;
|
||||
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
|
||||
if (step == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
|
|
@ -602,7 +721,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
}
|
||||
|
||||
// Clear the genvar_tmp field in the scope to reflect that the
|
||||
// genvar is no longer value for evaluating expressions.
|
||||
// genvar is no longer valid for evaluating expressions.
|
||||
container->genvar_tmp = perm_string();
|
||||
|
||||
return true;
|
||||
|
|
@ -611,7 +730,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
|
||||
{
|
||||
probe_expr_width(des, container, loop_test);
|
||||
need_constant_expr = true;
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
|
||||
if (test == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
|
|
@ -634,14 +755,45 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
|||
}
|
||||
|
||||
hname_t use_name (scope_name);
|
||||
if (container->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< scope_name << " already used in this context."
|
||||
<< endl;
|
||||
// A generate "if" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
|
||||
ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate condition "
|
||||
<< (else_flag? "(else)" : "(if)")
|
||||
|
|
@ -671,7 +823,9 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
|||
bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||
{
|
||||
probe_expr_width(des, container, loop_test);
|
||||
need_constant_expr = true;
|
||||
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
|
||||
if (case_value_co == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar case"
|
||||
|
|
@ -702,9 +856,17 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
bool match_flag = false;
|
||||
for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) {
|
||||
probe_expr_width(des, container, item->item_test[idx]);
|
||||
need_constant_expr = true;
|
||||
NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1);
|
||||
need_constant_expr = false;
|
||||
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
|
||||
assert(item_value_co);
|
||||
if (item_value_co == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate "
|
||||
<< " genvar case item expression: "
|
||||
<< *item->item_test[idx] << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate case "
|
||||
|
|
@ -739,6 +901,44 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
|
||||
// The name of the scope to generate, whatever that item is.
|
||||
hname_t use_name (item->scope_name);
|
||||
// A generate "case" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a genvar.
|
||||
if (container->find_genvar(item->scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(item->scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = container->get_parameter(item->scope_name, ex_msb,
|
||||
ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
item->probe_for_direct_nesting_();
|
||||
if (item->direct_nested_) {
|
||||
|
|
@ -760,13 +960,46 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||
{
|
||||
hname_t use_name (scope_name);
|
||||
if (container->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< scope_name << " already used in this context."
|
||||
<< endl;
|
||||
// A generate "block" can not have the same name as another scope
|
||||
// object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"named event in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
|
||||
ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: Generate named block "
|
||||
<< ": Generate scope=" << use_name << endl;
|
||||
|
|
@ -791,6 +1024,12 @@ void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
|
|||
|
||||
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
||||
{
|
||||
// Add the genvars to this scope.
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
|
||||
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
|
||||
scope->add_genvar((*cur).first, (*cur).second);
|
||||
}
|
||||
|
||||
// Scan the generated scope for nested generate schemes,
|
||||
// and *generate* new scopes, which is slightly different
|
||||
// from simple elaboration.
|
||||
|
|
@ -886,36 +1125,77 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
|||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
|
||||
// Check for duplicate scopes. Simply look up the scope I'm
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (sc->child(hname_t(get_name()))) {
|
||||
cerr << get_fileline() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
// A module instance can not have the same name as another scope object.
|
||||
const NetScope *child = sc->child(hname_t(get_name()));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// A module instance can not have the same name as a genvar.
|
||||
if (sc->find_genvar(get_name())) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and genvar in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A module instance can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = sc->get_parameter(get_name(), ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and parameter in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// check for recursive instantiation by scanning the current
|
||||
// scope and its parents. Look for a module instantiation of
|
||||
// the same module, but farther up in the scope.
|
||||
|
||||
unsigned rl_count = 0;
|
||||
bool in_genblk = false;
|
||||
for (NetScope*scn = sc ; scn ; scn = scn->parent()) {
|
||||
if (scn->type() != NetScope::MODULE)
|
||||
// We need to know if we are inside a generate block to allow
|
||||
// recursive instances.
|
||||
if (scn->type() == NetScope::GENBLOCK) {
|
||||
in_genblk = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
|
||||
if (scn->type() != NetScope::MODULE) continue;
|
||||
|
||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue;
|
||||
|
||||
// We allow nested scopes if they are inside a generate block,
|
||||
// but only to a certain nesting depth.
|
||||
if (in_genblk) {
|
||||
rl_count += 1;
|
||||
if (rl_count > recursive_mod_limit) {
|
||||
cerr << get_fileline() << ": error: instance "
|
||||
<< scope_path(sc) << "." << get_name()
|
||||
<< " of module " << mod->mod_name()
|
||||
<< " is nested too deep." << endl;
|
||||
cerr << get_fileline() << ": : check for "
|
||||
"proper recursion termination or increase the "
|
||||
"limit (" << recursive_mod_limit
|
||||
<< ") with the -pRECURSIVE_MOD_LIMIT flag."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": error: You cannot instantiate "
|
||||
<< "module " << mod->mod_name() << " within itself." << endl;
|
||||
|
||||
cerr << get_fileline() << ": : The offending instance is "
|
||||
<< scope_path(sc) << "." << get_name() << " within "
|
||||
<< scope_path(scn) << "." << endl;
|
||||
|
||||
<< get_name() << " within " << scope_path(scn) << "." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -952,8 +1232,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
{
|
||||
if (msb_) probe_expr_width(des, sc, msb_);
|
||||
if (lsb_) probe_expr_width(des, sc, lsb_);
|
||||
need_constant_expr = true;
|
||||
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
|
||||
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
|
||||
need_constant_expr = false;
|
||||
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
|
||||
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
|
||||
|
||||
|
|
@ -1019,6 +1301,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
my_scope->time_from_timescale(mod->time_from_timescale);
|
||||
des->set_precision(mod->time_precision);
|
||||
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
|
|
@ -1075,9 +1358,9 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
PExpr*tmp = (*cur).second;
|
||||
// No expression means that the parameter is not
|
||||
// replaced at all.
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
if (tmp == 0) continue;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
if (val == 0) continue;
|
||||
replace_net[(*cur).first] = val;
|
||||
}
|
||||
|
||||
|
|
@ -1109,6 +1392,34 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
*/
|
||||
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
// A named event can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(hname_t(name_));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: named event and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named event can not have the same name as a genvar.
|
||||
if (scope->find_genvar(name_)) {
|
||||
cerr << get_fileline() << ": error: named event and "
|
||||
<< "genvar in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named event can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: named event and "
|
||||
<< "parameter in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetEvent*ev = new NetEvent(name_);
|
||||
ev->set_line(*this);
|
||||
scope->add_event(ev);
|
||||
|
|
@ -1189,13 +1500,37 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
if (pscope_name() != 0) {
|
||||
hname_t use_name(pscope_name());
|
||||
if (scope->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
// A named block can not have the same name as another scope
|
||||
// object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: named block and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// A named block can not have the same name as a genvar.
|
||||
if (scope->find_genvar(pscope_name())) {
|
||||
cerr << get_fileline() << ": error: named block and "
|
||||
"genvar in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named block can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(pscope_name(), ex_msb,
|
||||
ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: named block and "
|
||||
"parameter in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Elaborate block scope " << use_name
|
||||
|
|
|
|||
68
elab_sig.cc
68
elab_sig.cc
|
|
@ -126,7 +126,7 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
|
|||
|
||||
hname_t use_name ( (*cur).first );
|
||||
NetScope*fscope = scope->child(use_name);
|
||||
if (scope == 0) {
|
||||
if (fscope == 0) {
|
||||
cerr << (*cur).second->get_fileline() << ": internal error: "
|
||||
<< "Child scope for function " << (*cur).first
|
||||
<< " missing in " << scope_path(scope) << "." << endl;
|
||||
|
|
@ -599,9 +599,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
|
||||
ret_sig->set_scalar(false);
|
||||
|
||||
} else {
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG);
|
||||
ret_sig->set_scalar(true);
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_REG_S);
|
||||
|
|
@ -614,6 +616,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
|
@ -623,6 +626,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(false);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
|
@ -633,6 +637,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(true);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_REAL);
|
||||
break;
|
||||
|
|
@ -843,23 +848,63 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
|||
/*
|
||||
* Elaborate a source wire. The "wire" is the declaration of wires,
|
||||
* registers, ports and memories. The parser has already merged the
|
||||
* multiple properties of a wire (i.e., "input wire") so come the
|
||||
* elaboration this creates an object in the design that represent the
|
||||
* multiple properties of a wire (i.e., "input wire"), so come the
|
||||
* elaboration this creates an object in the design that represents the
|
||||
* defined item.
|
||||
*/
|
||||
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet::Type wtype = type_;
|
||||
if (wtype == NetNet::IMPLICIT)
|
||||
bool is_implicit_scalar = false;
|
||||
if (wtype == NetNet::IMPLICIT) {
|
||||
wtype = NetNet::WIRE;
|
||||
if (wtype == NetNet::IMPLICIT_REG)
|
||||
is_implicit_scalar = true;
|
||||
}
|
||||
if (wtype == NetNet::IMPLICIT_REG) {
|
||||
wtype = NetNet::REG;
|
||||
is_implicit_scalar = true;
|
||||
}
|
||||
|
||||
unsigned wid = 1;
|
||||
long lsb = 0, msb = 0;
|
||||
|
||||
des->errors += error_cnt_;
|
||||
|
||||
// A signal can not have the same name as a scope object.
|
||||
const NetScope *child = scope->child(hname_t(name_));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: signal and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a genvar.
|
||||
const LineInfo *genvar = scope->find_genvar(name_);
|
||||
if (genvar) {
|
||||
cerr << get_fileline() << ": error: signal and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
cerr << get_fileline() << ": error: signal and parameter in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a named event.
|
||||
const NetEvent *event = scope->find_event(name_);
|
||||
if (event) {
|
||||
cerr << get_fileline() << ": error: signal and named event in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (port_set_ || net_set_) {
|
||||
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
|
||||
bool bad_lsb = false, bad_msb = false;
|
||||
|
|
@ -902,6 +947,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
delete texpr;
|
||||
nmsb = pmsb;
|
||||
nlsb = plsb;
|
||||
/* An implicit port can have a range so note that here. */
|
||||
is_implicit_scalar = false;
|
||||
}
|
||||
if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
|
||||
if (port_msb_ == 0) assert(port_lsb_ == 0);
|
||||
|
|
@ -1095,8 +1142,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal "
|
||||
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_;
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype;
|
||||
if (!get_scalar()) {
|
||||
cerr << " ["<<msb<<":"<<lsb<<"]";
|
||||
}
|
||||
cerr << " " << name_;
|
||||
if (array_dimensions > 0) {
|
||||
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
|
||||
}
|
||||
|
|
@ -1108,6 +1158,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
|
||||
: new NetNet(scope, name_, wtype, msb, lsb);
|
||||
|
||||
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
|
||||
|
||||
ivl_variable_type_t use_data_type = data_type_;
|
||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||
use_data_type = IVL_VT_LOGIC;
|
||||
|
|
@ -1124,6 +1176,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_isint(get_isint());
|
||||
if (is_implicit_scalar) sig->set_scalar(true);
|
||||
else sig->set_scalar(get_scalar());
|
||||
|
||||
if (ivl_discipline_t dis = get_discipline()) {
|
||||
sig->set_discipline(dis);
|
||||
|
|
|
|||
209
elaborate.cc
209
elaborate.cc
|
|
@ -189,6 +189,14 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
need_driver_flag = false;
|
||||
}
|
||||
|
||||
/* When we are given a non-default strength value and if the
|
||||
* drive source is a bit, part or indexed select we need to
|
||||
* add a driver (BUFZ) to convey the strength information. */
|
||||
if ((drive0 != Link::STRONG || drive1 != Link::STRONG) &&
|
||||
(dynamic_cast<NetESelect*>(rval_expr))) {
|
||||
need_driver_flag = true;
|
||||
}
|
||||
|
||||
if (need_driver_flag) {
|
||||
NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(),
|
||||
rval->vector_width());
|
||||
|
|
@ -234,8 +242,10 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
|
|||
gates, then I am expected to make more than one
|
||||
gate. Figure out how many are desired. */
|
||||
if (msb_) {
|
||||
need_constant_expr = true;
|
||||
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
|
||||
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
|
||||
need_constant_expr = false;
|
||||
|
||||
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
|
||||
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
|
||||
|
|
@ -623,7 +633,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
return;
|
||||
}
|
||||
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope);
|
||||
ivl_assert(*this, lval_sigs[idx]);
|
||||
// The only way this should return zero is if an error
|
||||
// happened, so for that case just return.
|
||||
if (lval_sigs[idx] == 0) return;
|
||||
|
||||
// For now, assume all the outputs are the same width.
|
||||
ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());
|
||||
|
|
@ -966,6 +978,28 @@ static bool need_bufz_for_input_port(const vector<NetNet*>&prts)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a wire or tri to a tri0 or tri1 as needed to make
|
||||
* an unconnected drive pull for floating inputs.
|
||||
*/
|
||||
static void convert_net(Design*des, const LineInfo *line,
|
||||
NetNet *net, NetNet::Type type)
|
||||
{
|
||||
// If the types already match just return.
|
||||
if (net->type() == type) return;
|
||||
|
||||
// We can only covert a wire or tri to have a default pull.
|
||||
if (net->type() == NetNet::WIRE || net->type() == NetNet::TRI) {
|
||||
net->type(type);
|
||||
return;
|
||||
}
|
||||
|
||||
// We may have to support this at some point in time!
|
||||
cerr << line->get_fileline() << ": sorry: Can not pull floating "
|
||||
"input type '" << net->type() << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Instantiate a module by recursively elaborating it. Set the path of
|
||||
* the recursive elaboration so that signal names get properly
|
||||
|
|
@ -1058,7 +1092,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
|
||||
// No named bindings, just use the positional list I
|
||||
// already have.
|
||||
assert(pin_count() == rmod->port_count());
|
||||
ivl_assert(*this, pin_count() == rmod->port_count());
|
||||
pins = get_pins();
|
||||
}
|
||||
|
||||
|
|
@ -1093,28 +1127,50 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// null parameter is passed in.
|
||||
|
||||
if (pins[idx] == 0) {
|
||||
// We need this information to support the
|
||||
// unconnected_drive directive and for a
|
||||
// unconnected input warning when asked for.
|
||||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
if (mport.size() == 0) continue;
|
||||
|
||||
// While we're here, look to see if this
|
||||
// unconnected (from the outside) port is an
|
||||
// input. If so, consider printing a port binding
|
||||
// warning.
|
||||
if (warn_portbinding) {
|
||||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
if (mport.size() == 0)
|
||||
continue;
|
||||
perm_string pname = peek_tail_name(mport[0]->path());
|
||||
|
||||
perm_string pname = peek_tail_name(mport[0]->path());
|
||||
NetNet*tmp = instance[0]->find_signal(pname);
|
||||
ivl_assert(*this, tmp);
|
||||
|
||||
NetNet*tmp = instance[0]->find_signal(pname);
|
||||
assert(tmp);
|
||||
if (tmp->port_type() == NetNet::PINPUT) {
|
||||
// If we have an unconnected input convert it
|
||||
// as needed if an unconnected_drive directive
|
||||
// was given. This only works for tri or wire!
|
||||
switch (rmod->uc_drive) {
|
||||
case Module::UCD_PULL0:
|
||||
convert_net(des, this, tmp, NetNet::TRI0);
|
||||
break;
|
||||
case Module::UCD_PULL1:
|
||||
convert_net(des, this, tmp, NetNet::TRI1);
|
||||
break;
|
||||
case Module::UCD_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp->port_type() == NetNet::PINPUT) {
|
||||
// Print a waring for an unconnected input.
|
||||
if (warn_portbinding) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "Instantiating module "
|
||||
<< rmod->mod_name()
|
||||
<< " with dangling input port "
|
||||
<< rmod->ports[idx]->name
|
||||
<< "." << endl;
|
||||
<< " with dangling input port '"
|
||||
<< rmod->ports[idx]->name;
|
||||
switch (rmod->uc_drive) {
|
||||
case Module::UCD_PULL0:
|
||||
cerr << "' (pulled low)." << endl;
|
||||
break;
|
||||
case Module::UCD_PULL1:
|
||||
cerr << "' (pulled high)." << endl;
|
||||
break;
|
||||
case Module::UCD_NONE:
|
||||
cerr << "' (floating)." << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1146,13 +1202,13 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) {
|
||||
unsigned lbase = inst * mport.size();
|
||||
PEIdent*pport = mport[ldx];
|
||||
assert(pport);
|
||||
ivl_assert(*this, pport);
|
||||
prts[lbase + ldx]
|
||||
= pport->elaborate_port(des, inst_scope);
|
||||
if (prts[lbase + ldx] == 0)
|
||||
continue;
|
||||
|
||||
assert(prts[lbase + ldx]);
|
||||
ivl_assert(*this, prts[lbase + ldx]);
|
||||
prts_vector_width += prts[lbase + ldx]->vector_width();
|
||||
}
|
||||
}
|
||||
|
|
@ -1167,7 +1223,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// We know by design that each instance has the same
|
||||
// width port. Therefore, the prts_pin_count must be an
|
||||
// even multiple of the instance count.
|
||||
assert(prts_vector_width % instance.size() == 0);
|
||||
ivl_assert(*this, prts_vector_width % instance.size() == 0);
|
||||
|
||||
unsigned desired_vector_width = prts_vector_width;
|
||||
if (instance.size() != 1)
|
||||
|
|
@ -1284,12 +1340,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
|
||||
}
|
||||
|
||||
assert(sig);
|
||||
ivl_assert(*this, sig);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if ((prts.size() >= 1)
|
||||
&& (prts[0]->port_type() != NetNet::PINPUT)) {
|
||||
assert(sig->type() != NetNet::REG);
|
||||
ivl_assert(*this, sig->type() != NetNet::REG);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1515,43 +1571,34 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
|||
module or primitive, it interprets them as parameter
|
||||
overrides. Correct that misconception here. */
|
||||
if (overrides_) {
|
||||
PDelays tmp_del;
|
||||
tmp_del.set_delays(overrides_, false);
|
||||
tmp_del.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
|
||||
|
||||
if (dynamic_cast<NetEConst*> (rise_expr)) {
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Delay expressions must be "
|
||||
<< "constant for primitives." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
if (overrides_->count() > 2) {
|
||||
cerr << get_fileline() << ": error: UDPs take at most two "
|
||||
"delay arguments." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (dynamic_cast<NetEConst*> (fall_expr)) {
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Delay expressions must be "
|
||||
<< "constant for primitives." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
PDelays tmp_del;
|
||||
tmp_del.set_delays(overrides_, false);
|
||||
tmp_del.eval_delays(des, scope, rise_expr, fall_expr,
|
||||
decay_expr);
|
||||
|
||||
if (! dynamic_cast<NetEConst*> (rise_expr)) {
|
||||
cerr << get_fileline() << ": error: UDP rising delay "
|
||||
"expression must be constant." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (! dynamic_cast<NetEConst*> (fall_expr)) {
|
||||
cerr << get_fileline() << ": error: UDP falling delay "
|
||||
"expression must be constant." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *fall_expr << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dynamic_cast<NetEConst*> (decay_expr)) {
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Delay expressions must be "
|
||||
<< "constant for primitives." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
assert(udp);
|
||||
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
|
||||
net->rise_time(rise_expr);
|
||||
|
|
@ -1815,6 +1862,20 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
|
|||
probe_expr_width(des, scope, expr);
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
units, and return an adjusted NetEConst. */
|
||||
|
|
@ -2583,6 +2644,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
ivl_variable_type_t lv_type = lv->expr_type();
|
||||
|
||||
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]);
|
||||
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
|
||||
cerr << evt->get_fileline() << ": error: An event '"
|
||||
<< evt->event()->name() << "' can not be a user "
|
||||
"task argument." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
if (wid > rv->expr_width()) {
|
||||
rv->set_width(wid);
|
||||
rv = pad_to_width(rv, wid, *this);
|
||||
|
|
@ -3041,6 +3109,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
|||
break;
|
||||
|
||||
default:
|
||||
pr = NULL;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
|
@ -3716,15 +3785,26 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
/* Do not elaborate specify delay paths if this feature is
|
||||
turned off. */
|
||||
if (!gn_specify_blocks_flag)
|
||||
return;
|
||||
if (!gn_specify_blocks_flag) return;
|
||||
|
||||
ivl_assert(*this, conditional || (condition==0));
|
||||
|
||||
ndelays = delays.size();
|
||||
if (ndelays > 12)
|
||||
ndelays = 12;
|
||||
if (ndelays > 12) ndelays = 12;
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
/* Elaborate the delay values themselves. Remember to scale
|
||||
|
|
@ -4289,6 +4369,7 @@ Design* elaborate(list<perm_string>roots)
|
|||
scope->set_line(rmod);
|
||||
scope->time_unit(rmod->time_unit);
|
||||
scope->time_precision(rmod->time_precision);
|
||||
scope->time_from_timescale(rmod->time_from_timescale);
|
||||
scope->default_nettype(rmod->default_nettype);
|
||||
des->set_precision(rmod->time_precision);
|
||||
|
||||
|
|
@ -4308,14 +4389,17 @@ Design* elaborate(list<perm_string>roots)
|
|||
des->elaboration_work_list.push_back(es);
|
||||
}
|
||||
|
||||
// After the work items for the root scope elaboration, push a
|
||||
// work item to process the defparams.
|
||||
des->elaboration_work_list.push_back(new top_defparams(des));
|
||||
|
||||
// Run the work list of scope elaborations until the list is
|
||||
// empty. This list is initially populated above where the
|
||||
// initial root scopes are primed.
|
||||
while (! des->elaboration_work_list.empty()) {
|
||||
// Push a work item to process the defparams of any scopes
|
||||
// that are elaborated during this pass. For the first pass
|
||||
// this will be all the root scopes. For subsequent passes
|
||||
// it will be any scopes created during the previous pass
|
||||
// by a generate construct or instance array.
|
||||
des->elaboration_work_list.push_back(new top_defparams(des));
|
||||
|
||||
// Transfer the queue to a temporary queue.
|
||||
list<elaborator_work_item_t*> cur_queue;
|
||||
while (! des->elaboration_work_list.empty()) {
|
||||
|
|
@ -4369,6 +4453,7 @@ Design* elaborate(list<perm_string>roots)
|
|||
NetScope *scope = root_elems[i]->scope;
|
||||
|
||||
rc &= rmod->elaborate(des, scope);
|
||||
delete root_elems[i];
|
||||
}
|
||||
|
||||
if (rc == false) {
|
||||
|
|
|
|||
31
eval_tree.cc
31
eval_tree.cc
|
|
@ -133,7 +133,7 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
|
|||
|
||||
if (debug_eval_tree) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Partially evalutate " << *this
|
||||
<< "Partially evaluate " << *this
|
||||
<< " using (a+2)-1 --> (a+1) transform." << endl;
|
||||
}
|
||||
|
||||
|
|
@ -381,6 +381,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
|
|||
break;
|
||||
|
||||
default:
|
||||
lv = 0.0;
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unexpected expression type? " << le->expr_type() << endl;
|
||||
assert(0);
|
||||
|
|
@ -401,6 +402,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
|
|||
break;
|
||||
|
||||
default:
|
||||
rv = 0.0;
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unexpected expression type? " << ri->expr_type() << endl;
|
||||
assert(0);
|
||||
|
|
@ -585,6 +587,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
|
|||
break;
|
||||
|
||||
default:
|
||||
lv = 0.0;
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unexpected expression type? " << le->expr_type() << endl;
|
||||
assert(0);
|
||||
|
|
@ -605,6 +608,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
|
|||
break;
|
||||
|
||||
default:
|
||||
rv = 0.0;
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unexpected expression type? " << ri->expr_type() << endl;
|
||||
assert(0);
|
||||
|
|
@ -996,6 +1000,11 @@ NetExpr* NetEBPow::eval_tree_real_()
|
|||
|
||||
NetECReal*res = new NetECReal( pow(lval,rval) );
|
||||
res->set_line(*this);
|
||||
|
||||
if (debug_eval_tree)
|
||||
cerr << get_fileline() << ": debug: Evaluate (real) "
|
||||
<< lval << " ** " << rval << " --> " << *res << endl;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1016,7 +1025,14 @@ NetExpr* NetEBPow::eval_tree(int prune_to_width)
|
|||
verinum lval = lc->value();
|
||||
verinum rval = rc->value();
|
||||
|
||||
return new NetEConst( pow(lval,rval) );
|
||||
NetEConst*res = new NetEConst( pow(lval,rval) );
|
||||
res->set_line(*this);
|
||||
|
||||
if (debug_eval_tree)
|
||||
cerr << get_fileline() << ": debug: Evaluate "
|
||||
<< lval << " ** " << rval << " --> " << *res << endl;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1161,16 +1177,6 @@ NetEConst* NetEConcat::eval_tree(int prune_to_width)
|
|||
|
||||
if (local_errors > 0) return 0;
|
||||
|
||||
// Handle the special case that the repeat expression is
|
||||
// zero. In this case, just return a 0 value with the expected
|
||||
// width.
|
||||
if (repeat_val == 0) {
|
||||
verinum val (verinum::V0, expr_width());
|
||||
NetEConst*res = new NetEConst(val);
|
||||
res->set_width(val.len());
|
||||
return res;
|
||||
}
|
||||
|
||||
// At this point, the "gap" is the width of a single repeat of
|
||||
// the concatenation. The total width of the result is the gap
|
||||
// times the repeat count.
|
||||
|
|
@ -1713,6 +1719,7 @@ NetExpr* evaluate_clog2(NetExpr*&arg_)
|
|||
res = integer_width;
|
||||
|
||||
verinum tmp (res, integer_width);
|
||||
tmp.has_sign(true);
|
||||
NetEConst*rtn = new NetEConst(tmp);
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
perm_string oname = osig->scope()->local_symbol();
|
||||
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
|
||||
|
|
@ -199,6 +200,7 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width);
|
||||
break;
|
||||
default:
|
||||
gate = NULL;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
|
@ -390,6 +392,7 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
NetNet::IMPLICIT, width);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(powr->pin_Result(), osig->pin(0));
|
||||
|
|
@ -426,6 +429,7 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
NetNet::IMPLICIT, width);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(mult->pin_Result(), osig->pin(0));
|
||||
|
|
@ -601,8 +605,8 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const bool right_flag = op_ == 'r' || op_ == 'R';
|
||||
const bool signed_flag = op_ == 'R';
|
||||
const bool right_flag = op_ == 'r' || op_ == 'R';
|
||||
const bool signed_flag = has_sign() && op_ == 'R';
|
||||
|
||||
/* Detect the special case where the shift amount is
|
||||
constant. Evaluate the shift amount, and simply reconnect
|
||||
|
|
@ -719,28 +723,42 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
{
|
||||
/* First, synthesize the operands. */
|
||||
unsigned nparms = parms_.count();
|
||||
NetNet**tmp = new NetNet*[parms_.count()];
|
||||
bool flag = true;
|
||||
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
|
||||
if (tmp[idx] == 0)
|
||||
flag = false;
|
||||
if (parms_[idx]->expr_width() == 0) {
|
||||
/* We need to synthesize a replication of zero. */
|
||||
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
|
||||
assert(tmp[idx] == 0);
|
||||
nparms -= 1;
|
||||
} else {
|
||||
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
|
||||
if (tmp[idx] == 0) flag = false;
|
||||
/* Set the data type to the first one found. */
|
||||
if (data_type == IVL_VT_NO_TYPE) {
|
||||
data_type = tmp[idx]->data_type();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag == false)
|
||||
return 0;
|
||||
if (flag == false) return 0;
|
||||
|
||||
ivl_assert(*this, tmp[0]);
|
||||
ivl_assert(*this, data_type != IVL_VT_NO_TYPE);
|
||||
|
||||
/* If this is a replication of zero just return 0. */
|
||||
if (expr_width() == 0) return 0;
|
||||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
perm_string path = scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
osig->data_type(tmp[0]->data_type());
|
||||
osig->data_type(data_type);
|
||||
|
||||
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
|
||||
osig->vector_width(),
|
||||
parms_.count() * repeat());
|
||||
nparms * repeat());
|
||||
concat->set_line(*this);
|
||||
des->add_node(concat);
|
||||
connect(concat->pin(0), osig->pin(0));
|
||||
|
|
@ -750,7 +768,7 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
unsigned concat_item = parms_.count()-idx-1;
|
||||
ivl_assert(*this, tmp[concat_item]);
|
||||
if (tmp[concat_item] == 0) continue;
|
||||
connect(concat->pin(cur_pin), tmp[concat_item]->pin(0));
|
||||
cur_pin += 1;
|
||||
count_input_width += tmp[concat_item]->vector_width();
|
||||
|
|
@ -773,6 +791,11 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
|
|||
{
|
||||
perm_string path = scope->local_symbol();
|
||||
unsigned width=expr_width();
|
||||
if (width == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Found a zero width constant!" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
|
|
@ -841,6 +864,7 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width);
|
||||
break;
|
||||
default:
|
||||
gate = NULL;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
|
@ -909,11 +933,6 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetUReduce::TYPE rtype = NetUReduce::NONE;
|
||||
|
||||
switch (op()) {
|
||||
|
|
@ -944,8 +963,13 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(),
|
||||
rtype, isig->vector_width());
|
||||
|
||||
des->add_node(gate);
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(1+idx), isig->pin(idx));
|
||||
|
|
@ -1067,7 +1091,8 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
if (base_ != 0) {
|
||||
off = base_->synthesize(des, scope, root);
|
||||
|
||||
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width());
|
||||
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width(),
|
||||
base_->has_sign());
|
||||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
|
|
@ -1347,6 +1372,10 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
/* Synthesize the arguments. */
|
||||
bool errors = false;
|
||||
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
|
||||
if (dynamic_cast<NetEEvent*> (parms_[idx])) {
|
||||
errors = true;
|
||||
continue;
|
||||
}
|
||||
NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
|
||||
if (tmp == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to synthesize "
|
||||
|
|
@ -1384,9 +1413,15 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
/* Connect the pins to the arguments. */
|
||||
NetFuncDef*def = func_->func_def();
|
||||
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
|
||||
NetNet*tmp = pad_to_width(des, eparms[idx],
|
||||
def->port(idx)->vector_width(), *this);
|
||||
connect(net->pin(idx+1), tmp->pin(0));
|
||||
unsigned width = def->port(idx)->vector_width();
|
||||
NetNet*tmp;
|
||||
if (eparms[idx]->get_signed()) {
|
||||
tmp = pad_to_width_signed(des, eparms[idx], width, *this);
|
||||
} else {
|
||||
tmp = pad_to_width(des, eparms[idx], width, *this);
|
||||
}
|
||||
NetNet*tmpc = crop_to_width(des, tmp, width);
|
||||
connect(net->pin(idx+1), tmpc->pin(0));
|
||||
}
|
||||
|
||||
return osig;
|
||||
|
|
|
|||
|
|
@ -499,65 +499,3 @@ already seems to exist amongst VCD viewers in the wild, this behavior
|
|||
seems to be acceptable according to the standard, is a better mirror
|
||||
of 4-value behavior in the dead zone, and appears more user friendly
|
||||
when viewed by reasonable viewers.
|
||||
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
|
||||
$Log: ieee1364-notes.txt,v $
|
||||
Revision 1.19 2007/04/18 02:36:13 steve
|
||||
Put to iverilog wiki for further notes.
|
||||
|
||||
Revision 1.18 2007/03/22 16:08:16 steve
|
||||
Spelling fixes from Larry
|
||||
|
||||
Revision 1.17 2003/07/15 03:49:22 steve
|
||||
Spelling fixes.
|
||||
|
||||
Revision 1.16 2003/04/14 03:40:21 steve
|
||||
Make some effort to preserve bits while
|
||||
operating on constant values.
|
||||
|
||||
Revision 1.15 2003/02/16 23:39:08 steve
|
||||
NaN in dead zones of VCD dumps.
|
||||
|
||||
Revision 1.14 2003/02/06 17:51:36 steve
|
||||
Edge of vectors notes.
|
||||
|
||||
Revision 1.13 2002/08/20 04:11:53 steve
|
||||
Support parameters with defined ranges.
|
||||
|
||||
Revision 1.12 2002/06/11 03:34:33 steve
|
||||
Spelling patch (Larry Doolittle)
|
||||
|
||||
Revision 1.11 2002/04/27 02:38:04 steve
|
||||
Support selecting bits from parameters.
|
||||
|
||||
Revision 1.10 2002/03/31 01:54:13 steve
|
||||
Notes about scheduling
|
||||
|
||||
Revision 1.9 2002/01/26 02:08:07 steve
|
||||
Handle x in l-value of set/x
|
||||
|
||||
Revision 1.8 2001/08/01 05:17:31 steve
|
||||
Accept empty port lists to module instantiation.
|
||||
|
||||
Revision 1.7 2001/02/17 05:27:31 steve
|
||||
I allow function ports to have types.
|
||||
|
||||
Revision 1.6 2001/02/12 16:48:04 steve
|
||||
Rant about bit widths.
|
||||
|
||||
Revision 1.5 2001/01/02 17:28:08 steve
|
||||
Resolve repeat ambiguity in favor of loop.
|
||||
|
||||
Revision 1.4 2001/01/01 19:12:35 steve
|
||||
repeat loops ambiguity.
|
||||
|
||||
Revision 1.3 2000/12/15 00:21:46 steve
|
||||
rounding of time and x in primitives.
|
||||
|
||||
Revision 1.2 2000/11/19 22:03:04 steve
|
||||
Integer parameter comments.
|
||||
|
||||
Revision 1.1 2000/07/23 18:06:31 steve
|
||||
Document ieee1364 issues.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
.TH iverilog-vpi 1 "November 19th, 2008" "" "Version 0.9.devel"
|
||||
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog-vpi
|
||||
[--name=\fIname\fP]
|
||||
[\-\-name=\fIname\fP]
|
||||
\fIsourcefile\fP...
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIiverilog-vpi\fP is a tool to simplify the compilation of VPI
|
||||
\fIiverilog\-vpi\fP is a tool to simplify the compilation of VPI
|
||||
modules for use with Icarus Verilog. It takes on the command line a
|
||||
list of C or C++ source files, and generates as output a linked VPI
|
||||
module. See the \fBvvp\fP(1) man page for a description of how the
|
||||
|
|
@ -20,8 +20,7 @@ first source file is named \fIfoo.c\fP, the output becomes
|
|||
\fIfoo.vpi\fP.
|
||||
|
||||
.SH OPTIONS
|
||||
.l
|
||||
\fIiverilog-vpi\fP accepts the following options:
|
||||
\fIiverilog\-vpi\fP accepts the following options:
|
||||
.TP 8
|
||||
.B -l\fIlibrary\fP
|
||||
Include the named library in the link of the VPI module. This allows
|
||||
|
|
@ -54,7 +53,7 @@ These flags provide compile time information.
|
|||
|
||||
.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
|
||||
support the more intractable development environment. These flags help
|
||||
the program locate parts that it needs.
|
||||
|
||||
|
|
@ -62,7 +61,7 @@ the program locate parts that it needs.
|
|||
.B -mingw=\fIpath\fP
|
||||
Tell the program the root of the Mingw compiler tool suite. The
|
||||
\fBvvp\fP runtime is compiled with this compiler, and this is the
|
||||
compiler that \fIiverilog-vpi\fP expects to use to compile your source
|
||||
compiler that \fIiverilog\-vpi\fP expects to use to compile your source
|
||||
code. This is normally not needed, and if you do use it, it is only
|
||||
needed once. The compiler will save the \fIpath\fP in the registry for
|
||||
use later.
|
||||
|
|
@ -76,7 +75,7 @@ stored in the registry for future use.
|
|||
|
||||
.SH "UNIX-ONLY OPTIONS"
|
||||
|
||||
The UNIX version of \fIiverilog-vpi\fP includes additional flags to
|
||||
The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
|
||||
let Makefile gurus peek at the configuration of the \fIiverilog\fP
|
||||
installation. This way, Makefiles can be written that handle complex VPI
|
||||
builds natively, and without hard-coding values that depend on the
|
||||
|
|
@ -104,9 +103,9 @@ requests a 32bit vpi binary instead of the default 64bit binary.
|
|||
.P
|
||||
Example GNU makefile that takes advantage of these flags:
|
||||
.IP "" 4
|
||||
CFLAGS = -Wall -O $(CFLAGS_$@)
|
||||
CFLAGS = \-Wall \-O $(CFLAGS_$@)
|
||||
.br
|
||||
VPI_CFLAGS := $(shell iverilog-vpi --cflags)
|
||||
VPI_CFLAGS := $(shell iverilog-vpi \-\-cflags)
|
||||
.br
|
||||
CFLAGS_messagev.o = $(VPI_CFLAGS)
|
||||
.br
|
||||
|
|
@ -129,7 +128,7 @@ iverilog(1), vvp(1),
|
|||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002-2008 Stephen Williams
|
||||
Copyright \(co 2002\-2009 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
|
||||
# These are the variables used for compiling files
|
||||
CC=@IVCC@
|
||||
CC="@IVCC@"
|
||||
CXX=@IVCXX@
|
||||
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
|
||||
|
||||
|
|
|
|||
1
ivl.def
1
ivl.def
|
|
@ -161,6 +161,7 @@ ivl_scope_event
|
|||
ivl_scope_events
|
||||
ivl_scope_file
|
||||
ivl_scope_is_auto
|
||||
ivl_scope_is_cell
|
||||
ivl_scope_lineno
|
||||
ivl_scope_logs
|
||||
ivl_scope_log
|
||||
|
|
|
|||
|
|
@ -1537,6 +1537,9 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
|||
* ivl_scope_is_auto
|
||||
* Is the task or function declared to be automatic?
|
||||
*
|
||||
* ivl_scope_is_cell
|
||||
* Is the module defined to be a cell?
|
||||
*
|
||||
* ivl_scope_var
|
||||
* ivl_scope_vars
|
||||
* REMOVED
|
||||
|
|
@ -1614,6 +1617,7 @@ extern unsigned ivl_scope_events(ivl_scope_t net);
|
|||
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
|
||||
extern const char* ivl_scope_file(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_is_auto(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_is_cell(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_lineno(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_logs(ivl_scope_t net);
|
||||
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
Icarus Verilog LOADABLE TARGET API (ivl_target)
|
||||
|
||||
Copyright 2002 Stephen Williams <steve@icarus.com>
|
||||
$Id: ivl_target.txt,v 1.3 2002/06/11 03:34:33 steve Exp $
|
||||
|
||||
|
||||
The ivl_target API is the interface available to modules that the
|
||||
|
|
@ -38,14 +37,3 @@ other LPM device with outputs.
|
|||
|
||||
There are ivl_lpm_size() input ports, each with the width
|
||||
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().
|
||||
|
||||
$Log: ivl_target.txt,v $
|
||||
Revision 1.3 2002/06/11 03:34:33 steve
|
||||
Spelling patch (Larry Doolittle)
|
||||
|
||||
Revision 1.2 2002/03/17 19:31:17 steve
|
||||
Add API to support user defined function.
|
||||
|
||||
Revision 1.1 2002/03/09 02:10:22 steve
|
||||
Add the NetUserFunc netlist node.
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ distclean: clean
|
|||
rm -f Makefile config.log
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
../config.status --file=$@
|
||||
cd ..; ./config.status --file=ivlpp/$@
|
||||
|
||||
O = main.o lexor.o
|
||||
|
||||
|
|
@ -74,4 +74,4 @@ uninstall:
|
|||
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
|
||||
|
||||
lexor.o: lexor.c globals.h
|
||||
main.o: main.c globals.h ../version.h
|
||||
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h
|
||||
|
|
|
|||
|
|
@ -64,13 +64,8 @@ struct include_stack_t
|
|||
/* If we are reparsing a macro expansion, file is 0 and this
|
||||
* member points to the string in progress
|
||||
*/
|
||||
const char* str;
|
||||
|
||||
/* If we are reparsing a macro expansion, this member indicates
|
||||
* the amount of space it occupies in the macro expansion buffer.
|
||||
* This will be zero for macros without arguments.
|
||||
*/
|
||||
int ebs;
|
||||
char* str;
|
||||
char* orig_str;
|
||||
|
||||
int stringify_flag;
|
||||
|
||||
|
|
@ -462,7 +457,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
|||
<IFCCOMMENT>\n\r |
|
||||
<IFCCOMMENT>\r\n |
|
||||
<IFCCOMMENT>\n |
|
||||
<IFCCOMMENT>\r { istack->lineno += 1; }
|
||||
<IFCCOMMENT>\r { istack->lineno += 1; fputc('\n', yyout); }
|
||||
<IFCCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { }
|
||||
|
|
@ -599,7 +594,8 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
|||
|
||||
<MA_ADD>"(" { macro_add_to_arg(0); ma_parenthesis_level++; }
|
||||
|
||||
<MA_ADD>"," { macro_finish_arg(); }
|
||||
<MA_ADD>"," { if (ma_parenthesis_level > 0) macro_add_to_arg(0);
|
||||
else macro_finish_arg(); }
|
||||
|
||||
<MA_ADD>")" {
|
||||
if (ma_parenthesis_level > 0) {
|
||||
|
|
@ -1352,10 +1348,17 @@ static void do_expand(int use_args)
|
|||
struct include_stack_t*isp;
|
||||
int head = 0;
|
||||
int tail = 0;
|
||||
const char *cp;
|
||||
unsigned escapes = 0;
|
||||
char *str_buf = 0;
|
||||
|
||||
if (cur_macro->keyword)
|
||||
{
|
||||
fprintf(yyout, "%s", cur_macro->value);
|
||||
if (do_expand_stringify_flag) {
|
||||
do_expand_stringify_flag = 0;
|
||||
fputc('"', yyout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1364,6 +1367,7 @@ static void do_expand(int use_args)
|
|||
head = exp_buf_size - exp_buf_free;
|
||||
expand_using_args();
|
||||
tail = exp_buf_size - exp_buf_free;
|
||||
exp_buf_free += tail - head;
|
||||
|
||||
if (tail == head)
|
||||
return;
|
||||
|
|
@ -1376,14 +1380,47 @@ static void do_expand(int use_args)
|
|||
if (use_args)
|
||||
{
|
||||
isp->str = &exp_buf[head];
|
||||
isp->ebs = tail - head;
|
||||
}
|
||||
else
|
||||
{
|
||||
isp->str = cur_macro->value;
|
||||
isp->ebs = 0;
|
||||
}
|
||||
|
||||
/* Escape some characters if we are making a string version. */
|
||||
for (cp = isp->str; (cp = strpbrk(cp, "\"\\")); cp += 1, escapes += 1);
|
||||
if (escapes && isp->stringify_flag) {
|
||||
unsigned idx = 0;
|
||||
str_buf = (char *) malloc(strlen(isp->str)+3*escapes+1);
|
||||
for (cp = isp->str; *cp; cp += 1) {
|
||||
if (*cp == '"') {
|
||||
str_buf[idx] = '\\';
|
||||
str_buf[idx+1] = '0';
|
||||
str_buf[idx+2] = '4';
|
||||
str_buf[idx+3] = '2';
|
||||
idx += 4;
|
||||
continue;
|
||||
}
|
||||
if (*cp == '\\') {
|
||||
str_buf[idx] = '\\';
|
||||
str_buf[idx+1] = '1';
|
||||
str_buf[idx+2] = '3';
|
||||
str_buf[idx+3] = '4';
|
||||
idx += 4;
|
||||
continue;
|
||||
}
|
||||
str_buf[idx] = *cp;
|
||||
idx += 1;
|
||||
}
|
||||
str_buf[idx] = 0;
|
||||
idx += 1;
|
||||
|
||||
exp_buf_free -= idx;
|
||||
|
||||
isp->str = str_buf;
|
||||
} else
|
||||
isp->str = strdup(isp->str);
|
||||
|
||||
isp->orig_str = isp->str;
|
||||
isp->next = istack;
|
||||
istack->yybs = YY_CURRENT_BUFFER;
|
||||
istack = isp;
|
||||
|
|
@ -1572,7 +1609,7 @@ static int load_next_input()
|
|||
else
|
||||
line_mask_flag = 1;
|
||||
|
||||
exp_buf_free += isp->ebs;
|
||||
free(isp->orig_str);
|
||||
}
|
||||
|
||||
if (isp->stringify_flag) {
|
||||
|
|
@ -1749,7 +1786,6 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
isp->path = strdup(paths[0]);
|
||||
isp->file = fopen(paths[0], "r");
|
||||
isp->str = 0;
|
||||
isp->ebs = 0;
|
||||
isp->lineno = 0;
|
||||
isp->stringify_flag = 0;
|
||||
isp->comment = NULL;
|
||||
|
|
@ -1779,7 +1815,6 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
isp->path = strdup(paths[idx]);
|
||||
isp->file = 0;
|
||||
isp->str = 0;
|
||||
isp->ebs = 0;
|
||||
isp->next = 0;
|
||||
isp->lineno = 0;
|
||||
isp->stringify_flag = 0;
|
||||
|
|
@ -1807,4 +1842,5 @@ void destroy_lexor()
|
|||
# endif
|
||||
# endif
|
||||
free(def_buf);
|
||||
free(exp_buf);
|
||||
}
|
||||
|
|
|
|||
56
ivlpp/main.c
56
ivlpp/main.c
|
|
@ -18,7 +18,8 @@ const char COPYRIGHT[] =
|
|||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include "version.h"
|
||||
# include "version_base.h"
|
||||
# include "version_tag.h"
|
||||
|
||||
const char NOTICE[] =
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
|
|
@ -214,26 +215,34 @@ int main(int argc, char*argv[])
|
|||
FILE*precomp_out = NULL;
|
||||
|
||||
/* Define preprocessor keywords that I plan to just pass. */
|
||||
/* From 1364-2005 Chapter 19. */
|
||||
define_macro("begin_keywords", "`begin_keywords", 1, 0);
|
||||
define_macro("celldefine", "`celldefine", 1, 0);
|
||||
define_macro("default_decay_time", "`default_decay_time", 1, 0);
|
||||
define_macro("default_nettype", "`default_nettype", 1, 0);
|
||||
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0);
|
||||
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
|
||||
define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
|
||||
define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
|
||||
define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
|
||||
define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
|
||||
define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
|
||||
define_macro("end_keywords", "`end_keywords", 1, 0);
|
||||
define_macro("endcelldefine", "`endcelldefine", 1, 0);
|
||||
define_macro("endprotect", "`endprotect", 1, 0);
|
||||
define_macro("line", "`line", 1, 0);
|
||||
define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
|
||||
define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0);
|
||||
define_macro("protect", "`protect", 1, 0);
|
||||
define_macro("pragma", "`pragma", 1, 0);
|
||||
define_macro("resetall", "`resetall", 1, 0);
|
||||
define_macro("suppress_faults", "`suppress_faults", 1, 0);
|
||||
define_macro("timescale", "`timescale", 1, 0);
|
||||
define_macro("unconnected_drive", "`unconnected_drive", 1, 0);
|
||||
|
||||
/* From 1364-2005 Annex D. */
|
||||
define_macro("default_decay_time", "`default_decay_time", 1, 0);
|
||||
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0);
|
||||
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
|
||||
define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
|
||||
define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
|
||||
define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
|
||||
|
||||
/* From other places. */
|
||||
define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
|
||||
define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
|
||||
define_macro("endprotect", "`endprotect", 1, 0);
|
||||
define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
|
||||
define_macro("protect", "`protect", 1, 0);
|
||||
define_macro("suppress_faults", "`suppress_faults", 1, 0);
|
||||
define_macro("uselib", "`uselib", 1, 0);
|
||||
|
||||
include_cnt = 2;
|
||||
|
|
@ -357,14 +366,17 @@ int main(int argc, char*argv[])
|
|||
if (precomp_out_path) {
|
||||
precomp_out = fopen(precomp_out_path, "wb");
|
||||
if (precomp_out == 0) {
|
||||
if (out_path) fclose(out);
|
||||
perror(precomp_out_path);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(dep_path) {
|
||||
if (dep_path) {
|
||||
depend_file = fopen(dep_path, "a");
|
||||
if (depend_file == 0) {
|
||||
if (out_path) fclose(out);
|
||||
if (precomp_out) fclose(precomp_out);
|
||||
perror(dep_path);
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -372,24 +384,32 @@ int main(int argc, char*argv[])
|
|||
|
||||
if (source_cnt == 0) {
|
||||
fprintf(stderr, "%s: No input files given.\n", argv[0]);
|
||||
if (out_path) fclose(out);
|
||||
if (depend_file) fclose(depend_file);
|
||||
if (precomp_out) fclose(precomp_out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Pass to the lexical analyzer the list of input file, and
|
||||
start scanning. */
|
||||
reset_lexor(out, source_list);
|
||||
if (yylex()) return -1;
|
||||
if (yylex()) {
|
||||
if (out_path) fclose(out);
|
||||
if (depend_file) fclose(depend_file);
|
||||
if (precomp_out) fclose(precomp_out);
|
||||
return -1;
|
||||
}
|
||||
destroy_lexor();
|
||||
|
||||
if(depend_file) {
|
||||
fclose(depend_file);
|
||||
}
|
||||
if (depend_file) fclose(depend_file);
|
||||
|
||||
if (precomp_out) {
|
||||
dump_precompiled_defines(precomp_out);
|
||||
fclose(precomp_out);
|
||||
}
|
||||
|
||||
if (out_path) fclose(out);
|
||||
|
||||
/* Free the source and include directory lists. */
|
||||
for (lp = 0; lp < source_cnt; lp += 1) {
|
||||
free(source_list[lp]);
|
||||
|
|
|
|||
540
lexor.lex
540
lexor.lex
|
|
@ -67,9 +67,6 @@ static const char* set_file_name(char*text)
|
|||
return path;
|
||||
}
|
||||
|
||||
|
||||
extern void pform_set_timescale(int, int, const char*file, unsigned line);
|
||||
|
||||
void reset_lexor();
|
||||
static void line_directive();
|
||||
static void line_directive2();
|
||||
|
|
@ -83,11 +80,15 @@ static verinum*make_unsized_hex(const char*txt);
|
|||
static int dec_buf_div2(char *buf);
|
||||
|
||||
static void process_timescale(const char*txt);
|
||||
static void process_ucdrive(const char*txt);
|
||||
|
||||
static list<int> keyword_mask_stack;
|
||||
|
||||
static int comment_enter;
|
||||
static bool in_module = false;
|
||||
static bool in_UDP = false;
|
||||
bool in_celldefine = false;
|
||||
UCDriveType uc_drive = UCD_NONE;
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
|
|
@ -96,6 +97,7 @@ static bool in_module = false;
|
|||
%x CSTRING
|
||||
%s UDPTABLE
|
||||
%x PPTIMESCALE
|
||||
%x PPUCDRIVE
|
||||
%x PPDEFAULT_NETTYPE
|
||||
%x PPBEGIN_KEYWORDS
|
||||
%s EDGES
|
||||
|
|
@ -107,8 +109,9 @@ S [afpnumkKMGT]
|
|||
|
||||
%%
|
||||
|
||||
^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
|
||||
^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); }
|
||||
/* Recognize the various line directives. */
|
||||
^"#line"[ \t]+.+ { line_directive(); }
|
||||
^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
|
||||
|
||||
[ \t\b\f\r] { ; }
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
|
@ -237,6 +240,14 @@ S [afpnumkKMGT]
|
|||
in_module = false;
|
||||
break;
|
||||
|
||||
case K_primitive:
|
||||
in_UDP = true;
|
||||
break;
|
||||
|
||||
case K_endprimitive:
|
||||
in_UDP = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
yylval.text = 0;
|
||||
break;
|
||||
|
|
@ -263,22 +274,35 @@ S [afpnumkKMGT]
|
|||
return IDENTIFIER; }
|
||||
|
||||
\$([a-zA-Z0-9$_]+) {
|
||||
if (strcmp(yytext,"$setuphold") == 0)
|
||||
return K_Ssetuphold;
|
||||
if (strcmp(yytext,"$attribute") == 0)
|
||||
return KK_attribute;
|
||||
/* The 1364-1995 timing checks. */
|
||||
if (strcmp(yytext,"$hold") == 0)
|
||||
return K_Shold;
|
||||
if (strcmp(yytext,"$nochange") == 0)
|
||||
return K_Snochange;
|
||||
if (strcmp(yytext,"$period") == 0)
|
||||
return K_Speriod;
|
||||
if (strcmp(yytext,"$recovery") == 0)
|
||||
return K_Srecovery;
|
||||
if (strcmp(yytext,"$recrem") == 0)
|
||||
return K_Srecrem;
|
||||
if (strcmp(yytext,"$setup") == 0)
|
||||
return K_Ssetup;
|
||||
if (strcmp(yytext,"$setuphold") == 0)
|
||||
return K_Ssetuphold;
|
||||
if (strcmp(yytext,"$skew") == 0)
|
||||
return K_Sskew;
|
||||
if (strcmp(yytext,"$width") == 0)
|
||||
return K_Swidth;
|
||||
/* The new 1364-2001 timing checks. */
|
||||
if (strcmp(yytext,"$fullskew") == 0)
|
||||
return K_Sfullskew;
|
||||
if (strcmp(yytext,"$recrem") == 0)
|
||||
return K_Srecrem;
|
||||
if (strcmp(yytext,"$removal") == 0)
|
||||
return K_Sremoval;
|
||||
if (strcmp(yytext,"$timeskew") == 0)
|
||||
return K_Stimeskew;
|
||||
|
||||
if (strcmp(yytext,"$attribute") == 0)
|
||||
return KK_attribute;
|
||||
yylval.text = strdupnew(yytext);
|
||||
return SYSTEM_IDENTIFIER; }
|
||||
|
||||
|
|
@ -348,7 +372,7 @@ S [afpnumkKMGT]
|
|||
return REALTIME; }
|
||||
|
||||
|
||||
/* Notice and handle the timescale directive. */
|
||||
/* Notice and handle the `timescale directive. */
|
||||
|
||||
^{W}?`timescale { BEGIN(PPTIMESCALE); }
|
||||
<PPTIMESCALE>.* { process_timescale(yytext); }
|
||||
|
|
@ -362,28 +386,74 @@ S [afpnumkKMGT]
|
|||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
/* Notice and handle the `celldefine and `endcelldefine directives. */
|
||||
|
||||
^{W}?`celldefine{W}? { in_celldefine = true; }
|
||||
^{W}?`endcelldefine{W}? { in_celldefine = false; }
|
||||
|
||||
/* Notice and handle the resetall directive. */
|
||||
|
||||
^{W}?`resetall{W}? {
|
||||
if (in_module) {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
|
||||
"`resetall directive can not be inside a module "
|
||||
"definition." << endl;
|
||||
error_count += 1;
|
||||
} else if (in_UDP) {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
|
||||
"`resetall directive can not be inside a UDP "
|
||||
"definition." << endl;
|
||||
error_count += 1;
|
||||
} else {
|
||||
pform_set_default_nettype(NetNet::WIRE, yylloc.text,
|
||||
yylloc.first_line);
|
||||
in_celldefine = false;
|
||||
uc_drive = UCD_NONE;
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
} }
|
||||
|
||||
/* Notice and handle the `unconnected_drive directive. */
|
||||
^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); }
|
||||
<PPUCDRIVE>.* { process_ucdrive(yytext); }
|
||||
<PPUCDRIVE>\n {
|
||||
if (in_module) {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
|
||||
"`unconnected_drive directive can not be inside a "
|
||||
"module definition." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
^{W}?`nounconnected_drive{W}? {
|
||||
if (in_module) {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
|
||||
"`nounconnected_drive directive can not be inside a "
|
||||
"module definition." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
uc_drive = UCD_NONE; }
|
||||
|
||||
/* These are directives that I do not yet support. I think that IVL
|
||||
should handle these, not an external preprocessor. */
|
||||
/* From 1364-2005 Chapter 19. */
|
||||
^{W}?`pragme{W}?.* { }
|
||||
|
||||
^{W}?`celldefine{W}?.* { }
|
||||
/* From 1364-2005 Annex D. */
|
||||
^{W}?`default_decay_time{W}?.* { }
|
||||
^{W}?`default_trireg_strength{W}?.* { }
|
||||
^{W}?`delay_mode_distributed{W}?.* { }
|
||||
^{W}?`delay_mode_unit{W}?.* { }
|
||||
^{W}?`delay_mode_path{W}?.* { }
|
||||
^{W}?`delay_mode_unit{W}?.* { }
|
||||
^{W}?`delay_mode_zero{W}?.* { }
|
||||
|
||||
/* From other places. */
|
||||
^{W}?`disable_portfaults{W}?.* { }
|
||||
^{W}?`enable_portfaults{W}?.* { }
|
||||
^{W}?`endcelldefine{W}?.* { }
|
||||
`endprotect { }
|
||||
^{W}?`line{W}?.* { }
|
||||
^{W}?`nosuppress_faults{W}?.* { }
|
||||
^{W}?`nounconnected_drive{W}?.* { }
|
||||
`protect { }
|
||||
^{W}?`resetall{W}?.* { }
|
||||
^{W}?`suppress_faults{W}?.* { }
|
||||
^{W}?`unconnected_drive{W}?.* { }
|
||||
^{W}?`uselib{W}?.* { }
|
||||
|
||||
^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
|
||||
|
|
@ -447,16 +517,38 @@ S [afpnumkKMGT]
|
|||
NetNet::Type net_type;
|
||||
size_t wordlen = strcspn(yytext, " \t\f\r\n");
|
||||
yytext[wordlen] = 0;
|
||||
/* Add support for other wire types and better error detection. */
|
||||
if (strcmp(yytext,"wire") == 0) {
|
||||
net_type = NetNet::WIRE;
|
||||
|
||||
} else if (strcmp(yytext,"tri") == 0) {
|
||||
net_type = NetNet::TRI;
|
||||
|
||||
} else if (strcmp(yytext,"tri0") == 0) {
|
||||
net_type = NetNet::TRI0;
|
||||
|
||||
} else if (strcmp(yytext,"tri1") == 0) {
|
||||
net_type = NetNet::TRI1;
|
||||
|
||||
} else if (strcmp(yytext,"wand") == 0) {
|
||||
net_type = NetNet::WAND;
|
||||
|
||||
} else if (strcmp(yytext,"triand") == 0) {
|
||||
net_type = NetNet::TRIAND;
|
||||
|
||||
} else if (strcmp(yytext,"wor") == 0) {
|
||||
net_type = NetNet::WOR;
|
||||
|
||||
} else if (strcmp(yytext,"trior") == 0) {
|
||||
net_type = NetNet::TRIOR;
|
||||
|
||||
} else if (strcmp(yytext,"none") == 0) {
|
||||
net_type = NetNet::NONE;
|
||||
|
||||
} else {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line
|
||||
<< ": error: Net type " << yytext
|
||||
<< " is not a valid (and supported)"
|
||||
<< " is not a valid (or supported)"
|
||||
<< " default net type." << endl;
|
||||
net_type = NetNet::WIRE;
|
||||
error_count += 1;
|
||||
|
|
@ -483,6 +575,12 @@ S [afpnumkKMGT]
|
|||
<< endl;
|
||||
}
|
||||
|
||||
^{W}?`elsif{W}?.* {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: `elsif not supported. Use an external preprocessor."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
^{W}?`endif{W}?.* {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: `endif not supported. Use an external preprocessor."
|
||||
|
|
@ -495,6 +593,12 @@ S [afpnumkKMGT]
|
|||
<< endl;
|
||||
}
|
||||
|
||||
^{W}?`ifndef{W}?.* {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: `ifndef not supported. Use an external preprocessor."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
^`include{W}?.* {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: `include not supported. Use an external preprocessor."
|
||||
|
|
@ -936,6 +1040,128 @@ static verinum*make_unsized_dec(const char*ptr)
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the string to a time unit or precision.
|
||||
* Returns true on failure.
|
||||
*/
|
||||
static bool get_timescale_const(const char *&cp, int &res, bool is_unit)
|
||||
{
|
||||
/* Check for the 1 digit. */
|
||||
if (*cp != '1') {
|
||||
if (is_unit) {
|
||||
VLerror(yylloc, "Invalid `timescale unit constant "
|
||||
"(1st digit)");
|
||||
} else {
|
||||
VLerror(yylloc, "Invalid `timescale precision constant "
|
||||
"(1st digit)");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
cp += 1;
|
||||
|
||||
/* Check the number of zeros after the 1. */
|
||||
res = strspn(cp, "0");
|
||||
if (res > 2) {
|
||||
if (is_unit) {
|
||||
VLerror(yylloc, "Invalid `timescale unit constant "
|
||||
"(number of zeros)");
|
||||
} else {
|
||||
VLerror(yylloc, "Invalid `timescale precision constant "
|
||||
"(number of zeros)");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
cp += res;
|
||||
|
||||
/* Skip any space between the digits and the scaling string. */
|
||||
cp += strspn(cp, " \t");
|
||||
|
||||
/* Now process the scaling string. */
|
||||
if (strncmp("s", cp, 1) == 0) {
|
||||
res -= 0;
|
||||
cp += 1;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("ms", cp, 2) == 0) {
|
||||
res -= 3;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("us", cp, 2) == 0) {
|
||||
res -= 6;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("ns", cp, 2) == 0) {
|
||||
res -= 9;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("ps", cp, 2) == 0) {
|
||||
res -= 12;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
} else if (strncmp("fs", cp, 2) == 0) {
|
||||
res -= 15;
|
||||
cp += 2;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (is_unit) {
|
||||
VLerror(yylloc, "Invalid `timescale unit scale");
|
||||
} else {
|
||||
VLerror(yylloc, "Invalid `timescale precision scale");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* process either a pull0 or a pull1.
|
||||
*/
|
||||
static void process_ucdrive(const char*txt)
|
||||
{
|
||||
UCDriveType ucd = UCD_NONE;
|
||||
const char*cp = txt + strspn(txt, " \t");
|
||||
|
||||
/* Skip the space after the `unconnected_drive directive. */
|
||||
if (cp == txt) {
|
||||
VLerror(yylloc, "Space required after `unconnected_drive "
|
||||
"directive.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for the pull keyword. */
|
||||
if (strncmp("pull", cp, 4) != 0) {
|
||||
VLerror(yylloc, "pull required for `unconnected_drive "
|
||||
"directive.");
|
||||
return;
|
||||
}
|
||||
cp += 4;
|
||||
if (*cp == '0') ucd = UCD_PULL0;
|
||||
else if (*cp == '1') ucd = UCD_PULL1;
|
||||
else {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
|
||||
"`unconnected_drive does not support 'pull" << *cp
|
||||
<< "'." << endl;
|
||||
error_count += 1;
|
||||
return;
|
||||
}
|
||||
cp += 1;
|
||||
|
||||
/* Verify that only space and/or a single line comment is left. */
|
||||
cp += strspn(cp, " \t");
|
||||
if (strncmp(cp, "//", 2) != 0 &&
|
||||
(size_t)(cp-yytext) != strlen(yytext)) {
|
||||
VLerror(yylloc, "Invalid `unconnected_dirve directive (extra "
|
||||
"garbage after precision).");
|
||||
return;
|
||||
}
|
||||
|
||||
uc_drive = ucd;
|
||||
}
|
||||
|
||||
/*
|
||||
* The timescale parameter has the form:
|
||||
|
|
@ -943,98 +1169,46 @@ static verinum*make_unsized_dec(const char*ptr)
|
|||
*/
|
||||
static void process_timescale(const char*txt)
|
||||
{
|
||||
unsigned num;
|
||||
const char*cp = txt + strspn(txt, " \t");
|
||||
char*tmp;
|
||||
const char*ctmp;
|
||||
|
||||
/* Skip the space after the `timescale directive. */
|
||||
if (cp == txt) {
|
||||
VLerror(yylloc, "Space required after `timescale directive.");
|
||||
return;
|
||||
}
|
||||
|
||||
int unit = 0;
|
||||
int prec = 0;
|
||||
|
||||
num = strtoul(cp, &tmp, 10);
|
||||
if (num == 0) {
|
||||
VLerror(yylloc, "Invalid timescale string.");
|
||||
return;
|
||||
}
|
||||
/* Get the time units. */
|
||||
if (get_timescale_const(cp, unit, true)) return;
|
||||
|
||||
while (num >= 10) {
|
||||
unit += 1;
|
||||
num /= 10;
|
||||
}
|
||||
if (num != 1) {
|
||||
VLerror(yylloc, "Invalid timescale unit number.");
|
||||
return;
|
||||
}
|
||||
|
||||
cp = tmp;
|
||||
/* Skip any space after the time units, the '/' and any
|
||||
* space after the '/'. */
|
||||
cp += strspn(cp, " \t");
|
||||
ctmp = cp + strcspn(cp, " \t/");
|
||||
|
||||
if (strncmp("s", cp, ctmp-cp) == 0) {
|
||||
unit -= 0;
|
||||
|
||||
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
|
||||
unit -= 3;
|
||||
|
||||
} else if (strncmp("us", cp, ctmp-cp) == 0) {
|
||||
unit -= 6;
|
||||
|
||||
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
|
||||
unit -= 9;
|
||||
|
||||
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
|
||||
unit -= 12;
|
||||
|
||||
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
|
||||
unit -= 15;
|
||||
|
||||
} else {
|
||||
VLerror(yylloc, "Invalid timescale unit of measurement");
|
||||
if (*cp != '/') {
|
||||
VLerror(yylloc, "`timescale separator '/' appears to be missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
cp = ctmp;
|
||||
cp += strspn(cp, " \t/");
|
||||
|
||||
num = strtoul(cp, &tmp, 10);
|
||||
if (num == 0) {
|
||||
VLerror(yylloc, "Invalid timescale string.");
|
||||
return;
|
||||
}
|
||||
assert(num);
|
||||
while (num >= 10) {
|
||||
prec += 1;
|
||||
num /= 10;
|
||||
}
|
||||
if (num != 1) {
|
||||
VLerror(yylloc, "Invalid timescale precision number.");
|
||||
return;
|
||||
}
|
||||
|
||||
cp = tmp;
|
||||
cp += 1;
|
||||
cp += strspn(cp, " \t");
|
||||
ctmp = cp + strcspn(cp, " \t\r");
|
||||
|
||||
if (strncmp("s", cp, ctmp-cp) == 0) {
|
||||
prec -= 0;
|
||||
/* Get the time precision. */
|
||||
if (get_timescale_const(cp, prec, false)) return;
|
||||
|
||||
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
|
||||
prec -= 3;
|
||||
/* Verify that only space and/or a single line comment is left. */
|
||||
cp += strspn(cp, " \t");
|
||||
if (strncmp(cp, "//", 2) != 0 &&
|
||||
(size_t)(cp-yytext) != strlen(yytext)) {
|
||||
VLerror(yylloc, "Invalid `timescale directive (extra garbage "
|
||||
"after precision).");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (strncmp("us", cp, ctmp-cp) == 0) {
|
||||
prec -= 6;
|
||||
|
||||
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
|
||||
prec -= 9;
|
||||
|
||||
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
|
||||
prec -= 12;
|
||||
|
||||
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
|
||||
prec -= 15;
|
||||
|
||||
} else {
|
||||
VLerror(yylloc, "Invalid timescale precision units of measurement");
|
||||
/* The time unit must be greater than or equal to the precision. */
|
||||
if (unit < prec) {
|
||||
VLerror(yylloc, "error: `timescale unit must not be less than "
|
||||
"the precision.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1053,47 +1227,149 @@ int yywrap()
|
|||
*/
|
||||
static void line_directive()
|
||||
{
|
||||
char*qt1 = strchr(yytext, '"');
|
||||
assert(qt1);
|
||||
qt1 += 1;
|
||||
char *cpr;
|
||||
/* Skip any leading space. */
|
||||
char *cp = strchr(yytext, '#');
|
||||
/* Skip the #line directive. */
|
||||
assert(strncmp(cp, "#line", 5) == 0);
|
||||
cp += 5;
|
||||
/* Skip the space after the #line directive. */
|
||||
cp += strspn(cp, " \t");
|
||||
|
||||
char*qt2 = strchr(qt1, '"');
|
||||
assert(qt2);
|
||||
/* Find the starting " and skip it. */
|
||||
char*fn_start = strchr(cp, '"');
|
||||
if (cp != fn_start) {
|
||||
VLerror(yylloc, "Invalid #line directive (file name start).");
|
||||
return;
|
||||
}
|
||||
fn_start += 1;
|
||||
|
||||
char*buf = new char[qt2-qt1+1];
|
||||
strncpy(buf, qt1, qt2-qt1);
|
||||
buf[qt2-qt1] = 0;
|
||||
/* Find the last ". */
|
||||
char*fn_end = strrchr(fn_start, '"');
|
||||
if (!fn_end) {
|
||||
VLerror(yylloc, "Invalid #line directive (file name end).");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the file name and assign it to yylloc. */
|
||||
char*buf = new char[fn_end-fn_start+1];
|
||||
strncpy(buf, fn_start, fn_end-fn_start);
|
||||
buf[fn_end-fn_start] = 0;
|
||||
|
||||
/* Skip the space after the file name. */
|
||||
cp = fn_end;
|
||||
cp += 1;
|
||||
cpr = cp;
|
||||
cpr += strspn(cp, " \t");
|
||||
if (cp == cpr) {
|
||||
VLerror(yylloc, "Invalid #line directive (missing space after "
|
||||
"file name).");
|
||||
return;
|
||||
}
|
||||
cp = cpr;
|
||||
|
||||
/* Get the line number and verify that it is correct. */
|
||||
unsigned long lineno = strtoul(cp, &cpr, 10);
|
||||
if (cp == cpr) {
|
||||
VLerror(yylloc, "Invalid line number for #line directive.");
|
||||
return;
|
||||
}
|
||||
cp = cpr;
|
||||
|
||||
/* Verify that only space is left. */
|
||||
cpr += strspn(cp, " \t");
|
||||
if ((size_t)(cpr-yytext) != strlen(yytext)) {
|
||||
VLerror(yylloc, "Invalid #line directive (extra garbage after "
|
||||
"line number).");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now we can assign the new values to yyloc. */
|
||||
yylloc.text = set_file_name(buf);
|
||||
|
||||
qt2 += 1;
|
||||
yylloc.first_line = strtoul(qt2,0,0);
|
||||
yylloc.first_line = lineno;
|
||||
}
|
||||
|
||||
/*
|
||||
* The line directive matches lines of the form `line N "foo" M and
|
||||
* calls this function. Here I parse out the file name and line
|
||||
* number, and change the yylloc to suite. M is ignored.
|
||||
*/
|
||||
static void line_directive2()
|
||||
{
|
||||
assert(strncmp(yytext,"`line",5) == 0);
|
||||
char*cp = yytext + strlen("`line");
|
||||
cp += strspn(cp, " ");
|
||||
yylloc.first_line = strtoul(cp,&cp,10);
|
||||
char *cpr;
|
||||
/* Skip any leading space. */
|
||||
char *cp = strchr(yytext, '`');
|
||||
/* Skip the `line directive. */
|
||||
assert(strncmp(cp, "`line", 5) == 0);
|
||||
cp += 5;
|
||||
|
||||
yylloc.first_line -= 1;
|
||||
/* strtoul skips leading space. */
|
||||
unsigned long lineno = strtoul(cp, &cpr, 10);
|
||||
if (cp == cpr) {
|
||||
VLerror(yylloc, "Invalid line number for `line directive.");
|
||||
return;
|
||||
}
|
||||
lineno -= 1;
|
||||
cp = cpr;
|
||||
|
||||
cp += strspn(cp, " ");
|
||||
if (*cp == 0) return;
|
||||
/* Skip the space between the line number and the file name. */
|
||||
cpr += strspn(cp, " \t");
|
||||
if (cp == cpr) {
|
||||
VLerror(yylloc, "Invalid `line directive (missing space after "
|
||||
"line number).");
|
||||
return;
|
||||
}
|
||||
cp = cpr;
|
||||
|
||||
char*qt1 = strchr(yytext, '"');
|
||||
assert(qt1);
|
||||
qt1 += 1;
|
||||
/* Find the starting " and skip it. */
|
||||
char*fn_start = strchr(cp, '"');
|
||||
if (cp != fn_start) {
|
||||
VLerror(yylloc, "Invalid `line directive (file name start).");
|
||||
return;
|
||||
}
|
||||
fn_start += 1;
|
||||
|
||||
char*qt2 = strchr(qt1, '"');
|
||||
assert(qt2);
|
||||
/* Find the last ". */
|
||||
char*fn_end = strrchr(fn_start, '"');
|
||||
if (!fn_end) {
|
||||
VLerror(yylloc, "Invalid `line directive (file name end).");
|
||||
return;
|
||||
}
|
||||
|
||||
char*buf = new char[qt2-qt1+1];
|
||||
strncpy(buf, qt1, qt2-qt1);
|
||||
buf[qt2-qt1] = 0;
|
||||
/* Skip the space after the file name. */
|
||||
cp = fn_end + 1;
|
||||
cpr = cp;
|
||||
cpr += strspn(cp, " \t");
|
||||
if (cp == cpr) {
|
||||
VLerror(yylloc, "Invalid `line directive (missing space after "
|
||||
"file name).");
|
||||
return;
|
||||
}
|
||||
cp = cpr;
|
||||
|
||||
/* Check that the level is correct, we do not need the level. */
|
||||
if (strspn(cp, "012") != 1) {
|
||||
VLerror(yylloc, "Invalid level for `line directive.");
|
||||
return;
|
||||
}
|
||||
cp += 1;
|
||||
|
||||
/* Verify that only space and/or a single line comment is left. */
|
||||
cp += strspn(cp, " \t");
|
||||
if (strncmp(cp, "//", 2) != 0 &&
|
||||
(size_t)(cp-yytext) != strlen(yytext)) {
|
||||
VLerror(yylloc, "Invalid `line directive (extra garbage after "
|
||||
"level).");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the file name and assign it and the line number to yylloc. */
|
||||
char*buf = new char[fn_end-fn_start+1];
|
||||
strncpy(buf, fn_start, fn_end-fn_start);
|
||||
buf[fn_end-fn_start] = 0;
|
||||
|
||||
yylloc.text = set_file_name(buf);
|
||||
yylloc.first_line = lineno;
|
||||
}
|
||||
|
||||
extern FILE*vl_input;
|
||||
|
|
@ -1105,3 +1381,17 @@ void reset_lexor()
|
|||
/* Announce the first file name. */
|
||||
yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_lexor()
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,165 +11,183 @@
|
|||
%}
|
||||
struct lexor_keyword { const char*name; int mask; int tokenType; };
|
||||
%%
|
||||
abs, GN_KEYWORDS_VAMS_2_3, K_abs
|
||||
abstol, GN_KEYWORDS_VAMS_2_3, K_abstol
|
||||
access, GN_KEYWORDS_VAMS_2_3, K_access
|
||||
acos, GN_KEYWORDS_VAMS_2_3, K_acos
|
||||
acosh, GN_KEYWORDS_VAMS_2_3, K_acosh
|
||||
always, GN_KEYWORDS_1364_1995, K_always
|
||||
always_comb, GN_KEYWORDS_1800_2005, K_always_comb
|
||||
always_ff, GN_KEYWORDS_1800_2005, K_always_ff
|
||||
always_latch, GN_KEYWORDS_1800_2005, K_always_latch
|
||||
analog, GN_KEYWORDS_VAMS_2_3, K_analog
|
||||
and, GN_KEYWORDS_1364_1995, K_and
|
||||
asin, GN_KEYWORDS_VAMS_2_3, K_asin
|
||||
asinh, GN_KEYWORDS_VAMS_2_3, K_asinh
|
||||
assert, GN_KEYWORDS_1800_2005, K_assert
|
||||
assign, GN_KEYWORDS_1364_1995, K_assign
|
||||
atan, GN_KEYWORDS_VAMS_2_3, K_atan
|
||||
atan2, GN_KEYWORDS_VAMS_2_3, K_atan2
|
||||
atanh, GN_KEYWORDS_VAMS_2_3, K_atanh
|
||||
automatic, GN_KEYWORDS_1364_2001, K_automatic
|
||||
begin, GN_KEYWORDS_1364_1995, K_begin
|
||||
bool, GN_KEYWORDS_ICARUS, K_bool
|
||||
buf, GN_KEYWORDS_1364_1995, K_buf
|
||||
bufif0, GN_KEYWORDS_1364_1995, K_bufif0
|
||||
bufif1, GN_KEYWORDS_1364_1995, K_bufif1
|
||||
case, GN_KEYWORDS_1364_1995, K_case
|
||||
casex, GN_KEYWORDS_1364_1995, K_casex
|
||||
casez, GN_KEYWORDS_1364_1995, K_casez
|
||||
ceil, GN_KEYWORDS_VAMS_2_3, K_ceil
|
||||
cmos, GN_KEYWORDS_1364_1995, K_cmos
|
||||
continuous, GN_KEYWORDS_VAMS_2_3, K_continuous
|
||||
cos, GN_KEYWORDS_VAMS_2_3, K_cos
|
||||
cosh, GN_KEYWORDS_VAMS_2_3, K_cosh
|
||||
ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature
|
||||
deassign, GN_KEYWORDS_1364_1995, K_deassign
|
||||
default, GN_KEYWORDS_1364_1995, K_default
|
||||
defparam, GN_KEYWORDS_1364_1995, K_defparam
|
||||
disable, GN_KEYWORDS_1364_1995, K_disable
|
||||
discipline, GN_KEYWORDS_VAMS_2_3, K_discipline
|
||||
discrete, GN_KEYWORDS_VAMS_2_3, K_discrete
|
||||
domain, GN_KEYWORDS_VAMS_2_3, K_domain
|
||||
edge, GN_KEYWORDS_1364_1995, K_edge
|
||||
else, GN_KEYWORDS_1364_1995, K_else
|
||||
end, GN_KEYWORDS_1364_1995, K_end
|
||||
endcase, GN_KEYWORDS_1364_1995, K_endcase
|
||||
enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline
|
||||
endfunction, GN_KEYWORDS_1364_1995, K_endfunction
|
||||
endgenerate, GN_KEYWORDS_1364_1995, K_endgenerate
|
||||
endmodule, GN_KEYWORDS_1364_1995, K_endmodule
|
||||
endnature, GN_KEYWORDS_VAMS_2_3, K_endnature
|
||||
endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive
|
||||
endspecify, GN_KEYWORDS_1364_1995, K_endspecify
|
||||
endtable, GN_KEYWORDS_1364_1995, K_endtable
|
||||
endtask, GN_KEYWORDS_1364_1995, K_endtask
|
||||
event, GN_KEYWORDS_1364_1995, K_event
|
||||
exclude, GN_KEYWORDS_VAMS_2_3, K_exclude
|
||||
exp, GN_KEYWORDS_VAMS_2_3, K_exp
|
||||
floor, GN_KEYWORDS_VAMS_2_3, K_floor
|
||||
flow, GN_KEYWORDS_VAMS_2_3, K_flow
|
||||
for, GN_KEYWORDS_1364_1995, K_for
|
||||
force, GN_KEYWORDS_1364_1995, K_force
|
||||
forever, GN_KEYWORDS_1364_1995, K_forever
|
||||
fork, GN_KEYWORDS_1364_1995, K_fork
|
||||
from, GN_KEYWORDS_VAMS_2_3, K_from
|
||||
function, GN_KEYWORDS_1364_1995, K_function
|
||||
generate, GN_KEYWORDS_1364_2001, K_generate
|
||||
genvar, GN_KEYWORDS_1364_2001, K_genvar
|
||||
ground, GN_KEYWORDS_VAMS_2_3, K_ground
|
||||
highz0, GN_KEYWORDS_1364_1995, K_highz0
|
||||
highz1, GN_KEYWORDS_1364_1995, K_highz1
|
||||
hypot, GN_KEYWORDS_VAMS_2_3, K_hypot
|
||||
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
|
||||
if, GN_KEYWORDS_1364_1995, K_if
|
||||
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
|
||||
inf, GN_KEYWORDS_VAMS_2_3, K_inf
|
||||
initial, GN_KEYWORDS_1364_1995, K_initial
|
||||
inout, GN_KEYWORDS_1364_1995, K_inout
|
||||
input, GN_KEYWORDS_1364_1995, K_input
|
||||
integer, GN_KEYWORDS_1364_1995, K_integer
|
||||
join, GN_KEYWORDS_1364_1995, K_join
|
||||
large, GN_KEYWORDS_1364_1995, K_large
|
||||
ln, GN_KEYWORDS_VAMS_2_3, K_ln
|
||||
localparam, GN_KEYWORDS_1364_2001, K_localparam
|
||||
log, GN_KEYWORDS_VAMS_2_3, K_log
|
||||
logic, GN_KEYWORDS_ICARUS, K_logic
|
||||
macromodule, GN_KEYWORDS_1364_1995, K_macromodule
|
||||
max, GN_KEYWORDS_VAMS_2_3, K_max
|
||||
medium, GN_KEYWORDS_1364_1995, K_medium
|
||||
min, GN_KEYWORDS_VAMS_2_3, K_min
|
||||
module, GN_KEYWORDS_1364_1995, K_module
|
||||
nand, GN_KEYWORDS_1364_1995, K_nand
|
||||
nature, GN_KEYWORDS_VAMS_2_3, K_nature
|
||||
negedge, GN_KEYWORDS_1364_1995, K_negedge
|
||||
nmos, GN_KEYWORDS_1364_1995, K_nmos
|
||||
nor, GN_KEYWORDS_1364_1995, K_nor
|
||||
not, GN_KEYWORDS_1364_1995, K_not
|
||||
notif0, GN_KEYWORDS_1364_1995, K_notif0
|
||||
notif1, GN_KEYWORDS_1364_1995, K_notif1
|
||||
or, GN_KEYWORDS_1364_1995, K_or
|
||||
output, GN_KEYWORDS_1364_1995, K_output
|
||||
parameter, GN_KEYWORDS_1364_1995, K_parameter
|
||||
pmos, GN_KEYWORDS_1364_1995, K_pmos
|
||||
posedge, GN_KEYWORDS_1364_1995, K_posedge
|
||||
potential, GN_KEYWORDS_VAMS_2_3, K_potential
|
||||
pow, GN_KEYWORDS_VAMS_2_3, K_pow
|
||||
primitive, GN_KEYWORDS_1364_1995, K_primitive
|
||||
pull0, GN_KEYWORDS_1364_1995, K_pull0
|
||||
pull1, GN_KEYWORDS_1364_1995, K_pull1
|
||||
pulldown, GN_KEYWORDS_1364_1995, K_pulldown
|
||||
pullup, GN_KEYWORDS_1364_1995, K_pullup
|
||||
rcmos, GN_KEYWORDS_1364_1995, K_rcmos
|
||||
real, GN_KEYWORDS_1364_1995, K_real
|
||||
realtime, GN_KEYWORDS_1364_1995, K_realtime
|
||||
reg, GN_KEYWORDS_1364_1995, K_reg
|
||||
release, GN_KEYWORDS_1364_1995, K_release
|
||||
repeat, GN_KEYWORDS_1364_1995, K_repeat
|
||||
rnmos, GN_KEYWORDS_1364_1995, K_rnmos
|
||||
rpmos, GN_KEYWORDS_1364_1995, K_rpmos
|
||||
rtran, GN_KEYWORDS_1364_1995, K_rtran
|
||||
rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0
|
||||
rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1
|
||||
scalared, GN_KEYWORDS_1364_1995, K_scalared
|
||||
signed, GN_KEYWORDS_1364_2001, K_signed
|
||||
sin, GN_KEYWORDS_VAMS_2_3, K_sin
|
||||
sinh, GN_KEYWORDS_VAMS_2_3, K_sinh
|
||||
small, GN_KEYWORDS_1364_1995, K_small
|
||||
specify, GN_KEYWORDS_1364_1995, K_specify
|
||||
specparam, GN_KEYWORDS_1364_1995, K_specparam
|
||||
sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt
|
||||
string, GN_KEYWORDS_VAMS_2_3, K_string
|
||||
strong0, GN_KEYWORDS_1364_1995, K_strong0
|
||||
strong1, GN_KEYWORDS_1364_1995, K_strong1
|
||||
supply0, GN_KEYWORDS_1364_1995, K_supply0
|
||||
supply1, GN_KEYWORDS_1364_1995, K_supply1
|
||||
table, GN_KEYWORDS_1364_1995, K_table
|
||||
tan, GN_KEYWORDS_VAMS_2_3, K_tan
|
||||
tanh, GN_KEYWORDS_VAMS_2_3, K_tanh
|
||||
task, GN_KEYWORDS_1364_1995, K_task
|
||||
time, GN_KEYWORDS_1364_1995, K_time
|
||||
tran, GN_KEYWORDS_1364_1995, K_tran
|
||||
tranif0, GN_KEYWORDS_1364_1995, K_tranif0
|
||||
tranif1, GN_KEYWORDS_1364_1995, K_tranif1
|
||||
tri, GN_KEYWORDS_1364_1995, K_tri
|
||||
tri0, GN_KEYWORDS_1364_1995, K_tri0
|
||||
tri1, GN_KEYWORDS_1364_1995, K_tri1
|
||||
triand, GN_KEYWORDS_1364_1995, K_triand
|
||||
trior, GN_KEYWORDS_1364_1995, K_trior
|
||||
trireg, GN_KEYWORDS_1364_1995, K_trireg
|
||||
units, GN_KEYWORDS_VAMS_2_3, K_units
|
||||
vectored, GN_KEYWORDS_1364_1995, K_vectored
|
||||
wait, GN_KEYWORDS_1364_1995, K_wait
|
||||
wand, GN_KEYWORDS_1364_1995, K_wand
|
||||
weak0, GN_KEYWORDS_1364_1995, K_weak0
|
||||
weak1, GN_KEYWORDS_1364_1995, K_weak1
|
||||
while, GN_KEYWORDS_1364_1995, K_while
|
||||
wire, GN_KEYWORDS_1364_1995, K_wire
|
||||
wone, GN_KEYWORDS_1364_1995, K_wone
|
||||
wor, GN_KEYWORDS_1364_1995, K_wor
|
||||
xnor, GN_KEYWORDS_1364_1995, K_xnor
|
||||
xor, GN_KEYWORDS_1364_1995, K_xor
|
||||
abs, GN_KEYWORDS_VAMS_2_3, K_abs
|
||||
abstol, GN_KEYWORDS_VAMS_2_3, K_abstol
|
||||
access, GN_KEYWORDS_VAMS_2_3, K_access
|
||||
acos, GN_KEYWORDS_VAMS_2_3, K_acos
|
||||
acosh, GN_KEYWORDS_VAMS_2_3, K_acosh
|
||||
always, GN_KEYWORDS_1364_1995, K_always
|
||||
always_comb, GN_KEYWORDS_1800_2005, K_always_comb
|
||||
always_ff, GN_KEYWORDS_1800_2005, K_always_ff
|
||||
always_latch, GN_KEYWORDS_1800_2005, K_always_latch
|
||||
analog, GN_KEYWORDS_VAMS_2_3, K_analog
|
||||
and, GN_KEYWORDS_1364_1995, K_and
|
||||
asin, GN_KEYWORDS_VAMS_2_3, K_asin
|
||||
asinh, GN_KEYWORDS_VAMS_2_3, K_asinh
|
||||
assert, GN_KEYWORDS_1800_2005, K_assert
|
||||
assign, GN_KEYWORDS_1364_1995, K_assign
|
||||
atan, GN_KEYWORDS_VAMS_2_3, K_atan
|
||||
atan2, GN_KEYWORDS_VAMS_2_3, K_atan2
|
||||
atanh, GN_KEYWORDS_VAMS_2_3, K_atanh
|
||||
automatic, GN_KEYWORDS_1364_2001, K_automatic
|
||||
begin, GN_KEYWORDS_1364_1995, K_begin
|
||||
bool, GN_KEYWORDS_ICARUS, K_bool
|
||||
buf, GN_KEYWORDS_1364_1995, K_buf
|
||||
bufif0, GN_KEYWORDS_1364_1995, K_bufif0
|
||||
bufif1, GN_KEYWORDS_1364_1995, K_bufif1
|
||||
case, GN_KEYWORDS_1364_1995, K_case
|
||||
casex, GN_KEYWORDS_1364_1995, K_casex
|
||||
casez, GN_KEYWORDS_1364_1995, K_casez
|
||||
ceil, GN_KEYWORDS_VAMS_2_3, K_ceil
|
||||
cell, GN_KEYWORDS_1364_2001_CONFIG, K_cell
|
||||
cmos, GN_KEYWORDS_1364_1995, K_cmos
|
||||
config, GN_KEYWORDS_1364_2001_CONFIG, K_config
|
||||
continuous, GN_KEYWORDS_VAMS_2_3, K_continuous
|
||||
cos, GN_KEYWORDS_VAMS_2_3, K_cos
|
||||
cosh, GN_KEYWORDS_VAMS_2_3, K_cosh
|
||||
ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature
|
||||
deassign, GN_KEYWORDS_1364_1995, K_deassign
|
||||
default, GN_KEYWORDS_1364_1995, K_default
|
||||
defparam, GN_KEYWORDS_1364_1995, K_defparam
|
||||
design, GN_KEYWORDS_1364_2001_CONFIG, K_design
|
||||
disable, GN_KEYWORDS_1364_1995, K_disable
|
||||
discipline, GN_KEYWORDS_VAMS_2_3, K_discipline
|
||||
discrete, GN_KEYWORDS_VAMS_2_3, K_discrete
|
||||
domain, GN_KEYWORDS_VAMS_2_3, K_domain
|
||||
edge, GN_KEYWORDS_1364_1995, K_edge
|
||||
else, GN_KEYWORDS_1364_1995, K_else
|
||||
end, GN_KEYWORDS_1364_1995, K_end
|
||||
endcase, GN_KEYWORDS_1364_1995, K_endcase
|
||||
endconfig, GN_KEYWORDS_1364_2001_CONFIG, K_endconfig
|
||||
enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline
|
||||
endfunction, GN_KEYWORDS_1364_1995, K_endfunction
|
||||
endgenerate, GN_KEYWORDS_1364_2001, K_endgenerate
|
||||
endmodule, GN_KEYWORDS_1364_1995, K_endmodule
|
||||
endnature, GN_KEYWORDS_VAMS_2_3, K_endnature
|
||||
endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive
|
||||
endspecify, GN_KEYWORDS_1364_1995, K_endspecify
|
||||
endtable, GN_KEYWORDS_1364_1995, K_endtable
|
||||
endtask, GN_KEYWORDS_1364_1995, K_endtask
|
||||
event, GN_KEYWORDS_1364_1995, K_event
|
||||
exclude, GN_KEYWORDS_VAMS_2_3, K_exclude
|
||||
exp, GN_KEYWORDS_VAMS_2_3, K_exp
|
||||
floor, GN_KEYWORDS_VAMS_2_3, K_floor
|
||||
flow, GN_KEYWORDS_VAMS_2_3, K_flow
|
||||
for, GN_KEYWORDS_1364_1995, K_for
|
||||
force, GN_KEYWORDS_1364_1995, K_force
|
||||
forever, GN_KEYWORDS_1364_1995, K_forever
|
||||
fork, GN_KEYWORDS_1364_1995, K_fork
|
||||
from, GN_KEYWORDS_VAMS_2_3, K_from
|
||||
function, GN_KEYWORDS_1364_1995, K_function
|
||||
generate, GN_KEYWORDS_1364_2001, K_generate
|
||||
genvar, GN_KEYWORDS_1364_2001, K_genvar
|
||||
ground, GN_KEYWORDS_VAMS_2_3, K_ground
|
||||
highz0, GN_KEYWORDS_1364_1995, K_highz0
|
||||
highz1, GN_KEYWORDS_1364_1995, K_highz1
|
||||
hypot, GN_KEYWORDS_VAMS_2_3, K_hypot
|
||||
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
|
||||
if, GN_KEYWORDS_1364_1995, K_if
|
||||
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
|
||||
incdir, GN_KEYWORDS_1364_2001_CONFIG, K_incdir
|
||||
include, GN_KEYWORDS_1364_2001_CONFIG, K_include
|
||||
inf, GN_KEYWORDS_VAMS_2_3, K_inf
|
||||
initial, GN_KEYWORDS_1364_1995, K_initial
|
||||
inout, GN_KEYWORDS_1364_1995, K_inout
|
||||
input, GN_KEYWORDS_1364_1995, K_input
|
||||
instance, GN_KEYWORDS_1364_2001_CONFIG, K_instance
|
||||
integer, GN_KEYWORDS_1364_1995, K_integer
|
||||
join, GN_KEYWORDS_1364_1995, K_join
|
||||
large, GN_KEYWORDS_1364_1995, K_large
|
||||
liblist, GN_KEYWORDS_1364_2001_CONFIG, K_liblist
|
||||
library, GN_KEYWORDS_1364_2001_CONFIG, K_library
|
||||
ln, GN_KEYWORDS_VAMS_2_3, K_ln
|
||||
localparam, GN_KEYWORDS_1364_2001, K_localparam
|
||||
log, GN_KEYWORDS_VAMS_2_3, K_log
|
||||
logic, GN_KEYWORDS_ICARUS, K_logic
|
||||
macromodule, GN_KEYWORDS_1364_1995, K_macromodule
|
||||
max, GN_KEYWORDS_VAMS_2_3, K_max
|
||||
medium, GN_KEYWORDS_1364_1995, K_medium
|
||||
min, GN_KEYWORDS_VAMS_2_3, K_min
|
||||
module, GN_KEYWORDS_1364_1995, K_module
|
||||
nand, GN_KEYWORDS_1364_1995, K_nand
|
||||
nature, GN_KEYWORDS_VAMS_2_3, K_nature
|
||||
negedge, GN_KEYWORDS_1364_1995, K_negedge
|
||||
nmos, GN_KEYWORDS_1364_1995, K_nmos
|
||||
nor, GN_KEYWORDS_1364_1995, K_nor
|
||||
noshowcancelled, GN_KEYWORDS_1364_2001, K_noshowcancelled
|
||||
not, GN_KEYWORDS_1364_1995, K_not
|
||||
notif0, GN_KEYWORDS_1364_1995, K_notif0
|
||||
notif1, GN_KEYWORDS_1364_1995, K_notif1
|
||||
or, GN_KEYWORDS_1364_1995, K_or
|
||||
output, GN_KEYWORDS_1364_1995, K_output
|
||||
parameter, GN_KEYWORDS_1364_1995, K_parameter
|
||||
pmos, GN_KEYWORDS_1364_1995, K_pmos
|
||||
posedge, GN_KEYWORDS_1364_1995, K_posedge
|
||||
potential, GN_KEYWORDS_VAMS_2_3, K_potential
|
||||
pow, GN_KEYWORDS_VAMS_2_3, K_pow
|
||||
primitive, GN_KEYWORDS_1364_1995, K_primitive
|
||||
pull0, GN_KEYWORDS_1364_1995, K_pull0
|
||||
pull1, GN_KEYWORDS_1364_1995, K_pull1
|
||||
pulldown, GN_KEYWORDS_1364_1995, K_pulldown
|
||||
pullup, GN_KEYWORDS_1364_1995, K_pullup
|
||||
pulsestyle_onevent, GN_KEYWORDS_1364_2001, K_pulsestyle_onevent
|
||||
pulsestyle_ondetect, GN_KEYWORDS_1364_2001, K_pulsestyle_ondetect
|
||||
rcmos, GN_KEYWORDS_1364_1995, K_rcmos
|
||||
real, GN_KEYWORDS_1364_1995, K_real
|
||||
realtime, GN_KEYWORDS_1364_1995, K_realtime
|
||||
reg, GN_KEYWORDS_1364_1995, K_reg
|
||||
release, GN_KEYWORDS_1364_1995, K_release
|
||||
repeat, GN_KEYWORDS_1364_1995, K_repeat
|
||||
rnmos, GN_KEYWORDS_1364_1995, K_rnmos
|
||||
rpmos, GN_KEYWORDS_1364_1995, K_rpmos
|
||||
rtran, GN_KEYWORDS_1364_1995, K_rtran
|
||||
rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0
|
||||
rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1
|
||||
scalared, GN_KEYWORDS_1364_1995, K_scalared
|
||||
showcancelled, GN_KEYWORDS_1364_2001, K_showcancelled
|
||||
signed, GN_KEYWORDS_1364_2001, K_signed
|
||||
sin, GN_KEYWORDS_VAMS_2_3, K_sin
|
||||
sinh, GN_KEYWORDS_VAMS_2_3, K_sinh
|
||||
small, GN_KEYWORDS_1364_1995, K_small
|
||||
specify, GN_KEYWORDS_1364_1995, K_specify
|
||||
specparam, GN_KEYWORDS_1364_1995, K_specparam
|
||||
sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt
|
||||
string, GN_KEYWORDS_VAMS_2_3, K_string
|
||||
strong0, GN_KEYWORDS_1364_1995, K_strong0
|
||||
strong1, GN_KEYWORDS_1364_1995, K_strong1
|
||||
supply0, GN_KEYWORDS_1364_1995, K_supply0
|
||||
supply1, GN_KEYWORDS_1364_1995, K_supply1
|
||||
table, GN_KEYWORDS_1364_1995, K_table
|
||||
tan, GN_KEYWORDS_VAMS_2_3, K_tan
|
||||
tanh, GN_KEYWORDS_VAMS_2_3, K_tanh
|
||||
task, GN_KEYWORDS_1364_1995, K_task
|
||||
time, GN_KEYWORDS_1364_1995, K_time
|
||||
tran, GN_KEYWORDS_1364_1995, K_tran
|
||||
tranif0, GN_KEYWORDS_1364_1995, K_tranif0
|
||||
tranif1, GN_KEYWORDS_1364_1995, K_tranif1
|
||||
tri, GN_KEYWORDS_1364_1995, K_tri
|
||||
tri0, GN_KEYWORDS_1364_1995, K_tri0
|
||||
tri1, GN_KEYWORDS_1364_1995, K_tri1
|
||||
triand, GN_KEYWORDS_1364_1995, K_triand
|
||||
trior, GN_KEYWORDS_1364_1995, K_trior
|
||||
trireg, GN_KEYWORDS_1364_1995, K_trireg
|
||||
units, GN_KEYWORDS_VAMS_2_3, K_units
|
||||
# Reserved for future use!
|
||||
unsigned, GN_KEYWORDS_1364_2001, K_unsigned
|
||||
use, GN_KEYWORDS_1364_2001_CONFIG, K_use
|
||||
uwire, GN_KEYWORDS_1364_2005, K_uwire
|
||||
vectored, GN_KEYWORDS_1364_1995, K_vectored
|
||||
wait, GN_KEYWORDS_1364_1995, K_wait
|
||||
wand, GN_KEYWORDS_1364_1995, K_wand
|
||||
weak0, GN_KEYWORDS_1364_1995, K_weak0
|
||||
weak1, GN_KEYWORDS_1364_1995, K_weak1
|
||||
while, GN_KEYWORDS_1364_1995, K_while
|
||||
wire, GN_KEYWORDS_1364_1995, K_wire
|
||||
# This is the name originally proposed for uwire and is deprecated!
|
||||
wone, GN_KEYWORDS_1364_2005, K_wone
|
||||
wor, GN_KEYWORDS_1364_1995, K_wor
|
||||
xnor, GN_KEYWORDS_1364_1995, K_xnor
|
||||
xor, GN_KEYWORDS_1364_1995, K_xor
|
||||
%%
|
||||
|
||||
int lexor_keyword_mask = 0;
|
||||
|
|
|
|||
|
|
@ -59,11 +59,13 @@ all: dep libveriuser.a $(ALL32)
|
|||
|
||||
check: all
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
../config.status --file=$@
|
||||
Makefile: $(srcdir)/Makefile.in
|
||||
cd ..; ./config.status --file=libveriuser/$@
|
||||
|
||||
config.h: $(srcdir)/config.h.in ../config.status
|
||||
../config.status --header=$@
|
||||
stamp-config-h: $(srcdir)/config.h.in ../config.status
|
||||
@rm -f $@
|
||||
cd ..; ./config.status --header=libveriuser/config.h
|
||||
config.h: stamp-config-h
|
||||
|
||||
libveriuser.o: $O
|
||||
$(LD) -r -o $@ $O
|
||||
|
|
@ -76,16 +78,17 @@ libveriuser.a: libveriuser.o
|
|||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
%.o: %.c config.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep libveriuser.a libveriuser.o bin32
|
||||
rm -rf *.o dep libveriuser.a libveriuser.o
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log config.h
|
||||
rm -f Makefile config.log
|
||||
rm -f config.h stamp-config-h
|
||||
|
||||
install:: all installdirs $(libdir)/libveriuser$(suffix).a $(INSTALL32)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_configure.c,v 1.4 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <acc_user.h>
|
||||
#include <vpi_user.h>
|
||||
|
|
@ -70,41 +67,14 @@ int acc_configure(PLI_INT32 config_param, const char*value)
|
|||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "acc_configure(config=%d, %s)\n",
|
||||
config_param, value);
|
||||
(int)config_param, value);
|
||||
}
|
||||
|
||||
vpi_printf("XXXX acc_configure(%d, %s)\n", config_param, value);
|
||||
vpi_printf("XXXX acc_configure(%d, %s)\n", (int)config_param,
|
||||
value);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_configure.c,v $
|
||||
* Revision 1.4 2003/12/17 15:45:07 steve
|
||||
* Add acc_set_scope function.
|
||||
*
|
||||
* Revision 1.3 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
* 3) removes now extraneous flushes
|
||||
* 4) fixes acc_next() bug
|
||||
*
|
||||
* Revision 1.2 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_param.c,v 1.4 2003/06/17 16:55:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <vpi_user.h>
|
||||
|
|
@ -43,31 +40,8 @@ double acc_fetch_paramval(handle object)
|
|||
|
||||
default:
|
||||
vpi_printf("XXXX: parameter %s has type %d\n",
|
||||
vpi_get_str(vpiName, object), val.format);
|
||||
vpi_get_str(vpiName, object), (int)val.format);
|
||||
assert(0);
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_param.c,v $
|
||||
* Revision 1.4 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
* 3) removes now extraneous flushes
|
||||
* 4) fixes acc_next() bug
|
||||
*
|
||||
* Revision 1.3 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.2 2003/03/14 04:59:54 steve
|
||||
* Better message when asserting funky value type.
|
||||
*
|
||||
* Revision 1.1 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_tfarg.c,v 1.10 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <vpi_user.h>
|
||||
#include <acc_user.h>
|
||||
|
|
@ -50,7 +47,7 @@ double acc_fetch_itfarg(PLI_INT32 n, handle obj)
|
|||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "%s: acc_fetch_itfarg(%d, %p) --> %f\n",
|
||||
vpi_get_str(vpiName, obj), n, obj, rtn);
|
||||
vpi_get_str(vpiName, obj), (int)n, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -85,7 +82,7 @@ PLI_INT32 acc_fetch_itfarg_int(PLI_INT32 n, handle obj)
|
|||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "%s: acc_fetch_itfarg_int(%d, %p) --> %d\n",
|
||||
vpi_get_str(vpiName, obj), n, obj, rtn);
|
||||
vpi_get_str(vpiName, obj), (int)n, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -121,7 +118,7 @@ char *acc_fetch_itfarg_str(PLI_INT32 n, handle obj)
|
|||
if (pli_trace) {
|
||||
fprintf(pli_trace, "%s: acc_fetch_itfarg_str(%d, %p) --> \"%s\"\n",
|
||||
vpi_get_str(vpiName, obj),
|
||||
n, obj, rtn? rtn : "");
|
||||
(int)n, obj, rtn? rtn : "");
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -131,45 +128,3 @@ char *acc_fetch_tfarg_str(PLI_INT32 n)
|
|||
{
|
||||
return acc_fetch_itfarg_str(n, vpi_handle(vpiSysTfCall,0));
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_tfarg.c,v $
|
||||
* Revision 1.10 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.9 2004/02/18 02:51:59 steve
|
||||
* Fix type mismatches of various VPI functions.
|
||||
*
|
||||
* Revision 1.8 2003/06/14 01:16:17 steve
|
||||
* ihand is system task, not scope.
|
||||
*
|
||||
* Revision 1.7 2003/06/13 19:23:42 steve
|
||||
* Add a bunch more PLI1 routines.
|
||||
*
|
||||
* Revision 1.6 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.5 2003/03/14 04:58:50 steve
|
||||
* Free the iterator when Im done.
|
||||
*
|
||||
* Revision 1.4 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
* Revision 1.3 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/06/07 02:58:58 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_type.c,v 1.8 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <acc_user.h>
|
||||
# include <vpi_user.h>
|
||||
|
|
@ -62,7 +59,7 @@ PLI_INT32 acc_fetch_type(handle obj)
|
|||
|
||||
default:
|
||||
vpi_printf("acc_fetch_type: vpiType %d is what accType?\n",
|
||||
vpi_get(vpiType, obj));
|
||||
(int)vpi_get(vpiType, obj));
|
||||
return accUnknown;
|
||||
}
|
||||
|
||||
|
|
@ -118,43 +115,3 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
|
|||
return accUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_type.c,v $
|
||||
* Revision 1.8 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.7 2003/06/04 01:56:20 steve
|
||||
* 1) Adds configure logic to clean up compiler warnings
|
||||
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
|
||||
* tf_isetrealdelay, acc_handle_scope
|
||||
* 3) makes acc_next reentrant
|
||||
* 4) adds basic vpiWire type support
|
||||
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
|
||||
* 6) add vpiLeftRange/RigthRange to signals
|
||||
*
|
||||
* Revision 1.6 2003/05/30 04:18:31 steve
|
||||
* Add acc_next function.
|
||||
*
|
||||
* Revision 1.5 2003/05/29 02:35:41 steve
|
||||
* acc_fetch_type supports module.
|
||||
*
|
||||
* Revision 1.4 2003/04/24 18:57:06 steve
|
||||
* Add acc_fetch_fulltype function.
|
||||
*
|
||||
* Revision 1.3 2003/04/12 18:57:14 steve
|
||||
* More acc_ function stubs.
|
||||
*
|
||||
* Revision 1.2 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_fetch_type_str.c,v 1.5 2003/04/12 18:57:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <vpi_user.h>
|
||||
|
|
@ -41,34 +38,9 @@ char* acc_fetch_type_str(PLI_INT32 type)
|
|||
return "accConstant";
|
||||
|
||||
default:
|
||||
vpi_printf("XXXX acc_fetch_type_str(%d);\n", type);
|
||||
vpi_printf("XXXX acc_fetch_type_str(%d);\n", (int)type);
|
||||
return "acc_fetch_type_str(unknown)";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_fetch_type_str.c,v $
|
||||
* Revision 1.5 2003/04/12 18:57:14 steve
|
||||
* More acc_ function stubs.
|
||||
*
|
||||
* Revision 1.4 2003/03/13 05:07:46 steve
|
||||
* Declaration warnings.
|
||||
*
|
||||
* Revision 1.3 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
* Revision 1.2 2003/02/19 04:37:04 steve
|
||||
* fullname for accConstant.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2003 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2003-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_next.c,v 1.4 2006/10/30 22:45:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <acc_user.h>
|
||||
|
|
@ -37,7 +34,7 @@ handle acc_next(PLI_INT32 *type, handle scope, handle prev)
|
|||
PLI_INT32 *ip;
|
||||
fprintf(pli_trace, "acc_next(%p <", type);
|
||||
for (ip = type; *ip; ip++) {
|
||||
fprintf(pli_trace, "%s%d", ip != type ? "," : "", *ip);
|
||||
fprintf(pli_trace, "%s%d", ip != type ? "," : "", (int)*ip);
|
||||
}
|
||||
fprintf(pli_trace, ">, %p", scope);
|
||||
if (scope)
|
||||
|
|
@ -91,28 +88,3 @@ handle acc_next_scope(handle scope, handle prev)
|
|||
PLI_INT32 type[2] = {accScope, 0};
|
||||
return acc_next(type, scope, prev);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_next.c,v $
|
||||
* Revision 1.4 2006/10/30 22:45:37 steve
|
||||
* Updates for Cygwin portability (pr1585922)
|
||||
*
|
||||
* Revision 1.3 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
* 3) removes now extraneous flushes
|
||||
* 4) fixes acc_next() bug
|
||||
*
|
||||
* Revision 1.2 2003/06/04 01:56:20 steve
|
||||
* 1) Adds configure logic to clean up compiler warnings
|
||||
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
|
||||
* tf_isetrealdelay, acc_handle_scope
|
||||
* 3) makes acc_next reentrant
|
||||
* 4) adds basic vpiWire type support
|
||||
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
|
||||
* 6) add vpiLeftRange/RigthRange to signals
|
||||
*
|
||||
* Revision 1.1 2003/05/30 04:18:31 steve
|
||||
* Add acc_next function.
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002, 2003 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_object_of_type.c,v 1.6 2004/02/18 02:51:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <vpi_user.h>
|
||||
|
|
@ -35,7 +32,7 @@ int acc_object_of_type(handle object, PLI_INT32 type)
|
|||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)",
|
||||
object, vpi_get_str(vpiName, object), type);
|
||||
object, vpi_get_str(vpiName, object), (int)type);
|
||||
fflush(pli_trace);
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +74,8 @@ int acc_object_of_type(handle object, PLI_INT32 type)
|
|||
break;
|
||||
|
||||
default:
|
||||
vpi_printf("acc_object_of_type: Unknown type %d\n", type);
|
||||
vpi_printf("acc_object_of_type: Unknown type %d\n",
|
||||
(int)type);
|
||||
rtn = 0;
|
||||
}
|
||||
|
||||
|
|
@ -98,36 +96,3 @@ int acc_object_in_typelist(handle object, PLI_INT32*typelist)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_object_of_type.c,v $
|
||||
* Revision 1.6 2004/02/18 02:51:59 steve
|
||||
* Fix type mismatches of various VPI functions.
|
||||
*
|
||||
* Revision 1.5 2003/06/04 01:56:20 steve
|
||||
* 1) Adds configure logic to clean up compiler warnings
|
||||
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
|
||||
* tf_isetrealdelay, acc_handle_scope
|
||||
* 3) makes acc_next reentrant
|
||||
* 4) adds basic vpiWire type support
|
||||
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
|
||||
* 6) add vpiLeftRange/RigthRange to signals
|
||||
*
|
||||
* Revision 1.4 2003/05/30 04:18:31 steve
|
||||
* Add acc_next function.
|
||||
*
|
||||
* Revision 1.3 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/06/07 02:58:58 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_set_value.c,v 1.3 2003/05/18 00:16:35 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <acc_user.h>
|
||||
|
|
@ -45,7 +42,7 @@ int acc_set_value(handle object, p_setval_value value, p_setval_delay delay)
|
|||
case accPureTransportDelay: flags = vpiPureTransportDelay; break;
|
||||
case accForceFlag: flags = vpiForceFlag; break;
|
||||
case accReleaseFlag: flags = vpiReleaseFlag; break;
|
||||
default: assert(0); break;
|
||||
default: flags = -1; assert(0); break;
|
||||
}
|
||||
|
||||
/* map acc_time to vpi_time */
|
||||
|
|
@ -113,19 +110,3 @@ int acc_set_value(handle object, p_setval_value value, p_setval_delay delay)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: a_set_value.c,v $
|
||||
* Revision 1.3 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/06/07 02:58:59 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: a_vcl.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <vpi_user.h>
|
||||
#include <acc_user.h>
|
||||
|
|
@ -185,13 +182,13 @@ void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
|||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "acc_vcl_add(<%s>, ..., %p, %d)\n",
|
||||
vpi_get_str(vpiFullName, obj), data, vcl_flag);
|
||||
vpi_get_str(vpiFullName, obj), data, (int)vcl_flag);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vpi_printf("XXXX acc_vcl_add(<type=%d>, ..., %d);\n",
|
||||
vpi_get(vpiType, obj), vcl_flag);
|
||||
(int)vpi_get(vpiType, obj), (int)vcl_flag);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -202,36 +199,3 @@ void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
|||
{
|
||||
vpi_printf("XXXX acc_vcl_delete(...)\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: a_vcl.c,v $
|
||||
* Revision 1.7 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.6 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
* 3) removes now extraneous flushes
|
||||
* 4) fixes acc_next() bug
|
||||
*
|
||||
* Revision 1.5 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.4 2003/04/30 01:09:29 steve
|
||||
* Conditionally include malloc.h
|
||||
*
|
||||
* Revision 1.3 2003/04/24 02:02:37 steve
|
||||
* Clean up some simple warnings.
|
||||
*
|
||||
* Revision 1.2 2003/04/20 02:48:39 steve
|
||||
* Support value change callbacks.
|
||||
*
|
||||
* Revision 1.1 2003/04/12 18:57:14 steve
|
||||
* More acc_ function stubs.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ int tf_isetdelay(PLI_INT32 delay, void*ss)
|
|||
if (pli_trace) {
|
||||
fprintf(pli_trace, "%s: tf_isetdelay(%d, ...)"
|
||||
" <unit=%d, prec=%d>;\n",
|
||||
vpi_get_str(vpiName, sys), delay, unit, prec);
|
||||
vpi_get_str(vpiName, sys), (int)delay, unit, prec);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: getp.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <assert.h>
|
||||
# include <ctype.h>
|
||||
|
|
@ -53,6 +50,8 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj)
|
|||
{
|
||||
value.format = vpiStringVal;
|
||||
vpi_get_value(arg_h, &value);
|
||||
/* The following may generate a compilation warning, but this
|
||||
* functionality is required by some versions of the standard. */
|
||||
rtn = (int) value.value.str; /* Oh my */
|
||||
} else {
|
||||
value.format = vpiIntVal;
|
||||
|
|
@ -65,7 +64,7 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj)
|
|||
out:
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_igetp(n=%d, obj=%p) --> %d\n",
|
||||
n, obj, rtn);
|
||||
(int)n, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -112,7 +111,7 @@ double tf_igetrealp(PLI_INT32 n, void *obj)
|
|||
out:
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_igetrealp(n=%d, obj=%p) --> %f\n",
|
||||
n, obj, rtn);
|
||||
(int)n, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -169,7 +168,7 @@ char *tf_istrgetp(PLI_INT32 n, PLI_INT32 fmt, void *obj)
|
|||
out:
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_istrgetp(n=%d, fmt=%c, obj=%p) --> \"%s\"\n",
|
||||
n, fmt, obj, rtn);
|
||||
(int)n, (int)fmt, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -181,34 +180,3 @@ char *tf_strgetp(PLI_INT32 n, PLI_INT32 fmt)
|
|||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: getp.c,v $
|
||||
* Revision 1.7 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.6 2003/06/17 16:55:07 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
* 3) removes now extraneous flushes
|
||||
* 4) fixes acc_next() bug
|
||||
*
|
||||
* Revision 1.5 2003/05/30 04:22:13 steve
|
||||
* Add tf_strgetp functions.
|
||||
*
|
||||
* Revision 1.4 2003/05/29 03:46:21 steve
|
||||
* Add tf_getp/putp support for integers
|
||||
* and real valued arguments.
|
||||
*
|
||||
* Add tf_mipname function.
|
||||
*
|
||||
* Revision 1.3 2003/03/15 05:42:39 steve
|
||||
* free argument iterators.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/06/07 02:58:59 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: getsimtime.c,v 1.11 2003/06/21 23:40:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include <veriuser.h>
|
||||
#include <vpi_user.h>
|
||||
|
|
@ -62,9 +59,10 @@ char *tf_strgettime(void)
|
|||
time.type = vpiSimTime;
|
||||
vpi_get_time (0, &time);
|
||||
if (time.high)
|
||||
snprintf(buf, sizeof(buf)-1, "%u%08u", time.high, time.low);
|
||||
snprintf(buf, sizeof(buf)-1, "%u%08u", (unsigned int)time.high,
|
||||
(unsigned int)time.low);
|
||||
else
|
||||
snprintf(buf, sizeof(buf)-1, "%u", time.low);
|
||||
snprintf(buf, sizeof(buf)-1, "%u", (unsigned int)time.low);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +138,7 @@ PLI_INT32 tf_gettimeprecision(void)
|
|||
|
||||
if (pli_trace)
|
||||
fprintf(pli_trace, "tf_gettimeprecision(<%s>) --> %d\n",
|
||||
vpi_get_str(vpiName, sys), rc);
|
||||
vpi_get_str(vpiName, sys), (int)rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -163,7 +161,7 @@ PLI_INT32 tf_igettimeprecision(void*obj)
|
|||
|
||||
if (pli_trace)
|
||||
fprintf(pli_trace, "tf_igettimeprecision(<%s>) --> %d\n",
|
||||
obj? vpi_get_str(vpiName, obj) : ".", rc);
|
||||
obj? vpi_get_str(vpiName, obj) : ".", (int)rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -179,47 +177,3 @@ PLI_INT32 tf_igettimeunit(void*obj)
|
|||
{
|
||||
return vpi_get(!obj ? vpiTimePrecision : vpiTimeUnit, (vpiHandle)obj);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: getsimtime.c,v $
|
||||
* Revision 1.11 2003/06/21 23:40:15 steve
|
||||
* gettimeprecision will null argument has specific meaning.
|
||||
*
|
||||
* Revision 1.10 2003/06/13 19:23:42 steve
|
||||
* Add a bunch more PLI1 routines.
|
||||
*
|
||||
* Revision 1.9 2003/06/04 01:56:20 steve
|
||||
* 1) Adds configure logic to clean up compiler warnings
|
||||
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
|
||||
* tf_isetrealdelay, acc_handle_scope
|
||||
* 3) makes acc_next reentrant
|
||||
* 4) adds basic vpiWire type support
|
||||
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
|
||||
* 6) add vpiLeftRange/RigthRange to signals
|
||||
*
|
||||
* Revision 1.8 2003/05/30 04:01:55 steve
|
||||
* Add tf_scale_longdelay.
|
||||
*
|
||||
* Revision 1.7 2003/05/28 03:14:20 steve
|
||||
* Missing time related declarations.
|
||||
*
|
||||
* Revision 1.6 2003/05/27 16:22:10 steve
|
||||
* PLI get time units/precision.
|
||||
*
|
||||
* Revision 1.5 2003/04/12 18:57:14 steve
|
||||
* More acc_ function stubs.
|
||||
*
|
||||
* Revision 1.4 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
* Revision 1.3 2003/03/06 00:27:54 steve
|
||||
* Fill in required fields when getting time.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/05/31 18:25:51 steve
|
||||
* Add tf_getlongtime (mruff)
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* vi:sw=6
|
||||
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com)
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: putp.c,v 1.7 2004/09/10 23:13:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <assert.h>
|
||||
# include <veriuser.h>
|
||||
|
|
@ -48,7 +45,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
|
|||
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_iputp(<return>, value=%d, func=%s) "
|
||||
"--> %d\n", value, vpi_get_str(vpiName, obj), 0);
|
||||
"--> %d\n", (int)value, vpi_get_str(vpiName, obj), 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -57,7 +54,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
|
|||
if ((n == 0) && (type != vpiSysFuncCall)) {
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_iputp(<ERROR>, value=%d, func=%s) "
|
||||
"--> %d\n", value, vpi_get_str(vpiName, obj), 1);
|
||||
"--> %d\n", (int)value, vpi_get_str(vpiName, obj), 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -82,7 +79,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
|
|||
out:
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_iputp(n=%d, value=%d, obj=%p) --> %d\n",
|
||||
n, value, obj, rtn);
|
||||
(int)n, (int)value, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -131,7 +128,7 @@ free:
|
|||
out:
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "tf_iputrealp(n=%d, value=%f, obj=%p) --> %d\n",
|
||||
n, value, obj, rtn);
|
||||
(int)n, value, obj, rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
|
@ -143,33 +140,3 @@ PLI_INT32 tf_putrealp(PLI_INT32 n, double value)
|
|||
|
||||
return rtn;
|
||||
}
|
||||
/*
|
||||
* $Log: putp.c,v $
|
||||
* Revision 1.7 2004/09/10 23:13:05 steve
|
||||
* Compile cleanup of C code.
|
||||
*
|
||||
* Revision 1.6 2003/06/26 03:20:24 steve
|
||||
* Correct handle of put to function return value.
|
||||
*
|
||||
* Revision 1.5 2003/06/17 16:55:08 steve
|
||||
* 1) setlinebuf() for vpi_trace
|
||||
* 2) Addes error checks for trace file opens
|
||||
* 3) removes now extraneous flushes
|
||||
* 4) fixes acc_next() bug
|
||||
*
|
||||
* Revision 1.4 2003/05/29 03:46:21 steve
|
||||
* Add tf_getp/putp support for integers
|
||||
* and real valued arguments.
|
||||
*
|
||||
* Add tf_mipname function.
|
||||
*
|
||||
* Revision 1.3 2003/03/15 05:42:39 steve
|
||||
* free argument iterators.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/06/07 16:21:13 steve
|
||||
* Add tf_putlongp and tf_putp.
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* vi:sw=6
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
|
||||
* Michael Runyan (mrunyan at chiaro.com)
|
||||
*
|
||||
|
|
@ -322,6 +322,7 @@ static PLI_INT32 callback(p_cb_data data)
|
|||
reason = reason_reactivate;
|
||||
break;
|
||||
default:
|
||||
reason = -1;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -78,10 +78,11 @@ bool load_module(const char*type)
|
|||
|
||||
if (ivlpp_string) {
|
||||
char*cmdline = (char*)malloc(strlen(ivlpp_string) +
|
||||
strlen(path) + 2);
|
||||
strlen(path) + 4);
|
||||
strcpy(cmdline, ivlpp_string);
|
||||
strcat(cmdline, " ");
|
||||
strcat(cmdline, " \"");
|
||||
strcat(cmdline, path);
|
||||
strcat(cmdline, "\"");
|
||||
FILE*file = popen(cmdline, "r");
|
||||
|
||||
if (verbose_flag)
|
||||
|
|
|
|||
81
main.cc
81
main.cc
|
|
@ -20,7 +20,8 @@ const char COPYRIGHT[] =
|
|||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include "version.h"
|
||||
# include "version_base.h"
|
||||
# include "version_tag.h"
|
||||
|
||||
const char NOTICE[] =
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
|
|
@ -77,7 +78,7 @@ extern "C" const char*optarg;
|
|||
/* Count errors detected in flag processing. */
|
||||
unsigned flag_errors = 0;
|
||||
|
||||
const char*basedir = ".";
|
||||
const char*basedir = strdup(".");
|
||||
|
||||
/*
|
||||
* These are the language support control flags. These support which
|
||||
|
|
@ -115,6 +116,9 @@ bool warn_implicit = false;
|
|||
bool warn_timescale = false;
|
||||
bool warn_portbinding = false;
|
||||
bool warn_inf_loop = false;
|
||||
bool warn_ob_select = false;
|
||||
bool warn_sens_entire_vec = false;
|
||||
bool warn_sens_entire_arr = false;
|
||||
|
||||
bool error_implicit = false;
|
||||
|
||||
|
|
@ -128,6 +132,13 @@ bool debug_elab_pexpr = false;
|
|||
bool debug_synth2 = false;
|
||||
bool debug_optimizer = false;
|
||||
|
||||
/*
|
||||
* Miscellaneous flags.
|
||||
*/
|
||||
bool disable_virtual_pins = false;
|
||||
unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364?
|
||||
unsigned recursive_mod_limit = 10;
|
||||
|
||||
/*
|
||||
* Verbose messages enabled.
|
||||
*/
|
||||
|
|
@ -135,6 +146,9 @@ bool verbose_flag = false;
|
|||
|
||||
unsigned integer_width = 32;
|
||||
|
||||
int def_ts_units = 0;
|
||||
int def_ts_prec = 0;
|
||||
|
||||
/*
|
||||
* Keep a heap of identifier strings that I encounter. This is a more
|
||||
* efficient way to allocate those strings.
|
||||
|
|
@ -214,6 +228,9 @@ static void process_generation_flag(const char*gen)
|
|||
} else if (strcmp(gen,"2001") == 0) {
|
||||
generation_flag = GN_VER2001;
|
||||
|
||||
} else if (strcmp(gen,"2001-noconfig") == 0) {
|
||||
generation_flag = GN_VER2001_NOCONFIG;
|
||||
|
||||
} else if (strcmp(gen,"2005") == 0) {
|
||||
generation_flag = GN_VER2005;
|
||||
|
||||
|
|
@ -267,7 +284,7 @@ static void parm_to_flagmap(const string&flag)
|
|||
unsigned off = flag.find('=');
|
||||
if (off > flag.size()) {
|
||||
key = flag;
|
||||
value = "";
|
||||
value = strdup("");
|
||||
|
||||
} else {
|
||||
key = flag.substr(0, off);
|
||||
|
|
@ -386,6 +403,7 @@ static void read_iconfig_file(const char*ipath)
|
|||
}
|
||||
|
||||
if (strcmp(buf, "basedir") == 0) {
|
||||
free((char *)basedir);
|
||||
basedir = strdup(cp);
|
||||
|
||||
} else if (strcmp(buf, "debug") == 0) {
|
||||
|
|
@ -459,6 +477,7 @@ static void read_iconfig_file(const char*ipath)
|
|||
flags["VPI_MODULE_LIST"] = vpi_module_list;
|
||||
|
||||
} else if (strcmp(buf, "out") == 0) {
|
||||
free((char *)flags["-o"]);
|
||||
flags["-o"] = strdup(cp);
|
||||
|
||||
} else if (strcmp(buf, "sys_func") == 0) {
|
||||
|
|
@ -476,12 +495,21 @@ static void read_iconfig_file(const char*ipath)
|
|||
case 'l':
|
||||
warn_inf_loop = true;
|
||||
break;
|
||||
case 's':
|
||||
warn_ob_select = true;
|
||||
break;
|
||||
case 'p':
|
||||
warn_portbinding = true;
|
||||
break;
|
||||
case 't':
|
||||
warn_timescale = true;
|
||||
break;
|
||||
case 'v':
|
||||
warn_sens_entire_vec = true;
|
||||
break;
|
||||
case 'a':
|
||||
warn_sens_entire_arr = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -516,6 +544,7 @@ static void read_iconfig_file(const char*ipath)
|
|||
|
||||
}
|
||||
}
|
||||
fclose(ifile);
|
||||
}
|
||||
|
||||
extern Design* elaborate(list <perm_string> root);
|
||||
|
|
@ -542,6 +571,30 @@ inline static void times(struct tms *) { }
|
|||
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
|
||||
#endif // ! defined(HAVE_TIMES)
|
||||
|
||||
static void EOC_cleanup(void)
|
||||
{
|
||||
cleanup_sys_func_table();
|
||||
|
||||
for (list<const char*>::iterator suf = library_suff.begin() ;
|
||||
suf != library_suff.end() ; suf ++ ) {
|
||||
free((char *)*suf);
|
||||
}
|
||||
library_suff.clear();
|
||||
|
||||
free((char *) basedir);
|
||||
free(ivlpp_string);
|
||||
free(depfile_name);
|
||||
|
||||
for (map<string, const char*>::iterator flg = flags.begin() ;
|
||||
flg != flags.end() ; flg ++ ) {
|
||||
free((char *)flg->second);
|
||||
}
|
||||
flags.clear();
|
||||
|
||||
lex_strings.cleanup();
|
||||
filename_strings.cleanup();
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
bool help_flag = false;
|
||||
|
|
@ -554,11 +607,11 @@ int main(int argc, char*argv[])
|
|||
|
||||
struct tms cycles[5];
|
||||
|
||||
library_suff.push_back(".v");
|
||||
library_suff.push_back(strdup(".v"));
|
||||
|
||||
vpi_module_list = strdup("system");
|
||||
flags["VPI_MODULE_LIST"] = vpi_module_list;
|
||||
flags["-o"] = "a.out";
|
||||
flags["-o"] = strdup("a.out");
|
||||
min_typ_max_flag = TYP;
|
||||
min_typ_max_warn = 10;
|
||||
|
||||
|
|
@ -650,9 +703,10 @@ int main(int argc, char*argv[])
|
|||
lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
|
||||
break;
|
||||
case GN_VER2001:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
|
||||
case GN_VER2001_NOCONFIG:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001;
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
|
||||
break;
|
||||
case GN_VER2005:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
|
||||
|
|
@ -680,6 +734,9 @@ int main(int argc, char*argv[])
|
|||
case GN_VER1995:
|
||||
cout << "IEEE1364-1995";
|
||||
break;
|
||||
case GN_VER2001_NOCONFIG:
|
||||
cout << "IEEE1364-2001-noconfig";
|
||||
break;
|
||||
case GN_VER2001:
|
||||
cout << "IEEE1364-2001";
|
||||
break;
|
||||
|
|
@ -709,7 +766,17 @@ int main(int argc, char*argv[])
|
|||
cout << endl << "PARSING INPUT" << endl;
|
||||
}
|
||||
|
||||
const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"];
|
||||
if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0;
|
||||
|
||||
flag_tmp = flags["ARRAY_SIZE_LIMIT"];
|
||||
if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0);
|
||||
|
||||
flag_tmp = flags["RECURSIVE_MOD_LIMIT"];
|
||||
if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0);
|
||||
|
||||
/* Parse the input. Make the pform. */
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
int rc = pform_parse(argv[optind]);
|
||||
|
||||
if (pf_path) {
|
||||
|
|
@ -906,6 +973,8 @@ int main(int argc, char*argv[])
|
|||
<< endl;
|
||||
}
|
||||
|
||||
delete des;
|
||||
EOC_cleanup();
|
||||
return 0;
|
||||
|
||||
errors_summary:
|
||||
|
|
|
|||
40
mingw.txt
40
mingw.txt
|
|
@ -1,3 +1,8 @@
|
|||
Please NOTE:
|
||||
|
||||
These directions are slightly outdated and need to be updated.
|
||||
The plan is to rewrite all this using the latest MinGW at
|
||||
some time in the not too distant future (CR Aug. 2009)
|
||||
|
||||
|
||||
MINGW PORT OF ICARUS VERILOG
|
||||
|
|
@ -49,7 +54,7 @@ critical, but these are the versions I use.
|
|||
Mingw32-5.x <http://www.mingw.org>
|
||||
... including the sub-packages binutils, gcc-core and gcc-g++
|
||||
if you are given the option.
|
||||
readline-4.2-20010727.zip <http://mingwrep.sourceforge.net>
|
||||
readline-5.0-1 <http://gnuwin32.sourceforge.net>
|
||||
bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
|
||||
zlib-1.2.3 <http://gnuwin32.sourceforge.net>
|
||||
gperf-3.0.1 <http://gnuwin32.sourceforge.net>
|
||||
|
|
@ -79,7 +84,7 @@ Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are
|
|||
self-installing packages. Install msys first, and then msysDTC. Most
|
||||
likely, you want to install them in c:/msys. (The msysDTK is installed
|
||||
in the same location, as it is an add-on.)
|
||||
|
||||
|
||||
This install should be easy and reliable.
|
||||
|
||||
The installation will leave an "msys" icon on your desktop and in the
|
||||
|
|
@ -110,29 +115,6 @@ 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
|
||||
|
||||
There is a collection of precompiled libraries and add-on packages
|
||||
that are intended for use with the Mingw32 compiler. These do not come
|
||||
with simplified Windows installers, but they are pretty easy to
|
||||
install by hand. Icarus Verilog uses the readline-4.2 package from
|
||||
that collection.
|
||||
|
||||
Since I installed Mingw32 in c:\mingw, I also created a
|
||||
Mingw-packages directory called c:\mingw-packages. The install, then,
|
||||
is as easy as this:
|
||||
|
||||
<msys shell>
|
||||
$ cd c:/mingw-packages
|
||||
$ unzip readline-4.2-20010727.zip
|
||||
[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.
|
||||
|
||||
* Install GnuWin32 Packages
|
||||
|
||||
The GnuWin32 project is a collections of open source programs and
|
||||
|
|
@ -148,6 +130,7 @@ You will need these gnuwin32 packages to compile Icarus Verilog:
|
|||
gperf-3.0.1.exe
|
||||
bison-2.1.exe
|
||||
flex-2.5.4a.exe
|
||||
readline-5.0-1.exe
|
||||
|
||||
I suggest creating a common directory for holding all your gnuwin32
|
||||
packages. I use C:\gnuwin32. The download page at the gnuwin32 site
|
||||
|
|
@ -218,8 +201,8 @@ without white space.
|
|||
Now, configure the source to make the makefiles and configuration
|
||||
details. Run these commands:
|
||||
|
||||
$ CPPFLAGS="-Ic:/gnuwin32/include -Ic:/mingw-packages/include"
|
||||
$ LDFLAGS="-Lc:/gnuwin32/lib -Lc:/mingw-packages/lib"
|
||||
$ CPPFLAGS="-Ic:/gnuwin32/include
|
||||
$ LDFLAGS="-Lc:/gnuwin32/lib
|
||||
$ export CPPFLAGS LDFLAGS
|
||||
$ ./configure --prefix=c:/iverilog
|
||||
|
||||
|
|
@ -271,7 +254,8 @@ You may find that you need to put some of the prerequisite DLLs into
|
|||
the d:\iverilog\bin directory. These include:
|
||||
|
||||
c:\mingw\bin\mingw10.dll
|
||||
c:\mingw-packages\bin\libreadline.dll
|
||||
c:\gnuwin32\bin\readline.dll
|
||||
c:\gnuwin32\bin\history.dll
|
||||
c:\gnuwin32\bin\bzip2.dll
|
||||
c:\gnuwin32\bin\zlib.dll
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -490,7 +490,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
|||
void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
|
||||
{
|
||||
NetExpr*expr = (*cur).second.expr;
|
||||
assert(expr);
|
||||
if (expr == NULL) return; // This is an invalid parameter so return.
|
||||
|
||||
NetECReal*res = 0;
|
||||
eval_expr(expr);
|
||||
|
|
|
|||
17
net_expr.cc
17
net_expr.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -257,15 +257,13 @@ ivl_variable_type_t NetEBMinMax::expr_type() const
|
|||
NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r)
|
||||
: NetEBinary(op__, l, r)
|
||||
{
|
||||
if (expr_type() == IVL_VT_REAL)
|
||||
if (expr_type() == IVL_VT_REAL) {
|
||||
expr_width(1);
|
||||
else
|
||||
expr_width(l->expr_width() + r->expr_width());
|
||||
|
||||
if (expr_type() == IVL_VT_REAL)
|
||||
cast_signed(true);
|
||||
else
|
||||
} else {
|
||||
expr_width(l->expr_width() + r->expr_width());
|
||||
cast_signed(l->has_sign() && r->has_sign());
|
||||
}
|
||||
}
|
||||
|
||||
NetEBMult::~NetEBMult()
|
||||
|
|
@ -294,8 +292,8 @@ NetEBPow::NetEBPow(char op__, NetExpr*l, NetExpr*r)
|
|||
: NetEBinary(op__, l, r)
|
||||
{
|
||||
assert(op__ == 'p');
|
||||
/* This is incorrect! a * (2^b - 1) is close. */
|
||||
expr_width(l->expr_width()+r->expr_width());
|
||||
/* You could need up to a * (2^b - 1) bits. */
|
||||
expr_width(l->expr_width());
|
||||
cast_signed(l->has_sign() || r->has_sign());
|
||||
}
|
||||
|
||||
|
|
@ -438,6 +436,7 @@ NetECReal::NetECReal(const verireal&val)
|
|||
: value_(val)
|
||||
{
|
||||
expr_width(1);
|
||||
cast_signed(true);
|
||||
}
|
||||
|
||||
NetECReal::~NetECReal()
|
||||
|
|
|
|||
21
net_link.cc
21
net_link.cc
|
|
@ -173,7 +173,7 @@ void Link::unlink()
|
|||
|
||||
bool Link::is_equal(const Link&that) const
|
||||
{
|
||||
return (node_ == that.node_) && (pin_ == that.pin_);
|
||||
return (get_obj() == that.get_obj()) && (get_pin() == that.get_pin());
|
||||
}
|
||||
|
||||
bool Link::is_linked() const
|
||||
|
|
@ -261,6 +261,25 @@ verinum::V Nexus::get_init() const
|
|||
return verinum::Vz;
|
||||
}
|
||||
|
||||
bool Nexus::assign_lval() const
|
||||
{
|
||||
assert(list_);
|
||||
for (Link*cur = list_ ; cur ; cur = cur->next_) {
|
||||
|
||||
const NetPins*obj;
|
||||
unsigned pin;
|
||||
cur->cur_link(obj, pin);
|
||||
const NetNet*net = dynamic_cast<const NetNet*> (obj);
|
||||
if (net == 0)
|
||||
continue;
|
||||
|
||||
if (net->peek_lref())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Nexus::drivers_present() const
|
||||
{
|
||||
assert(list_);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
# include <cassert>
|
||||
# include <typeinfo>
|
||||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
|
|
@ -114,6 +115,11 @@ NexusSet* NetESelect::nex_input(bool rem_out)
|
|||
}
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
/* See the comment for NetESignal below. */
|
||||
if (base_ && warn_sens_entire_vec) {
|
||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||
"bits in '" << *expr_ << "'." << endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +139,25 @@ NexusSet* NetESFunc::nex_input(bool rem_out)
|
|||
|
||||
NexusSet* NetESignal::nex_input(bool rem_out)
|
||||
{
|
||||
/*
|
||||
* This is not what I would expect for the various selects (bit,
|
||||
* part, index, array). This code adds all the bits/array words
|
||||
* instead of building the appropriate select and then using it
|
||||
* as the trigger. Other simulators also add everything.
|
||||
*/
|
||||
NexusSet*result = new NexusSet;
|
||||
/* If we have an array index add it to the sensitivity list. */
|
||||
if (word_) {
|
||||
NexusSet*tmp;
|
||||
tmp = word_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
if (warn_sens_entire_arr) {
|
||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||
<< net_->array_count() << " words in array '"
|
||||
<< name() << "'." << endl;
|
||||
}
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
||||
result->add(net_->pin(idx).nexus());
|
||||
|
||||
|
|
|
|||
54
net_scope.cc
54
net_scope.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -41,17 +41,20 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
|
|||
events_ = 0;
|
||||
lcounter_ = 0;
|
||||
is_auto_ = false;
|
||||
is_cell_ = false;
|
||||
|
||||
if (up) {
|
||||
default_nettype_ = up->default_nettype();
|
||||
time_unit_ = up->time_unit();
|
||||
time_prec_ = up->time_precision();
|
||||
time_from_timescale_ = up->time_from_timescale();
|
||||
sib_ = up_->sub_;
|
||||
up_->sub_ = this;
|
||||
} else {
|
||||
default_nettype_ = NetNet::NONE;
|
||||
time_unit_ = 0;
|
||||
time_prec_ = 0;
|
||||
time_from_timescale_ = false;
|
||||
assert(t == MODULE);
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +233,31 @@ NetScope::TYPE NetScope::type() const
|
|||
return type_;
|
||||
}
|
||||
|
||||
void NetScope::print_type(ostream&stream) const
|
||||
{
|
||||
switch (type_) {
|
||||
case BEGIN_END:
|
||||
stream << "sequential block";
|
||||
break;
|
||||
case FORK_JOIN:
|
||||
stream << "parallel block";
|
||||
break;
|
||||
case FUNC:
|
||||
stream << "function";
|
||||
break;
|
||||
case MODULE:
|
||||
stream << "module <" << (module_name_ ? module_name_.str() : "")
|
||||
<< "> instance";
|
||||
break;
|
||||
case TASK:
|
||||
stream << "task";
|
||||
break;
|
||||
case GENBLOCK:
|
||||
stream << "generate block";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NetScope::set_task_def(NetTaskDef*def)
|
||||
{
|
||||
assert( type_ == TASK );
|
||||
|
|
@ -295,6 +323,11 @@ void NetScope::time_precision(int val)
|
|||
time_prec_ = val;
|
||||
}
|
||||
|
||||
void NetScope::time_from_timescale(bool val)
|
||||
{
|
||||
time_from_timescale_ = val;
|
||||
}
|
||||
|
||||
int NetScope::time_unit() const
|
||||
{
|
||||
return time_unit_;
|
||||
|
|
@ -305,6 +338,11 @@ int NetScope::time_precision() const
|
|||
return time_prec_;
|
||||
}
|
||||
|
||||
bool NetScope::time_from_timescale() const
|
||||
{
|
||||
return time_from_timescale_;
|
||||
}
|
||||
|
||||
void NetScope::default_nettype(NetNet::Type nt)
|
||||
{
|
||||
default_nettype_ = nt;
|
||||
|
|
@ -357,6 +395,20 @@ NetEvent* NetScope::find_event(perm_string name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void NetScope::add_genvar(perm_string name, LineInfo *li)
|
||||
{
|
||||
assert((type_ == MODULE) || (type_ == GENBLOCK));
|
||||
genvars_[name] = li;
|
||||
}
|
||||
|
||||
LineInfo* NetScope::find_genvar(perm_string name)
|
||||
{
|
||||
if (genvars_.find(name) != genvars_.end())
|
||||
return genvars_[name];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NetScope::add_signal(NetNet*net)
|
||||
{
|
||||
signals_map_[net->name()]=net;
|
||||
|
|
|
|||
134
netlist.cc
134
netlist.cc
|
|
@ -78,8 +78,8 @@ ostream& operator<< (ostream&o, NetNet::Type t)
|
|||
case NetNet::WIRE:
|
||||
o << "wire";
|
||||
break;
|
||||
case NetNet::WONE:
|
||||
o << "wone";
|
||||
case NetNet::UWIRE:
|
||||
o << "uwire";
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
|
@ -172,26 +172,51 @@ Link* find_next_output(Link*lnk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetPins::NetPins(unsigned npins)
|
||||
: npins_(npins)
|
||||
void NetPins::devirtualize_pins(void)
|
||||
{
|
||||
if (pins_) return;
|
||||
if (npins_ > array_size_limit) {
|
||||
cerr << get_fileline() << ": error: pin count " << npins_ <<
|
||||
" exceeds " << array_size_limit <<
|
||||
" (set by -pARRAY_SIZE_LIMIT)" << endl;
|
||||
assert(0);
|
||||
}
|
||||
if (debug_optimizer && npins_ > 1000) cerr << "debug: devirtualizing " << npins_ << " pins." << endl;
|
||||
|
||||
pins_ = new Link[npins_];
|
||||
pins_[0].pin_zero_ = true;
|
||||
pins_[0].node_ = this;
|
||||
pins_[0].dir_ = default_dir_;
|
||||
pins_[0].init_ = default_init_;
|
||||
|
||||
for (unsigned idx = 1 ; idx < npins_ ; idx += 1) {
|
||||
pins_[idx].pin_zero_ = false;
|
||||
pins_[idx].pin_ = idx;
|
||||
pins_[idx].dir_ = default_dir_;
|
||||
pins_[idx].init_ = default_init_;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetPins::pins_are_virtual(void) const
|
||||
{
|
||||
return pins_ == NULL;
|
||||
}
|
||||
|
||||
NetPins::NetPins(unsigned npins)
|
||||
: npins_(npins)
|
||||
{
|
||||
pins_ = NULL; // Wait until someone asks.
|
||||
if (disable_virtual_pins) devirtualize_pins(); // Ask. Bummer.
|
||||
}
|
||||
|
||||
NetPins::~NetPins()
|
||||
{
|
||||
delete[]pins_;
|
||||
if (pins_) delete[]pins_;
|
||||
}
|
||||
|
||||
Link& NetPins::pin(unsigned idx)
|
||||
{
|
||||
if (!pins_) devirtualize_pins();
|
||||
if (idx >= npins_) {
|
||||
cerr << get_fileline() << ": internal error: pin("<<idx<<")"
|
||||
<< " out of bounds("<<npins_<<")" << endl;
|
||||
|
|
@ -207,11 +232,27 @@ Link& NetPins::pin(unsigned idx)
|
|||
|
||||
const Link& NetPins::pin(unsigned idx) const
|
||||
{
|
||||
if (!pins_ && !disable_virtual_pins) {
|
||||
cerr << get_fileline() << ": internal error: pin is unexpectedly"
|
||||
" virtual, try again with -pDISABLE_VIRTUAL_PINS=true" << endl;
|
||||
assert(0);
|
||||
}
|
||||
assert(pins_);
|
||||
assert(idx < npins_);
|
||||
assert(idx == 0? pins_[0].pin_zero_ : pins_[idx].pin_==idx);
|
||||
return pins_[idx];
|
||||
}
|
||||
|
||||
void NetPins::set_default_dir(Link::DIR d)
|
||||
{
|
||||
default_dir_ = d;
|
||||
}
|
||||
|
||||
void NetPins::set_default_init(verinum::V val)
|
||||
{
|
||||
default_init_ = val;
|
||||
}
|
||||
|
||||
bool NetPins::is_linked(void)
|
||||
{
|
||||
bool linked_flag = false;
|
||||
|
|
@ -228,6 +269,11 @@ bool NetPins::is_linked(void)
|
|||
NetObj::NetObj(NetScope*s, perm_string n, unsigned np)
|
||||
: NetPins(np), scope_(s), name_(n), delay1_(0), delay2_(0), delay3_(0)
|
||||
{
|
||||
/* Don't
|
||||
ivl_assert(*this, np > 0);
|
||||
* because it would happen before we get to print a useful
|
||||
* message in the NetNet constructor
|
||||
*/
|
||||
}
|
||||
|
||||
NetObj::~NetObj()
|
||||
|
|
@ -269,6 +315,9 @@ NetBranch::~NetBranch()
|
|||
NetBus::NetBus(NetScope*s, unsigned pin_count__)
|
||||
: NetObj(s, perm_string::literal(""), pin_count__)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx <pin_count__ ; idx += 1) {
|
||||
pin(idx).set_dir(Link::PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
NetBus::~NetBus()
|
||||
|
|
@ -442,8 +491,8 @@ const Link& NetDelaySrc::condit_pin() const
|
|||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
|
||||
signed_(false), isint_(false), discipline_(0), msb_(npins-1), lsb_(0),
|
||||
dimensions_(0),
|
||||
signed_(false), isint_(false), is_scalar_(false),
|
||||
discipline_(0), msb_(npins-1), lsb_(0), dimensions_(0),
|
||||
s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
|
|
@ -479,7 +528,11 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
|||
|
||||
void NetNet::initialize_value_and_dir(verinum::V init_value, Link::DIR dir)
|
||||
{
|
||||
if (1) {
|
||||
if (pins_are_virtual()) {
|
||||
if (0) cerr << "NetNet setting Link default value and dir" << endl;
|
||||
set_default_init(init_value);
|
||||
set_default_dir(dir);
|
||||
} else {
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(dir);
|
||||
pin(idx).set_init(init_value);
|
||||
|
|
@ -491,7 +544,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
long ms, long ls)
|
||||
: NetObj(s, n, 1), type_(t),
|
||||
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
|
||||
isint_(false), discipline_(0), msb_(ms), lsb_(ls), dimensions_(0), s0_(0), e0_(0),
|
||||
isint_(false), is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
|
||||
dimensions_(0), s0_(0), e0_(0),
|
||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
|
|
@ -524,10 +578,16 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
|
||||
static unsigned calculate_count(long s, long e)
|
||||
{
|
||||
if (s >= e)
|
||||
return s - e + 1;
|
||||
else
|
||||
return e - s + 1;
|
||||
unsigned long r;
|
||||
if (s >= e) {
|
||||
r = s - e;
|
||||
} else {
|
||||
r = e - s;
|
||||
}
|
||||
if (r >= UINT_MAX) {
|
||||
return 0;
|
||||
}
|
||||
return r + 1;
|
||||
}
|
||||
|
||||
NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
||||
|
|
@ -535,10 +595,15 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
: NetObj(s, n, calculate_count(array_s, array_e)),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
|
||||
discipline_(0), msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e),
|
||||
is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
|
||||
dimensions_(1), s0_(array_s), e0_(array_e),
|
||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
ivl_assert(*this, s);
|
||||
if (pin_count() == 0) {
|
||||
cerr << "Array too big [" << array_s << ":" << array_e << "]" << endl;
|
||||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
||||
verinum::V init_value = verinum::Vz;
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
|
@ -664,6 +729,16 @@ void NetNet::set_isint(bool flag)
|
|||
isint_ = flag;
|
||||
}
|
||||
|
||||
bool NetNet::get_scalar() const
|
||||
{
|
||||
return is_scalar_;
|
||||
}
|
||||
|
||||
void NetNet::set_scalar(bool flag)
|
||||
{
|
||||
is_scalar_ = flag;
|
||||
}
|
||||
|
||||
ivl_discipline_t NetNet::get_discipline() const
|
||||
{
|
||||
return discipline_;
|
||||
|
|
@ -732,7 +807,9 @@ bool NetNet::array_addr_swapped() const
|
|||
|
||||
unsigned NetNet::array_count() const
|
||||
{
|
||||
return calculate_count(s0_, e0_);
|
||||
unsigned c = calculate_count(s0_, e0_);
|
||||
ivl_assert(*this, c > 0);
|
||||
return c;
|
||||
}
|
||||
|
||||
bool NetNet::array_index_is_valid(long sb) const
|
||||
|
|
@ -808,9 +885,8 @@ const NetDelaySrc* NetNet::delay_path(unsigned idx) const
|
|||
NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
|
||||
NetPartSelect::dir_t dir__)
|
||||
: NetNode(sig->scope(), sig->scope()->local_symbol(), 2),
|
||||
off_(off), wid_(wid), dir_(dir__)
|
||||
off_(off), wid_(wid), dir_(dir__), signed_flag_(false)
|
||||
{
|
||||
connect(pin(1), sig->pin(0));
|
||||
set_line(*sig);
|
||||
|
||||
switch (dir_) {
|
||||
|
|
@ -823,27 +899,28 @@ NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
|
|||
pin(1).set_dir(Link::OUTPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
connect(pin(1), sig->pin(0));
|
||||
}
|
||||
|
||||
NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
|
||||
unsigned wid)
|
||||
unsigned wid, bool signed_flag)
|
||||
: NetNode(sig->scope(), sig->scope()->local_symbol(), 3),
|
||||
off_(0), wid_(wid), dir_(VP)
|
||||
off_(0), wid_(wid), dir_(VP), signed_flag_(signed_flag)
|
||||
{
|
||||
connect(pin(1), sig->pin(0));
|
||||
connect(pin(2), sel->pin(0));
|
||||
|
||||
switch (dir_) {
|
||||
case NetPartSelect::VP:
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(1).set_dir(Link::INPUT);
|
||||
break;
|
||||
case NetPartSelect::PV:
|
||||
pin(0).set_dir(Link::INPUT);
|
||||
pin(1).set_dir(Link::OUTPUT);
|
||||
break;
|
||||
/* Only a vector to part can be a variable select. */
|
||||
assert(0);
|
||||
}
|
||||
pin(2).set_dir(Link::INPUT);
|
||||
|
||||
connect(pin(1), sig->pin(0));
|
||||
connect(pin(2), sel->pin(0));
|
||||
}
|
||||
|
||||
NetPartSelect::~NetPartSelect()
|
||||
|
|
@ -2271,12 +2348,12 @@ NetNet* NetESignal::sig()
|
|||
return net_;
|
||||
}
|
||||
|
||||
unsigned NetESignal::lsi() const
|
||||
long NetESignal::lsi() const
|
||||
{
|
||||
return net_->lsb();
|
||||
}
|
||||
|
||||
unsigned NetESignal::msi() const
|
||||
long NetESignal::msi() const
|
||||
{
|
||||
return net_->msb();
|
||||
}
|
||||
|
|
@ -2591,6 +2668,7 @@ static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc)
|
|||
/* This should never happen since delay_type_from_expr() only
|
||||
* returns three different values. */
|
||||
default:
|
||||
result = NO_DELAY;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
44
netlist.h
44
netlist.h
|
|
@ -193,11 +193,17 @@ class NetPins : public LineInfo {
|
|||
const Link&pin(unsigned idx) const;
|
||||
|
||||
void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const;
|
||||
void set_default_dir(Link::DIR d);
|
||||
void set_default_init(verinum::V val);
|
||||
bool is_linked();
|
||||
bool pins_are_virtual(void) const;
|
||||
void devirtualize_pins(void);
|
||||
|
||||
private:
|
||||
Link*pins_;
|
||||
const unsigned npins_;
|
||||
Link::DIR default_dir_;
|
||||
verinum::V default_init_;
|
||||
};
|
||||
|
||||
/* =========
|
||||
|
|
@ -341,6 +347,11 @@ class Nexus {
|
|||
|
||||
NetNet* pick_any_net();
|
||||
|
||||
/* This method returns true if there are any assignments that
|
||||
use this nexus as an l-value. This can be true if the nexus
|
||||
is a variable, but also if this is a net with a force. */
|
||||
bool assign_lval() const;
|
||||
|
||||
/* This method returns true if there are any drivers
|
||||
(including variables) attached to this nexus. */
|
||||
bool drivers_present() const;
|
||||
|
|
@ -536,7 +547,7 @@ class NetNet : public NetObj {
|
|||
public:
|
||||
enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1,
|
||||
SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG,
|
||||
WONE };
|
||||
UWIRE };
|
||||
|
||||
enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT };
|
||||
|
||||
|
|
@ -575,6 +586,9 @@ class NetNet : public NetObj {
|
|||
bool get_isint() const;
|
||||
void set_isint(bool);
|
||||
|
||||
bool get_scalar() const;
|
||||
void set_scalar(bool);
|
||||
|
||||
/* Attach a discipline to the net. */
|
||||
ivl_discipline_t get_discipline() const;
|
||||
void set_discipline(ivl_discipline_t dis);
|
||||
|
|
@ -644,6 +658,7 @@ class NetNet : public NetObj {
|
|||
ivl_variable_type_t data_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
bool is_scalar_;
|
||||
ivl_discipline_t discipline_;
|
||||
|
||||
long msb_, lsb_;
|
||||
|
|
@ -710,6 +725,9 @@ class NetScope : public Attrib {
|
|||
void rem_event(NetEvent*);
|
||||
NetEvent*find_event(perm_string name);
|
||||
|
||||
/* These methods add or find a genvar that lives in this scope. */
|
||||
void add_genvar(perm_string name, LineInfo *li);
|
||||
LineInfo* find_genvar(perm_string name);
|
||||
|
||||
/* These methods manage signals. The add_ and rem_signal
|
||||
methods are used by the NetNet objects to make themselves
|
||||
|
|
@ -728,6 +746,7 @@ class NetScope : public Attrib {
|
|||
const NetScope* child(const hname_t&name) const;
|
||||
|
||||
TYPE type() const;
|
||||
void print_type(ostream&) const;
|
||||
|
||||
void set_task_def(NetTaskDef*);
|
||||
void set_func_def(NetFuncDef*);
|
||||
|
|
@ -750,6 +769,10 @@ class NetScope : public Attrib {
|
|||
void is_auto(bool is_auto__) { is_auto_ = is_auto__; };
|
||||
bool is_auto() const { return is_auto_; };
|
||||
|
||||
/* Is the module a cell (is in a `celldefine) */
|
||||
void is_cell(bool is_cell__) { is_cell_ = is_cell__; };
|
||||
bool is_cell() const { return is_cell_; };
|
||||
|
||||
const NetTaskDef* task_def() const;
|
||||
const NetFuncDef* func_def() const;
|
||||
|
||||
|
|
@ -767,9 +790,11 @@ class NetScope : public Attrib {
|
|||
|
||||
void time_unit(int);
|
||||
void time_precision(int);
|
||||
void time_from_timescale(bool);
|
||||
|
||||
int time_unit() const;
|
||||
int time_precision() const;
|
||||
bool time_from_timescale() const;
|
||||
|
||||
void default_nettype(NetNet::Type);
|
||||
NetNet::Type default_nettype() const;
|
||||
|
|
@ -877,10 +902,13 @@ class NetScope : public Attrib {
|
|||
unsigned def_lineno_;
|
||||
|
||||
signed char time_unit_, time_prec_;
|
||||
bool time_from_timescale_;
|
||||
NetNet::Type default_nettype_;
|
||||
|
||||
NetEvent *events_;
|
||||
|
||||
map<perm_string,LineInfo*> genvars_;
|
||||
|
||||
typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
|
||||
std::map <perm_string,NetNet*> signals_map_;
|
||||
perm_string module_name_;
|
||||
|
|
@ -894,7 +922,7 @@ class NetScope : public Attrib {
|
|||
NetScope*sub_;
|
||||
|
||||
unsigned lcounter_;
|
||||
bool is_auto_;
|
||||
bool is_auto_, is_cell_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1772,12 +1800,14 @@ class NetPartSelect : public NetNode {
|
|||
explicit NetPartSelect(NetNet*sig,
|
||||
unsigned off, unsigned wid, dir_t dir);
|
||||
explicit NetPartSelect(NetNet*sig, NetNet*sel,
|
||||
unsigned wid);
|
||||
unsigned wid, bool signed_flag = false);
|
||||
~NetPartSelect();
|
||||
|
||||
unsigned base() const;
|
||||
unsigned width() const;
|
||||
dir_t dir() const;
|
||||
/* Is the select signal signed? */
|
||||
bool signed_flag() const { return signed_flag_; }
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
bool emit_node(struct target_t*tgt) const;
|
||||
|
|
@ -1786,6 +1816,7 @@ class NetPartSelect : public NetNode {
|
|||
unsigned off_;
|
||||
unsigned wid_;
|
||||
dir_t dir_;
|
||||
bool signed_flag_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -3256,6 +3287,7 @@ class NetEBAdd : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void cast_signed(bool sign_flag);
|
||||
virtual NetEBAdd* dup_expr() const;
|
||||
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
@ -3278,6 +3310,7 @@ class NetEBDiv : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void cast_signed(bool sign_flag);
|
||||
virtual NetEBDiv* dup_expr() const;
|
||||
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
@ -3408,6 +3441,7 @@ class NetEBMult : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void cast_signed(bool sign_flag);
|
||||
virtual NetEBMult* dup_expr() const;
|
||||
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
@ -3803,8 +3837,8 @@ class NetESignal : public NetExpr {
|
|||
const NetNet* sig() const;
|
||||
NetNet* sig();
|
||||
// Declared vector dimensions for the signal.
|
||||
unsigned msi() const;
|
||||
unsigned lsi() const;
|
||||
long msi() const;
|
||||
long lsi() const;
|
||||
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
|
|
|
|||
47
netlist.txt
47
netlist.txt
|
|
@ -16,7 +16,6 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: netlist.txt,v 1.10 2000/07/23 18:06:15 steve Exp $"
|
||||
|
||||
|
||||
Note that the netlist.h header contains detailed descriptions of how
|
||||
|
|
@ -291,49 +290,3 @@ values. These are filled in during scope elaboration and are used in
|
|||
subsequent elaboration phases to arrange for scaling of delays. This
|
||||
information can also be used by the code generator to scale times back
|
||||
to the units of the scope, if that is desired.
|
||||
|
||||
$Log: netlist.txt,v $
|
||||
Revision 1.10 2000/07/23 18:06:15 steve
|
||||
Document time scale in netlists.
|
||||
|
||||
Revision 1.9 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.8 2000/03/08 04:36:54 steve
|
||||
Redesign the implementation of scopes and parameters.
|
||||
I now generate the scopes and notice the parameters
|
||||
in a separate pass over the pform. Once the scopes
|
||||
are generated, I can process overrides and evalutate
|
||||
paremeters before elaboration begins.
|
||||
|
||||
Revision 1.7 1999/11/28 23:42:02 steve
|
||||
NetESignal object no longer need to be NetNode
|
||||
objects. Let them keep a pointer to NetNet objects.
|
||||
|
||||
Revision 1.6 1999/11/21 00:13:09 steve
|
||||
Support memories in continuous assignments.
|
||||
|
||||
Revision 1.5 1999/11/02 04:55:34 steve
|
||||
Add the synthesize method to NetExpr to handle
|
||||
synthesis of expressions, and use that method
|
||||
to improve r-value handling of LPM_FF synthesis.
|
||||
|
||||
Modify the XNF target to handle LPM_FF objects.
|
||||
|
||||
Revision 1.4 1999/09/29 00:03:27 steve
|
||||
Spelling fixes from Larry.
|
||||
|
||||
Revision 1.3 1999/07/24 02:11:20 steve
|
||||
Elaborate task input ports.
|
||||
|
||||
Revision 1.2 1999/07/21 01:15:29 steve
|
||||
Document netlist semantics.
|
||||
|
||||
Revision 1.1 1999/05/27 04:13:08 steve
|
||||
Handle expression bit widths with non-fatal errors.
|
||||
|
||||
|
|
|
|||
|
|
@ -416,6 +416,7 @@ const char *human_readable_op(const char op, bool unary)
|
|||
case '-': type = "-"; break;
|
||||
case '*': type = "*"; break;
|
||||
case '/': type = "/"; break;
|
||||
case '%': type = "%"; break;
|
||||
|
||||
case '<': type = "<"; break;
|
||||
case '>': type = ">"; break;
|
||||
|
|
@ -447,6 +448,7 @@ const char *human_readable_op(const char op, bool unary)
|
|||
|
||||
case 'p': type = "**"; break; // Power
|
||||
default:
|
||||
type = "???";
|
||||
assert(0);
|
||||
}
|
||||
return type;
|
||||
|
|
|
|||
|
|
@ -231,4 +231,8 @@ const char *human_readable_op(const char op, bool unary = false);
|
|||
enum const_bool { C_NON, C_0, C_1, C_X };
|
||||
const_bool const_logical(const NetExpr*expr);
|
||||
|
||||
extern bool dly_used_no_timescale;
|
||||
extern bool dly_used_timescale;
|
||||
extern bool display_ts_dly_warning;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -134,7 +134,7 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid)
|
|||
NetNet::WIRE, wid);
|
||||
tmp->data_type(net->data_type());
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*tmp);
|
||||
tmp->set_line(*net);
|
||||
connect(ps->pin(0), tmp->pin(0));
|
||||
|
||||
return tmp;
|
||||
|
|
|
|||
314
parse.y
314
parse.y
|
|
@ -55,6 +55,13 @@ static PTask* current_task = 0;
|
|||
static PFunction* current_function = 0;
|
||||
static stack<PBlock*> current_block_stack;
|
||||
|
||||
/* This is used to keep track of the extra arguments after the notifier
|
||||
* in the $setuphold and $recrem timing checks. This allows us to print
|
||||
* a warning message that the delayed signals will not be created. We
|
||||
* need to do this since not driving these signals creates real
|
||||
* simulation issues. */
|
||||
static unsigned args_after_notifier;
|
||||
|
||||
/* Later version of bison (including 1.35) will not compile in stack
|
||||
extension if the output is compiled with C++ and either the YYSTYPE
|
||||
or YYLTYPE are provided by the source code. However, I can get the
|
||||
|
|
@ -80,6 +87,22 @@ static stack<PBlock*> current_block_stack;
|
|||
const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
|
||||
const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
||||
|
||||
static list<pair<perm_string,PExpr*> >* make_port_list(char*id, PExpr*expr)
|
||||
{
|
||||
list<pair<perm_string,PExpr*> >*tmp = new list<pair<perm_string,PExpr*> >;
|
||||
tmp->push_back(make_pair(lex_strings.make(id), expr));
|
||||
delete[]id;
|
||||
return tmp;
|
||||
}
|
||||
static list<pair<perm_string,PExpr*> >* make_port_list(list<pair<perm_string,
|
||||
PExpr*> >*tmp,
|
||||
char*id, PExpr*expr)
|
||||
{
|
||||
tmp->push_back(make_pair(lex_strings.make(id), expr));
|
||||
delete[]id;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static list<perm_string>* list_from_identifier(char*id)
|
||||
{
|
||||
list<perm_string>*tmp = new list<perm_string>;
|
||||
|
|
@ -146,6 +169,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
strdup. They can be put into lists with the texts type. */
|
||||
char*text;
|
||||
list<perm_string>*perm_strings;
|
||||
|
||||
list<pair<perm_string,PExpr*> >*port_list;
|
||||
|
||||
pform_name_t*pform_name;
|
||||
|
||||
ivl_discipline_t discipline;
|
||||
|
|
@ -210,40 +236,56 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
%token K_PO_POS K_PO_NEG K_POW
|
||||
%token K_PSTAR K_STARP
|
||||
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
||||
%token K_abs K_abstol K_access K_acos K_acosh K_asin K_analog K_asinh
|
||||
%token K_atan K_atanh K_atan2 K_automatic
|
||||
%token K_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case
|
||||
%token K_casex K_casez K_ceil K_cmos K_continuous K_cos K_cosh
|
||||
%token K_ddt_nature K_deassign K_default K_defparam K_disable K_discrete
|
||||
%token K_domain K_edge K_edge_descriptor K_discipline
|
||||
%token K_else K_end K_endcase K_enddiscipline K_endfunction K_endgenerate
|
||||
%token K_endmodule K_endnature
|
||||
%token K_endprimitive K_endspecify K_endtable K_endtask K_event
|
||||
%token K_exclude K_exp K_floor K_flow K_from
|
||||
%token K_for K_force K_forever K_fork K_function K_generate K_genvar
|
||||
%token K_ground K_highz0 K_highz1 K_hypot K_idt_nature K_if K_ifnone K_inf
|
||||
%token K_initial K_inout K_input K_integer K_join K_large K_ln K_localparam
|
||||
%token K_log K_logic K_macromodule K_max
|
||||
%token K_medium K_min K_module K_nand K_nature K_negedge
|
||||
%token K_nmos K_nor K_not K_notif0
|
||||
%token K_notif1 K_or K_output K_parameter K_pmos K_posedge K_potential
|
||||
%token K_pow K_primitive
|
||||
%token K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real K_realtime
|
||||
%token K_reg K_release K_repeat
|
||||
%token K_rnmos K_rpmos K_rtran K_rtranif0 K_rtranif1 K_scalared
|
||||
%token K_signed K_sin K_sinh K_small K_specify
|
||||
%token K_specparam K_sqrt K_string K_strong0 K_strong1 K_supply0 K_supply1
|
||||
%token K_table
|
||||
%token K_tan K_tanh K_task
|
||||
%token K_time K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand
|
||||
%token K_trior K_trireg K_units K_vectored K_wait K_wand K_weak0 K_weak1
|
||||
%token K_while K_wire
|
||||
%token K_wone K_wor K_xnor K_xor
|
||||
%token K_Shold K_Speriod K_Srecovery K_Srecrem K_Ssetup K_Swidth K_Ssetuphold
|
||||
%token K_edge_descriptor
|
||||
|
||||
/* The base tokens from 1364-1995. */
|
||||
%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_edge 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_force K_forever K_fork K_function K_highz0 K_highz1 K_if
|
||||
%token K_ifnone K_initial K_inout K_input K_integer K_join K_large
|
||||
%token K_macromodule K_medium K_module K_nand K_negedge K_nmos K_nor
|
||||
%token K_not K_notif0 K_notif1 K_or K_output K_parameter K_pmos K_posedge
|
||||
%token K_primitive K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real
|
||||
%token K_realtime K_reg K_release K_repeat K_rnmos K_rpmos K_rtran
|
||||
%token K_rtranif0 K_rtranif1 K_scalared K_small K_specify K_specparam
|
||||
%token K_strong0 K_strong1 K_supply0 K_supply1 K_table K_task K_time
|
||||
%token K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand K_trior
|
||||
%token K_trireg K_vectored K_wait K_wand K_weak0 K_weak1 K_while K_wire
|
||||
%token K_wor K_xnor K_xor
|
||||
|
||||
%token K_Shold K_Snochange K_Speriod K_Srecovery K_Ssetup K_Ssetuphold
|
||||
%token K_Sskew K_Swidth
|
||||
|
||||
/* Icarus specific tokens. */
|
||||
%token KK_attribute K_bool K_logic
|
||||
|
||||
/* The new tokens from 1364-2001. */
|
||||
%token K_automatic K_endgenerate K_generate K_genvar K_localparam
|
||||
%token K_noshowcancelled K_pulsestyle_onevent K_pulsestyle_ondetect
|
||||
%token K_showcancelled K_signed K_unsigned
|
||||
|
||||
%token K_Sfullskew K_Srecrem K_Sremoval K_Stimeskew
|
||||
|
||||
/* The 1364-2001 configuration tokens. */
|
||||
%token K_cell K_config K_design K_endconfig K_incdir K_include K_instance
|
||||
%token K_liblist K_library K_use
|
||||
|
||||
/* The new tokens from 1364-2005. */
|
||||
%token K_wone K_uwire
|
||||
|
||||
/* The new tokens from 1800-2005. */
|
||||
%token K_always_comb K_always_ff K_always_latch K_assert
|
||||
|
||||
%token KK_attribute
|
||||
/* The new tokens for Verilog-AMS 2.3. */
|
||||
%token K_abs K_abstol K_access K_acos K_acosh K_analog K_asin K_asinh
|
||||
%token K_atan K_atan2 K_atanh K_ceil K_continuous K_cos K_cosh
|
||||
%token K_ddt_nature K_discipline K_discrete K_domain K_enddiscipline
|
||||
%token K_endnature K_exclude K_exp K_floor K_flow K_from K_ground
|
||||
%token K_hypot K_idt_nature K_inf K_ln K_log K_max K_min K_nature
|
||||
%token K_potential K_pow K_sin K_sinh K_sqrt K_string K_tan K_tanh
|
||||
%token K_units
|
||||
|
||||
%type <flag> from_exclude
|
||||
%type <number> number
|
||||
|
|
@ -260,7 +302,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
|||
%type <expr> udp_initial_expr_opt
|
||||
|
||||
%type <text> register_variable net_variable real_variable
|
||||
%type <perm_strings> register_variable_list net_variable_list real_variable_list list_of_identifiers
|
||||
%type <perm_strings> register_variable_list net_variable_list
|
||||
%type <perm_strings> real_variable_list list_of_identifiers
|
||||
%type <port_list> list_of_port_identifiers
|
||||
|
||||
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
||||
|
||||
|
|
@ -682,6 +726,7 @@ delay_value_simple
|
|||
description
|
||||
: module
|
||||
| udp_primitive
|
||||
| config_declaration
|
||||
| nature_declaration
|
||||
| discipline_declaration
|
||||
| KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')'
|
||||
|
|
@ -746,6 +791,54 @@ nature_item
|
|||
{ delete[] $3; }
|
||||
;
|
||||
|
||||
config_declaration
|
||||
: K_config IDENTIFIER ';'
|
||||
K_design lib_cell_identifiers ';'
|
||||
list_of_config_rule_statements
|
||||
K_endconfig
|
||||
{ cerr << @1 << ": sorry: config declarations are not supported and "
|
||||
"will be skipped." << endl;
|
||||
delete[] $2;
|
||||
}
|
||||
;
|
||||
|
||||
lib_cell_identifiers
|
||||
: /* The BNF implies this can be blank, but I'm not sure exactly what
|
||||
* this means. */
|
||||
| lib_cell_identifiers lib_cell_id
|
||||
;
|
||||
|
||||
list_of_config_rule_statements
|
||||
: /* config rules are optional. */
|
||||
| list_of_config_rule_statements config_rule_statement
|
||||
;
|
||||
|
||||
config_rule_statement
|
||||
: K_default K_liblist list_of_libraries ';'
|
||||
| K_instance hierarchy_identifier K_liblist list_of_libraries ';'
|
||||
{ delete $2; }
|
||||
| K_instance hierarchy_identifier K_use lib_cell_id opt_config ';'
|
||||
{ delete $2; }
|
||||
| K_cell lib_cell_id K_liblist list_of_libraries ';'
|
||||
| K_cell lib_cell_id K_use lib_cell_id opt_config ';'
|
||||
;
|
||||
|
||||
opt_config
|
||||
: /* The use clause takse an optional :config. */
|
||||
| ':' K_config
|
||||
|
||||
lib_cell_id
|
||||
: IDENTIFIER
|
||||
{ delete[] $1; }
|
||||
| IDENTIFIER '.' IDENTIFIER
|
||||
{ delete[] $1; delete[] $3; }
|
||||
;
|
||||
|
||||
list_of_libraries
|
||||
: /* A NULL library means use the parents cell library. */
|
||||
| list_of_libraries IDENTIFIER
|
||||
{ delete[] $2; }
|
||||
|
||||
drive_strength
|
||||
: '(' dr_strength0 ',' dr_strength1 ')'
|
||||
{ $$.str0 = $2.str0;
|
||||
|
|
@ -900,6 +993,21 @@ expression
|
|||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| '~' '&' expr_primary %prec UNARY_PREC
|
||||
{ yyerror(@1, "error: '~' '&' is not a valid expression. "
|
||||
"Please use operator '~&' instead.");
|
||||
$$ = 0;
|
||||
}
|
||||
| '~' '|' expr_primary %prec UNARY_PREC
|
||||
{ yyerror(@1, "error: '~' '|' is not a valid expression. "
|
||||
"Please use operator '~|' instead.");
|
||||
$$ = 0;
|
||||
}
|
||||
| '~' '^' expr_primary %prec UNARY_PREC
|
||||
{ yyerror(@1, "error: '~' '^' is not a valid expression. "
|
||||
"Please use operator '~^' instead.");
|
||||
$$ = 0;
|
||||
}
|
||||
| K_NAND expr_primary %prec UNARY_PREC
|
||||
{ PEUnary*tmp = new PEUnary('A', $2);
|
||||
FILE_NAME(tmp, @2);
|
||||
|
|
@ -1647,6 +1755,17 @@ list_of_identifiers
|
|||
{ $$ = list_from_identifier($1, $3); }
|
||||
;
|
||||
|
||||
list_of_port_identifiers
|
||||
: IDENTIFIER
|
||||
{ $$ = make_port_list($1, 0); }
|
||||
| IDENTIFIER '=' expression
|
||||
{ $$ = make_port_list($1, $3); }
|
||||
| list_of_port_identifiers ',' IDENTIFIER
|
||||
{ $$ = make_port_list($1, $3, 0); }
|
||||
| list_of_port_identifiers ',' IDENTIFIER '=' expression
|
||||
{ $$ = make_port_list($1, $3, $5); }
|
||||
;
|
||||
|
||||
|
||||
/* The list_of_ports and list_of_port_declarations rules are the
|
||||
port list formats for module ports. The list_of_ports_opt rule is
|
||||
|
|
@ -1876,7 +1995,20 @@ module : attribute_list_opt module_start IDENTIFIER
|
|||
{ pform_module_set_ports($6); }
|
||||
module_item_list_opt
|
||||
K_endmodule
|
||||
{ pform_endmodule($3);
|
||||
{ Module::UCDriveType ucd;
|
||||
switch (uc_drive) {
|
||||
case UCD_NONE:
|
||||
default:
|
||||
ucd = Module::UCD_NONE;
|
||||
break;
|
||||
case UCD_PULL0:
|
||||
ucd = Module::UCD_PULL0;
|
||||
break;
|
||||
case UCD_PULL1:
|
||||
ucd = Module::UCD_PULL1;
|
||||
break;
|
||||
}
|
||||
pform_endmodule($3, in_celldefine, ucd);
|
||||
delete[]$3;
|
||||
}
|
||||
|
||||
|
|
@ -1991,9 +2123,20 @@ module_item
|
|||
SR_BOTH);
|
||||
}
|
||||
|
||||
| K_output var_type signed_opt range_opt list_of_identifiers ';'
|
||||
{ pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT,
|
||||
IVL_VT_NO_TYPE, 0, SR_BOTH);
|
||||
| K_output var_type signed_opt range_opt list_of_port_identifiers ';'
|
||||
{ list<pair<perm_string,PExpr*> >::const_iterator pp;
|
||||
list<perm_string>*tmp = new list<perm_string>;
|
||||
for (pp = $5->begin(); pp != $5->end(); pp++) {
|
||||
tmp->push_back((*pp).first);
|
||||
}
|
||||
pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT,
|
||||
IVL_VT_NO_TYPE, 0, SR_BOTH);
|
||||
for (pp = $5->begin(); pp != $5->end(); pp++) {
|
||||
if ((*pp).second) {
|
||||
pform_make_reginit(@1, (*pp).first, (*pp).second);
|
||||
}
|
||||
}
|
||||
delete $5;
|
||||
}
|
||||
|
||||
/* var_type declaration (reg variables) cannot be input or output,
|
||||
|
|
@ -2124,8 +2267,7 @@ module_item
|
|||
|
||||
| K_task automatic_opt IDENTIFIER ';'
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope($3, $2);
|
||||
FILE_NAME(current_task, @1);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
task_item_list_opt
|
||||
statement_or_null
|
||||
|
|
@ -2137,12 +2279,11 @@ module_item
|
|||
delete[]$3;
|
||||
}
|
||||
|
||||
| K_task automatic_opt IDENTIFIER
|
||||
| K_task automatic_opt IDENTIFIER '('
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope($3, $2);
|
||||
FILE_NAME(current_task, @1);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
'(' task_port_decl_list ')' ';'
|
||||
task_port_decl_list ')' ';'
|
||||
block_item_decls_opt
|
||||
statement_or_null
|
||||
K_endtask
|
||||
|
|
@ -2152,6 +2293,23 @@ module_item
|
|||
current_task = 0;
|
||||
delete[]$3;
|
||||
}
|
||||
|
||||
| K_task automatic_opt IDENTIFIER '(' ')' ';'
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
block_item_decls_opt
|
||||
statement_or_null
|
||||
K_endtask
|
||||
{ current_task->set_ports(0);
|
||||
current_task->set_statement($9);
|
||||
pform_pop_scope();
|
||||
current_task = 0;
|
||||
cerr << @3 << ": warning: task definition for \"" << $3
|
||||
<< "\" has an empty port declaration list!" << endl;
|
||||
delete[]$3;
|
||||
}
|
||||
|
||||
| K_task automatic_opt IDENTIFIER error K_endtask
|
||||
{
|
||||
pform_pop_scope();
|
||||
|
|
@ -2166,8 +2324,7 @@ module_item
|
|||
|
||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER ';'
|
||||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope($4, $2);
|
||||
FILE_NAME(current_function, @1);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
function_item_list statement
|
||||
K_endfunction
|
||||
|
|
@ -2181,8 +2338,7 @@ module_item
|
|||
|
||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER
|
||||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope($4, $2);
|
||||
FILE_NAME(current_function, @1);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
'(' task_port_decl_list ')' ';'
|
||||
block_item_decls_opt
|
||||
|
|
@ -2244,7 +2400,7 @@ module_item
|
|||
}
|
||||
}
|
||||
| K_generate K_begin ':' IDENTIFIER {
|
||||
pform_start_generate_nblock(@1, $4);
|
||||
pform_start_generate_nblock(@2, $4);
|
||||
} module_item_list_opt K_end K_endgenerate
|
||||
{ /* Detect and warn about anachronistic named begin/end use */
|
||||
if (generation_flag > GN_VER2001) {
|
||||
|
|
@ -2410,7 +2566,12 @@ net_type
|
|||
| K_supply1 { $$ = NetNet::SUPPLY1; }
|
||||
| K_wor { $$ = NetNet::WOR; }
|
||||
| K_trior { $$ = NetNet::TRIOR; }
|
||||
| K_wone { $$ = NetNet::WONE; }
|
||||
| K_wone { $$ = NetNet::UWIRE;
|
||||
cerr << @1.text << ":" << @1.first_line << ": warning: "
|
||||
"'wone' is deprecated, please use 'uwire' "
|
||||
"instead." << endl;
|
||||
}
|
||||
| K_uwire { $$ = NetNet::UWIRE; }
|
||||
;
|
||||
|
||||
var_type
|
||||
|
|
@ -3095,10 +3256,20 @@ specify_item
|
|||
}
|
||||
pform_module_specify_path(tmp);
|
||||
}
|
||||
| K_Sfullskew '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
delete $9;
|
||||
}
|
||||
| K_Shold '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Snochange '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
delete $9;
|
||||
}
|
||||
| K_Speriod '(' spec_reference_event ',' delay_value
|
||||
spec_notifier_opt ')' ';'
|
||||
{ delete $5;
|
||||
|
|
@ -3107,6 +3278,15 @@ specify_item
|
|||
',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Srecrem '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
delete $9;
|
||||
}
|
||||
| K_Sremoval '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Ssetup '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
|
|
@ -3116,10 +3296,13 @@ specify_item
|
|||
{ delete $7;
|
||||
delete $9;
|
||||
}
|
||||
| K_Srecrem '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
|
||||
| K_Sskew '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Stimeskew '(' spec_reference_event ',' spec_reference_event
|
||||
',' delay_value spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
delete $9;
|
||||
}
|
||||
| K_Swidth '(' spec_reference_event ',' delay_value ',' expression
|
||||
spec_notifier_opt ')' ';'
|
||||
|
|
@ -3129,6 +3312,18 @@ specify_item
|
|||
| K_Swidth '(' spec_reference_event ',' delay_value ')' ';'
|
||||
{ delete $5;
|
||||
}
|
||||
| K_pulsestyle_onevent specify_path_identifiers ';'
|
||||
{ delete $2;
|
||||
}
|
||||
| K_pulsestyle_ondetect specify_path_identifiers ';'
|
||||
{ delete $2;
|
||||
}
|
||||
| K_showcancelled specify_path_identifiers ';'
|
||||
{ delete $2;
|
||||
}
|
||||
| K_noshowcancelled specify_path_identifiers ';'
|
||||
{ delete $2;
|
||||
}
|
||||
;
|
||||
|
||||
specify_item_list
|
||||
|
|
@ -3338,15 +3533,22 @@ spec_notifier_opt
|
|||
;
|
||||
spec_notifier
|
||||
: ','
|
||||
{ }
|
||||
{ args_after_notifier = 0; }
|
||||
| ',' hierarchy_identifier
|
||||
{ delete $2; }
|
||||
{ args_after_notifier = 0; delete $2; }
|
||||
| spec_notifier ','
|
||||
{ }
|
||||
{ args_after_notifier += 1; }
|
||||
| spec_notifier ',' hierarchy_identifier
|
||||
{ delete $3; }
|
||||
{ args_after_notifier += 1;
|
||||
if (args_after_notifier >= 3) {
|
||||
cerr << @3 << ": warning: timing checks are not supported "
|
||||
"and delayed signal \"" << *$3
|
||||
<< "\" will not be driven." << endl;
|
||||
}
|
||||
delete $3; }
|
||||
/* How do we match this path? */
|
||||
| IDENTIFIER
|
||||
{ delete[]$1; }
|
||||
{ args_after_notifier = 0; delete[]$1; }
|
||||
;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __parse_api_H
|
||||
#define __parse_api_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -46,4 +46,9 @@ extern int pform_parse(const char*path, FILE*file =0);
|
|||
|
||||
extern string vl_file;
|
||||
|
||||
extern void pform_set_timescale(int units, int prec, const char*file,
|
||||
unsigned lineno);
|
||||
extern int def_ts_units;
|
||||
extern int def_ts_prec;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __parse_misc_H
|
||||
#define __parse_misc_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -60,9 +60,15 @@ extern void VLerror(const YYLTYPE&loc, const char*msg);
|
|||
#define yywarn VLwarn
|
||||
extern void VLwarn(const YYLTYPE&loc, const char*msg);
|
||||
|
||||
extern void destroy_lexor();
|
||||
|
||||
extern ostream& operator << (ostream&, const YYLTYPE&loc);
|
||||
|
||||
extern unsigned error_count, warn_count;
|
||||
extern unsigned long based_size;
|
||||
|
||||
extern bool in_celldefine;
|
||||
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
|
||||
extern UCDriveType uc_drive;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
195
pform.cc
195
pform.cc
|
|
@ -70,11 +70,11 @@ static NetNet::Type pform_default_nettype = NetNet::WIRE;
|
|||
* These variables track the current time scale, as well as where the
|
||||
* timescale was set. This supports warnings about tangled timescales.
|
||||
*/
|
||||
static int pform_time_unit = 0;
|
||||
static int pform_time_prec = 0;
|
||||
static int pform_time_unit;
|
||||
static int pform_time_prec;
|
||||
|
||||
static char*pform_timescale_file = 0;
|
||||
static unsigned pform_timescale_line = 0;
|
||||
static unsigned pform_timescale_line;
|
||||
|
||||
static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno)
|
||||
{
|
||||
|
|
@ -103,7 +103,7 @@ void pform_pop_scope()
|
|||
}
|
||||
}
|
||||
|
||||
PTask* pform_push_task_scope(char*name, bool is_auto)
|
||||
PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
|
||||
{
|
||||
perm_string task_name = lex_strings.make(name);
|
||||
|
||||
|
|
@ -111,11 +111,30 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
|
|||
if (pform_cur_generate) {
|
||||
task = new PTask(task_name, pform_cur_generate->lexical_scope,
|
||||
is_auto);
|
||||
FILE_NAME(task, loc);
|
||||
// Check if the task is already in the dictionary.
|
||||
if (pform_cur_generate->tasks.find(task->pscope_name()) !=
|
||||
pform_cur_generate->tasks.end()) {
|
||||
cerr << task->get_fileline() << ": error: duplicate "
|
||||
"definition for task '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "' (generate)."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
}
|
||||
pform_cur_generate->tasks[task->pscope_name()] = task;
|
||||
pform_cur_generate->lexical_scope = task;
|
||||
} else {
|
||||
task = new PTask(task_name, lexical_scope,
|
||||
is_auto);
|
||||
FILE_NAME(task, loc);
|
||||
// Check if the task is already in the dictionary.
|
||||
if (pform_cur_module->tasks.find(task->pscope_name()) !=
|
||||
pform_cur_module->tasks.end()) {
|
||||
cerr << task->get_fileline() << ": error: duplicate "
|
||||
"definition for task '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
pform_cur_module->tasks[task->pscope_name()] = task;
|
||||
lexical_scope = task;
|
||||
}
|
||||
|
|
@ -123,7 +142,8 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
|
|||
return task;
|
||||
}
|
||||
|
||||
PFunction* pform_push_function_scope(char*name, bool is_auto)
|
||||
PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
|
||||
bool is_auto)
|
||||
{
|
||||
perm_string func_name = lex_strings.make(name);
|
||||
|
||||
|
|
@ -131,11 +151,30 @@ PFunction* pform_push_function_scope(char*name, bool is_auto)
|
|||
if (pform_cur_generate) {
|
||||
func = new PFunction(func_name, pform_cur_generate->lexical_scope,
|
||||
is_auto);
|
||||
FILE_NAME(func, loc);
|
||||
// Check if the function is already in the dictionary.
|
||||
if (pform_cur_generate->funcs.find(func->pscope_name()) !=
|
||||
pform_cur_generate->funcs.end()) {
|
||||
cerr << func->get_fileline() << ": error: duplicate "
|
||||
"definition for function '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "' (generate)."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
}
|
||||
pform_cur_generate->funcs[func->pscope_name()] = func;
|
||||
pform_cur_generate->lexical_scope = func;
|
||||
} else {
|
||||
func = new PFunction(func_name, lexical_scope,
|
||||
is_auto);
|
||||
FILE_NAME(func, loc);
|
||||
// Check if the function is already in the dictionary.
|
||||
if (pform_cur_module->funcs.find(func->pscope_name()) !=
|
||||
pform_cur_module->funcs.end()) {
|
||||
cerr << func->get_fileline() << ": error: duplicate "
|
||||
"definition for function '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
pform_cur_module->funcs[func->pscope_name()] = func;
|
||||
lexical_scope = func;
|
||||
}
|
||||
|
|
@ -259,10 +298,25 @@ void pform_set_timescale(int unit, int prec,
|
|||
first_flag = false;
|
||||
}
|
||||
|
||||
pform_timescale_file = strdup(file);
|
||||
if (file) pform_timescale_file = strdup(file);
|
||||
else pform_timescale_file = 0;
|
||||
pform_timescale_line = lineno;
|
||||
|
||||
if (warn_timescale && first_flag && (pform_modules.size() > 0)) {
|
||||
if (!warn_timescale || !first_flag || !file) return;
|
||||
|
||||
/* Look to see if we have any modules without a timescale. */
|
||||
bool have_no_ts = false;
|
||||
map<perm_string,Module*>::iterator mod;
|
||||
for (mod = pform_modules.begin(); mod != pform_modules.end(); mod++) {
|
||||
const Module*mp = (*mod).second;
|
||||
if (mp->time_from_timescale ||
|
||||
mp->timescale_warn_done) continue;
|
||||
have_no_ts = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we do then print a message for the new ones. */
|
||||
if (have_no_ts) {
|
||||
cerr << file << ":" << lineno << ": warning: "
|
||||
<< "Some modules have no timescale. This may cause"
|
||||
<< endl;
|
||||
|
|
@ -273,7 +327,10 @@ void pform_set_timescale(int unit, int prec,
|
|||
map<perm_string,Module*>::iterator mod;
|
||||
for (mod = pform_modules.begin()
|
||||
; mod != pform_modules.end() ; mod++) {
|
||||
const Module*mp = (*mod).second;
|
||||
Module*mp = (*mod).second;
|
||||
if (mp->time_from_timescale ||
|
||||
mp->timescale_warn_done) continue;
|
||||
mp->timescale_warn_done = true;
|
||||
|
||||
cerr << file << ":" << lineno << ": : "
|
||||
<< " -- module " << (*mod).first
|
||||
|
|
@ -342,6 +399,9 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno,
|
|||
pform_cur_module = new Module(lex_name);
|
||||
pform_cur_module->time_unit = pform_time_unit;
|
||||
pform_cur_module->time_precision = pform_time_prec;
|
||||
/* If we have a timescale file then the time information is from
|
||||
* a timescale directive. */
|
||||
pform_cur_module->time_from_timescale = pform_timescale_file != 0;
|
||||
pform_cur_module->default_nettype = pform_default_nettype;
|
||||
|
||||
FILE_NAME(pform_cur_module, file, lineno);
|
||||
|
|
@ -407,11 +467,14 @@ void pform_module_set_ports(vector<Module::port_t*>*ports)
|
|||
}
|
||||
}
|
||||
|
||||
void pform_endmodule(const char*name)
|
||||
void pform_endmodule(const char*name, bool in_celldefine,
|
||||
Module::UCDriveType uc_drive)
|
||||
{
|
||||
assert(pform_cur_module);
|
||||
perm_string mod_name = pform_cur_module->mod_name();
|
||||
assert(strcmp(name, mod_name) == 0);
|
||||
pform_cur_module->is_cell = in_celldefine;
|
||||
pform_cur_module->uc_drive = uc_drive;
|
||||
|
||||
map<perm_string,Module*>::const_iterator test =
|
||||
pform_modules.find(mod_name);
|
||||
|
|
@ -434,13 +497,31 @@ void pform_endmodule(const char*name)
|
|||
pform_cur_module = 0;
|
||||
}
|
||||
|
||||
static void pform_add_genvar(const struct vlltype&li, const perm_string&name,
|
||||
map<perm_string,LineInfo*>&genvars)
|
||||
{
|
||||
LineInfo*lni = new LineInfo();
|
||||
FILE_NAME(lni, li);
|
||||
if (genvars.find(name) != genvars.end()) {
|
||||
cerr << lni->get_fileline() << ": error: genvar '"
|
||||
<< name << "' has already been declared." << endl;
|
||||
cerr << genvars[name]->get_fileline()
|
||||
<< ": the previous declaration is here." << endl;
|
||||
error_count += 1;
|
||||
delete lni;
|
||||
} else {
|
||||
genvars[name] = lni;
|
||||
}
|
||||
}
|
||||
|
||||
void pform_genvars(const struct vlltype&li, list<perm_string>*names)
|
||||
{
|
||||
list<perm_string>::const_iterator cur;
|
||||
for (cur = names->begin(); cur != names->end() ; *cur++) {
|
||||
LineInfo*lni = new LineInfo();
|
||||
FILE_NAME(lni, li);
|
||||
pform_cur_module->genvars[*cur] = lni;
|
||||
if (pform_cur_generate)
|
||||
pform_add_genvar(li, *cur, pform_cur_generate->genvars);
|
||||
else
|
||||
pform_add_genvar(li, *cur, pform_cur_module->genvars);
|
||||
}
|
||||
|
||||
delete names;
|
||||
|
|
@ -455,7 +536,6 @@ void pform_start_generate_for(const struct vlltype&li,
|
|||
|
||||
FILE_NAME(gen, li);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
gen->parent = pform_cur_generate;
|
||||
pform_cur_generate = gen;
|
||||
|
||||
|
|
@ -476,7 +556,6 @@ void pform_start_generate_if(const struct vlltype&li, PExpr*test)
|
|||
|
||||
FILE_NAME(gen, li);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
gen->parent = pform_cur_generate;
|
||||
pform_cur_generate = gen;
|
||||
|
||||
|
|
@ -499,7 +578,6 @@ void pform_start_generate_else(const struct vlltype&li)
|
|||
|
||||
FILE_NAME(gen, li);
|
||||
|
||||
// For now, assume that generates do not nest.
|
||||
gen->parent = pform_cur_generate;
|
||||
pform_cur_generate = gen;
|
||||
|
||||
|
|
@ -1028,13 +1106,13 @@ static void pform_set_net_range(perm_string name,
|
|||
if (range == 0) {
|
||||
/* This is the special case that we really mean a
|
||||
scalar. Set a fake range. */
|
||||
cur->set_range(0, 0, rt);
|
||||
cur->set_range(0, 0, rt, true);
|
||||
|
||||
} else {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1], rt);
|
||||
cur->set_range((*range)[0], (*range)[1], rt, false);
|
||||
}
|
||||
cur->set_signed(signed_flag);
|
||||
|
||||
|
|
@ -1068,9 +1146,21 @@ void pform_set_net_range(list<perm_string>*names,
|
|||
*/
|
||||
static void pform_make_event(perm_string name, const char*fn, unsigned ln)
|
||||
{
|
||||
LexicalScope*scope = pform_get_cur_scope();
|
||||
|
||||
// Check if the named event is already in the dictionary.
|
||||
if (scope->events.find(name) != scope->events.end()) {
|
||||
LineInfo tloc;
|
||||
FILE_NAME(&tloc, fn, ln);
|
||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
||||
"for named event '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
PEvent*event = new PEvent(name);
|
||||
FILE_NAME(event, fn, ln);
|
||||
pform_get_cur_scope()->events[name] = event;
|
||||
scope->events[name] = event;
|
||||
}
|
||||
|
||||
void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln)
|
||||
|
|
@ -1396,14 +1486,16 @@ void pform_module_define_port(const struct vlltype&li,
|
|||
|
||||
if (range == 0) {
|
||||
cur->set_range(0, 0, (type == NetNet::IMPLICIT) ? SR_PORT :
|
||||
SR_BOTH);
|
||||
SR_BOTH,
|
||||
true);
|
||||
|
||||
} else {
|
||||
assert(range->count() == 2);
|
||||
assert((*range)[0]);
|
||||
assert((*range)[1]);
|
||||
cur->set_range((*range)[0], (*range)[1],
|
||||
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
|
||||
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH,
|
||||
false);
|
||||
}
|
||||
|
||||
if (attr) {
|
||||
|
|
@ -1483,7 +1575,7 @@ void pform_makewire(const vlltype&li, perm_string name,
|
|||
<< " to " << dt << "." << endl;
|
||||
}
|
||||
ivl_assert(*cur, flag);
|
||||
cur->set_range(0, 0, SR_NET);
|
||||
cur->set_range(0, 0, SR_NET, true);
|
||||
cur->set_signed(true);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1673,7 +1765,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
|||
|
||||
/* If there is a range involved, it needs to be set. */
|
||||
if (range)
|
||||
curw->set_range((*range)[0], (*range)[1], SR_PORT);
|
||||
curw->set_range((*range)[0], (*range)[1], SR_PORT, false);
|
||||
|
||||
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
|
||||
|
||||
|
|
@ -1763,13 +1855,32 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
bool signed_flag, svector<PExpr*>*range, PExpr*expr,
|
||||
LexicalScope::range_t*value_range)
|
||||
{
|
||||
if (pform_get_cur_scope() == pform_cur_generate) {
|
||||
LexicalScope*scope = pform_get_cur_scope();
|
||||
if (scope == pform_cur_generate) {
|
||||
VLerror("parameter declarations are not permitted in generate blocks");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the parameter name is already in the dictionary.
|
||||
if (scope->parameters.find(name) != scope->parameters.end()) {
|
||||
LineInfo tloc;
|
||||
FILE_NAME(&tloc, loc);
|
||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
||||
"for parameter '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
if (scope->localparams.find(name) != scope->localparams.end()) {
|
||||
LineInfo tloc;
|
||||
FILE_NAME(&tloc, loc);
|
||||
cerr << tloc.get_fileline() << ": error: localparam and "
|
||||
"parameter in '" << pform_cur_module->mod_name()
|
||||
<< "' have the same name '" << name << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
assert(expr);
|
||||
Module::param_expr_t&parm = pform_get_cur_scope()->parameters[name];
|
||||
Module::param_expr_t&parm = scope->parameters[name];
|
||||
FILE_NAME(&parm, loc);
|
||||
|
||||
parm.expr = expr;
|
||||
|
|
@ -1788,7 +1899,7 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
parm.signed_flag = signed_flag;
|
||||
parm.range = value_range;
|
||||
|
||||
if (pform_get_cur_scope() == pform_cur_module)
|
||||
if (scope == pform_cur_module)
|
||||
pform_cur_module->param_names.push_back(name);
|
||||
}
|
||||
|
||||
|
|
@ -1796,6 +1907,26 @@ void pform_set_localparam(const struct vlltype&loc,
|
|||
perm_string name, ivl_variable_type_t type,
|
||||
bool signed_flag, svector<PExpr*>*range, PExpr*expr)
|
||||
{
|
||||
LexicalScope*scope = pform_get_cur_scope();
|
||||
|
||||
// Check if the localparam name is already in the dictionary.
|
||||
if (scope->localparams.find(name) != scope->localparams.end()) {
|
||||
LineInfo tloc;
|
||||
FILE_NAME(&tloc, loc);
|
||||
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
||||
"for localparam '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
if (scope->parameters.find(name) != scope->parameters.end()) {
|
||||
LineInfo tloc;
|
||||
FILE_NAME(&tloc, loc);
|
||||
cerr << tloc.get_fileline() << ": error: parameter and "
|
||||
"localparam in '" << pform_cur_module->mod_name()
|
||||
<< "' have the same name '" << name << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
assert(expr);
|
||||
Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name];
|
||||
FILE_NAME(&parm, loc);
|
||||
|
|
@ -1819,6 +1950,15 @@ void pform_set_localparam(const struct vlltype&loc,
|
|||
|
||||
void pform_set_specparam(perm_string name, PExpr*expr)
|
||||
{
|
||||
// Check if the specparam name is already in the dictionary.
|
||||
if (pform_cur_module->specparams.find(name) !=
|
||||
pform_cur_module->specparams.end()) {
|
||||
cerr << expr->get_fileline() << ": error: duplicate definition "
|
||||
"for specparam '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
assert(expr);
|
||||
pform_cur_module->specparams[name] = expr;
|
||||
}
|
||||
|
|
@ -1933,7 +2073,7 @@ static void pform_set_reg_integer(perm_string name)
|
|||
|
||||
cur->set_range(new PENumber(new verinum(integer_width-1, integer_width)),
|
||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
||||
SR_NET);
|
||||
SR_NET, false);
|
||||
cur->set_signed(true);
|
||||
}
|
||||
|
||||
|
|
@ -1964,7 +2104,7 @@ static void pform_set_reg_time(perm_string name)
|
|||
|
||||
cur->set_range(new PENumber(new verinum(TIME_WIDTH-1, integer_width)),
|
||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
||||
SR_NET);
|
||||
SR_NET, false);
|
||||
}
|
||||
|
||||
void pform_set_reg_time(list<perm_string>*names)
|
||||
|
|
@ -2045,6 +2185,7 @@ int pform_parse(const char*path, FILE*file)
|
|||
error_count += 1;
|
||||
}
|
||||
|
||||
destroy_lexor();
|
||||
return error_count;
|
||||
}
|
||||
|
||||
|
|
|
|||
13
pform.h
13
pform.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __pform_H
|
||||
#define __pform_H
|
||||
/*
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -159,7 +159,8 @@ extern void pform_module_define_port(const struct vlltype&li,
|
|||
extern Module::port_t* pform_module_port_reference(perm_string name,
|
||||
const char*file,
|
||||
unsigned lineno);
|
||||
extern void pform_endmodule(const char*);
|
||||
extern void pform_endmodule(const char*, bool in_celldefine,
|
||||
Module::UCDriveType uc_drive);
|
||||
|
||||
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
|
||||
svector<PWire*>*decl, list<string>*table,
|
||||
|
|
@ -180,8 +181,10 @@ extern void pform_make_udp(perm_string name,
|
|||
*/
|
||||
extern void pform_pop_scope();
|
||||
|
||||
extern PTask*pform_push_task_scope(char*name, bool is_auto);
|
||||
extern PFunction*pform_push_function_scope(char*name, bool is_auto);
|
||||
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||
bool is_auto);
|
||||
extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name,
|
||||
bool is_auto);
|
||||
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
||||
|
||||
extern void pform_put_behavior_in_scope(AProcess*proc);
|
||||
|
|
@ -191,7 +194,7 @@ extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
|||
|
||||
/*
|
||||
* This function takes the list of names as new genvars to declare in
|
||||
* the current module scope.
|
||||
* the current module or generate scope.
|
||||
*/
|
||||
extern void pform_genvars(const struct vlltype&li, list<perm_string>*names);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -410,6 +410,8 @@ void PDelays::dump_delays(ostream&out) const
|
|||
if (delay_[0] && delay_[1] && delay_[2])
|
||||
out << "#(" << *delay_[0] << "," << *delay_[1] << "," <<
|
||||
*delay_[2] << ")";
|
||||
else if (delay_[0] && delay_[1])
|
||||
out << "#(" << *delay_[0] << "," << *delay_[1] << ")";
|
||||
else if (delay_[0])
|
||||
out << "#" << *delay_[0];
|
||||
else
|
||||
|
|
@ -1032,6 +1034,12 @@ void PGenerate::dump(ostream&out, unsigned indent) const
|
|||
(*idx)->dump(out, indent+2);
|
||||
}
|
||||
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_iter_t;
|
||||
for (genvar_iter_t cur = genvars.begin()
|
||||
; cur != genvars.end() ; cur++) {
|
||||
out << setw(indent+2) << "" << "genvar " << ((*cur).first) << ";" << endl;
|
||||
}
|
||||
|
||||
for (list<PGenerate*>::const_iterator idx = generate_schemes.begin()
|
||||
; idx != generate_schemes.end() ; idx++) {
|
||||
(*idx)->dump(out, indent+2);
|
||||
|
|
@ -1147,7 +1155,9 @@ void Module::dump(ostream&out) const
|
|||
out << " *) ";
|
||||
}
|
||||
|
||||
out << "module " << mod_name() << ";" << endl;
|
||||
out << "module " << mod_name() << ";";
|
||||
if (is_cell) out << " // Is in `celldefine.";
|
||||
out << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
|
||||
port_t*cur = ports[idx];
|
||||
|
|
|
|||
|
|
@ -10,4 +10,6 @@
|
|||
|
||||
echo "Building version_tag.h with git describe"
|
||||
tmp=`git describe | sed -e 's;\(.*\);#define VERSION_TAG "\1";'`
|
||||
echo "$tmp" > version_tag.h
|
||||
echo "#ifndef VERSION_TAG" > version_tag.h
|
||||
echo "$tmp" >> version_tag.h
|
||||
echo "#endif" >> version_tag.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script makes a release from a git repository. The input is
|
||||
# the number for a snapshot and the path to a temporary directory.
|
||||
# for example:
|
||||
#
|
||||
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
|
||||
#
|
||||
# The above assumes that there is a tag "v0_9_1" at the point
|
||||
# to be released. (The tag has the "v", but the argument to this
|
||||
# script does not have the "v"). This script extracts based on the
|
||||
# tag, uses the temporary directory to stage intermediate results,
|
||||
# and finally creates a file called verilog-0.9.1.tar.gz that
|
||||
# contains the release ready to go.
|
||||
#
|
||||
# The complete steps to make a release x.y.z generally are:
|
||||
#
|
||||
# (Edit version_base.h and verilog.spec to reflect the version)
|
||||
#
|
||||
# git tag -a v0_9_1
|
||||
# (Make the tag in the local git repository.)
|
||||
#
|
||||
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
|
||||
# (Make the snapshot bundle verilog-0.9.1.tar.gz)
|
||||
#
|
||||
# git push --tags
|
||||
# (Publish the tag to the repository.)
|
||||
#
|
||||
id=$1
|
||||
destdir=$2
|
||||
|
||||
# The git tag to use.
|
||||
tag="v"`echo $id | tr '.' '_'`
|
||||
|
||||
# The prefix is the directory that contains the extracted files
|
||||
# of the bundle. This is also the name of the bundle file itself.
|
||||
prefix="verilog-$id"
|
||||
|
||||
if [ ! -d $destdir ]; then
|
||||
echo "ERROR: Directory $destdir does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -e $destdir/$prefix ]; then
|
||||
echo "ERROR: $destdir/$prefix already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Exporting $tag to $destdir/$prefix..."
|
||||
git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - )
|
||||
|
||||
versionh="$destdir/$prefix/version_tag.h"
|
||||
echo "Create $versionh ..."
|
||||
echo "#ifndef VERSION_TAG" > $versionh
|
||||
echo "#define VERSION_TAG \"$tag\"" >> $versionh
|
||||
echo "#endif" >> $versionh
|
||||
|
||||
echo "Running autoconf.sh..."
|
||||
( cd $destdir/$prefix && sh autoconf.sh )
|
||||
|
||||
echo "Making bundle $prefix.tar.gz..."
|
||||
tar czf $prefix.tar.gz --exclude=autom4te.cache -C "$destdir" $prefix
|
||||
|
||||
echo "Removing temporary $destdir/$prefix..."
|
||||
rm -rf "$destdir/$prefix"
|
||||
|
||||
echo done
|
||||
|
|
@ -47,9 +47,11 @@ fi
|
|||
echo "Exporting $tag to $destdir/$prefix..."
|
||||
git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - )
|
||||
|
||||
versionh="$destdir/$prefix/version.h"
|
||||
versionh="$destdir/$prefix/version_tag.h"
|
||||
echo "Create $versionh ..."
|
||||
echo "#define VERSION_TAG \"$tag\"" > $versionh
|
||||
echo "#ifndef VERSION_TAG" > $versionh
|
||||
echo "#define VERSION_TAG \"$tag\"" >> $versionh
|
||||
echo "#endif" >> $versionh
|
||||
|
||||
echo "Running autoconf.sh..."
|
||||
( cd $destdir/$prefix && sh autoconf.sh )
|
||||
|
|
|
|||
38
set_width.cc
38
set_width.cc
|
|
@ -106,6 +106,18 @@ bool NetEBAdd::set_width(unsigned w, bool)
|
|||
return wid == w;
|
||||
}
|
||||
|
||||
void NetEBAdd::cast_signed(bool sign_flag)
|
||||
{
|
||||
if (has_sign() == sign_flag)
|
||||
return;
|
||||
|
||||
if (sign_flag == false) {
|
||||
left_->cast_signed(sign_flag);
|
||||
right_->cast_signed(sign_flag);
|
||||
}
|
||||
cast_signed_base_(sign_flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* The bitwise logical operators have operands the same size as the
|
||||
* result. Anything else is a mess. I first try to get the operands to
|
||||
|
|
@ -168,6 +180,19 @@ bool NetEBDiv::set_width(unsigned w, bool)
|
|||
return w == expr_width();
|
||||
}
|
||||
|
||||
void NetEBDiv::cast_signed(bool sign_flag)
|
||||
{
|
||||
if (has_sign() == sign_flag)
|
||||
return;
|
||||
|
||||
if (sign_flag == false) {
|
||||
left_->cast_signed(sign_flag);
|
||||
right_->cast_signed(sign_flag);
|
||||
}
|
||||
|
||||
cast_signed_base_(sign_flag);
|
||||
}
|
||||
|
||||
bool NetEBLogic::set_width(unsigned w, bool)
|
||||
{
|
||||
bool flag;
|
||||
|
|
@ -192,6 +217,19 @@ bool NetEBMult::set_width(unsigned w, bool)
|
|||
return true;
|
||||
}
|
||||
|
||||
void NetEBMult::cast_signed(bool sign_flag)
|
||||
{
|
||||
if (has_sign() == sign_flag)
|
||||
return;
|
||||
|
||||
if (sign_flag == false) {
|
||||
left_->cast_signed(sign_flag);
|
||||
right_->cast_signed(sign_flag);
|
||||
}
|
||||
|
||||
cast_signed_base_(sign_flag);
|
||||
}
|
||||
|
||||
bool NetEBPow::set_width(unsigned w, bool last_chance)
|
||||
{
|
||||
return w == expr_width();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
# $Id: README-solaris_pkg.txt,v 1.3 2007/02/26 19:49:49 steve Exp $
|
||||
|
||||
Notes about the solaris package.
|
||||
|
||||
I. Installing a prebuilt solaris package
|
||||
|
|
|
|||
14
sys_funcs.cc
14
sys_funcs.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2004-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -46,6 +46,16 @@ struct sfunc_return_type_cell : sfunc_return_type {
|
|||
|
||||
static struct sfunc_return_type_cell*sfunc_stack = 0;
|
||||
|
||||
void cleanup_sys_func_table()
|
||||
{
|
||||
struct sfunc_return_type_cell *next, *cur = sfunc_stack;
|
||||
while (cur) {
|
||||
next = cur->next;
|
||||
delete cur;
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
const struct sfunc_return_type* lookup_sys_func(const char*name)
|
||||
{
|
||||
/* First, try to find then name in the function stack. */
|
||||
|
|
@ -186,7 +196,7 @@ int load_sys_func_table(const char*path)
|
|||
fprintf(stderr, "%s:%s: Unknown type: %s\n",
|
||||
path, name, stype);
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
23
t-dll-api.cc
23
t-dll-api.cc
|
|
@ -545,6 +545,8 @@ extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net)
|
||||
|
|
@ -1268,6 +1270,8 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
|
|||
return net->u_.ufunc.ports - 1;
|
||||
case IVL_LPM_REPEAT:
|
||||
return net->u_.repeat.count;
|
||||
case IVL_LPM_CONCAT:
|
||||
return net->u_.concat.inputs;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -1655,6 +1659,12 @@ extern "C" unsigned ivl_scope_is_auto(ivl_scope_t net)
|
|||
return net->is_auto;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_scope_is_cell(ivl_scope_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->is_cell;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_scope_lineno(ivl_scope_t net)
|
||||
{
|
||||
assert(net);
|
||||
|
|
@ -1893,10 +1903,17 @@ extern "C" const char* ivl_signal_name(ivl_signal_t net)
|
|||
extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word)
|
||||
{
|
||||
assert(word < net->array_words);
|
||||
if (net->array_words > 1)
|
||||
return net->pins[word];
|
||||
else
|
||||
if (net->array_words > 1) {
|
||||
if (net->pins) {
|
||||
return net->pins[word];
|
||||
} else {
|
||||
// net->pins can be NULL for a virtualized reg array.
|
||||
assert(net->type_ == IVL_SIT_REG);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return net->pin;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ivl_signal_msb(ivl_signal_t net)
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ void dll_target::expr_concat(const NetEConcat*net)
|
|||
cur->type_ = IVL_EX_CONCAT;
|
||||
cur->value_ = IVL_VT_VECTOR;
|
||||
cur->width_ = net->expr_width();
|
||||
cur->signed_ = 0;
|
||||
cur->signed_ = net->has_sign() ? 1 : 0;
|
||||
|
||||
cur->u_.concat_.rept = net->repeat();
|
||||
cur->u_.concat_.parms = net->nparms();
|
||||
|
|
@ -308,6 +308,7 @@ void dll_target::expr_event(const NetEEvent*net)
|
|||
assert(expr_);
|
||||
|
||||
expr_->type_ = IVL_EX_EVENT;
|
||||
FILE_NAME(expr_, net);
|
||||
expr_->value_= IVL_VT_VOID;
|
||||
|
||||
/* Locate the event by name. Save the ivl_event_t in the
|
||||
|
|
@ -351,6 +352,7 @@ void dll_target::expr_select(const NetESelect*net)
|
|||
|
||||
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
|
||||
assert(expr_);
|
||||
FILE_NAME(expr_, net);
|
||||
|
||||
expr_->type_ = IVL_EX_SELECT;
|
||||
expr_->value_= IVL_VT_VECTOR;
|
||||
|
|
@ -450,10 +452,10 @@ void dll_target::expr_signal(const NetESignal*net)
|
|||
|
||||
/* Make account for the special case that this is a reference
|
||||
to an array as a whole. We detect this case by noting that
|
||||
this is an array (more than 1 word) and there is no word
|
||||
select expression. In that case, this is an IVL_EX_ARRAY
|
||||
expression instead of a SIGNAL expression. */
|
||||
if (sig->array_words > 1 && word_expr == 0) {
|
||||
this is an array (more than 0 array dimensions) and that
|
||||
there is no word select expression. For this case, we have
|
||||
an IVL_EX_ARRAY expression instead of a SIGNAL expression. */
|
||||
if (sig->array_dimensions_ > 0 && word_expr == 0) {
|
||||
expr_->type_ = IVL_EX_ARRAY;
|
||||
expr_->width_ = 0; // Doesn't make much sense for arrays.
|
||||
}
|
||||
|
|
|
|||
28
t-dll.cc
28
t-dll.cc
|
|
@ -46,7 +46,6 @@ inline ivl_dll_t ivl_dlopen(const char *name)
|
|||
|
||||
inline void * ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
{
|
||||
FARPROC sym;
|
||||
return (void*)GetProcAddress((HMODULE)dll, nm);
|
||||
}
|
||||
|
||||
|
|
@ -2147,13 +2146,18 @@ bool dll_target::part_select(const NetPartSelect*net)
|
|||
obj->type = IVL_LPM_PART_PV;
|
||||
break;
|
||||
}
|
||||
FILE_NAME(obj, net);
|
||||
obj->name = net->name(); // NetPartSelect names are permallocated.
|
||||
assert(net->scope());
|
||||
obj->scope = find_scope(des_, net->scope());
|
||||
assert(obj->scope);
|
||||
|
||||
/* Part selects are always unsigned. */
|
||||
obj->u_.part.signed_flag = 0;
|
||||
/* Part selects are always unsigned, so we use this to indicate
|
||||
* if the part select base signal is signed or not. */
|
||||
if (net->signed_flag())
|
||||
obj->u_.part.signed_flag = 1;
|
||||
else
|
||||
obj->u_.part.signed_flag = 0;
|
||||
|
||||
/* Choose the width of the part select. */
|
||||
obj->width = net->width();
|
||||
|
|
@ -2389,6 +2393,7 @@ void dll_target::scope(const NetScope*net)
|
|||
scop->nattr = net->attr_cnt();
|
||||
scop->attr = fill_in_attributes(net);
|
||||
scop->is_auto = net->is_auto();
|
||||
scop->is_cell = net->is_cell();
|
||||
|
||||
switch (net->type()) {
|
||||
case NetScope::MODULE:
|
||||
|
|
@ -2510,6 +2515,10 @@ void dll_target::signal(const NetNet*net)
|
|||
assert(0);
|
||||
break;
|
||||
|
||||
case NetNet::UWIRE:
|
||||
cerr << net->get_fileline()
|
||||
<< ": warning: uwire is not currently supported, converting "
|
||||
"it to a wire!" << endl;
|
||||
case NetNet::TRI:
|
||||
case NetNet::WIRE:
|
||||
case NetNet::IMPLICIT:
|
||||
|
|
@ -2560,12 +2569,22 @@ void dll_target::signal(const NetNet*net)
|
|||
obj->array_base = net->array_first();
|
||||
obj->array_words = net->array_count();
|
||||
obj->array_addr_swapped = net->array_addr_swapped() ? 1 : 0;
|
||||
|
||||
assert(obj->array_words == net->pin_count());
|
||||
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
|
||||
"t-dll creating nexus array " << obj->array_words << " long" << endl;
|
||||
if (obj->array_words > 1 && net->pins_are_virtual()) {
|
||||
obj->pins = NULL;
|
||||
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
|
||||
"t-dll used NULL for big nexus array" << endl;
|
||||
return;
|
||||
}
|
||||
if (obj->array_words > 1)
|
||||
obj->pins = new ivl_nexus_t[obj->array_words];
|
||||
|
||||
for (unsigned idx = 0 ; idx < obj->array_words ; idx += 1) {
|
||||
|
||||
const Nexus*nex = net->pin(idx).nexus();
|
||||
const Nexus*nex = net->pins_are_virtual() ? 0 : net->pin(idx).nexus();
|
||||
if (nex == 0) {
|
||||
// Special case: This pin is connected to
|
||||
// nothing. This can happen, for example, if the
|
||||
|
|
@ -2597,6 +2616,7 @@ void dll_target::signal(const NetNet*net)
|
|||
obj->pin = tmp;
|
||||
}
|
||||
}
|
||||
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: t-dll done with big nexus array" << endl;
|
||||
}
|
||||
|
||||
bool dll_target::signal_paths(const NetNet*net)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue