mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4100f20a69 | ||
|
|
bedf946fb2 | ||
|
|
b9e67157c6 | ||
|
|
b30b2a183b | ||
|
|
9ab3bcdde3 | ||
|
|
5df3bbe188 | ||
|
|
8cf12416c0 | ||
|
|
b7c2c83c88 | ||
|
|
3b6da93331 | ||
|
|
b4642d3fd4 | ||
|
|
88a2b0b911 | ||
|
|
954e127f1d | ||
|
|
7654add5e5 | ||
|
|
85a37ea53f | ||
|
|
b337acebcc | ||
|
|
fb9ca54c95 | ||
|
|
1a15d41523 | ||
|
|
e378cc5791 | ||
|
|
748c189c79 | ||
|
|
b89be6c4b9 | ||
|
|
df207807b6 | ||
|
|
1f2b40cff1 | ||
|
|
734400fd37 | ||
|
|
f19979d928 | ||
|
|
19be7a53da | ||
|
|
e56af34fb0 | ||
|
|
7737aa20e8 | ||
|
|
ead046201c | ||
|
|
0aa7c3f659 | ||
|
|
4aa7222022 | ||
|
|
86e3c78776 | ||
|
|
40076287ea | ||
|
|
ca81db8edf | ||
|
|
ae68a80e98 | ||
|
|
beb7c58375 | ||
|
|
e080b9d565 | ||
|
|
ca2db37039 | ||
|
|
194825f78e | ||
|
|
55bd765ea0 | ||
|
|
b03d61e2cf | ||
|
|
6fc0e5167b | ||
|
|
0065be011f | ||
|
|
3f7cbce58c | ||
|
|
246b62e322 | ||
|
|
7c2fdd1ee9 | ||
|
|
f77aa2623c | ||
|
|
20847a3ff5 | ||
|
|
eb6d42acf9 | ||
|
|
094d676a8b | ||
|
|
71306ceb1d | ||
|
|
8bbfc7fc22 | ||
|
|
19baba12b1 | ||
|
|
15b8819136 | ||
|
|
3fae8ade05 | ||
|
|
f9bbf31d65 | ||
|
|
df1da3dda9 | ||
|
|
c83f2a4abd | ||
|
|
ad53833040 | ||
|
|
bc8c85668a | ||
|
|
d12a3dde45 | ||
|
|
301c878c0f | ||
|
|
bd55bfa071 | ||
|
|
6d2f09b579 | ||
|
|
4bfea7f54d | ||
|
|
55906486d8 | ||
|
|
d5478e6e08 | ||
|
|
d88d85c172 | ||
|
|
59c3c536c7 | ||
|
|
a007458cb8 | ||
|
|
d051912f21 | ||
|
|
a547158a50 | ||
|
|
95f2351aa0 | ||
|
|
698aaffb0b | ||
|
|
73eccecbf8 | ||
|
|
ae4a261463 | ||
|
|
c9f0d0cec2 | ||
|
|
4fa1e45d45 | ||
|
|
1b3d252bfe | ||
|
|
a9ba4a9fcd | ||
|
|
7f49619875 | ||
|
|
696660639a | ||
|
|
da4323062d | ||
|
|
a901e171b2 | ||
|
|
6e41d532fe | ||
|
|
4fc78ffb58 | ||
|
|
8137f41fc3 | ||
|
|
2e9471797d | ||
|
|
344248cea0 | ||
|
|
2789e3dba5 | ||
|
|
cca759a41e | ||
|
|
4f7b3d8882 | ||
|
|
2b330b78b7 | ||
|
|
d47ca1912b | ||
|
|
3fd2108b10 | ||
|
|
96e2a407f4 | ||
|
|
cdf18c96f4 | ||
|
|
53acaa05b8 | ||
|
|
fb85679068 | ||
|
|
9558e14479 | ||
|
|
4af0af93bf | ||
|
|
df4bc950fe | ||
|
|
250394f72b | ||
|
|
ca83fd6dc1 | ||
|
|
d5e9e7cd2b | ||
|
|
9a96f621ef | ||
|
|
5d7ce096c6 | ||
|
|
c9f8109c06 | ||
|
|
a20b4f2864 | ||
|
|
44a19d2a0a | ||
|
|
02f3beb8db | ||
|
|
3269cc3d90 | ||
|
|
fb70a1f4ab | ||
|
|
df0aa483ce | ||
|
|
c83f12a55c | ||
|
|
9704f59566 | ||
|
|
2923893d34 | ||
|
|
890dab0742 | ||
|
|
607e26b041 | ||
|
|
ea75290f65 | ||
|
|
a176054118 | ||
|
|
9a697dc5f5 | ||
|
|
cfdb852843 | ||
|
|
2e67a91982 | ||
|
|
074ca9330d | ||
|
|
f0d7cdcb20 | ||
|
|
40d961e059 | ||
|
|
e5de759236 | ||
|
|
e26a75c59d | ||
|
|
8701145b40 | ||
|
|
a2558886c8 | ||
|
|
f818ee86ae | ||
|
|
ad0dbdaa9c | ||
|
|
a9f14b294f | ||
|
|
a435ae98f9 | ||
|
|
481b261458 | ||
|
|
48df52d743 | ||
|
|
0af0d3b171 | ||
|
|
8287cf35e7 | ||
|
|
fab7924cc2 | ||
|
|
0ab739e8b1 | ||
|
|
2dcd4d171b | ||
|
|
e7f4d18c3d | ||
|
|
1611362c22 | ||
|
|
2327698160 | ||
|
|
71c1f00ec2 | ||
|
|
6574a126ef | ||
|
|
1e68086355 | ||
|
|
326cc8fd67 | ||
|
|
4afcb421bd | ||
|
|
8d21917035 | ||
|
|
4ca7f8834c | ||
|
|
b43299c8da | ||
|
|
b763809f5e | ||
|
|
2cb97f7475 | ||
|
|
6283df7491 | ||
|
|
acc4490370 | ||
|
|
f85c1a995a | ||
|
|
809e5fda8a | ||
|
|
dce245da5a | ||
|
|
d261c4cd27 | ||
|
|
c33299d542 | ||
|
|
ebdf8a5f3c | ||
|
|
c8852d183f | ||
|
|
9f161b20ef | ||
|
|
40f9d64973 | ||
|
|
4a2e68a0fd | ||
|
|
bcd90d3401 | ||
|
|
114af7d33f | ||
|
|
7b83d2de49 | ||
|
|
850de5913d | ||
|
|
bb9ee46f40 | ||
|
|
e94fc1305b | ||
|
|
3e4e8feb29 | ||
|
|
fedf347b1a | ||
|
|
285277a50b | ||
|
|
323c96f42f | ||
|
|
7dee344ea9 | ||
|
|
65bce588e4 | ||
|
|
233ff1b744 | ||
|
|
0837e39787 | ||
|
|
86db565a21 | ||
|
|
d6ac5e5001 | ||
|
|
e6443f1981 | ||
|
|
d13e6c73db | ||
|
|
79ca7f3cb5 | ||
|
|
cfd07ccd34 | ||
|
|
48047d523a | ||
|
|
eeb8fc2626 |
@@ -24,6 +24,8 @@ src/Makefile_obj$
|
|||||||
include/verilated.mk$
|
include/verilated.mk$
|
||||||
config.cache$
|
config.cache$
|
||||||
config.status$
|
config.status$
|
||||||
|
verilator.log
|
||||||
|
verilator.tex
|
||||||
verilator_bin.*
|
verilator_bin.*
|
||||||
.vcsmx_rebuild$
|
.vcsmx_rebuild$
|
||||||
autom4te\.cache/
|
autom4te\.cache/
|
||||||
|
|||||||
+38
-21
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
# redistribute it and/or modify it under the terms of either the GNU
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -88,7 +88,10 @@ pkgdatadir = @pkgdatadir@
|
|||||||
datarootdir = @datarootdir@
|
datarootdir = @datarootdir@
|
||||||
|
|
||||||
# Compile options
|
# Compile options
|
||||||
|
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||||
|
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||||
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
|
|
||||||
#### End of system configuration section. ####
|
#### End of system configuration section. ####
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -101,8 +104,6 @@ INFOS = README internals.txt verilator.txt verilator.html verilator.1 verilator.
|
|||||||
|
|
||||||
# Files that can be generated, but should be up to date for a distribution.
|
# Files that can be generated, but should be up to date for a distribution.
|
||||||
DISTDEP = info Makefile
|
DISTDEP = info Makefile
|
||||||
# Files to distribute.
|
|
||||||
DISTBIN = $(wildcard bin/verilator-*)
|
|
||||||
|
|
||||||
DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||||
*.in *.ac \
|
*.in *.ac \
|
||||||
@@ -120,6 +121,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
|||||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||||
test_verilated/vgen*.pl \
|
test_verilated/vgen*.pl \
|
||||||
|
test_regress/t/tsub/*.v* \
|
||||||
test_regress/t/*.cpp \
|
test_regress/t/*.cpp \
|
||||||
test_regress/t/*.h \
|
test_regress/t/*.h \
|
||||||
test_regress/t/*.dat \
|
test_regress/t/*.dat \
|
||||||
@@ -128,7 +130,6 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
|||||||
test_regress/t/*.pl \
|
test_regress/t/*.pl \
|
||||||
test_regress/t/*.pf \
|
test_regress/t/*.pf \
|
||||||
test_regress/t/*.v* \
|
test_regress/t/*.v* \
|
||||||
verilator.* \
|
|
||||||
|
|
||||||
INST_PROJ_FILES = \
|
INST_PROJ_FILES = \
|
||||||
bin/verilator \
|
bin/verilator \
|
||||||
@@ -170,7 +171,7 @@ msg_test:
|
|||||||
@echo
|
@echo
|
||||||
|
|
||||||
.PHONY:test
|
.PHONY:test
|
||||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
|
||||||
test: test_vcs test_c test_sc test_sp test_verilated test_regress
|
test: test_vcs test_c test_sc test_sp test_verilated test_regress
|
||||||
else
|
else
|
||||||
test: test_c test_sc test_sp
|
test: test_c test_sc test_sp
|
||||||
@@ -202,17 +203,18 @@ test_regress: all_nomsg
|
|||||||
info: $(INFOS)
|
info: $(INFOS)
|
||||||
|
|
||||||
# Use --no-split to avoid creating filenames > 14 chars.
|
# Use --no-split to avoid creating filenames > 14 chars.
|
||||||
verilator.1: bin/verilator
|
verilator.1: ${srcdir}/bin/verilator
|
||||||
pod2man $< $@
|
pod2man $< $@
|
||||||
|
|
||||||
verilator.txt: bin/verilator
|
verilator.txt: ${srcdir}/bin/verilator
|
||||||
$(POD2TEXT) $< $@
|
$(POD2TEXT) $< $@
|
||||||
|
|
||||||
verilator.html: bin/verilator
|
verilator.html: ${srcdir}/bin/verilator
|
||||||
pod2html $< >$@
|
pod2html $< >$@
|
||||||
|
|
||||||
verilator.pdf: bin/verilator $(DISTCONFIG)
|
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||||
pod2latex --full --out verilator.tex bin/verilator
|
verilator.pdf: ${srcdir}/bin/verilator Makefile
|
||||||
|
pod2latex --full --out verilator.tex ${srcdir}/bin/verilator
|
||||||
cat < verilator.tex \
|
cat < verilator.tex \
|
||||||
| sed 's/\\begin{document}/\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geometry}\n\\begin{document}/' \
|
| sed 's/\\begin{document}/\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geometry}\n\\begin{document}/' \
|
||||||
| sed 's/\\begin{document}/\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n\\begin{document}/' \
|
| sed 's/\\begin{document}/\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n\\begin{document}/' \
|
||||||
@@ -256,7 +258,7 @@ VL_INST_DATA_SRCDIR_FILES = \
|
|||||||
test_v/*.[chv]* \
|
test_v/*.[chv]* \
|
||||||
test_c/*.[chv]* test_c/Makefile test_c/Makefile_obj \
|
test_c/*.[chv]* test_c/Makefile test_c/Makefile_obj \
|
||||||
test_sc/*.[chv]* test_sc/Makefile test_sc/Makefile_obj \
|
test_sc/*.[chv]* test_sc/Makefile test_sc/Makefile_obj \
|
||||||
test_sp/*.[chv]* test_sp/Makefile test_sp/Makefile_obj \
|
test_sp/Makefile test_sp/Makefile_obj \
|
||||||
|
|
||||||
installbin:
|
installbin:
|
||||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
|
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
|
||||||
@@ -267,9 +269,11 @@ installbin:
|
|||||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
|
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
|
||||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
|
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
|
||||||
|
|
||||||
|
# Man files can either be part of the original kit, or built in current directory
|
||||||
|
# So important we use $< so VPATH is searched
|
||||||
installman: $(VL_INST_MAN_FILES)
|
installman: $(VL_INST_MAN_FILES)
|
||||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||||
for p in $(VL_INST_MAN_FILES) ; do \
|
for p in $< ; do \
|
||||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -314,6 +318,8 @@ install: all_nomsg installbin installman installdata install-msg
|
|||||||
install-here: installman ftp
|
install-here: installman ftp
|
||||||
|
|
||||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||||
|
DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h)
|
||||||
|
|
||||||
DIRPROJECT := $(shell project_dir --project)
|
DIRPROJECT := $(shell project_dir --project)
|
||||||
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
|
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
|
||||||
INST_PROJ_CVS = cp_if_cvs_diff
|
INST_PROJ_CVS = cp_if_cvs_diff
|
||||||
@@ -322,7 +328,7 @@ install-project: dist
|
|||||||
@echo "Install-project to $(DIRPROJECT)"
|
@echo "Install-project to $(DIRPROJECT)"
|
||||||
strip verilator_bin*
|
strip verilator_bin*
|
||||||
$(MAKE) install-project-quick
|
$(MAKE) install-project-quick
|
||||||
for p in verilator.1 ; do \
|
for p in $(VL_INST_MAN_FILES) ; do \
|
||||||
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
||||||
done
|
done
|
||||||
$(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
$(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
||||||
@@ -346,7 +352,7 @@ install-cadtools: dist
|
|||||||
strip verilator_bin*
|
strip verilator_bin*
|
||||||
$(MAKE) install-cadtools-quick
|
$(MAKE) install-cadtools-quick
|
||||||
$(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1
|
$(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1
|
||||||
for p in verilator.1 ; do \
|
for p in $(VL_INST_MAN_FILES) ; do \
|
||||||
$(INSTALL_DATA) $$p $(VERILATOR_CAD_DIR)/man/man1/$$p; \
|
$(INSTALL_DATA) $$p $(VERILATOR_CAD_DIR)/man/man1/$$p; \
|
||||||
done
|
done
|
||||||
$(INST_PROJ_CVS) $(DISTNAME).tgz $(VERILATOR_CAD_DIR)/verilator.tgz
|
$(INST_PROJ_CVS) $(DISTNAME).tgz $(VERILATOR_CAD_DIR)/verilator.tgz
|
||||||
@@ -370,6 +376,15 @@ endif
|
|||||||
# VERILATOR_AUTHOR_SITE
|
# VERILATOR_AUTHOR_SITE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CPPCHECK = cppcheck
|
||||||
|
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject
|
||||||
|
CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp)
|
||||||
|
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
|
||||||
|
|
||||||
|
cppcheck: $(CPPCHECK_DEP)
|
||||||
|
%.cppcheck: %.cpp
|
||||||
|
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -I$(srcdir)/include -I$(srcdir)/src $<
|
||||||
|
|
||||||
ftp: info
|
ftp: info
|
||||||
|
|
||||||
install-msg:
|
install-msg:
|
||||||
@@ -390,8 +405,13 @@ Makefile: Makefile.in config.status $(IN_WILD)
|
|||||||
src/Makefile: src/Makefile.in Makefile
|
src/Makefile: src/Makefile.in Makefile
|
||||||
config.status: configure
|
config.status: configure
|
||||||
./config.status --recheck
|
./config.status --recheck
|
||||||
|
|
||||||
configure: configure.ac
|
configure: configure.ac
|
||||||
|
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||||
|
autoconf --warnings=all
|
||||||
|
else
|
||||||
autoconf
|
autoconf
|
||||||
|
endif
|
||||||
|
|
||||||
maintainer-clean::
|
maintainer-clean::
|
||||||
@echo "This command is intended for maintainers to use;"
|
@echo "This command is intended for maintainers to use;"
|
||||||
@@ -432,15 +452,12 @@ dist-file-list:
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Distributions
|
# Distributions
|
||||||
|
|
||||||
DISTCONFIG = ${srcdir}/src/config_build.h.in
|
DISTTITLE := Verilator $(word 1,$(PACKAGE_VERSION))
|
||||||
|
DISTNAME := verilator-$(word 1,$(PACKAGE_VERSION))
|
||||||
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
|
DISTDATEPRE := $(word 2,$(PACKAGE_VERSION))
|
||||||
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
|
DISTDATE := $(subst /,-,$(DISTDATEPRE))
|
||||||
DISTDATEPRE := $(shell sed -e '/DTVERSION/!d' -e 's/.*\([1-2][0-9][0-9][0-9].[0-9]*[0-9].[0-9]*[0-9]\).*/\1/' -e q $(DISTCONFIG))
|
|
||||||
DISTNAMEREV := $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q src/config_rev.h)
|
|
||||||
|
|
||||||
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
|
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
|
||||||
DISTDATE := $(subst /,-,$(DISTDATEPRE))
|
|
||||||
|
|
||||||
tag:
|
tag:
|
||||||
svnorcvs tag $(DISTTAGNAME)
|
svnorcvs tag $(DISTTAGNAME)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// DESCRIPTION: Verilator: List of To Do issues.
|
// DESCRIPTION: Verilator: List of To Do issues.
|
||||||
//
|
//
|
||||||
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -62,11 +62,15 @@ Usability:
|
|||||||
* Print version/etc message at runtime. (4.000?)
|
* Print version/etc message at runtime. (4.000?)
|
||||||
Include number of lines of code, percent comments, code complexity measurement
|
Include number of lines of code, percent comments, code complexity measurement
|
||||||
<-80chars------------------------------------------------------------------->
|
<-80chars------------------------------------------------------------------->
|
||||||
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2010.
|
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2011.
|
||||||
Verilated #### modules, #### instances, ##### sigs,
|
Verilated #### modules, #### instances, ##### sigs,
|
||||||
#### non-comment lines, ##### ops, ### KB model size
|
#### non-comment lines, ##### ops, ### KB model size
|
||||||
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
|
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
|
||||||
|
|
||||||
|
Lint:
|
||||||
|
* CDCRSTLOGIC should allow filtering with paths
|
||||||
|
"waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR"
|
||||||
|
|
||||||
Internal Code:
|
Internal Code:
|
||||||
* Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
|
* Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
|
||||||
and removing it will speed up and simplify all the other code.
|
and removing it will speed up and simplify all the other code.
|
||||||
|
|||||||
+494
-119
File diff suppressed because it is too large
Load Diff
@@ -99,7 +99,7 @@ sub filter {
|
|||||||
next if $line =~ / This=/;
|
next if $line =~ / This=/;
|
||||||
$line =~ s/0x[a-f0-9]+/0x/g;
|
$line =~ s/0x[a-f0-9]+/0x/g;
|
||||||
$line =~ s/<e[0-9]+\#?>/<e>/g;
|
$line =~ s/<e[0-9]+\#?>/<e>/g;
|
||||||
$line =~ s/{\d+}/{}/g if !$Opt_Lineno;
|
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
|
||||||
print $f2 $line;
|
print $f2 $line;
|
||||||
}
|
}
|
||||||
$f1->close;
|
$f1->close;
|
||||||
@@ -109,7 +109,7 @@ sub filter {
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval => 2);
|
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ Do not show differences in line numbering.
|
|||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/verilator>.
|
The latest version is available from L<http://www.veripool.org/verilator>.
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. This package is free software; you can
|
Copyright 2005-2011 by Wilson Snyder. This package is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
|||||||
if 0;
|
if 0;
|
||||||
# DESCRIPTION: Print include statements for each ARGV
|
# DESCRIPTION: Print include statements for each ARGV
|
||||||
#
|
#
|
||||||
# Copyright 2003-2010 by Wilson Snyder. This package is free software; you can
|
# Copyright 2003-2011 by Wilson Snyder. This package is free software; you can
|
||||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ profcfunc($Opt_File);
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval => 2);
|
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/>.
|
The latest version is available from L<http://www.veripool.org/>.
|
||||||
|
|
||||||
Copyright 2007-2010 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2007-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
+100
-31
@@ -1,35 +1,83 @@
|
|||||||
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
|
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||||
dnl
|
#
|
||||||
dnl Copyright 2003-2010 by Wilson Snyder. Verilator is free software; you can
|
# Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
dnl redistribute it and/or modify it under the terms of either the GNU Lesser
|
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
dnl General Public License Version 3 or the Perl Artistic License Version 2.0.
|
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
AC_INIT(src/Verilator.cpp)
|
AC_INIT([Verilator],[3.830])
|
||||||
AC_CONFIG_HEADER(src/config_build.h)
|
AC_CONFIG_HEADER(src/config_build.h)
|
||||||
|
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
||||||
|
|
||||||
dnl Special Substitutions
|
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||||
AC_ARG_ENABLE(defenv,
|
|
||||||
[AS_HELP_STRING([--disable-defenv], [disable hardcoded default environment variables])],
|
# Special Substitutions - CFG_WITH_DEFENV
|
||||||
CFG_WITH_DEFENV=$enableval,
|
AC_MSG_CHECKING(whether to disable hardcoded paths)
|
||||||
CFG_WITH_DEFENV=yes)
|
AC_ARG_ENABLE([defenv],
|
||||||
|
[AS_HELP_STRING([--disable-defenv],
|
||||||
|
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) CFG_WITH_DEFENV=yes ;;
|
||||||
|
no) CFG_WITH_DEFENV=no ;;
|
||||||
|
*) AC_MSG_ERROR([bad value ${enableval} for --disable-defenv]) ;;
|
||||||
|
esac],
|
||||||
|
CFG_WITH_DEFENV=yes)
|
||||||
AC_SUBST(CFG_WITH_DEFENV)
|
AC_SUBST(CFG_WITH_DEFENV)
|
||||||
|
AC_MSG_RESULT($CFG_WITH_DEFENV)
|
||||||
|
|
||||||
dnl Compiler flags
|
# Special Substitutions - CFG_WITH_CCWARN
|
||||||
|
AC_MSG_CHECKING(whether to show and stop on compilation warnings)
|
||||||
|
AC_ARG_ENABLE([ccwarn],
|
||||||
|
[AS_HELP_STRING([--enable-ccwarn],
|
||||||
|
[enable showing and stopping on compilation warnings])],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) CFG_WITH_CCWARN=yes ;;
|
||||||
|
no) CFG_WITH_CCWARN=no ;;
|
||||||
|
*) AC_MSG_ERROR([bad value ${enableval} for --enable-ccwarn]) ;;
|
||||||
|
esac],
|
||||||
|
[case "x${VERILATOR_AUTHOR_SITE}" in
|
||||||
|
x) CFG_WITH_CCWARN=no ;;
|
||||||
|
*) CFG_WITH_CCWARN=yes ;;
|
||||||
|
esac]
|
||||||
|
)
|
||||||
|
AC_SUBST(CFG_WITH_CCWARN)
|
||||||
|
AC_MSG_RESULT($CFG_WITH_CCWARN)
|
||||||
|
|
||||||
|
# Special Substitutions - CFG_WITH_LONGTESTS
|
||||||
|
AC_MSG_CHECKING(whether to run long tests)
|
||||||
|
AC_ARG_ENABLE([longtests],
|
||||||
|
[AS_HELP_STRING([--enable-longtests],
|
||||||
|
[enable running long developer tests])],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) CFG_WITH_LONGTESTS=yes ;;
|
||||||
|
no) CFG_WITH_LONGTESTS=no ;;
|
||||||
|
*) AC_MSG_ERROR([bad value ${enableval} for --enable-longtests]) ;;
|
||||||
|
esac],
|
||||||
|
[case "x${VERILATOR_AUTHOR_SITE}" in
|
||||||
|
x) CFG_WITH_LONGTESTS=no ;;
|
||||||
|
*) CFG_WITH_LONGTESTS=yes ;;
|
||||||
|
esac]
|
||||||
|
)
|
||||||
|
AC_SUBST(CFG_WITH_LONGTESTS)
|
||||||
|
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
CFLAGS=-I${includedir}
|
CFLAGS=-I${includedir}
|
||||||
CPPFLAGS=-I${includedir}
|
CPPFLAGS=-I${includedir}
|
||||||
CXXFLAGS=-I${includedir}
|
CXXFLAGS=-I${includedir}
|
||||||
LDFLAGS=-L${libdir}
|
LDFLAGS=-L${libdir}
|
||||||
|
|
||||||
dnl Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
AC_MSG_CHECKING([that C++ compiler can compile simple program])
|
AC_MSG_CHECKING([that C++ compiler can compile simple program])
|
||||||
AC_TRY_RUN([int main() { return 0; }],
|
AC_RUN_IFELSE(
|
||||||
|
[AC_LANG_SOURCE([int main() { return 0; }])],
|
||||||
AC_MSG_RESULT(yes),
|
AC_MSG_RESULT(yes),
|
||||||
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]))
|
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
|
||||||
|
AC_MSG_RESULT(yes))
|
||||||
|
|
||||||
AC_PATH_PROG(PERL,perl)
|
AC_PATH_PROG(PERL,perl)
|
||||||
if test "x$PERL" = "x" ; then
|
if test "x$PERL" = "x" ; then
|
||||||
@@ -44,33 +92,54 @@ if test "x$YACC" = "x" ; then
|
|||||||
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
|
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
dnl Checks for header files.
|
# Checks for typedefs, structures
|
||||||
AC_HEADER_STDC
|
|
||||||
AC_HEADER_SYS_WAIT
|
|
||||||
AC_CHECK_HEADERS(fcntl.h unistd.h inttypes.h sys/file.h sys/time.h sys/un.h math.h stdint.h mingw/stdint.h)
|
|
||||||
|
|
||||||
dnl Checks for typedefs, structures
|
|
||||||
AC_CHECK_TYPE(size_t,unsigned int)
|
AC_CHECK_TYPE(size_t,unsigned int)
|
||||||
AC_CHECK_TYPE(uint_t,unsigned int)
|
|
||||||
AC_CHECK_TYPE(ulong_t,unsigned long)
|
|
||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
AC_STRUCT_TM
|
|
||||||
|
|
||||||
dnl Checks for compiler characteristics.
|
# Checks for compiler characteristics.
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
|
||||||
dnl Checks for library functions.
|
AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||||
|
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
|
||||||
|
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||||
|
# -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
|
||||||
|
CXXFLAGS="$CXXFLAGS $1 -Werror"
|
||||||
|
AC_MSG_CHECKING([whether $CXX accepts $1])
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([],[])],
|
||||||
|
[_my_result=yes],
|
||||||
|
[_my_result=no])
|
||||||
|
AC_MSG_RESULT($_my_result)
|
||||||
|
if test "$_my_result" = "yes" ; then
|
||||||
|
CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED $1"
|
||||||
|
fi
|
||||||
|
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||||
|
])# _MY_CXX_CHECK_OPT
|
||||||
|
|
||||||
dnl Checks for system services
|
# For example, -Wno-div-by-zero isn't in 4.1.2
|
||||||
|
_MY_CXX_CHECK_OPT(-Wno-char-subscripts)
|
||||||
|
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
|
||||||
|
# without this flag, even though there's a conditional to prevent the divide.
|
||||||
|
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
||||||
|
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
||||||
|
_MY_CXX_CHECK_OPT(-Wno-sign-compare)
|
||||||
|
_MY_CXX_CHECK_OPT(-Wno-uninitialized)
|
||||||
|
_MY_CXX_CHECK_OPT(-Wno-unused-parameter)
|
||||||
|
_MY_CXX_CHECK_OPT(-Wno-unused-variable)
|
||||||
|
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||||
|
|
||||||
dnl Other install directories
|
# Checks for library functions.
|
||||||
|
|
||||||
|
# Checks for system services
|
||||||
|
|
||||||
|
# Other install directories
|
||||||
pkgdatadir=${datadir}/verilator
|
pkgdatadir=${datadir}/verilator
|
||||||
AC_SUBST(pkgdatadir)
|
AC_SUBST(pkgdatadir)
|
||||||
|
|
||||||
AC_OUTPUT(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
AC_OUTPUT
|
||||||
|
|
||||||
AC_MSG_RESULT([])
|
AC_MSG_RESULT([])
|
||||||
AC_MSG_RESULT([Now type 'gmake'])
|
AC_MSG_RESULT([Now type 'make' (or sometimes 'gmake') to build Verilator.])
|
||||||
AC_MSG_RESULT([])
|
AC_MSG_RESULT([])
|
||||||
|
|||||||
+79
-13
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -26,7 +26,6 @@
|
|||||||
#define _VERILATED_CPP_
|
#define _VERILATED_CPP_
|
||||||
#include "verilated_imp.h"
|
#include "verilated_imp.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
|
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
|
||||||
|
|
||||||
@@ -285,12 +284,15 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
|||||||
// Note also assumes variables < 64 are not wide, this assumption is
|
// Note also assumes variables < 64 are not wide, this assumption is
|
||||||
// sometimes not true in low-level routines written here in verilated.cpp
|
// sometimes not true in low-level routines written here in verilated.cpp
|
||||||
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
|
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
|
||||||
|
static VL_THREAD char tmpf[VL_VALUE_STRING_MAX_WIDTH];
|
||||||
|
const char* pctp = NULL; // Most recent %##.##g format
|
||||||
bool inPct = false;
|
bool inPct = false;
|
||||||
bool widthSet = false;
|
bool widthSet = false;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
const char* pos = formatp;
|
const char* pos = formatp;
|
||||||
for (; *pos; ++pos) {
|
for (; *pos; ++pos) {
|
||||||
if (!inPct && pos[0]=='%') {
|
if (!inPct && pos[0]=='%') {
|
||||||
|
pctp = pos;
|
||||||
inPct = true;
|
inPct = true;
|
||||||
widthSet = false;
|
widthSet = false;
|
||||||
width = 0;
|
width = 0;
|
||||||
@@ -312,6 +314,9 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
|||||||
widthSet = true;
|
widthSet = true;
|
||||||
width = width*10 + (fmt - '0');
|
width = width*10 + (fmt - '0');
|
||||||
break;
|
break;
|
||||||
|
case '.':
|
||||||
|
inPct = true; // Get more digits
|
||||||
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
output += '%';
|
output += '%';
|
||||||
break;
|
break;
|
||||||
@@ -325,6 +330,18 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
|||||||
output += cstrp;
|
output += cstrp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'e':
|
||||||
|
case 'f':
|
||||||
|
case 'g': {
|
||||||
|
const int lbits = va_arg(ap, int);
|
||||||
|
double d = va_arg(ap, double);
|
||||||
|
if (lbits) {} // UNUSED - always 64
|
||||||
|
strncpy(tmpf, pctp, pos-pctp+1);
|
||||||
|
tmpf[pos-pctp+1] = '\0';
|
||||||
|
sprintf(tmp, tmpf, d);
|
||||||
|
output += tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
// Deal with all read-and-print somethings
|
// Deal with all read-and-print somethings
|
||||||
const int lbits = va_arg(ap, int);
|
const int lbits = va_arg(ap, int);
|
||||||
@@ -358,14 +375,26 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
|||||||
case 'd': { // Signed decimal
|
case 'd': { // Signed decimal
|
||||||
int digits=sprintf(tmp,"%" VL_PRI64 "d",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld)));
|
int digits=sprintf(tmp,"%" VL_PRI64 "d",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld)));
|
||||||
int needmore = width-digits;
|
int needmore = width-digits;
|
||||||
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
|
if (needmore>0) {
|
||||||
|
if (pctp && pctp[0] && pctp[1]=='0') { //%0
|
||||||
|
output.append(needmore,'0'); // Pre-pad zero
|
||||||
|
} else {
|
||||||
|
output.append(needmore,' '); // Pre-pad spaces
|
||||||
|
}
|
||||||
|
}
|
||||||
output += tmp;
|
output += tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'u': { // Unsigned decimal
|
case 'u': { // Unsigned decimal
|
||||||
int digits=sprintf(tmp,"%" VL_PRI64 "u",ld);
|
int digits=sprintf(tmp,"%" VL_PRI64 "u",ld);
|
||||||
int needmore = width-digits;
|
int needmore = width-digits;
|
||||||
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
|
if (needmore>0) {
|
||||||
|
if (pctp && pctp[0] && pctp[1]=='0') { //%0
|
||||||
|
output.append(needmore,'0'); // Pre-pad zero
|
||||||
|
} else {
|
||||||
|
output.append(needmore,' '); // Pre-pad spaces
|
||||||
|
}
|
||||||
|
}
|
||||||
output += tmp;
|
output += tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -569,6 +598,17 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||||||
VL_SET_WQ(owp,ld);
|
VL_SET_WQ(owp,ld);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'f':
|
||||||
|
case 'e':
|
||||||
|
case 'g': { // Real number
|
||||||
|
_vl_vsss_skipspace(fp,floc,fromp);
|
||||||
|
_vl_vsss_read(fp,floc,fromp, tmp, "+-.0123456789eE");
|
||||||
|
if (!tmp[0]) goto done;
|
||||||
|
union { double r; vlsint64_t ld; } u;
|
||||||
|
u.r = strtod(tmp, NULL);
|
||||||
|
VL_SET_WQ(owp,u.ld);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 't': // FALLTHRU // Time
|
case 't': // FALLTHRU // Time
|
||||||
case 'u': { // Unsigned decimal
|
case 'u': { // Unsigned decimal
|
||||||
_vl_vsss_skipspace(fp,floc,fromp);
|
_vl_vsss_skipspace(fp,floc,fromp);
|
||||||
@@ -628,6 +668,10 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
// File I/O
|
// File I/O
|
||||||
|
|
||||||
|
FILE* VL_CVT_I_FP(IData lhs) {
|
||||||
|
return VerilatedImp::fdToFp(lhs);
|
||||||
|
}
|
||||||
|
|
||||||
void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
|
void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
|
||||||
// See also VL_DATA_TO_STRING_NW
|
// See also VL_DATA_TO_STRING_NW
|
||||||
int lsb=obits-1;
|
int lsb=obits-1;
|
||||||
@@ -655,8 +699,8 @@ void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
|
|||||||
for (; i<bytes; i++) { *op++ = 0; }
|
for (; i<bytes; i++) { *op++ = 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
IData VL_FGETS_IXQ(int obits, void* destp, QData fpq) {
|
IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
|
||||||
FILE* fp = VL_CVT_Q_FP(fpq);
|
FILE* fp = VL_CVT_I_FP(fpi);
|
||||||
if (VL_UNLIKELY(!fp)) return 0;
|
if (VL_UNLIKELY(!fp)) return 0;
|
||||||
|
|
||||||
// The string needs to be padded with 0's in unused spaces in front of
|
// The string needs to be padded with 0's in unused spaces in front of
|
||||||
@@ -683,16 +727,26 @@ IData VL_FGETS_IXQ(int obits, void* destp, QData fpq) {
|
|||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
|
||||||
QData VL_FOPEN_QI(QData filename, IData mode) {
|
IData VL_FOPEN_QI(QData filename, IData mode) {
|
||||||
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
||||||
return VL_FOPEN_WI(2, fnw, mode);
|
return VL_FOPEN_WI(2, fnw, mode);
|
||||||
}
|
}
|
||||||
QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
||||||
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||||
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
|
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
|
||||||
char modez[5];
|
char modez[5];
|
||||||
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
|
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
|
||||||
return VL_CVT_FP_Q(fopen(filenamez,modez));
|
return VL_FOPEN_S(filenamez,modez);
|
||||||
|
}
|
||||||
|
IData VL_FOPEN_S(const char* filenamep, const char* modep) {
|
||||||
|
return VerilatedImp::fdNew(fopen(filenamep,modep));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VL_FCLOSE_I(IData fdi) {
|
||||||
|
FILE* fp = VL_CVT_I_FP(fdi);
|
||||||
|
if (VL_UNLIKELY(!fp)) return;
|
||||||
|
fclose(fp);
|
||||||
|
VerilatedImp::fdDelete(fdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
|
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
|
||||||
@@ -726,8 +780,8 @@ void VL_WRITEF(const char* formatp, ...) {
|
|||||||
VL_PRINTF("%s", output.c_str());
|
VL_PRINTF("%s", output.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VL_FWRITEF(QData fpq, const char* formatp, ...) {
|
void VL_FWRITEF(IData fpi, const char* formatp, ...) {
|
||||||
FILE* fp = VL_CVT_Q_FP(fpq);
|
FILE* fp = VL_CVT_I_FP(fpi);
|
||||||
if (VL_UNLIKELY(!fp)) return;
|
if (VL_UNLIKELY(!fp)) return;
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -739,8 +793,8 @@ void VL_FWRITEF(QData fpq, const char* formatp, ...) {
|
|||||||
fputs(output.c_str(), fp);
|
fputs(output.c_str(), fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
IData VL_FSCANF_IX(QData fpq, const char* formatp, ...) {
|
IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) {
|
||||||
FILE* fp = VL_CVT_Q_FP(fpq);
|
FILE* fp = VL_CVT_I_FP(fpi);
|
||||||
if (VL_UNLIKELY(!fp)) return 0;
|
if (VL_UNLIKELY(!fp)) return 0;
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -883,6 +937,17 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IData VL_SYSTEM_IQ(QData lhs) {
|
||||||
|
IData lhsw[2]; VL_SET_WQ(lhsw, lhs);
|
||||||
|
return VL_SYSTEM_IW(2, lhsw);
|
||||||
|
}
|
||||||
|
IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
|
||||||
|
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||||
|
_VL_VINT_TO_STRING(lhswords*VL_WORDSIZE, filenamez, filenamep);
|
||||||
|
int code = system(filenamez);
|
||||||
|
return code >> 8; // Want exit status
|
||||||
|
}
|
||||||
|
|
||||||
IData VL_TESTPLUSARGS_I(const char* formatp) {
|
IData VL_TESTPLUSARGS_I(const char* formatp) {
|
||||||
string match = VerilatedImp::argPlusMatch(formatp);
|
string match = VerilatedImp::argPlusMatch(formatp);
|
||||||
if (match == "") return 0;
|
if (match == "") return 0;
|
||||||
@@ -1038,6 +1103,7 @@ VerilatedScope::VerilatedScope() {
|
|||||||
m_callbacksp = NULL;
|
m_callbacksp = NULL;
|
||||||
m_namep = NULL;
|
m_namep = NULL;
|
||||||
m_funcnumMax = 0;
|
m_funcnumMax = 0;
|
||||||
|
m_symsp = NULL;
|
||||||
m_varsp = NULL;
|
m_varsp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-30
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
// <iostream> avoided to reduce compile time
|
// <iostream> avoided to reduce compile time
|
||||||
// <string> avoided and instead in verilated_heavy.h to reduce compile time
|
// <string> avoided and instead in verilated_heavy.h to reduce compile time
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -321,11 +322,14 @@ extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a
|
|||||||
extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool is_modulus);
|
extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool is_modulus);
|
||||||
|
|
||||||
/// File I/O
|
/// File I/O
|
||||||
extern IData VL_FGETS_IXQ(int obits, void* destp, QData fpq);
|
extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi);
|
||||||
|
|
||||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
extern IData VL_FOPEN_S(const char* filenamep, const char* mode);
|
||||||
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||||
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
extern IData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||||
|
inline IData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||||
|
|
||||||
|
extern void VL_FCLOSE_I(IData fdi);
|
||||||
|
|
||||||
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||||
WDataInP ofilename, void* memp, IData start, IData end);
|
WDataInP ofilename, void* memp, IData start, IData end);
|
||||||
@@ -336,15 +340,19 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
|
|||||||
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
|
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
|
||||||
|
|
||||||
extern void VL_WRITEF(const char* formatp, ...);
|
extern void VL_WRITEF(const char* formatp, ...);
|
||||||
extern void VL_FWRITEF(QData fpq, const char* formatp, ...);
|
extern void VL_FWRITEF(IData fpi, const char* formatp, ...);
|
||||||
|
|
||||||
extern IData VL_FSCANF_IX(QData fpq, const char* formatp, ...);
|
extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...);
|
||||||
extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...);
|
extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...);
|
||||||
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...);
|
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...);
|
||||||
extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
|
extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
|
||||||
|
|
||||||
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...);
|
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...);
|
||||||
|
|
||||||
|
extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs);
|
||||||
|
extern IData VL_SYSTEM_IQ(QData lhs);
|
||||||
|
inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); }
|
||||||
|
|
||||||
extern IData VL_TESTPLUSARGS_I(const char* formatp);
|
extern IData VL_TESTPLUSARGS_I(const char* formatp);
|
||||||
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
|
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
|
||||||
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
||||||
@@ -364,15 +372,24 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
|||||||
#define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) ))
|
#define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) ))
|
||||||
#define _VL_SET_QII(ld,rd) ( ((QData)(ld)<<VL_ULL(32)) | (QData)(rd) )
|
#define _VL_SET_QII(ld,rd) ( ((QData)(ld)<<VL_ULL(32)) | (QData)(rd) )
|
||||||
|
|
||||||
|
/// Return FILE* from IData
|
||||||
|
extern FILE* VL_CVT_I_FP(IData lhs);
|
||||||
|
|
||||||
// Use a union to avoid cast-to-different-size warnings
|
// Use a union to avoid cast-to-different-size warnings
|
||||||
/// Return FILE* from QData
|
|
||||||
static inline FILE* VL_CVT_Q_FP(QData lhs) { union { FILE* fp; QData q; } u; u.q=lhs; return u.fp; }
|
|
||||||
/// Return void* from QData
|
/// Return void* from QData
|
||||||
static inline void* VL_CVT_Q_VP(QData lhs) { union { void* fp; QData q; } u; u.q=lhs; return u.fp; }
|
static inline void* VL_CVT_Q_VP(QData lhs) { union { void* fp; QData q; } u; u.q=lhs; return u.fp; }
|
||||||
/// Return QData from FILE*
|
|
||||||
static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q=0; u.fp=fp; return u.q; }
|
|
||||||
/// Return QData from void*
|
/// Return QData from void*
|
||||||
static inline QData VL_CVT_VP_Q(void* fp) { union { void* fp; QData q; } u; u.q=0; u.fp=fp; return u.q; }
|
static inline QData VL_CVT_VP_Q(void* fp) { union { void* fp; QData q; } u; u.q=0; u.fp=fp; return u.q; }
|
||||||
|
/// Return double from QData (bits, not numerically)
|
||||||
|
static inline double VL_CVT_D_Q(QData lhs) { union { double d; QData q; } u; u.q=lhs; return u.d; }
|
||||||
|
/// Return QData from double (bits, not numerically)
|
||||||
|
static inline QData VL_CVT_Q_D(double lhs) { union { double d; QData q; } u; u.d=lhs; return u.q; }
|
||||||
|
/// Return double from QData (numeric)
|
||||||
|
static inline double VL_ITOR_D_I(IData lhs) { return ((double)((vlsint32_t)(lhs))); }
|
||||||
|
/// Return QData from double (numeric)
|
||||||
|
static inline IData VL_RTOI_I_D(double lhs) { return ((vlsint32_t)(VL_TRUNC(lhs))); }
|
||||||
|
/// Return QData from double (numeric)
|
||||||
|
static inline IData VL_RTOIROUND_I_D(double lhs) { return ((vlsint32_t)(VL_ROUND(lhs))); }
|
||||||
|
|
||||||
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
|
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
|
||||||
// (Requires clean input)
|
// (Requires clean input)
|
||||||
@@ -391,6 +408,9 @@ void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp);
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Pli macros
|
// Pli macros
|
||||||
|
|
||||||
|
#ifndef VL_TIME_PRECISION
|
||||||
|
# define VL_TIME_PRECISION -12 ///< Timescale units only for for VPI return - picoseconds
|
||||||
|
#endif
|
||||||
#ifndef VL_TIME_MULTIPLIER
|
#ifndef VL_TIME_MULTIPLIER
|
||||||
# define VL_TIME_MULTIPLIER 1
|
# define VL_TIME_MULTIPLIER 1
|
||||||
#endif
|
#endif
|
||||||
@@ -399,9 +419,11 @@ void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp);
|
|||||||
#if defined(SYSTEMC_VERSION) && (SYSTEMC_VERSION>20011000)
|
#if defined(SYSTEMC_VERSION) && (SYSTEMC_VERSION>20011000)
|
||||||
# define VL_TIME_I() ((IData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
# define VL_TIME_I() ((IData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
||||||
# define VL_TIME_Q() ((QData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
# define VL_TIME_Q() ((QData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
||||||
|
# define VL_TIME_D() ((double)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
||||||
#else
|
#else
|
||||||
# define VL_TIME_I() ((IData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
# define VL_TIME_I() ((IData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
||||||
# define VL_TIME_Q() ((QData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
# define VL_TIME_Q() ((QData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
||||||
|
# define VL_TIME_D() ((double)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
||||||
extern double sc_time_stamp();
|
extern double sc_time_stamp();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -942,16 +964,13 @@ static inline WDataOutP VL_SUB_W(int words, WDataOutP owp,WDataInP lwp,WDataInP
|
|||||||
return(owp);
|
return(owp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround
|
// Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround,
|
||||||
#if 1 //defined(__GNUC__) && __GNUC__ < 3
|
// we can't just
|
||||||
static inline IData VL_UNARYMIN_I(IData data) { return -data; }
|
//# define VL_NEGATE_I(data) (-(data))
|
||||||
static inline QData VL_UNARYMIN_Q(QData data) { return -data; }
|
static inline IData VL_NEGATE_I(IData data) { return -data; }
|
||||||
#else
|
static inline QData VL_NEGATE_Q(QData data) { return -data; }
|
||||||
# define VL_UNARYMIN_I(IData data) (-(data))
|
|
||||||
# define VL_UNARYMIN_Q(QData data) (-(data))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline WDataOutP VL_UNARYMIN_W(int words, WDataOutP owp,WDataInP lwp){
|
static inline WDataOutP VL_NEGATE_W(int words, WDataOutP owp,WDataInP lwp){
|
||||||
QData carry = 0;
|
QData carry = 0;
|
||||||
for (int i=0; i<words; i++) {
|
for (int i=0; i<words; i++) {
|
||||||
carry = carry + (QData)(IData)(~lwp[i]);
|
carry = carry + (QData)(IData)(~lwp[i]);
|
||||||
@@ -998,18 +1017,18 @@ static inline WDataOutP VL_MULS_WWW(int,int lbits,int, WDataOutP owp,WDataInP lw
|
|||||||
IData lneg = VL_SIGN_I(lbits,lwp[words-1]);
|
IData lneg = VL_SIGN_I(lbits,lwp[words-1]);
|
||||||
if (lneg) { // Negate lhs
|
if (lneg) { // Negate lhs
|
||||||
lwusp = lwstore;
|
lwusp = lwstore;
|
||||||
VL_UNARYMIN_W(words, lwstore, lwp);
|
VL_NEGATE_W(words, lwstore, lwp);
|
||||||
lwstore[words-1] &= VL_MASK_I(lbits); // Clean it
|
lwstore[words-1] &= VL_MASK_I(lbits); // Clean it
|
||||||
}
|
}
|
||||||
IData rneg = VL_SIGN_I(lbits,rwp[words-1]);
|
IData rneg = VL_SIGN_I(lbits,rwp[words-1]);
|
||||||
if (rneg) { // Negate rhs
|
if (rneg) { // Negate rhs
|
||||||
rwusp = rwstore;
|
rwusp = rwstore;
|
||||||
VL_UNARYMIN_W(words, rwstore, rwp);
|
VL_NEGATE_W(words, rwstore, rwp);
|
||||||
rwstore[words-1] &= VL_MASK_I(lbits); // Clean it
|
rwstore[words-1] &= VL_MASK_I(lbits); // Clean it
|
||||||
}
|
}
|
||||||
VL_MUL_W(words,owp,lwusp,rwusp);
|
VL_MUL_W(words,owp,lwusp,rwusp);
|
||||||
owp[words-1] &= VL_MASK_I(lbits); // Clean. Note it's ok for the multiply to overflow into the sign bit
|
owp[words-1] &= VL_MASK_I(lbits); // Clean. Note it's ok for the multiply to overflow into the sign bit
|
||||||
if ((lneg ^ rneg) & 1) { // Negate output (not using UNARYMIN, as owp==lwp)
|
if ((lneg ^ rneg) & 1) { // Negate output (not using NEGATE, as owp==lwp)
|
||||||
QData carry = 0;
|
QData carry = 0;
|
||||||
for (int i=0; i<words; i++) {
|
for (int i=0; i<words; i++) {
|
||||||
carry = carry + (QData)(IData)(~owp[i]);
|
carry = carry + (QData)(IData)(~owp[i]);
|
||||||
@@ -1056,12 +1075,12 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp,WDataInP lwp,WDataI
|
|||||||
IData rwstore[VL_MULS_MAX_WORDS];
|
IData rwstore[VL_MULS_MAX_WORDS];
|
||||||
WDataInP ltup = lwp;
|
WDataInP ltup = lwp;
|
||||||
WDataInP rtup = rwp;
|
WDataInP rtup = rwp;
|
||||||
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_UNARYMIN_W(VL_WORDS_I(lbits), lwstore, lwp)); }
|
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp)); }
|
||||||
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_UNARYMIN_W(VL_WORDS_I(lbits), rwstore, rwp)); }
|
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp)); }
|
||||||
if ((lsign && !rsign) || (!lsign && rsign)) {
|
if ((lsign && !rsign) || (!lsign && rsign)) {
|
||||||
IData qNoSign[VL_MULS_MAX_WORDS];
|
IData qNoSign[VL_MULS_MAX_WORDS];
|
||||||
VL_DIV_WWW(lbits,qNoSign,ltup,rtup);
|
VL_DIV_WWW(lbits,qNoSign,ltup,rtup);
|
||||||
_VL_CLEAN_INPLACE_W(lbits, VL_UNARYMIN_W(VL_WORDS_I(lbits), owp, qNoSign));
|
_VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
|
||||||
return owp;
|
return owp;
|
||||||
} else {
|
} else {
|
||||||
return VL_DIV_WWW(lbits,owp,ltup,rtup);
|
return VL_DIV_WWW(lbits,owp,ltup,rtup);
|
||||||
@@ -1075,12 +1094,12 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp,WDataInP lwp,WDa
|
|||||||
IData rwstore[VL_MULS_MAX_WORDS];
|
IData rwstore[VL_MULS_MAX_WORDS];
|
||||||
WDataInP ltup = lwp;
|
WDataInP ltup = lwp;
|
||||||
WDataInP rtup = rwp;
|
WDataInP rtup = rwp;
|
||||||
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_UNARYMIN_W(VL_WORDS_I(lbits), lwstore, lwp)); }
|
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp)); }
|
||||||
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_UNARYMIN_W(VL_WORDS_I(lbits), rwstore, rwp)); }
|
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp)); }
|
||||||
if (lsign) { // Only dividend sign matters for modulus
|
if (lsign) { // Only dividend sign matters for modulus
|
||||||
IData qNoSign[VL_MULS_MAX_WORDS];
|
IData qNoSign[VL_MULS_MAX_WORDS];
|
||||||
VL_MODDIV_WWW(lbits,qNoSign,ltup,rtup);
|
VL_MODDIV_WWW(lbits,qNoSign,ltup,rtup);
|
||||||
_VL_CLEAN_INPLACE_W(lbits, VL_UNARYMIN_W(VL_WORDS_I(lbits), owp, qNoSign));
|
_VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
|
||||||
return owp;
|
return owp;
|
||||||
} else {
|
} else {
|
||||||
return VL_MODDIV_WWW(lbits,owp,ltup,rtup);
|
return VL_MODDIV_WWW(lbits,owp,ltup,rtup);
|
||||||
@@ -1633,6 +1652,6 @@ static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
|
|||||||
|
|
||||||
#undef _END
|
#undef _END
|
||||||
|
|
||||||
// Debugging
|
//======================================================================
|
||||||
|
|
||||||
#endif /*_VERILATED_H_*/
|
#endif /*_VERILATED_H_*/
|
||||||
|
|||||||
+13
-7
@@ -2,7 +2,7 @@
|
|||||||
######################################################################
|
######################################################################
|
||||||
# DESCRIPTION: Makefile commands for all verilated target files
|
# DESCRIPTION: Makefile commands for all verilated target files
|
||||||
#
|
#
|
||||||
# Copyright 2003-2010 by Wilson Snyder. Verilator is free software; you can
|
# Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -13,6 +13,12 @@ LINK = @CXX@
|
|||||||
AR = ar
|
AR = ar
|
||||||
RANLIB = ranlib
|
RANLIB = ranlib
|
||||||
|
|
||||||
|
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||||
|
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||||
|
|
||||||
|
# Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero
|
||||||
|
CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Programs
|
# Programs
|
||||||
|
|
||||||
@@ -38,13 +44,9 @@ VK_CPPFLAGS_ALWAYS += \
|
|||||||
-DVM_TRACE=$(VM_TRACE) \
|
-DVM_TRACE=$(VM_TRACE) \
|
||||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||||
|
|
||||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||||
VK_CPPFLAGS_WALL += -Wall \
|
VK_CPPFLAGS_WALL += -Wall \
|
||||||
-Wno-char-subscripts \
|
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||||
-Wno-sign-compare \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-Wno-unused-variable \
|
|
||||||
-Wno-uninitialized \
|
|
||||||
-Werror
|
-Werror
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -116,6 +118,10 @@ ifeq ($(VM_SP),1)
|
|||||||
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
|
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
|
||||||
--preproc $(VK_CLASSES_SP)
|
--preproc $(VK_CLASSES_SP)
|
||||||
else
|
else
|
||||||
|
ifeq ($(VM_COVERAGE),1)
|
||||||
|
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||||
|
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||||
|
endif
|
||||||
preproc:
|
preproc:
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
+3
-7
@@ -5,7 +5,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -27,11 +27,7 @@
|
|||||||
`define coverage_block_off
|
`define coverage_block_off
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// Hide file descriptor difference
|
// Hide file descriptor difference - deprecated - for older versions
|
||||||
`ifdef verilator
|
`define verilator_file_descriptor integer
|
||||||
`define verilator_file_descriptor reg [63:0]
|
|
||||||
`else
|
|
||||||
`define verilator_file_descriptor integer
|
|
||||||
`endif
|
|
||||||
|
|
||||||
`endif // guard
|
`endif // guard
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2009-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#define _VERILATED_DPI_CPP_
|
#define _VERILATED_DPI_CPP_
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
#include "verilated_dpi.h"
|
||||||
#include "verilated_imp.h"
|
#include "verilated_imp.h"
|
||||||
|
|
||||||
// On MSVC++ we need svdpi.h to declare exports, not imports
|
// On MSVC++ we need svdpi.h to declare exports, not imports
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
|
// Version 2.0.
|
||||||
|
//
|
||||||
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// \brief Verilator: Common include for all Verilated C files that use DPI
|
||||||
|
///
|
||||||
|
/// This file is included automatically by Verilator at the top of
|
||||||
|
/// all C++ files it generates where DPI is used. It contains
|
||||||
|
/// DPI interface functions required by the Verilated code.
|
||||||
|
///
|
||||||
|
/// Code available from: http://www.veripool.org/verilator
|
||||||
|
///
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _VERILATED_DPI_H_
|
||||||
|
#define _VERILATED_DPI_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
|
#include "verilated.h" // Presumed done by caller
|
||||||
|
#include "svdpi.h"
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// SETTING OPERATORS
|
||||||
|
|
||||||
|
/// Return svBitVecVal from WData
|
||||||
|
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) {
|
||||||
|
int words = VL_WORDS_I(obits);
|
||||||
|
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
|
||||||
|
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||||
|
}
|
||||||
|
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) {
|
||||||
|
int words = VL_WORDS_I(obits);
|
||||||
|
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
|
||||||
|
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||||
|
}
|
||||||
|
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, svLogicVecVal* lwp) {
|
||||||
|
// Note we ignore X/Z in svLogicVecVal
|
||||||
|
int words = VL_WORDS_I(obits);
|
||||||
|
for (int i=0; i<words-1; i++) owp[i]=lwp[i].aval;
|
||||||
|
owp[words-1] = lwp[words-1].aval & VL_MASK_I(obits);
|
||||||
|
}
|
||||||
|
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) {
|
||||||
|
// Note we don't create X/Z in svLogicVecVal
|
||||||
|
int words = VL_WORDS_I(obits);
|
||||||
|
for (int i=0; i<words; i++) owp[i].bval=0;
|
||||||
|
for (int i=0; i<words-1; i++) owp[i].aval=lwp[i];
|
||||||
|
owp[words-1].aval = lwp[words-1] & VL_MASK_I(obits);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#endif // _VERILATED_DPI_H_
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2010-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+40
-2
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2009-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class VerilatedScope;
|
class VerilatedScope;
|
||||||
@@ -62,9 +63,18 @@ class VerilatedImp {
|
|||||||
ExportNameMap m_exportMap; ///< Map of <export_func_proto, func number>
|
ExportNameMap m_exportMap; ///< Map of <export_func_proto, func number>
|
||||||
int m_exportNext; ///< Next export funcnum
|
int m_exportNext; ///< Next export funcnum
|
||||||
|
|
||||||
|
// File I/O
|
||||||
|
vector<FILE*> m_fdps; ///< File descriptors
|
||||||
|
deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
public: // But only for verilated*.cpp
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedImp() : m_argVecLoaded(false), m_exportNext(0) {}
|
VerilatedImp() : m_argVecLoaded(false), m_exportNext(0) {
|
||||||
|
m_fdps.resize(3);
|
||||||
|
m_fdps[0] = stdin;
|
||||||
|
m_fdps[1] = stdout;
|
||||||
|
m_fdps[2] = stderr;
|
||||||
|
}
|
||||||
~VerilatedImp() {}
|
~VerilatedImp() {}
|
||||||
|
|
||||||
// METHODS - arguments
|
// METHODS - arguments
|
||||||
@@ -184,6 +194,34 @@ public: // But only for verilated*.cpp
|
|||||||
}
|
}
|
||||||
// We don't free up m_exportMap until the end, because we can't be sure
|
// We don't free up m_exportMap until the end, because we can't be sure
|
||||||
// what other models are using the assigned funcnum's.
|
// what other models are using the assigned funcnum's.
|
||||||
|
|
||||||
|
public: // But only for verilated*.cpp
|
||||||
|
// METHODS - file IO
|
||||||
|
static IData fdNew(FILE* fp) {
|
||||||
|
if (VL_UNLIKELY(!fp)) return 0;
|
||||||
|
// Bit 31 indicates it's a descriptor not a MCD
|
||||||
|
if (s_s.m_fdFree.empty()) {
|
||||||
|
// Need to create more space in m_fdps and m_fdFree
|
||||||
|
size_t start = s_s.m_fdps.size();
|
||||||
|
s_s.m_fdps.resize(start*2);
|
||||||
|
for (size_t i=start; i<start*2; i++) s_s.m_fdFree.push_back((IData)i);
|
||||||
|
}
|
||||||
|
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
|
||||||
|
s_s.m_fdps[idx] = fp;
|
||||||
|
return (idx | (1UL<<31)); // bit 31 indicates not MCD
|
||||||
|
}
|
||||||
|
static void fdDelete(IData fdi) {
|
||||||
|
IData idx = VL_MASK_I(31) & fdi;
|
||||||
|
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return;
|
||||||
|
if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free
|
||||||
|
s_s.m_fdps[idx] = NULL;
|
||||||
|
s_s.m_fdFree.push_back(idx);
|
||||||
|
}
|
||||||
|
static inline FILE* fdToFp(IData fdi) {
|
||||||
|
IData idx = VL_MASK_I(31) & fdi;
|
||||||
|
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL;
|
||||||
|
return s_s.m_fdps[idx];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2009-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// THIS MODULE IS PUBLICLY LICENSED
|
// THIS MODULE IS PUBLICLY LICENSED
|
||||||
//
|
//
|
||||||
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
|
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
|
||||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// THIS MODULE IS PUBLICLY LICENSED
|
// THIS MODULE IS PUBLICLY LICENSED
|
||||||
//
|
//
|
||||||
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
|
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
|
||||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
//
|
//
|
||||||
@@ -86,8 +86,8 @@ private:
|
|||||||
NameMap* m_namemapp; ///< List of names for the header
|
NameMap* m_namemapp; ///< List of names for the header
|
||||||
static vector<VerilatedVcd*> s_vcdVecp; ///< List of all created traces
|
static vector<VerilatedVcd*> s_vcdVecp; ///< List of all created traces
|
||||||
|
|
||||||
inline size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||||
inline size_t bufferInsertSize() { return 16*1024; }
|
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||||
void bufferFlush();
|
void bufferFlush();
|
||||||
void bufferCheck() {
|
void bufferCheck() {
|
||||||
// Flush the write buffer if there's not enough space left for new information
|
// Flush the write buffer if there's not enough space left for new information
|
||||||
@@ -110,6 +110,7 @@ private:
|
|||||||
void dumpHeader();
|
void dumpHeader();
|
||||||
void dumpPrep (vluint64_t timeui);
|
void dumpPrep (vluint64_t timeui);
|
||||||
void dumpFull (vluint64_t timeui);
|
void dumpFull (vluint64_t timeui);
|
||||||
|
// cppcheck-suppress functionConst
|
||||||
void dumpDone ();
|
void dumpDone ();
|
||||||
inline void printCode (vluint32_t code) {
|
inline void printCode (vluint32_t code) {
|
||||||
if (code>=(94*94*94)) *m_writep++ = ((char)((code/94/94/94)%94+33));
|
if (code>=(94*94*94)) *m_writep++ = ((char)((code/94/94/94)%94+33));
|
||||||
@@ -117,7 +118,7 @@ private:
|
|||||||
if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33));
|
if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33));
|
||||||
*m_writep++ = ((char)((code)%94+33));
|
*m_writep++ = ((char)((code)%94+33));
|
||||||
}
|
}
|
||||||
string stringCode (vluint32_t code) {
|
static string stringCode (vluint32_t code) {
|
||||||
string out;
|
string out;
|
||||||
if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33));
|
if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33));
|
||||||
if (code>=(94*94)) out += ((char)((code/94/94)%94+33));
|
if (code>=(94*94)) out += ((char)((code/94/94)%94+33));
|
||||||
@@ -141,6 +142,8 @@ public:
|
|||||||
m_evcd = false;
|
m_evcd = false;
|
||||||
m_scopeEscape = '.'; // Backward compatibility
|
m_scopeEscape = '.'; // Backward compatibility
|
||||||
m_wroteBytes = 0;
|
m_wroteBytes = 0;
|
||||||
|
m_fd = 0;
|
||||||
|
m_fullDump = true;
|
||||||
}
|
}
|
||||||
~VerilatedVcd();
|
~VerilatedVcd();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// THIS MODULE IS PUBLICLY LICENSED
|
// THIS MODULE IS PUBLICLY LICENSED
|
||||||
//
|
//
|
||||||
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
|
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
|
||||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// THIS MODULE IS PUBLICLY LICENSED
|
// THIS MODULE IS PUBLICLY LICENSED
|
||||||
//
|
//
|
||||||
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
|
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
|
||||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
|
||||||
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
|
// Version 2.0.
|
||||||
|
//
|
||||||
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// \brief Verilator: VPI implementation code
|
||||||
|
///
|
||||||
|
/// This file must be compiled and linked against all objects
|
||||||
|
/// created from Verilator or called by Verilator that use the VPI.
|
||||||
|
///
|
||||||
|
/// Code available from: http://www.veripool.org/verilator
|
||||||
|
///
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
#include "verilated_vpi.h"
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
VerilatedVpi VerilatedVpi::s_s; // Singleton
|
||||||
|
vluint8_t* VerilatedVpio::s_freeHead = NULL;
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
@@ -0,0 +1,857 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
|
||||||
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
|
// Version 2.0.
|
||||||
|
//
|
||||||
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// \brief Verilator: VPI implementation code
|
||||||
|
///
|
||||||
|
/// This file must be compiled and linked against all objects
|
||||||
|
/// created from Verilator or called by Verilator that use the VPI.
|
||||||
|
///
|
||||||
|
/// "//-" indicates features that are as yet unimplemented.
|
||||||
|
///
|
||||||
|
/// Code available from: http://www.veripool.org/verilator
|
||||||
|
///
|
||||||
|
//=========================================================================
|
||||||
|
|
||||||
|
#ifndef CHPI_VERILATED_VPI_H
|
||||||
|
#define CHPI_VERILATED_VPI_H 1
|
||||||
|
|
||||||
|
#include "verilated.h"
|
||||||
|
#include "verilated_syms.h"
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// From IEEE 1800-2009 annex K
|
||||||
|
|
||||||
|
#include "vltstd/vpi_user.h"
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// Internal macros
|
||||||
|
|
||||||
|
// Not supported yet
|
||||||
|
#define _VL_VPI_UNIMP() \
|
||||||
|
vl_fatal(__FILE__,__LINE__,"",Verilated::catName("Unsupported VPI function: ",VL_FUNC))
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#define VL_DEBUG_IF_PLI VL_DEBUG_IF
|
||||||
|
|
||||||
|
// Base VPI handled object
|
||||||
|
class VerilatedVpio {
|
||||||
|
// MEM MANGLEMENT
|
||||||
|
static vluint8_t* s_freeHead;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// CONSTRUCTORS
|
||||||
|
VerilatedVpio() {}
|
||||||
|
virtual ~VerilatedVpio() {}
|
||||||
|
inline static void* operator new(size_t size) {
|
||||||
|
// We new and delete tons of vpi structures, so keep them around
|
||||||
|
// To simplify our free list, we use a size large enough for all derived types
|
||||||
|
// We reserve word zero for the next pointer, as that's safer in case a
|
||||||
|
// dangling reference to the original remains around.
|
||||||
|
static size_t chunk = 96;
|
||||||
|
if (VL_UNLIKELY(size>chunk)) vl_fatal(__FILE__,__LINE__,"", "increase chunk");
|
||||||
|
if (VL_LIKELY(s_freeHead)) {
|
||||||
|
vluint8_t* newp = s_freeHead;
|
||||||
|
s_freeHead = *((vluint8_t**)newp);
|
||||||
|
return newp+8;
|
||||||
|
} else {
|
||||||
|
// +8: 8 bytes for next
|
||||||
|
vluint8_t* newp = (vluint8_t*)(::operator new(chunk+8));
|
||||||
|
return newp+8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline static void operator delete(void* obj, size_t size) {
|
||||||
|
vluint8_t* oldp = ((vluint8_t*)obj)-8;
|
||||||
|
*((void**)oldp) = s_freeHead;
|
||||||
|
s_freeHead = oldp;
|
||||||
|
}
|
||||||
|
// MEMBERS
|
||||||
|
static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast<VerilatedVpio*>((VerilatedVpio*)h); }
|
||||||
|
inline vpiHandle castVpiHandle() { return (vpiHandle)(this); }
|
||||||
|
// ACCESSORS
|
||||||
|
virtual const char* name() { return "<null>"; }
|
||||||
|
virtual const char* fullname() { return "<null>"; }
|
||||||
|
virtual const char* defname() { return "<null>"; }
|
||||||
|
virtual vpiHandle dovpi_scan() { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *);
|
||||||
|
|
||||||
|
class VerilatedVpioCb : public VerilatedVpio {
|
||||||
|
t_cb_data m_cbData;
|
||||||
|
s_vpi_value m_value;
|
||||||
|
QData m_time;
|
||||||
|
public:
|
||||||
|
// cppcheck-suppress uninitVar // m_value
|
||||||
|
VerilatedVpioCb(const t_cb_data* cbDatap, QData time)
|
||||||
|
: m_cbData(*cbDatap), m_time(time) {
|
||||||
|
m_cbData.value = &m_value;
|
||||||
|
}
|
||||||
|
virtual ~VerilatedVpioCb() {}
|
||||||
|
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
|
||||||
|
vluint32_t reason() const { return m_cbData.reason; }
|
||||||
|
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
|
||||||
|
t_cb_data* cb_datap() { return &(m_cbData); }
|
||||||
|
QData time() const { return m_time; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpioConst : public VerilatedVpio {
|
||||||
|
vlsint32_t m_num;
|
||||||
|
public:
|
||||||
|
VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
|
||||||
|
virtual ~VerilatedVpioConst() {}
|
||||||
|
static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
|
||||||
|
vlsint32_t num() const { return m_num; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpioRange : public VerilatedVpio {
|
||||||
|
vlsint32_t m_lhs; // Ranges can be signed
|
||||||
|
vlsint32_t m_rhs;
|
||||||
|
bool m_iteration;
|
||||||
|
public:
|
||||||
|
VerilatedVpioRange(vlsint32_t lhs, vlsint32_t rhs) : m_lhs(lhs), m_rhs(rhs), m_iteration(0) {}
|
||||||
|
virtual ~VerilatedVpioRange() {}
|
||||||
|
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
|
||||||
|
vlsint32_t lhs() const { return m_lhs; }
|
||||||
|
vlsint32_t rhs() const { return m_rhs; }
|
||||||
|
int iteration() const { return m_iteration; }
|
||||||
|
void iterationInc() { ++m_iteration; }
|
||||||
|
virtual vpiHandle dovpi_scan() {
|
||||||
|
if (!iteration()) {
|
||||||
|
VerilatedVpioRange* nextp = new VerilatedVpioRange(*this);
|
||||||
|
nextp->iterationInc();
|
||||||
|
return ((nextp)->castVpiHandle());
|
||||||
|
} else {
|
||||||
|
return 0; // End of list - only one deep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpioScope : public VerilatedVpio {
|
||||||
|
const VerilatedScope* m_scopep;
|
||||||
|
public:
|
||||||
|
VerilatedVpioScope(const VerilatedScope* scopep)
|
||||||
|
: m_scopep(scopep) {}
|
||||||
|
virtual ~VerilatedVpioScope() {}
|
||||||
|
static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
|
||||||
|
const VerilatedScope* scopep() const { return m_scopep; }
|
||||||
|
virtual const char* name() { return m_scopep->name(); }
|
||||||
|
virtual const char* fullname() { return m_scopep->name(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpioVar : public VerilatedVpio {
|
||||||
|
const VerilatedVar* m_varp;
|
||||||
|
const VerilatedScope* m_scopep;
|
||||||
|
vluint8_t* m_prevDatap; // Previous value of data, for cbValueChange
|
||||||
|
vluint32_t m_mask; // memoized variable mask
|
||||||
|
vluint32_t m_entSize; // memoized variable size
|
||||||
|
protected:
|
||||||
|
void* m_varDatap; // varp()->datap() adjusted for array entries
|
||||||
|
vlsint32_t m_index;
|
||||||
|
public:
|
||||||
|
VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep)
|
||||||
|
: m_varp(varp), m_scopep(scopep), m_index(0) {
|
||||||
|
m_prevDatap = NULL;
|
||||||
|
m_mask = VL_MASK_I(varp->range().bits());
|
||||||
|
m_entSize = varp->entSize();
|
||||||
|
m_varDatap = varp->datap();
|
||||||
|
}
|
||||||
|
virtual ~VerilatedVpioVar() {
|
||||||
|
if (m_prevDatap) { delete [] m_prevDatap; m_prevDatap = NULL; }
|
||||||
|
}
|
||||||
|
static inline VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVar*>((VerilatedVpio*)h); }
|
||||||
|
const VerilatedVar* varp() const { return m_varp; }
|
||||||
|
const VerilatedScope* scopep() const { return m_scopep; }
|
||||||
|
vluint32_t mask() const { return m_mask; }
|
||||||
|
vluint32_t entSize() const { return m_entSize; }
|
||||||
|
virtual const char* name() { return m_varp->name(); }
|
||||||
|
virtual const char* fullname() {
|
||||||
|
static VL_THREAD string out;
|
||||||
|
out = string(m_scopep->name())+"."+name();
|
||||||
|
return out.c_str();
|
||||||
|
}
|
||||||
|
void* prevDatap() const { return m_prevDatap; }
|
||||||
|
void* varDatap() const { return m_varDatap; }
|
||||||
|
void createPrevDatap() {
|
||||||
|
if (VL_UNLIKELY(!m_prevDatap)) {
|
||||||
|
m_prevDatap = new vluint8_t [entSize()];
|
||||||
|
memcpy(prevDatap(), varp()->datap(), entSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpioVarIndex : public VerilatedVpioVar {
|
||||||
|
public:
|
||||||
|
VerilatedVpioVarIndex(const VerilatedVar* varp, const VerilatedScope* scopep,
|
||||||
|
vlsint32_t index, int offset)
|
||||||
|
: VerilatedVpioVar(varp, scopep) {
|
||||||
|
m_index = index;
|
||||||
|
m_varDatap = ((vluint8_t*)varp->datap()) + entSize()*offset;
|
||||||
|
}
|
||||||
|
virtual ~VerilatedVpioVarIndex() {}
|
||||||
|
static inline VerilatedVpioVarIndex* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIndex*>((VerilatedVpio*)h); }
|
||||||
|
virtual const char* fullname() {
|
||||||
|
static VL_THREAD string out;
|
||||||
|
char num[20]; sprintf(num,"%d",m_index);
|
||||||
|
out = string(scopep()->name())+"."+name()+"["+num+"]";
|
||||||
|
return out.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpioVarIter : public VerilatedVpio {
|
||||||
|
const VerilatedScope* m_scopep;
|
||||||
|
VerilatedVarNameMap::iterator m_it;
|
||||||
|
bool m_started;
|
||||||
|
public:
|
||||||
|
VerilatedVpioVarIter(const VerilatedScope* scopep)
|
||||||
|
: m_scopep(scopep), m_started(false) { }
|
||||||
|
virtual ~VerilatedVpioVarIter() {}
|
||||||
|
static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
|
||||||
|
virtual vpiHandle dovpi_scan() {
|
||||||
|
if (VL_LIKELY(m_scopep->varsp())) {
|
||||||
|
if (VL_UNLIKELY(!m_started)) { m_it = m_scopep->varsp()->begin(); m_started=true; }
|
||||||
|
else if (VL_UNLIKELY(m_it == m_scopep->varsp()->end())) return 0;
|
||||||
|
else ++m_it;
|
||||||
|
if (m_it == m_scopep->varsp()->end()) return 0;
|
||||||
|
return ((new VerilatedVpioVar(&(m_it->second), m_scopep))
|
||||||
|
->castVpiHandle());
|
||||||
|
} else {
|
||||||
|
return 0; // End of list - only one deep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
struct VerilatedVpiTimedCbsCmp {
|
||||||
|
/// Ordering sets keyed by time, then callback descriptor
|
||||||
|
bool operator() (const pair<QData,VerilatedVpioCb*>& a,
|
||||||
|
const pair<QData,VerilatedVpioCb*>& b) const {
|
||||||
|
if (a.first < b.first) return 1;
|
||||||
|
if (a.first > b.first) return 0;
|
||||||
|
return a.second < b.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VerilatedVpi {
|
||||||
|
enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason
|
||||||
|
typedef set<VerilatedVpioCb*> VpioCbSet;
|
||||||
|
typedef set<pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
|
||||||
|
|
||||||
|
VpioCbSet m_cbObjSets[CB_ENUM_MAX_VALUE]; // Callbacks for each supported reason
|
||||||
|
VpioTimedCbs m_timedCbs; // Time based callbacks
|
||||||
|
|
||||||
|
static VerilatedVpi s_s; // Singleton
|
||||||
|
|
||||||
|
public:
|
||||||
|
VerilatedVpi() {}
|
||||||
|
~VerilatedVpi() {}
|
||||||
|
static void cbReasonAdd(VerilatedVpioCb* vop) {
|
||||||
|
if (vop->reason() == cbValueChange) {
|
||||||
|
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
|
||||||
|
varop->createPrevDatap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (VL_UNLIKELY(vop->reason() >= CB_ENUM_MAX_VALUE)) vl_fatal(__FILE__,__LINE__,"", "vpi bb reason too large");
|
||||||
|
s_s.m_cbObjSets[vop->reason()].insert(vop);
|
||||||
|
}
|
||||||
|
static void cbTimedAdd(VerilatedVpioCb* vop) {
|
||||||
|
s_s.m_timedCbs.insert(make_pair(vop->time(), vop));
|
||||||
|
}
|
||||||
|
static void cbReasonRemove(VerilatedVpioCb* cbp) {
|
||||||
|
VpioCbSet& cbObjSet = s_s.m_cbObjSets[cbp->reason()];
|
||||||
|
VpioCbSet::iterator it=cbObjSet.find(cbp);
|
||||||
|
if (VL_LIKELY(it != cbObjSet.end())) {
|
||||||
|
cbObjSet.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void cbTimedRemove(VerilatedVpioCb* cbp) {
|
||||||
|
VpioTimedCbs::iterator it=s_s.m_timedCbs.find(make_pair(cbp->time(),cbp));
|
||||||
|
if (VL_LIKELY(it != s_s.m_timedCbs.end())) {
|
||||||
|
s_s.m_timedCbs.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void callTimedCbs() {
|
||||||
|
QData time = VL_TIME_Q();
|
||||||
|
for (VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); it!=s_s.m_timedCbs.end(); ) {
|
||||||
|
if (VL_UNLIKELY(it->first <= time)) {
|
||||||
|
VerilatedVpioCb* vop = it->second;
|
||||||
|
++it; // iterator may be deleted by callback
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: timed_callback %p\n",vop););
|
||||||
|
(vop->cb_rtnp()) (vop->cb_datap());
|
||||||
|
}
|
||||||
|
else { ++it; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static QData cbNextDeadline() {
|
||||||
|
VpioTimedCbs::iterator it=s_s.m_timedCbs.begin();
|
||||||
|
if (VL_LIKELY(it!=s_s.m_timedCbs.end())) {
|
||||||
|
return it->first;
|
||||||
|
} else {
|
||||||
|
return ~VL_ULL(0); // maxquad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void callCbs(vluint32_t reason) {
|
||||||
|
VpioCbSet& cbObjSet = s_s.m_cbObjSets[reason];
|
||||||
|
for (VpioCbSet::iterator it=cbObjSet.begin(); it!=cbObjSet.end();) {
|
||||||
|
VerilatedVpioCb* vop = *it;
|
||||||
|
++it; // iterator may be deleted by callback
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: reason_callback %d %p\n",reason,vop););
|
||||||
|
(vop->cb_rtnp()) (vop->cb_datap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void callValueCbs() {
|
||||||
|
VpioCbSet& cbObjSet = s_s.m_cbObjSets[cbValueChange];
|
||||||
|
for (VpioCbSet::iterator it=cbObjSet.begin(); it!=cbObjSet.end();) {
|
||||||
|
VerilatedVpioCb* vop = *it;
|
||||||
|
++it; // iterator may be deleted by callback
|
||||||
|
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
|
||||||
|
void* newDatap = varop->varDatap();
|
||||||
|
void* prevDatap = varop->prevDatap(); // Was malloced when we added the callback
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_test %s v[0]=%d/%d %p %p\n",
|
||||||
|
varop->fullname(), *((CData*)newDatap), *((CData*)prevDatap),
|
||||||
|
newDatap, prevDatap););
|
||||||
|
if (memcmp(prevDatap, newDatap, varop->entSize())) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_callback %p %s v[0]=%d\n",
|
||||||
|
vop,varop->fullname(), *((CData*)newDatap)););
|
||||||
|
memcpy(prevDatap, newDatap, varop->entSize());
|
||||||
|
vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value);
|
||||||
|
(vop->cb_rtnp()) (vop->cb_datap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// callback related
|
||||||
|
|
||||||
|
vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
|
||||||
|
if (VL_UNLIKELY(!cb_data_p)) return NULL;
|
||||||
|
switch (cb_data_p->reason) {
|
||||||
|
case cbAfterDelay: {
|
||||||
|
QData time = 0;
|
||||||
|
if (cb_data_p->time) time = _VL_SET_QII(cb_data_p->time->high, cb_data_p->time->low);
|
||||||
|
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, VL_TIME_Q()+time);
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p delay=%" VL_PRI64 "d\n",cb_data_p->reason,vop,time););
|
||||||
|
VerilatedVpi::cbTimedAdd(vop);
|
||||||
|
return vop->castVpiHandle();
|
||||||
|
}
|
||||||
|
case cbReadWriteSynch: // FALLTHRU // Supported via vlt_main.cpp
|
||||||
|
case cbReadOnlySynch: // FALLTHRU // Supported via vlt_main.cpp
|
||||||
|
case cbNextSimTime: // FALLTHRU // Supported via vlt_main.cpp
|
||||||
|
case cbStartOfSimulation: // FALLTHRU // Supported via vlt_main.cpp
|
||||||
|
case cbEndOfSimulation: // FALLTHRU // Supported via vlt_main.cpp
|
||||||
|
case cbValueChange: // FALLTHRU // Supported via vlt_main.cpp
|
||||||
|
case cbEnterInteractive: // FALLTHRU // NOP, but need to return handle, so make object
|
||||||
|
case cbExitInteractive: // FALLTHRU // NOP, but need to return handle, so make object
|
||||||
|
case cbInteractiveScopeChange: { // FALLTHRU // NOP, but need to return handle, so make object
|
||||||
|
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, 0);
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p\n",cb_data_p->reason,vop););
|
||||||
|
VerilatedVpi::cbReasonAdd(vop);
|
||||||
|
return vop->castVpiHandle();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP(); return NULL;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_remove_cb(vpiHandle object) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_remove_cb %p\n",object););
|
||||||
|
VerilatedVpioCb* vop = VerilatedVpioCb::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
if (vop->cb_datap()->reason == cbAfterDelay) {
|
||||||
|
VerilatedVpi::cbTimedRemove(vop);
|
||||||
|
} else {
|
||||||
|
VerilatedVpi::cbReasonRemove(vop);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-void vpi_get_cb_info(vpiHandle object, p_cb_data cb_data_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-vpiHandle vpi_register_systf(p_vpi_systf_data systf_data_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-void vpi_get_systf_info(vpiHandle object, p_vpi_systf_data systf_data_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
// for obtaining handles
|
||||||
|
|
||||||
|
vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
|
||||||
|
if (VL_UNLIKELY(!namep)) return NULL;
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle_by_name %s %p\n",namep,scope););
|
||||||
|
VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope);
|
||||||
|
const VerilatedVar* varp;
|
||||||
|
const VerilatedScope* scopep;
|
||||||
|
string scopeAndName = namep;
|
||||||
|
if (voScopep) {
|
||||||
|
scopeAndName = string(voScopep->fullname()) + "." + namep;
|
||||||
|
namep = (PLI_BYTE8*)scopeAndName.c_str();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// This doesn't yet follow the hierarchy in the proper way
|
||||||
|
scopep = Verilated::scopeFind(namep);
|
||||||
|
if (scopep) { // Whole thing found as a scope
|
||||||
|
return (new VerilatedVpioScope(scopep))->castVpiHandle();
|
||||||
|
}
|
||||||
|
const char* baseNamep = scopeAndName.c_str();
|
||||||
|
string scopename;
|
||||||
|
const char* dotp = strrchr(namep, '.');
|
||||||
|
if (VL_LIKELY(dotp)) {
|
||||||
|
baseNamep = dotp+1;
|
||||||
|
scopename = string(namep,dotp-namep);
|
||||||
|
}
|
||||||
|
scopep = Verilated::scopeFind(scopename.c_str());
|
||||||
|
if (!scopep) return NULL;
|
||||||
|
varp = scopep->varFind(baseNamep);
|
||||||
|
}
|
||||||
|
if (!varp) return NULL;
|
||||||
|
return (new VerilatedVpioVar(varp, scopep))->castVpiHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
|
||||||
|
// Used to get array entries
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle_by_index %p %d\n",object, indx););
|
||||||
|
VerilatedVpioVar* varop = VerilatedVpioVar::castp(object);
|
||||||
|
if (VL_LIKELY(varop)) {
|
||||||
|
if (varop->varp()->dims()<2) return 0;
|
||||||
|
if (VL_LIKELY(varop->varp()->array().lhs() >= varop->varp()->array().rhs())) {
|
||||||
|
if (VL_UNLIKELY(indx > varop->varp()->array().lhs() || indx < varop->varp()->array().rhs())) return 0;
|
||||||
|
return (new VerilatedVpioVarIndex(varop->varp(), varop->scopep(), indx,
|
||||||
|
indx - varop->varp()->array().rhs()))
|
||||||
|
->castVpiHandle();
|
||||||
|
} else {
|
||||||
|
if (VL_UNLIKELY(indx < varop->varp()->array().lhs() || indx > varop->varp()->array().rhs())) return 0;
|
||||||
|
return (new VerilatedVpioVarIndex(varop->varp(), varop->scopep(), indx,
|
||||||
|
indx - varop->varp()->array().lhs()))
|
||||||
|
->castVpiHandle();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_VL_VPI_UNIMP(); return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for traversing relationships
|
||||||
|
|
||||||
|
vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle %d %p\n",type,object););
|
||||||
|
switch (type) {
|
||||||
|
case vpiLeftRange: // FALLTHRU
|
||||||
|
case vpiRightRange: {
|
||||||
|
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
|
||||||
|
vluint32_t num = ((type==vpiLeftRange)
|
||||||
|
? vop->varp()->range().lhs()
|
||||||
|
: vop->varp()->range().rhs());
|
||||||
|
return (new VerilatedVpioConst(num))->castVpiHandle();
|
||||||
|
} else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) {
|
||||||
|
vluint32_t num = ((type==vpiLeftRange)
|
||||||
|
? vop->lhs()
|
||||||
|
: vop->rhs());
|
||||||
|
return (new VerilatedVpioConst(num))->castVpiHandle();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-vpiHandle vpi_handle_multi(PLI_INT32 type, vpiHandle refHandle1, vpiHandle refHandle2, ... ) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_iterate %d %p\n",type,object););
|
||||||
|
switch (type) {
|
||||||
|
case vpiMemoryWord: {
|
||||||
|
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
if (vop->varp()->dims() < 2) return 0;
|
||||||
|
// Unsupported is multidim list
|
||||||
|
return ((new VerilatedVpioRange(vop->varp()->array().lhs(),
|
||||||
|
vop->varp()->array().rhs()))
|
||||||
|
->castVpiHandle());
|
||||||
|
}
|
||||||
|
case vpiReg: {
|
||||||
|
VerilatedVpioScope* vop = VerilatedVpioScope::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
return ((new VerilatedVpioVarIter(vop->scopep()))
|
||||||
|
->castVpiHandle());
|
||||||
|
}
|
||||||
|
case vpiIODecl: // Skipping - we'll put under reg
|
||||||
|
case vpiNet: // Skipping - we'll put under reg
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP(); return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vpiHandle vpi_scan(vpiHandle object) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_scan %p\n",object););
|
||||||
|
VerilatedVpio* vop = VerilatedVpio::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return NULL;
|
||||||
|
return vop->dovpi_scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
// for processing properties
|
||||||
|
|
||||||
|
PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
|
||||||
|
// Leave this in the header file - in many cases the compiler can constant propagate "object"
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get %d %p\n",property,object););
|
||||||
|
switch (property) {
|
||||||
|
case vpiTimePrecision: {
|
||||||
|
return VL_TIME_PRECISION;
|
||||||
|
}
|
||||||
|
case vpiType: {
|
||||||
|
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
return ((vop->varp()->dims()>1) ? vpiMemory : vpiReg);
|
||||||
|
}
|
||||||
|
case vpiDirection: {
|
||||||
|
// By forthought, the directions already are vpi enumerated
|
||||||
|
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
return vop->varp()->vldir();
|
||||||
|
}
|
||||||
|
case vpiVector: {
|
||||||
|
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
if (vop->varp()->dims()==0) return 0;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-PLI_INT64 vpi_get64(PLI_INT32 property, vpiHandle object) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
PLI_BYTE8 *vpi_get_str(PLI_INT32 property, vpiHandle object) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_str %d %p\n",property,object););
|
||||||
|
VerilatedVpio* vop = VerilatedVpio::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return NULL;
|
||||||
|
switch (property) {
|
||||||
|
case vpiName: {
|
||||||
|
return (PLI_BYTE8*)vop->name();
|
||||||
|
}
|
||||||
|
case vpiFullName: {
|
||||||
|
return (PLI_BYTE8*)vop->fullname();
|
||||||
|
}
|
||||||
|
case vpiDefName: {
|
||||||
|
return (PLI_BYTE8*)vop->defname();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delay processing
|
||||||
|
|
||||||
|
//-void vpi_get_delays(vpiHandle object, p_vpi_delay delay_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-void vpi_put_delays(vpiHandle object, p_vpi_delay delay_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
// value processing
|
||||||
|
|
||||||
|
void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_value %p\n",object););
|
||||||
|
if (VL_UNLIKELY(!value_p)) return;
|
||||||
|
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
|
||||||
|
// We presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal
|
||||||
|
if (value_p->format == vpiVectorVal) {
|
||||||
|
// Vector pointer must come from our memory pool
|
||||||
|
// It only needs to persist until the next vpi_get_value
|
||||||
|
static VL_THREAD t_vpi_vecval out[VL_MULS_MAX_WORDS*2];
|
||||||
|
value_p->value.vector = out;
|
||||||
|
switch (vop->varp()->vltype()) {
|
||||||
|
case VLVT_UINT8:
|
||||||
|
out[0].aval = *((CData*)(vop->varDatap()));
|
||||||
|
out[0].bval = 0;
|
||||||
|
return;
|
||||||
|
case VLVT_UINT16:
|
||||||
|
out[0].aval = *((SData*)(vop->varDatap()));
|
||||||
|
out[0].bval = 0;
|
||||||
|
return;
|
||||||
|
case VLVT_UINT32:
|
||||||
|
out[0].aval = *((IData*)(vop->varDatap()));
|
||||||
|
out[0].bval = 0;
|
||||||
|
return;
|
||||||
|
case VLVT_WDATA: {
|
||||||
|
int words = VL_WORDS_I(vop->varp()->range().bits());
|
||||||
|
if (VL_UNLIKELY(words >= VL_MULS_MAX_WORDS)) {
|
||||||
|
vl_fatal(__FILE__,__LINE__,"", "vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile");
|
||||||
|
}
|
||||||
|
WDataInP datap = ((IData*)(vop->varDatap()));
|
||||||
|
for (int i=0; i<words; i++) {
|
||||||
|
out[i].aval = datap[i];
|
||||||
|
out[i].bval = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case VLVT_UINT64: {
|
||||||
|
QData data = *((QData*)(vop->varDatap()));
|
||||||
|
out[1].aval = (IData)(data>>VL_ULL(32));
|
||||||
|
out[1].bval = 0;
|
||||||
|
out[0].aval = (IData)(data);
|
||||||
|
out[0].bval = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (vop->varp()->vltype()) {
|
||||||
|
case VLVT_UINT8:
|
||||||
|
value_p->value.integer = *((CData*)(vop->varDatap()));
|
||||||
|
return;
|
||||||
|
case VLVT_UINT16:
|
||||||
|
value_p->value.integer = *((SData*)(vop->varDatap()));
|
||||||
|
return;
|
||||||
|
case VLVT_UINT32:
|
||||||
|
value_p->value.integer = *((IData*)(vop->varDatap()));
|
||||||
|
return;
|
||||||
|
case VLVT_WDATA:
|
||||||
|
case VLVT_UINT64:
|
||||||
|
// Not legal
|
||||||
|
value_p->value.integer = 0;
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (VerilatedVpioConst* vop = VerilatedVpioConst::castp(object)) {
|
||||||
|
value_p->value.integer = vop->num();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
|
||||||
|
p_vpi_time time_p, PLI_INT32 flags) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_put_value %p %p\n",object, value_p););
|
||||||
|
if (VL_UNLIKELY(!value_p)) return 0;
|
||||||
|
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
|
||||||
|
// We presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_put_value name=%s fmt=%d vali=%d\n",
|
||||||
|
vop->fullname(), value_p->format, value_p->value.integer);
|
||||||
|
VL_PRINTF("-vltVpi: varp=%p putatp=%p\n",
|
||||||
|
vop->varp()->datap(), vop->varDatap()););
|
||||||
|
if (VL_UNLIKELY(!vop->varp()->isPublicRW())) {
|
||||||
|
VL_PRINTF("%%Warning: Ignoring vpi_put_value to signal marked read-only, use public_flat_rw instead: %s\n",
|
||||||
|
vop->fullname());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (value_p->format == vpiVectorVal) {
|
||||||
|
if (VL_UNLIKELY(!value_p->value.vector)) return NULL;
|
||||||
|
switch (vop->varp()->vltype()) {
|
||||||
|
case VLVT_UINT8:
|
||||||
|
*((CData*)(vop->varDatap())) = value_p->value.vector[0].aval;
|
||||||
|
return object;
|
||||||
|
case VLVT_UINT16:
|
||||||
|
*((SData*)(vop->varDatap())) = value_p->value.vector[0].aval;
|
||||||
|
return object;
|
||||||
|
case VLVT_UINT32:
|
||||||
|
*((IData*)(vop->varDatap())) = value_p->value.vector[0].aval;
|
||||||
|
return object;
|
||||||
|
case VLVT_WDATA: {
|
||||||
|
int words = VL_WORDS_I(vop->varp()->range().bits());
|
||||||
|
WDataOutP datap = ((IData*)(vop->varDatap()));
|
||||||
|
for (int i=0; i<words; i++) {
|
||||||
|
datap[i] = value_p->value.vector[i].aval;
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
case VLVT_UINT64: {
|
||||||
|
*((QData*)(vop->varDatap())) = _VL_SET_QII(
|
||||||
|
value_p->value.vector[1].aval,
|
||||||
|
value_p->value.vector[0].aval);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (vop->varp()->vltype()) {
|
||||||
|
case VLVT_UINT8:
|
||||||
|
*((CData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
|
||||||
|
return object;
|
||||||
|
case VLVT_UINT16:
|
||||||
|
*((SData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
|
||||||
|
return object;
|
||||||
|
case VLVT_UINT32:
|
||||||
|
*((IData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
|
||||||
|
return object;
|
||||||
|
case VLVT_WDATA: // FALLTHRU
|
||||||
|
case VLVT_UINT64: // FALLTHRU
|
||||||
|
default:
|
||||||
|
_VL_VPI_UNIMP();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_VL_VPI_UNIMP(); return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p,
|
||||||
|
//- PLI_INT32 *index_p, PLI_UINT32 num) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p,
|
||||||
|
//- PLI_INT32 *index_p, PLI_UINT32 num) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
|
||||||
|
// time processing
|
||||||
|
|
||||||
|
//-void vpi_get_time(vpiHandle object, p_vpi_time time_p) {
|
||||||
|
//- _VL_VPI_UNIMP();
|
||||||
|
//-}
|
||||||
|
|
||||||
|
// I/O routines
|
||||||
|
|
||||||
|
PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *filenamep) {
|
||||||
|
return VL_FOPEN_S(filenamep,"wb");
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) {
|
||||||
|
VL_FCLOSE_I(mcd); return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 mcd) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, PLI_BYTE8 *formatp, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap,formatp);
|
||||||
|
int chars = vpi_mcd_vprintf(mcd, formatp, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_printf(PLI_BYTE8 *formatp, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap,formatp);
|
||||||
|
int chars = vpi_vprintf(formatp, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_vprintf(PLI_BYTE8* formatp, va_list ap) {
|
||||||
|
return VL_VPRINTF(formatp, ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) {
|
||||||
|
FILE* fp = VL_CVT_I_FP(mcd);
|
||||||
|
if (VL_UNLIKELY(!fp)) return 0;
|
||||||
|
int chars = vfprintf(fp, format, ap);
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_flush(void) {
|
||||||
|
Verilated::flushCall();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) {
|
||||||
|
FILE* fp = VL_CVT_I_FP(mcd);
|
||||||
|
if (VL_UNLIKELY(!fp)) return 1;
|
||||||
|
fflush(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// utility routines
|
||||||
|
|
||||||
|
//-PLI_INT32 vpi_compare_objects(vpiHandle object1, vpiHandle object2) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-PLI_INT32 vpi_chk_error(p_vpi_error_info error_info_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_free_object(vpiHandle object) {
|
||||||
|
return vpi_release_handle(object); // Deprecated
|
||||||
|
}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_release_handle (vpiHandle object) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_release_handle %p\n",object););
|
||||||
|
VerilatedVpio* vop = VerilatedVpio::castp(object);
|
||||||
|
if (VL_UNLIKELY(!vop)) return 0;
|
||||||
|
vpi_remove_cb(object); // May not be a callback, but that's ok
|
||||||
|
delete vop;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
// routines added with 1364-2001
|
||||||
|
|
||||||
|
//-PLI_INT32 vpi_get_data(PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-PLI_INT32 vpi_put_data(PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-void *vpi_get_userdata(vpiHandle obj) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
//-PLI_INT32 vpi_put_userdata(vpiHandle obj, void *userdata) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
PLI_INT32 vpi_control(PLI_INT32 operation, ...) {
|
||||||
|
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_control %d\n",operation););
|
||||||
|
switch (operation) {
|
||||||
|
case vpiFinish: {
|
||||||
|
vl_finish(__FILE__,__LINE__,"*VPI*");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case vpiStop: {
|
||||||
|
vl_stop(__FILE__,__LINE__,"*VPI*");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_VL_VPI_UNIMP(); return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-vpiHandle vpi_handle_by_multi_index(vpiHandle obj, PLI_INT32 num_index, PLI_INT32 *index_array) {
|
||||||
|
//- _VL_VPI_UNIMP(); return 0;
|
||||||
|
//-}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#endif // Guard
|
||||||
+13
-1
@@ -1,7 +1,7 @@
|
|||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -221,6 +221,18 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
|||||||
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
|
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
|
||||||
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
|
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// Floating point
|
||||||
|
// #defines, to avoid requiring math.h on all compile runs
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define VL_TRUNC(n) (((n)<0) ? ceil((n)) : floor((n)))
|
||||||
|
# define VL_ROUND(n) (((n)<0) ? ceil((n)-0.5) : floor((n)+0.5))
|
||||||
|
#else
|
||||||
|
# define VL_TRUNC(n) trunc(n)
|
||||||
|
# define VL_ROUND(n) round(n)
|
||||||
|
#endif
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
#endif /*guard*/
|
#endif /*guard*/
|
||||||
|
|||||||
+7
-6
@@ -207,10 +207,10 @@ viewers let us know; ZGRViewer isn't great for large graphs.
|
|||||||
Tree files are dumps of the AST Tree and are produced between every major
|
Tree files are dumps of the AST Tree and are produced between every major
|
||||||
algorithmic stage. An example:
|
algorithmic stage. An example:
|
||||||
|
|
||||||
NETLIST 0x90fb00 <e1> {0} w0
|
NETLIST 0x90fb00 <e1> {a0} w0
|
||||||
1: MODULE 0x912b20 <e8822> {8} w0 top L2 [P]
|
1: MODULE 0x912b20 <e8822> {a8} w0 top L2 [P]
|
||||||
*1:2: VAR 0x91a780 <e74#> {22} w70 out_wide [O] WIRE
|
*1:2: VAR 0x91a780 <e74#> {a22} w70 out_wide [O] WIRE
|
||||||
1:2:1: BASICDTYPE 0x91a3c0 <e73> {22} w70 [logic]
|
1:2:1: BASICDTYPE 0x91a3c0 <e73> {a22} w70 [logic]
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
@@ -224,7 +224,8 @@ algorithmic stage. An example:
|
|||||||
this node. A trailing # indicates this node changed since the last tree
|
this node. A trailing # indicates this node changed since the last tree
|
||||||
dump was made. You can gdb break on this edit; see below.
|
dump was made. You can gdb break on this edit; see below.
|
||||||
|
|
||||||
"{22}" indicates this node is related to line 22 in the source.
|
"{a22}" indicates this node is related to line 22 in the source filename
|
||||||
|
"a", where "a" is the first file read, "z" the 36th, and "aa" the 37th.
|
||||||
|
|
||||||
"w70" indicates the width is 70 bits. sw70 would be signed 70 bits.
|
"w70" indicates the width is 70 bits. sw70 would be signed 70 bits.
|
||||||
|
|
||||||
@@ -250,7 +251,7 @@ what made a <e####> line in the tree dumps):
|
|||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/>.
|
The latest version is available from L<http://www.veripool.org/>.
|
||||||
|
|
||||||
Copyright 2008-2010 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2008-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2007-2010 by Wilson Snyder. This package is free software; you
|
# Copyright 2007-2011 by Wilson Snyder. This package is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2007-2010 by Wilson Snyder. This package is free software; you
|
# Copyright 2007-2011 by Wilson Snyder. This package is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|||||||
+2
-2
@@ -38,7 +38,7 @@ cwrite ("graph_export.cpp");
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval => 2);
|
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2005-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -43,7 +43,7 @@ dotwrite();
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval => 2);
|
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2005-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2007-2010 by Wilson Snyder. This package is free software; you
|
# Copyright 2007-2011 by Wilson Snyder. This package is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|||||||
+56
-12
@@ -12,12 +12,15 @@ use vars qw ($Debug);
|
|||||||
#======================================================================
|
#======================================================================
|
||||||
# main
|
# main
|
||||||
|
|
||||||
|
our $Opt_Stage = 0;
|
||||||
|
|
||||||
autoflush STDOUT 1;
|
autoflush STDOUT 1;
|
||||||
autoflush STDERR 1;
|
autoflush STDERR 1;
|
||||||
Getopt::Long::config ("no_auto_abbrev");
|
Getopt::Long::config ("no_auto_abbrev");
|
||||||
if (! GetOptions (
|
if (! GetOptions (
|
||||||
"debug" => sub { $Debug = 1; },
|
"debug" => sub { $Debug = 1; },
|
||||||
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
|
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
|
||||||
|
"stage=i" => \$Opt_Stage,
|
||||||
)) {
|
)) {
|
||||||
die "%Error: Bad usage, try 'install_test --help'\n";
|
die "%Error: Bad usage, try 'install_test --help'\n";
|
||||||
}
|
}
|
||||||
@@ -37,8 +40,10 @@ sub test {
|
|||||||
my $srcdir = getcwd();
|
my $srcdir = getcwd();
|
||||||
my $blddir = $srcdir."/test_regress/obj_dir/install_test_bld";
|
my $blddir = $srcdir."/test_regress/obj_dir/install_test_bld";
|
||||||
my $prefix = $srcdir."/test_regress/obj_dir/install_test_prefix";
|
my $prefix = $srcdir."/test_regress/obj_dir/install_test_prefix";
|
||||||
my $testdir = $srcdir."/test_regress/obj_dir/install_test_test";
|
my $testdirp= $srcdir."/test_regress/obj_dir/install_test_testp";
|
||||||
if (1) {
|
my $testdirn= $srcdir."/test_regress/obj_dir/install_test_testn";
|
||||||
|
|
||||||
|
if ($Opt_Stage <= 0) {
|
||||||
run("/bin/rm -rf $blddir");
|
run("/bin/rm -rf $blddir");
|
||||||
run("/bin/mkdir -p $blddir");
|
run("/bin/mkdir -p $blddir");
|
||||||
run("cd $blddir && $srcdir/configure --prefix $prefix");
|
run("cd $blddir && $srcdir/configure --prefix $prefix");
|
||||||
@@ -46,24 +51,63 @@ sub test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Install it under the prefix
|
# Install it under the prefix
|
||||||
if (1) {
|
if ($Opt_Stage <= 1) {
|
||||||
run("/bin/rm -rf $prefix");
|
run("/bin/rm -rf $prefix");
|
||||||
run("/bin/mkdir -p $prefix");
|
run("/bin/mkdir -p $prefix");
|
||||||
run("cd $blddir && make install");
|
run("cd $blddir && make install");
|
||||||
|
run("test -e $prefix/share/man/man1/verilator.1");
|
||||||
|
run("test -e $prefix/share/verilator/examples/test_c/Makefile");
|
||||||
|
run("test -e $prefix/share/verilator/include/verilated.h");
|
||||||
|
run("test -e $prefix/bin/verilator");
|
||||||
|
run("test -e $prefix/bin/verilator_bin");
|
||||||
|
run("test -e $prefix/bin/verilator_bin_dbg");
|
||||||
|
run("test -e $prefix/bin/verilator_profcfunc");
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run a test using just the path
|
# Run a test using just the path
|
||||||
if (1) {
|
if ($Opt_Stage <= 2) {
|
||||||
run("/bin/rm -rf $testdir");
|
my $dir = $testdirp;
|
||||||
run("/bin/mkdir -p $testdir");
|
run("/bin/rm -rf $dir");
|
||||||
|
run("/bin/mkdir -p $dir");
|
||||||
my $bin1 = $prefix."/bin";
|
my $bin1 = $prefix."/bin";
|
||||||
my $bin2 = $prefix."/share/bin";
|
my $bin2 = $prefix."/share/bin";
|
||||||
IO::File->new(">$testdir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); end endmodule'."\n");
|
write_verilog($dir);
|
||||||
run("cd $testdir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v");
|
run("cd $dir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v --exe foo.cpp");
|
||||||
run("cd $testdir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
|
run("cd $dir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
|
||||||
#Need .c file, and --exe for this to work
|
run("cd $dir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
|
||||||
#run("cd $testdir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Run a test using exact path to binary
|
||||||
|
if ($Opt_Stage <= 3) {
|
||||||
|
my $dir = $testdirn;
|
||||||
|
run("/bin/rm -rf $dir");
|
||||||
|
run("/bin/mkdir -p $dir");
|
||||||
|
write_verilog($dir);
|
||||||
|
my $bin1 = $prefix."/bin";
|
||||||
|
my $bin2 = $prefix."/share/bin";
|
||||||
|
run("cd $dir && $bin1/verilator --cc foo.v --exe foo.cpp");
|
||||||
|
run("cd $dir/obj_dir && make -f Vfoo.mk");
|
||||||
|
run("cd $dir/obj_dir && ./Vfoo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub write_verilog {
|
||||||
|
my $dir = shift;
|
||||||
|
IO::File->new(">$dir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); $finish; end endmodule'."\n");
|
||||||
|
my $fh = IO::File->new(">$dir/foo.cpp");
|
||||||
|
$fh->print('#include "Vfoo.h"' ,"\n");
|
||||||
|
$fh->print('unsigned int main_time = 0;' ,"\n");
|
||||||
|
$fh->print('double sc_time_stamp () {' ,"\n");
|
||||||
|
$fh->print(' return main_time;' ,"\n");
|
||||||
|
$fh->print('}' ,"\n");
|
||||||
|
$fh->print('int main() {' ,"\n");
|
||||||
|
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
|
||||||
|
$fh->print(' while (!Verilated::gotFinish()) {',"\n");
|
||||||
|
$fh->print(' top->eval();' ,"\n");
|
||||||
|
$fh->print(' main_time++;' ,"\n");
|
||||||
|
$fh->print(' }' ,"\n");
|
||||||
|
$fh->print(' top->final();' ,"\n");
|
||||||
|
$fh->print('}' ,"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
sub cleanenv {
|
sub cleanenv {
|
||||||
@@ -117,7 +161,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2009-2010 by Wilson Snyder. This package is free software; you
|
Copyright 2009-2011 by Wilson Snyder. This package is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
can redistribute it and/or modify it under the terms of either the GNU
|
||||||
Lesser General Public License Version 3 or the Perl Artistic License
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+2
-14
@@ -8,21 +8,9 @@ use strict;
|
|||||||
#======================================================================
|
#======================================================================
|
||||||
# main
|
# main
|
||||||
|
|
||||||
delete $ENV{MODULE_VERSION};
|
eval `modulecmd perl add axiom-athdl`;
|
||||||
_setup_modules();
|
|
||||||
module('add','axiom-athdl');
|
|
||||||
exec('atsim',@ARGV);
|
exec('atsim',@ARGV);
|
||||||
|
|
||||||
#######################################################################
|
|
||||||
# Modules package
|
|
||||||
|
|
||||||
sub _setup_modules {
|
|
||||||
# Load the 'module' command into the environment
|
|
||||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
|
||||||
(-f $init) or die "%Error: Script not found: $init,";
|
|
||||||
require $init;
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
@@ -40,7 +28,7 @@ invoke_atsim - Invoke tool under "modules" command
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. This package is free software; you
|
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
can redistribute it and/or modify it under the terms of either the GNU
|
||||||
Lesser General Public License Version 3 or the Perl Artistic License
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+2
-14
@@ -8,21 +8,9 @@ use strict;
|
|||||||
#======================================================================
|
#======================================================================
|
||||||
# main
|
# main
|
||||||
|
|
||||||
delete $ENV{MODULE_VERSION};
|
eval `modulecmd perl add cds-ius`;
|
||||||
_setup_modules();
|
|
||||||
module('add','cadence-ius');
|
|
||||||
exec('iccr',@ARGV);
|
exec('iccr',@ARGV);
|
||||||
|
|
||||||
#######################################################################
|
|
||||||
# Modules package
|
|
||||||
|
|
||||||
sub _setup_modules {
|
|
||||||
# Load the 'module' command into the environment
|
|
||||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
|
||||||
(-f $init) or die "%Error: Script not found: $init,";
|
|
||||||
require $init;
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
@@ -40,7 +28,7 @@ invoke_iccr - Invoke tool under "modules" command
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2007-2010 by Wilson Snyder. This package is free software; you
|
Copyright 2007-2011 by Wilson Snyder. This package is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
can redistribute it and/or modify it under the terms of either the GNU
|
||||||
Lesser General Public License Version 3 or the Perl Artistic License
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+2
-14
@@ -8,21 +8,9 @@ use strict;
|
|||||||
#======================================================================
|
#======================================================================
|
||||||
# main
|
# main
|
||||||
|
|
||||||
delete $ENV{MODULE_VERSION};
|
eval `modulecmd perl add cds-ius`;
|
||||||
_setup_modules();
|
|
||||||
module('add','cadence-ius');
|
|
||||||
exec('ncverilog',@ARGV);
|
exec('ncverilog',@ARGV);
|
||||||
|
|
||||||
#######################################################################
|
|
||||||
# Modules package
|
|
||||||
|
|
||||||
sub _setup_modules {
|
|
||||||
# Load the 'module' command into the environment
|
|
||||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
|
||||||
(-f $init) or die "%Error: Script not found: $init,";
|
|
||||||
require $init;
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
@@ -40,7 +28,7 @@ invoke_ncverilog - Invoke tool under "modules" command
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. This package is free software; you
|
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
can redistribute it and/or modify it under the terms of either the GNU
|
||||||
Lesser General Public License Version 3 or the Perl Artistic License
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+2
-14
@@ -8,21 +8,9 @@ use strict;
|
|||||||
#======================================================================
|
#======================================================================
|
||||||
# main
|
# main
|
||||||
|
|
||||||
delete $ENV{MODULE_VERSION};
|
eval `modulecmd perl add synopsys-vcs`;
|
||||||
_setup_modules();
|
|
||||||
module('add','synopsys-vcs');
|
|
||||||
exec('vcs',@ARGV);
|
exec('vcs',@ARGV);
|
||||||
|
|
||||||
#######################################################################
|
|
||||||
# Modules package
|
|
||||||
|
|
||||||
sub _setup_modules {
|
|
||||||
# Load the 'module' command into the environment
|
|
||||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
|
||||||
(-f $init) or die "%Error: Script not found: $init,";
|
|
||||||
require $init;
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
@@ -40,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. This package is free software; you
|
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
can redistribute it and/or modify it under the terms of either the GNU
|
||||||
Lesser General Public License Version 3 or the Perl Artistic License
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2010-2010 by Wilson Snyder. This package is free software; you
|
# Copyright 2010-2011 by Wilson Snyder. This package is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -81,6 +81,7 @@ sub prep {
|
|||||||
$line =~ s/SP_NOTICE.*// if $sp;
|
$line =~ s/SP_NOTICE.*// if $sp;
|
||||||
$line =~ s/vl_fatal.*// if !$sp;
|
$line =~ s/vl_fatal.*// if !$sp;
|
||||||
$line =~ s/VL_PRINT.*// if !$sp;
|
$line =~ s/VL_PRINT.*// if !$sp;
|
||||||
|
$line =~ s/Copyright \d+-\d+/Copyright #-#/g;
|
||||||
|
|
||||||
push @wf, $line;
|
push @wf, $line;
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ print '(query-replace-regexp "(\\([0-9a-z_]+\\))" "\\1" nil nil nil)',"\n";
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval => 2);
|
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ sub gentree {
|
|||||||
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||||
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
|
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
|
||||||
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
|
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
|
||||||
'UNARYMIN' => sub { p " -";p1; },
|
'NEGATE' => sub { p " -";p1; },
|
||||||
'VAR' => sub { p_var(); },
|
'VAR' => sub { p_var(); },
|
||||||
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||||
'VARREF' => sub { a1; },
|
'VARREF' => sub { a1; },
|
||||||
@@ -331,7 +331,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2010 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2005-2011 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
+38
-4
@@ -9,7 +9,7 @@ This is the Verilator Package README file.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
This package is Copyright 2003-2010 by Wilson Snyder. (Report bugs to
|
This package is Copyright 2003-2011 by Wilson Snyder. (Report bugs to
|
||||||
L<http://www.veripool.org/>.)
|
L<http://www.veripool.org/>.)
|
||||||
|
|
||||||
Verilator is free software; you can redistribute it and/or modify it under
|
Verilator is free software; you can redistribute it and/or modify it under
|
||||||
@@ -91,12 +91,24 @@ headers.
|
|||||||
|
|
||||||
=item
|
=item
|
||||||
|
|
||||||
|
You will need the C<flex> and C<bison> packages installed.
|
||||||
|
|
||||||
|
=item
|
||||||
|
|
||||||
C<cd> to the Verilator directory containing this README.
|
C<cd> to the Verilator directory containing this README.
|
||||||
|
|
||||||
=item
|
=item
|
||||||
|
|
||||||
You now have to decide how you're going to eventually install the kit.
|
You now have to decide how you're going to eventually install the kit.
|
||||||
|
|
||||||
|
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC,
|
||||||
|
SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
|
||||||
|
executable, so try to have them correct before configuring.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item 1.
|
||||||
|
|
||||||
Our personal favorite is to always run Verilator from the kit directory.
|
Our personal favorite is to always run Verilator from the kit directory.
|
||||||
This allows the easiest experimentation and upgrading. It's also how most
|
This allows the easiest experimentation and upgrading. It's also how most
|
||||||
EDA tools operate; to run any of them you point to the tarball.
|
EDA tools operate; to run any of them you point to the tarball.
|
||||||
@@ -105,12 +117,33 @@ EDA tools operate; to run any of them you point to the tarball.
|
|||||||
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
||||||
./configure
|
./configure
|
||||||
|
|
||||||
|
=item 2.
|
||||||
|
|
||||||
|
To install globally onto a "cad" disk with multiple versions of every tool,
|
||||||
|
and add it to path using Modules/modulecmd:
|
||||||
|
|
||||||
|
unset VERILATOR_ROOT # if your shell is bash
|
||||||
|
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||||
|
# For the tarball, use the version number instead of git describe
|
||||||
|
./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
|
||||||
|
|
||||||
|
After installing you'll want a module file like the following:
|
||||||
|
|
||||||
|
set install_root /CAD_DISK/verilator/{version-number-used-above}
|
||||||
|
setenv VERILATOR_ROOT $install_root
|
||||||
|
prepend-path PATH $install_root/bin
|
||||||
|
prepend-path MANPATH $install_root/man
|
||||||
|
|
||||||
|
=item 3.
|
||||||
|
|
||||||
The next option is to install it globally, using the normal system paths:
|
The next option is to install it globally, using the normal system paths:
|
||||||
|
|
||||||
unset VERILATOR_ROOT # if your shell is bash
|
unset VERILATOR_ROOT # if your shell is bash
|
||||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||||
./configure
|
./configure
|
||||||
|
|
||||||
|
=item 4.
|
||||||
|
|
||||||
Alternatively you can configure a prefix that install will populate, as
|
Alternatively you can configure a prefix that install will populate, as
|
||||||
most GNU tools support:
|
most GNU tools support:
|
||||||
|
|
||||||
@@ -118,9 +151,10 @@ most GNU tools support:
|
|||||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||||
./configure --prefix /opt/verilator-VERSION
|
./configure --prefix /opt/verilator-VERSION
|
||||||
|
|
||||||
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC,
|
Then after installing you will need to add /opt/verilator-VERSION/bin to
|
||||||
SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
|
PATH.
|
||||||
executable, so try to have them correct before configuring.
|
|
||||||
|
=back
|
||||||
|
|
||||||
=item
|
=item
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ This is the Verilator Package.
|
|||||||
@node Copyright, Description, Top, Top
|
@node Copyright, Description, Top, Top
|
||||||
@section Copyright
|
@section Copyright
|
||||||
|
|
||||||
This package is Copyright 2003-2010 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
|
This package is Copyright 2003-2011 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
|
||||||
|
|
||||||
Verilator is free software; you can redistribute it and/or modify it
|
Verilator is free software; you can redistribute it and/or modify it
|
||||||
under the terms of either the GNU Lesser General Public License
|
under the terms of either the GNU Lesser General Public License
|
||||||
|
|||||||
+14
-25
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
# redistribute it and/or modify it under the terms of either the GNU
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
|
||||||
#### End of system configuration section. ####
|
#### End of system configuration section. ####
|
||||||
|
|
||||||
@@ -32,25 +33,11 @@ default: dbg opt
|
|||||||
debug: dbg
|
debug: dbg
|
||||||
optimize: opt
|
optimize: opt
|
||||||
|
|
||||||
ifeq ($(OBJCACHE_HOSTS),)
|
|
||||||
ifneq ($(SLCHOOSED_HOST),)
|
|
||||||
ifeq ($(VERILATOR_AUTHOR_SITE),1)
|
|
||||||
export OBJCACHE_HOSTS := $(shell rschedule --no-allow-reserved --similar hostnames)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OBJCACHE_JOBS),)
|
|
||||||
ifneq ($(OBJCACHE_HOSTS),)
|
|
||||||
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(words $(CURDIR)),1)
|
ifneq ($(words $(CURDIR)),1)
|
||||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
UNDER_GIT = $(wildcard ../.git/logs/HEAD)
|
UNDER_GIT = $(wildcard ${srcdir}/../.git/logs/HEAD)
|
||||||
|
|
||||||
#*********************************************************************
|
#*********************************************************************
|
||||||
|
|
||||||
@@ -65,26 +52,25 @@ opt: ../verilator_bin
|
|||||||
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
|
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
|
||||||
../verilator_bin: ../verilator_bin_dbg
|
../verilator_bin: ../verilator_bin_dbg
|
||||||
-rm -rf $@ $@.exe
|
-rm -rf $@ $@.exe
|
||||||
-cp -p $< $@
|
-cp -p $<$(EXEEXT) $@$(EXEEXT)
|
||||||
-cp -p $<.exe $@.exe
|
|
||||||
else
|
else
|
||||||
../verilator_bin: obj_opt prefiles
|
../verilator_bin: obj_opt prefiles
|
||||||
cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial
|
cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial
|
||||||
cd obj_opt && $(MAKE) $(OBJCACHE_JOBS) TGT=../$@ -f ../Makefile_obj
|
cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dbg: ../verilator_bin_dbg
|
dbg: ../verilator_bin_dbg
|
||||||
../verilator_bin_dbg: obj_dbg prefiles
|
../verilator_bin_dbg: obj_dbg prefiles
|
||||||
cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
|
cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
|
||||||
cd obj_dbg && $(MAKE) $(OBJCACHE_JOBS) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
|
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
|
||||||
|
|
||||||
prefiles::
|
prefiles::
|
||||||
|
|
||||||
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
|
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
|
||||||
prefiles:: config_rev.h
|
prefiles:: config_rev.h
|
||||||
# This output goes into srcdir, as we need to distribute it as part of the kit.
|
# This output goes into srcdir if locally configured, as we need to distribute it as part of the kit.
|
||||||
config_rev.h: config_rev.pl ../.git/logs/HEAD
|
config_rev.h: ${srcdir}/config_rev.pl ${srcdir}/../.git/logs/HEAD
|
||||||
$(PERL) config_rev.pl . >$@
|
$(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
maintainer-copy::
|
maintainer-copy::
|
||||||
@@ -96,3 +82,6 @@ clean mostlyclean distclean maintainer-clean::
|
|||||||
|
|
||||||
distclean maintainer-clean::
|
distclean maintainer-clean::
|
||||||
-rm -f Makefile Makefile_obj config_build.h
|
-rm -f Makefile Makefile_obj config_build.h
|
||||||
|
|
||||||
|
maintainer-clean::
|
||||||
|
-rm -f config_rev.h
|
||||||
|
|||||||
+16
-15
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
# redistribute it and/or modify it under the terms of either the GNU
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -57,9 +57,11 @@ datarootdir = @datarootdir@
|
|||||||
pkgdatadir = @pkgdatadir@
|
pkgdatadir = @pkgdatadir@
|
||||||
|
|
||||||
# Compile options
|
# Compile options
|
||||||
|
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||||
CPPFLAGSNOWALL += @CPPFLAGS@
|
CPPFLAGS += @CPPFLAGS@
|
||||||
LDFLAGS += @LDFLAGS@
|
LDFLAGS += @LDFLAGS@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
|
||||||
#### End of system configuration section. ####
|
#### End of system configuration section. ####
|
||||||
|
|
||||||
@@ -85,17 +87,18 @@ endif
|
|||||||
# -lfl not needed as Flex invoked with %nowrap option
|
# -lfl not needed as Flex invoked with %nowrap option
|
||||||
LIBS = -lm
|
LIBS = -lm
|
||||||
|
|
||||||
CPPFLAGSNOWALL += -MMD
|
CPPFLAGS += -MMD
|
||||||
CPPFLAGSNOWALL += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir)
|
CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir)
|
||||||
CPPFLAGSNOWALL += -DYYDEBUG # Required to get nice error messages
|
CPPFLAGS += -DYYDEBUG # Required to get nice error messages
|
||||||
#CPPFLAGSNOWALL += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
|
#CPPFLAGS += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
|
||||||
CPPFLAGSNOWALL += $(COPT)
|
CPPFLAGS += $(COPT)
|
||||||
CPPFLAGS = $(CPPFLAGSNOWALL)
|
CPPFLAGS += -MP # Only works on recent GCC versions
|
||||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||||
CPPFLAGSNOWALL += -MP # Only works on recent GCC versions
|
|
||||||
CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
|
CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
|
||||||
#CPPFLAGS += -pedantic-errors
|
#CPPFLAGS += -pedantic-errors
|
||||||
endif
|
endif
|
||||||
|
CPPFLAGSWALL = $(CPPFLAGS)
|
||||||
|
CPPFLAGSNOWALL = $(CPPFLAGS) -Wno-unused
|
||||||
|
|
||||||
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
|
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
|
||||||
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
|
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
|
||||||
@@ -209,7 +212,6 @@ RAW_OBJS = \
|
|||||||
V3PreShell.o \
|
V3PreShell.o \
|
||||||
V3Premit.o \
|
V3Premit.o \
|
||||||
V3Scope.o \
|
V3Scope.o \
|
||||||
V3Signed.o \
|
|
||||||
V3Slice.o \
|
V3Slice.o \
|
||||||
V3Split.o \
|
V3Split.o \
|
||||||
V3SplitAs.o \
|
V3SplitAs.o \
|
||||||
@@ -221,6 +223,7 @@ RAW_OBJS = \
|
|||||||
V3Trace.o \
|
V3Trace.o \
|
||||||
V3TraceDecl.o \
|
V3TraceDecl.o \
|
||||||
V3Tristate.o \
|
V3Tristate.o \
|
||||||
|
V3Undriven.o \
|
||||||
V3Unknown.o \
|
V3Unknown.o \
|
||||||
V3Unroll.o \
|
V3Unroll.o \
|
||||||
V3Width.o \
|
V3Width.o \
|
||||||
@@ -250,8 +253,6 @@ $(TGT): V3Ast__gen_classes.h $(OBJS)
|
|||||||
@echo " Linking $@..."
|
@echo " Linking $@..."
|
||||||
-rm -rf $@ [email protected]
|
-rm -rf $@ [email protected]
|
||||||
${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}
|
${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}
|
||||||
@-(cp [email protected] $@ || true)
|
|
||||||
# ok if cp failes on linux, it's there to insure executable works on NT
|
|
||||||
|
|
||||||
V3Number_test: V3Number_test.o
|
V3Number_test: V3Number_test.o
|
||||||
${LINK} ${LDFLAGS} -o $@ $^ ${LIBS}
|
${LINK} ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||||
@@ -262,9 +263,9 @@ V3Number_test: V3Number_test.o
|
|||||||
$(PERL) $(ASTGEN) -I$(srcdir) $*.cpp
|
$(PERL) $(ASTGEN) -I$(srcdir) $*.cpp
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(OBJCACHE) ${CXX} ${CPPFLAGS} -c $<
|
$(OBJCACHE) ${CXX} ${CPPFLAGSWALL} -c $<
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(OBJCACHE) ${CC} ${CPPFLAGS} -c $<
|
$(OBJCACHE) ${CC} ${CPPFLAGSWALL} -c $<
|
||||||
|
|
||||||
V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
|
V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
|
||||||
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
|
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
|
||||||
|
|||||||
+53
-14
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -148,7 +148,11 @@ public:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
ActiveNamer() {}
|
ActiveNamer() {
|
||||||
|
m_scopep = NULL;
|
||||||
|
m_iActivep = NULL;
|
||||||
|
m_cActivep = NULL;
|
||||||
|
}
|
||||||
virtual ~ActiveNamer() {}
|
virtual ~ActiveNamer() {}
|
||||||
void main(AstScope* nodep) {
|
void main(AstScope* nodep) {
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
@@ -160,26 +164,58 @@ public:
|
|||||||
|
|
||||||
class ActiveDlyVisitor : public ActiveBaseVisitor {
|
class ActiveDlyVisitor : public ActiveBaseVisitor {
|
||||||
private:
|
private:
|
||||||
|
bool m_combo; // Combo logic
|
||||||
|
AstNode* m_alwaysp; // Always we're under
|
||||||
|
AstNode* m_assignp; // In assign
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||||
// Convert to a non-delayed assignment
|
if (m_combo) {
|
||||||
UINFO(5," ASSIGNDLY "<<nodep<<endl);
|
// Convert to a non-delayed assignment
|
||||||
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) blocks should be non-delayed assignments (=).");
|
UINFO(5," ASSIGNDLY "<<nodep<<endl);
|
||||||
AstNode* newp = new AstAssign (nodep->fileline(),
|
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
|
||||||
nodep->lhsp()->unlinkFrBack(),
|
AstNode* newp = new AstAssign (nodep->fileline(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->replaceWith(newp);
|
nodep->rhsp()->unlinkFrBack());
|
||||||
nodep->deleteTree(); nodep = NULL;
|
nodep->replaceWith(newp);
|
||||||
|
nodep->deleteTree(); nodep = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstAssign* nodep, AstNUser*) {
|
||||||
|
if (!m_combo) {
|
||||||
|
AstNode* las = m_assignp;
|
||||||
|
m_assignp = nodep;
|
||||||
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
|
m_assignp = las;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
|
AstVar* varp=nodep->varp();
|
||||||
|
if (!m_combo
|
||||||
|
&& m_assignp
|
||||||
|
&& !varp->isUsedLoopIdx() // Ignore loop indicies
|
||||||
|
&& !varp->isTemp()
|
||||||
|
) {
|
||||||
|
// Allow turning off warnings on the always, or the variable also
|
||||||
|
if (!m_alwaysp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
|
||||||
|
&& !m_assignp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
|
||||||
|
&& !varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
|
||||||
|
) {
|
||||||
|
m_alwaysp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always
|
||||||
|
varp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
|
||||||
|
nodep->v3warn(BLKSEQ,"Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Empty visitors, speed things up
|
|
||||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
|
|
||||||
//--------------------
|
//--------------------
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
ActiveDlyVisitor(AstNode* nodep) {
|
ActiveDlyVisitor(AstNode* nodep, bool combo) {
|
||||||
|
m_alwaysp = nodep;
|
||||||
|
m_combo = combo;
|
||||||
|
m_assignp = NULL;
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
virtual ~ActiveDlyVisitor() {}
|
virtual ~ActiveDlyVisitor() {}
|
||||||
@@ -317,7 +353,10 @@ private:
|
|||||||
|
|
||||||
// Warn and/or convert any delayed assignments
|
// Warn and/or convert any delayed assignments
|
||||||
if (combo && !sequent) {
|
if (combo && !sequent) {
|
||||||
ActiveDlyVisitor dlyvisitor (nodep);
|
ActiveDlyVisitor dlyvisitor (nodep, true);
|
||||||
|
}
|
||||||
|
else if (!combo && sequent) {
|
||||||
|
ActiveDlyVisitor dlyvisitor (nodep, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+10
-9
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -182,18 +182,18 @@ private:
|
|||||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||||
if (itemp->isDefault()) has_default=true;
|
if (itemp->isDefault()) has_default=true;
|
||||||
}
|
}
|
||||||
if (nodep->fullPragma()) {
|
if (nodep->fullPragma() || nodep->priorityPragma()) {
|
||||||
// Simply need to add a default if there isn't one already
|
// Simply need to add a default if there isn't one already
|
||||||
m_statAsFull++;
|
++m_statAsFull;
|
||||||
if (!has_default) {
|
if (!has_default) {
|
||||||
nodep->addItemsp(new AstCaseItem(nodep->fileline(), NULL/*DEFAULT*/,
|
nodep->addItemsp(new AstCaseItem(nodep->fileline(), NULL/*DEFAULT*/,
|
||||||
newFireAssert(nodep, "synthesis full_case, but non-match found")));
|
newFireAssert(nodep, "synthesis full_case, but non-match found")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nodep->parallelPragma()) {
|
if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) {
|
||||||
// Need to check that one, and only one of the case items match at any moment
|
// Need to check that one, and only one of the case items match at any moment
|
||||||
// If there's a default, we allow none to match, else exactly one must match
|
// If there's a default, we allow none to match, else exactly one must match
|
||||||
m_statAsFull++;
|
++m_statAsFull;
|
||||||
if (!has_default && !nodep->itemsp()) {
|
if (!has_default && !nodep->itemsp()) {
|
||||||
// Not parallel, but harmlessly so.
|
// Not parallel, but harmlessly so.
|
||||||
} else {
|
} else {
|
||||||
@@ -207,7 +207,8 @@ private:
|
|||||||
else propp = onep;
|
else propp = onep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AstNode* ohot = (has_default
|
bool allow_none = has_default || nodep->unique0Pragma();
|
||||||
|
AstNode* ohot = (allow_none
|
||||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||||
AstIf* ifp = new AstIf (nodep->fileline(),
|
AstIf* ifp = new AstIf (nodep->fileline(),
|
||||||
@@ -240,18 +241,18 @@ private:
|
|||||||
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
|
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
|
||||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
||||||
nodep->stmtsp(), nodep->name()); nodep=NULL;
|
nodep->stmtsp(), nodep->name()); nodep=NULL;
|
||||||
m_statAsCover++;
|
++m_statAsCover;
|
||||||
}
|
}
|
||||||
virtual void visit(AstPslAssert* nodep, AstNUser*) {
|
virtual void visit(AstPslAssert* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
||||||
NULL, nodep->name()); nodep=NULL;
|
NULL, nodep->name()); nodep=NULL;
|
||||||
m_statAsPsl++;
|
++m_statAsPsl;
|
||||||
}
|
}
|
||||||
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
newVAssertion(nodep, nodep->propp()); nodep=NULL;
|
newVAssertion(nodep, nodep->propp()); nodep=NULL;
|
||||||
m_statAsSV++;
|
++m_statAsSV;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+8
-5
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -74,7 +74,9 @@ void AstNode::init() {
|
|||||||
m_clonep = NULL;
|
m_clonep = NULL;
|
||||||
m_cloneCnt = 0;
|
m_cloneCnt = 0;
|
||||||
// Attributes
|
// Attributes
|
||||||
m_signed = false;
|
m_numeric = (int)AstNumeric::UNSIGNED;
|
||||||
|
m_didWidth = false;
|
||||||
|
m_doingWidth = false;
|
||||||
m_width = 0;
|
m_width = 0;
|
||||||
m_widthMin = 0;
|
m_widthMin = 0;
|
||||||
m_user1p = NULL;
|
m_user1p = NULL;
|
||||||
@@ -192,6 +194,7 @@ string AstNode::prettyName(const string& namein) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||||
|
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
|
||||||
return pretty;
|
return pretty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +430,7 @@ void AstNode::replaceWith(AstNode* newp) {
|
|||||||
repHandle.relink(newp);
|
repHandle.relink(newp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstNRelinker::dump(ostream& str) {
|
void AstNRelinker::dump(ostream& str) const {
|
||||||
str<<" BK="<<(uint32_t*)m_backp;
|
str<<" BK="<<(uint32_t*)m_backp;
|
||||||
str<<" ITER="<<(uint32_t*)m_iterpp;
|
str<<" ITER="<<(uint32_t*)m_iterpp;
|
||||||
str<<" CHG="<<(m_chg==RELINK_NEXT?"[NEXT] ":"");
|
str<<" CHG="<<(m_chg==RELINK_NEXT?"[NEXT] ":"");
|
||||||
@@ -872,7 +875,7 @@ bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext) {
|
|||||||
if (this==NULL || node2p==NULL) return false;
|
if (this==NULL || node2p==NULL) return false;
|
||||||
if (this->type() != node2p->type()
|
if (this->type() != node2p->type()
|
||||||
|| this->width() != node2p->width()
|
|| this->width() != node2p->width()
|
||||||
|| this->isSigned() != node2p->isSigned()
|
|| this->numeric() != node2p->numeric()
|
||||||
|| !this->same(node2p)) {
|
|| !this->same(node2p)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -944,7 +947,7 @@ void AstNode::checkTree() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstNode::dumpPtrs(ostream& os) {
|
void AstNode::dumpPtrs(ostream& os) const {
|
||||||
os<<"This="<<typeName()<<" "<<(void*)this;
|
os<<"This="<<typeName()<<" "<<(void*)this;
|
||||||
os<<" back="<<(void*)backp();
|
os<<" back="<<(void*)backp();
|
||||||
if (nextp()) os<<" next="<<(void*)nextp();
|
if (nextp()) os<<" next="<<(void*)nextp();
|
||||||
|
|||||||
+87
-28
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Number.h"
|
#include "V3Number.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "V3Ast__gen_classes.h" // From ./astgen
|
#include "V3Ast__gen_classes.h" // From ./astgen
|
||||||
// Things like:
|
// Things like:
|
||||||
@@ -56,9 +57,40 @@ public:
|
|||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
|
class AstNumeric {
|
||||||
|
public:
|
||||||
|
enum en {
|
||||||
|
UNSIGNED,
|
||||||
|
SIGNED,
|
||||||
|
DOUBLE
|
||||||
|
// Limited to 2 bits, unless change V3Ast's packing function
|
||||||
|
};
|
||||||
|
enum en m_e;
|
||||||
|
const char* ascii() const {
|
||||||
|
static const char* names[] = {
|
||||||
|
"UNSIGNED","SIGNED","DOUBLE"
|
||||||
|
};
|
||||||
|
return names[m_e];
|
||||||
|
};
|
||||||
|
inline AstNumeric () : m_e(UNSIGNED) {}
|
||||||
|
inline AstNumeric (en _e) : m_e(_e) {}
|
||||||
|
explicit inline AstNumeric (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
|
operator en () const { return m_e; }
|
||||||
|
inline bool isDouble() const { return m_e==DOUBLE; }
|
||||||
|
inline bool isSigned() const { return m_e==SIGNED; }
|
||||||
|
inline bool isUnsigned() const { return m_e==UNSIGNED; }
|
||||||
|
};
|
||||||
|
inline bool operator== (AstNumeric lhs, AstNumeric rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
|
inline bool operator== (AstNumeric lhs, AstNumeric::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
inline bool operator== (AstNumeric::en lhs, AstNumeric rhs) { return (lhs == rhs.m_e); }
|
||||||
|
inline ostream& operator<<(ostream& os, AstNumeric rhs) { return os<<rhs.ascii(); }
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
class AstPragmaType {
|
class AstPragmaType {
|
||||||
public:
|
public:
|
||||||
enum en {
|
enum en {
|
||||||
|
ILLEGAL,
|
||||||
COVERAGE_BLOCK_OFF,
|
COVERAGE_BLOCK_OFF,
|
||||||
INLINE_MODULE,
|
INLINE_MODULE,
|
||||||
NO_INLINE_MODULE,
|
NO_INLINE_MODULE,
|
||||||
@@ -67,7 +99,7 @@ public:
|
|||||||
PUBLIC_TASK
|
PUBLIC_TASK
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstPragmaType () {}
|
inline AstPragmaType () : m_e(ILLEGAL) {}
|
||||||
inline AstPragmaType (en _e) : m_e(_e) {}
|
inline AstPragmaType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstPragmaType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstPragmaType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -90,7 +122,7 @@ public:
|
|||||||
TRACE_CHANGE_SUB
|
TRACE_CHANGE_SUB
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstCFuncType () {}
|
inline AstCFuncType () : m_e(FT_NORMAL) {}
|
||||||
inline AstCFuncType (en _e) : m_e(_e) {}
|
inline AstCFuncType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstCFuncType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstCFuncType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -158,7 +190,7 @@ public:
|
|||||||
};
|
};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
};
|
};
|
||||||
inline AstEdgeType () {}
|
inline AstEdgeType () : m_e(ET_ILLEGAL) {}
|
||||||
inline AstEdgeType (en _e) : m_e(_e) {}
|
inline AstEdgeType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -172,6 +204,7 @@ public:
|
|||||||
class AstAttrType {
|
class AstAttrType {
|
||||||
public:
|
public:
|
||||||
enum en {
|
enum en {
|
||||||
|
ILLEGAL,
|
||||||
EXPR_BITS, // V3Const converts to constant
|
EXPR_BITS, // V3Const converts to constant
|
||||||
//
|
//
|
||||||
VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
||||||
@@ -182,19 +215,20 @@ public:
|
|||||||
VAR_PUBLIC_FLAT_RD, // V3LinkParse moves to AstVar::sigPublic
|
VAR_PUBLIC_FLAT_RD, // V3LinkParse moves to AstVar::sigPublic
|
||||||
VAR_PUBLIC_FLAT_RW, // V3LinkParse moves to AstVar::sigPublic
|
VAR_PUBLIC_FLAT_RW, // V3LinkParse moves to AstVar::sigPublic
|
||||||
VAR_ISOLATE_ASSIGNMENTS, // V3LinkParse moves to AstVar::attrIsolateAssign
|
VAR_ISOLATE_ASSIGNMENTS, // V3LinkParse moves to AstVar::attrIsolateAssign
|
||||||
|
VAR_SC_BV, // V3LinkParse moves to AstVar::attrScBv
|
||||||
VAR_SFORMAT // V3LinkParse moves to AstVar::attrSFormat
|
VAR_SFORMAT // V3LinkParse moves to AstVar::attrSFormat
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
"EXPR_BITS", "VAR_BASE",
|
"%E-AT", "EXPR_BITS", "VAR_BASE",
|
||||||
"VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
"VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
||||||
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
||||||
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SFORMAT"
|
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT"
|
||||||
};
|
};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
};
|
};
|
||||||
inline AstAttrType () {}
|
inline AstAttrType () : m_e(ILLEGAL) {}
|
||||||
inline AstAttrType (en _e) : m_e(_e) {}
|
inline AstAttrType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -208,8 +242,9 @@ public:
|
|||||||
class AstBasicDTypeKwd {
|
class AstBasicDTypeKwd {
|
||||||
public:
|
public:
|
||||||
enum en {
|
enum en {
|
||||||
|
UNKNOWN,
|
||||||
BIT, BYTE, CHANDLE, INT, INTEGER, LOGIC, LONGINT,
|
BIT, BYTE, CHANDLE, INT, INTEGER, LOGIC, LONGINT,
|
||||||
REAL, REALTIME, SHORTINT, SHORTREAL, TIME,
|
DOUBLE, SHORTINT, FLOAT, TIME,
|
||||||
// Closer to a class type, but limited usage
|
// Closer to a class type, but limited usage
|
||||||
STRING,
|
STRING,
|
||||||
// Internal types for mid-steps
|
// Internal types for mid-steps
|
||||||
@@ -220,8 +255,9 @@ public:
|
|||||||
enum en m_e;
|
enum en m_e;
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
|
"%E-unk",
|
||||||
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
|
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
|
||||||
"real", "realtime", "shortint", "shortreal", "time",
|
"real", "shortint", "shortreal", "time",
|
||||||
"string",
|
"string",
|
||||||
"VerilatedScope*", "char*",
|
"VerilatedScope*", "char*",
|
||||||
"LOGIC_IMPLICIT"
|
"LOGIC_IMPLICIT"
|
||||||
@@ -230,15 +266,16 @@ public:
|
|||||||
};
|
};
|
||||||
const char* dpiType() const {
|
const char* dpiType() const {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
|
"%E-unk",
|
||||||
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
|
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
|
||||||
"double", "double", "short int", "float", "long long",
|
"double", "short int", "float", "long long",
|
||||||
"const char*",
|
"const char*",
|
||||||
"dpiScope", "const char*",
|
"dpiScope", "const char*",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
};
|
};
|
||||||
inline AstBasicDTypeKwd () {}
|
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
|
||||||
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
||||||
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -251,6 +288,8 @@ public:
|
|||||||
case INTEGER: return 32;
|
case INTEGER: return 32;
|
||||||
case LOGIC: return 1;
|
case LOGIC: return 1;
|
||||||
case LONGINT: return 64;
|
case LONGINT: return 64;
|
||||||
|
case DOUBLE: return 64;
|
||||||
|
case FLOAT: return 32;
|
||||||
case SHORTINT: return 16;
|
case SHORTINT: return 16;
|
||||||
case TIME: return 64;
|
case TIME: return 64;
|
||||||
case STRING: return 64; // Just the pointer, for today
|
case STRING: return 64; // Just the pointer, for today
|
||||||
@@ -265,7 +304,7 @@ public:
|
|||||||
}
|
}
|
||||||
bool isZeroInit() const { // Otherwise initializes to X
|
bool isZeroInit() const { // Otherwise initializes to X
|
||||||
return (m_e==BIT || m_e==BYTE || m_e==CHANDLE || m_e==INT || m_e==LONGINT || m_e==SHORTINT
|
return (m_e==BIT || m_e==BYTE || m_e==CHANDLE || m_e==INT || m_e==LONGINT || m_e==SHORTINT
|
||||||
|| m_e==STRING);
|
|| m_e==STRING || m_e==DOUBLE || m_e==FLOAT);
|
||||||
}
|
}
|
||||||
bool isSloppy() const { // Don't be as anal about width warnings
|
bool isSloppy() const { // Don't be as anal about width warnings
|
||||||
return !(m_e==LOGIC || m_e==BIT);
|
return !(m_e==LOGIC || m_e==BIT);
|
||||||
@@ -274,10 +313,13 @@ public:
|
|||||||
return (m_e==LOGIC || m_e==BIT);
|
return (m_e==LOGIC || m_e==BIT);
|
||||||
}
|
}
|
||||||
bool isDpiUnsupported() const {
|
bool isDpiUnsupported() const {
|
||||||
return (m_e==LOGIC || m_e==TIME || m_e==REALTIME);
|
return (m_e==LOGIC || m_e==TIME);
|
||||||
}
|
}
|
||||||
bool isOpaque() const { // IE not a simple number we can bit optimize
|
bool isOpaque() const { // IE not a simple number we can bit optimize
|
||||||
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR);
|
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==DOUBLE || m_e==FLOAT);
|
||||||
|
}
|
||||||
|
bool isDouble() const {
|
||||||
|
return (m_e==DOUBLE);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
@@ -316,7 +358,7 @@ public:
|
|||||||
XTEMP
|
XTEMP
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstVarType () {}
|
inline AstVarType () : m_e(UNKNOWN) {}
|
||||||
inline AstVarType (en _e) : m_e(_e) {}
|
inline AstVarType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -374,7 +416,7 @@ public:
|
|||||||
CT_CASEZ
|
CT_CASEZ
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstCaseType () {}
|
inline AstCaseType () : m_e(CT_CASE) {}
|
||||||
inline AstCaseType (en _e) : m_e(_e) {}
|
inline AstCaseType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstCaseType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstCaseType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -396,7 +438,7 @@ public:
|
|||||||
DT_FATAL
|
DT_FATAL
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstDisplayType () {}
|
inline AstDisplayType () : m_e(DT_DISPLAY) {}
|
||||||
inline AstDisplayType (en _e) : m_e(_e) {}
|
inline AstDisplayType (en _e) : m_e(_e) {}
|
||||||
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en () const { return m_e; }
|
||||||
@@ -606,7 +648,7 @@ public:
|
|||||||
AstNRelinker() { m_backp=NULL; m_chg=RELINK_BAD; m_iterpp=NULL;}
|
AstNRelinker() { m_backp=NULL; m_chg=RELINK_BAD; m_iterpp=NULL;}
|
||||||
void relink(AstNode* newp);
|
void relink(AstNode* newp);
|
||||||
AstNode* oldp() const { return m_oldp; }
|
AstNode* oldp() const { return m_oldp; }
|
||||||
void dump(ostream& str=cout);
|
void dump(ostream& str=cout) const;
|
||||||
};
|
};
|
||||||
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
|
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
|
||||||
|
|
||||||
@@ -684,7 +726,9 @@ class AstNode {
|
|||||||
static int s_cloneCntGbl; // Count of which userp is set
|
static int s_cloneCntGbl; // Count of which userp is set
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
bool m_signed:1; // Node is signed
|
uint32_t m_numeric:2; // Node is real/signed - important that bitfields remain unsigned
|
||||||
|
bool m_didWidth:1; // Did V3Width computation
|
||||||
|
bool m_doingWidth:1; // Inside V3Width
|
||||||
// // Space for more bools here
|
// // Space for more bools here
|
||||||
|
|
||||||
int m_width; // Bit width of operation
|
int m_width; // Bit width of operation
|
||||||
@@ -717,6 +761,7 @@ class AstNode {
|
|||||||
void deleteTreeIter();
|
void deleteTreeIter();
|
||||||
void deleteNode();
|
void deleteNode();
|
||||||
static void relinkOneLink(AstNode*& pointpr, AstNode* newp);
|
static void relinkOneLink(AstNode*& pointpr, AstNode* newp);
|
||||||
|
// cppcheck-suppress functionConst
|
||||||
void debugTreeChange(const char* prefix, int lineno, bool next);
|
void debugTreeChange(const char* prefix, int lineno, bool next);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -780,6 +825,9 @@ public:
|
|||||||
static int instrCountLd() { return 2; } ///< Instruction cycles to load memory
|
static int instrCountLd() { return 2; } ///< Instruction cycles to load memory
|
||||||
static int instrCountMul() { return 3; } ///< Instruction cycles to multiply integers
|
static int instrCountMul() { return 3; } ///< Instruction cycles to multiply integers
|
||||||
static int instrCountPli() { return 20; } ///< Instruction cycles to call pli routines
|
static int instrCountPli() { return 20; } ///< Instruction cycles to call pli routines
|
||||||
|
static int instrCountDouble() { return 8; } ///< Instruction cycles to convert or do floats
|
||||||
|
static int instrCountDoubleDiv() { return 40; } ///< Instruction cycles to divide floats
|
||||||
|
static int instrCountDoubleTrig() { return 200; } ///< Instruction cycles to do triganomics
|
||||||
static int instrCountCall() { return instrCountBranch()+10; } ///< Instruction cycles to call subroutine
|
static int instrCountCall() { return instrCountBranch()+10; } ///< Instruction cycles to call subroutine
|
||||||
static int instrCountTime() { return instrCountCall()+5; } ///< Instruction cycles to determine simulation time
|
static int instrCountTime() { return instrCountCall()+5; } ///< Instruction cycles to determine simulation time
|
||||||
|
|
||||||
@@ -807,10 +855,18 @@ public:
|
|||||||
bool widthSized() const { return !m_widthMin || m_widthMin==m_width; }
|
bool widthSized() const { return !m_widthMin || m_widthMin==m_width; }
|
||||||
void width(int width, int sized) { m_width=width; m_widthMin=sized; }
|
void width(int width, int sized) { m_width=width; m_widthMin=sized; }
|
||||||
void widthFrom(AstNode* fromp) { if (fromp) { m_width=fromp->m_width; m_widthMin=fromp->m_widthMin; }}
|
void widthFrom(AstNode* fromp) { if (fromp) { m_width=fromp->m_width; m_widthMin=fromp->m_widthMin; }}
|
||||||
void widthSignedFrom(AstNode* fromp) { widthFrom(fromp); signedFrom(fromp); }
|
void widthSignedFrom(AstNode* fromp) { widthFrom(fromp); numericFrom(fromp); }
|
||||||
void signedFrom(AstNode* fromp) { if (fromp) { m_signed=fromp->m_signed; }}
|
void numericFrom(AstNode* fromp) { numeric(fromp->numeric()); }
|
||||||
void isSigned(bool flag) { m_signed=flag; }
|
void numeric(AstNumeric flag) { m_numeric = (int)flag; if (flag.isDouble()) width(64,64); }
|
||||||
bool isSigned() const { return m_signed; }
|
AstNumeric numeric() const { return AstNumeric(m_numeric); }
|
||||||
|
bool isDouble() const { return numeric().isDouble(); }
|
||||||
|
bool isSigned() const { return numeric().isSigned(); }
|
||||||
|
void isSigned(bool flag) { numeric(flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); }
|
||||||
|
bool isUnsigned() const { return numeric().isUnsigned(); }
|
||||||
|
void didWidth(bool flag) { m_didWidth=flag; }
|
||||||
|
bool didWidth() const { return m_didWidth; }
|
||||||
|
void doingWidth(bool flag) { m_doingWidth=flag; }
|
||||||
|
bool doingWidth() const { return m_doingWidth; }
|
||||||
bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); }
|
bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); }
|
||||||
bool isWide() const { return (width()>VL_QUADSIZE); }
|
bool isWide() const { return (width()>VL_QUADSIZE); }
|
||||||
|
|
||||||
@@ -898,7 +954,7 @@ public:
|
|||||||
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
|
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
|
||||||
void deleteTree(); // Always deletes the next link
|
void deleteTree(); // Always deletes the next link
|
||||||
void checkTree(); // User Interface version
|
void checkTree(); // User Interface version
|
||||||
void dumpPtrs(ostream& str=cout);
|
void dumpPtrs(ostream& str=cout) const;
|
||||||
void dumpTree(ostream& str=cout, const string& indent=" ", int maxDepth=0);
|
void dumpTree(ostream& str=cout, const string& indent=" ", int maxDepth=0);
|
||||||
void dumpTreeAndNext(ostream& str=cout, const string& indent=" ", int maxDepth=0);
|
void dumpTreeAndNext(ostream& str=cout, const string& indent=" ", int maxDepth=0);
|
||||||
void dumpTreeFile(const string& filename, bool append=false);
|
void dumpTreeFile(const string& filename, bool append=false);
|
||||||
@@ -965,6 +1021,7 @@ struct AstNodeTermop : public AstNodeMath {
|
|||||||
ASTNODE_BASE_FUNCS(NodeTermop)
|
ASTNODE_BASE_FUNCS(NodeTermop)
|
||||||
// Know no children, and hot function, so skip iterator for speed
|
// Know no children, and hot function, so skip iterator for speed
|
||||||
// See checkTreeIter also that asserts no children
|
// See checkTreeIter also that asserts no children
|
||||||
|
// cppcheck-suppress functionConst
|
||||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -976,10 +1033,13 @@ struct AstNodeUniop : public AstNodeMath {
|
|||||||
setOp1p(lhsp); }
|
setOp1p(lhsp); }
|
||||||
ASTNODE_BASE_FUNCS(NodeUniop)
|
ASTNODE_BASE_FUNCS(NodeUniop)
|
||||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||||
|
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||||
// METHODS
|
// METHODS
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs
|
||||||
virtual bool cleanLhs() = 0;
|
virtual bool cleanLhs() = 0;
|
||||||
virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size
|
virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size
|
||||||
|
virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
|
||||||
|
virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors?
|
||||||
virtual int instrCount() const { return widthInstrs(); }
|
virtual int instrCount() const { return widthInstrs(); }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
virtual bool same(AstNode*) const { return true; }
|
virtual bool same(AstNode*) const { return true; }
|
||||||
@@ -1002,6 +1062,7 @@ struct AstNodeBiop : public AstNodeMath {
|
|||||||
virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size
|
virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size
|
||||||
virtual bool sizeMattersRhs() = 0; // True if output result depends on rhs size
|
virtual bool sizeMattersRhs() = 0; // True if output result depends on rhs size
|
||||||
virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
|
virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
|
||||||
|
virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors?
|
||||||
virtual int instrCount() const { return widthInstrs(); }
|
virtual int instrCount() const { return widthInstrs(); }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
virtual bool same(AstNode*) const { return true; }
|
virtual bool same(AstNode*) const { return true; }
|
||||||
@@ -1223,6 +1284,7 @@ public:
|
|||||||
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
||||||
// Know no children, and hot function, so skip iterator for speed
|
// Know no children, and hot function, so skip iterator for speed
|
||||||
// See checkTreeIter also that asserts no children
|
// See checkTreeIter also that asserts no children
|
||||||
|
// cppcheck-suppress functionConst
|
||||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1274,7 +1336,6 @@ private:
|
|||||||
string m_name; // Name of task
|
string m_name; // Name of task
|
||||||
string m_cname; // Name of task if DPI import
|
string m_cname; // Name of task if DPI import
|
||||||
bool m_taskPublic:1; // Public task
|
bool m_taskPublic:1; // Public task
|
||||||
bool m_didSigning:1; // V3Signed completed; can skip iteration
|
|
||||||
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
|
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
|
||||||
bool m_prototype:1; // Just a prototype
|
bool m_prototype:1; // Just a prototype
|
||||||
bool m_dpiExport:1; // DPI exported
|
bool m_dpiExport:1; // DPI exported
|
||||||
@@ -1285,7 +1346,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp)
|
AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp)
|
||||||
: AstNode(fileline)
|
: AstNode(fileline)
|
||||||
, m_name(name), m_taskPublic(false), m_didSigning(false)
|
, m_name(name), m_taskPublic(false)
|
||||||
, m_attrIsolateAssign(false), m_prototype(false)
|
, m_attrIsolateAssign(false), m_prototype(false)
|
||||||
, m_dpiExport(false), m_dpiImport(false), m_dpiContext(false)
|
, m_dpiExport(false), m_dpiImport(false), m_dpiContext(false)
|
||||||
, m_dpiTask(false), m_pure(false) {
|
, m_dpiTask(false), m_pure(false) {
|
||||||
@@ -1312,8 +1373,6 @@ public:
|
|||||||
void scopeNamep(AstNode* nodep) { setNOp4p(nodep); }
|
void scopeNamep(AstNode* nodep) { setNOp4p(nodep); }
|
||||||
void taskPublic(bool flag) { m_taskPublic=flag; }
|
void taskPublic(bool flag) { m_taskPublic=flag; }
|
||||||
bool taskPublic() const { return m_taskPublic; }
|
bool taskPublic() const { return m_taskPublic; }
|
||||||
void didSigning(bool flag) { m_didSigning=flag; }
|
|
||||||
bool didSigning() const { return m_didSigning; }
|
|
||||||
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
||||||
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
||||||
void prototype(bool flag) { m_prototype = flag; }
|
void prototype(bool flag) { m_prototype = flag; }
|
||||||
|
|||||||
+14
-8
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -70,7 +70,7 @@ bool AstVar::isScQuad() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AstVar::isScBv() const {
|
bool AstVar::isScBv() const {
|
||||||
return (isSc() && width() >= v3Global.opt.pinsBv());
|
return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstVar::combineType(AstVarType type) {
|
void AstVar::combineType(AstVarType type) {
|
||||||
@@ -113,6 +113,10 @@ string AstVar::vlArgType(bool named, bool forReturn) const {
|
|||||||
arg += "const char*";
|
arg += "const char*";
|
||||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
||||||
arg += "const VerilatedScope*";
|
arg += "const VerilatedScope*";
|
||||||
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) {
|
||||||
|
arg += "double";
|
||||||
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) {
|
||||||
|
arg += "float";
|
||||||
} else if (strtype) {
|
} else if (strtype) {
|
||||||
if (isInOnly()) arg += "const ";
|
if (isInOnly()) arg += "const ";
|
||||||
arg += "string";
|
arg += "string";
|
||||||
@@ -185,7 +189,7 @@ string AstVar::cPubArgType(bool named, bool forReturn) const {
|
|||||||
} else if (isWide()) {
|
} else if (isWide()) {
|
||||||
arg += "uint32_t"; // []'s added later
|
arg += "uint32_t"; // []'s added later
|
||||||
} else {
|
} else {
|
||||||
arg += "uint64_t";
|
arg += "vluint64_t";
|
||||||
}
|
}
|
||||||
if (isWide()) {
|
if (isWide()) {
|
||||||
if (forReturn) v3error("Unsupported: Public functions with >64 bit outputs; make an output of a public task instead");
|
if (forReturn) v3error("Unsupported: Public functions with >64 bit outputs; make an output of a public task instead");
|
||||||
@@ -202,7 +206,6 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
|
|||||||
if (forReturn) named=false;
|
if (forReturn) named=false;
|
||||||
string arg;
|
string arg;
|
||||||
if (!basicp()) arg = "UNKNOWN";
|
if (!basicp()) arg = "UNKNOWN";
|
||||||
if (isWide()) v3error("Unsupported: DPI functions with vectored outputs > 32-bits");
|
|
||||||
if (basicp()->isBitLogic()) {
|
if (basicp()->isBitLogic()) {
|
||||||
if (widthMin() == 1) {
|
if (widthMin() == 1) {
|
||||||
arg = "unsigned char";
|
arg = "unsigned char";
|
||||||
@@ -238,7 +241,7 @@ string AstVar::scType() const {
|
|||||||
return "uint32_t";
|
return "uint32_t";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "uint64_t";
|
return "vluint64_t";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,8 +501,9 @@ void AstNode::dump(ostream& os) {
|
|||||||
//<<" "<<(void*)this->m_backp
|
//<<" "<<(void*)this->m_backp
|
||||||
<<" <e"<<dec<<editCount()
|
<<" <e"<<dec<<editCount()
|
||||||
<<((editCount()>=editCountLast())?"#>":">")
|
<<((editCount()>=editCountLast())?"#>":">")
|
||||||
<<" {"<<dec<<fileline()->lineno()<<"}"
|
<<" {"<<fileline()->filenameLetters()<<dec<<fileline()->lineno()<<"}"
|
||||||
<<" "<<(isSigned()?"s":"")
|
<<" "<<(isSigned()?"s":"")
|
||||||
|
<<(isDouble()?"d":"")
|
||||||
<<"w"<<(widthSized()?"":"u")<<width();
|
<<"w"<<(widthSized()?"":"u")<<width();
|
||||||
if (!widthSized()) os<<"/"<<widthMin();
|
if (!widthSized()) os<<"/"<<widthMin();
|
||||||
if (name()!="") os<<" "<<AstNode::quoteName(name());
|
if (name()!="") os<<" "<<AstNode::quoteName(name());
|
||||||
@@ -522,7 +526,7 @@ void AstBasicDType::dump(ostream& str) {
|
|||||||
str<<" ["<<keyword().ascii()<<"]";
|
str<<" ["<<keyword().ascii()<<"]";
|
||||||
if (implicit()) str<<" [IMPLICIT]";
|
if (implicit()) str<<" [IMPLICIT]";
|
||||||
}
|
}
|
||||||
void AstCast::dump(ostream& str) {
|
void AstCCast::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
str<<" sz"<<size();
|
str<<" sz"<<size();
|
||||||
}
|
}
|
||||||
@@ -609,8 +613,10 @@ void AstVar::dump(ostream& str) {
|
|||||||
else if (isInput()) str<<" [I]";
|
else if (isInput()) str<<" [I]";
|
||||||
else if (isOutput()) str<<" [O]";
|
else if (isOutput()) str<<" [O]";
|
||||||
}
|
}
|
||||||
if (isUsedClock()) str<<" [C]";
|
if (isConst()) str<<" [CONST]";
|
||||||
|
if (isUsedClock()) str<<" [CLK]";
|
||||||
if (isSigPublic()) str<<" [P]";
|
if (isSigPublic()) str<<" [P]";
|
||||||
|
if (isUsedLoopIdx()) str<<" [LOOP]";
|
||||||
if (attrClockEn()) str<<" [aCLKEN]";
|
if (attrClockEn()) str<<" [aCLKEN]";
|
||||||
if (attrIsolateAssign()) str<<" [aISO]";
|
if (attrIsolateAssign()) str<<" [aISO]";
|
||||||
if (attrFileDescr()) str<<" [aFD]";
|
if (attrFileDescr()) str<<" [aFD]";
|
||||||
|
|||||||
+520
-53
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -46,19 +46,25 @@ struct AstConst : public AstNodeMath {
|
|||||||
private:
|
private:
|
||||||
V3Number m_num; // Constant value
|
V3Number m_num; // Constant value
|
||||||
public:
|
public:
|
||||||
class Unsized32 {}; // for creator type-overload selection
|
|
||||||
AstConst(FileLine* fl, const V3Number& num)
|
AstConst(FileLine* fl, const V3Number& num)
|
||||||
:AstNodeMath(fl)
|
:AstNodeMath(fl)
|
||||||
,m_num(num) {
|
,m_num(num) {
|
||||||
width(m_num.width(), m_num.sized()?0:m_num.minWidth());
|
width(m_num.width(), m_num.sized()?0:m_num.minWidth());
|
||||||
isSigned(m_num.isSigned());
|
numeric(m_num.isDouble() ? AstNumeric::DOUBLE
|
||||||
|
: m_num.isSigned() ? AstNumeric::SIGNED
|
||||||
|
: AstNumeric::UNSIGNED);
|
||||||
}
|
}
|
||||||
AstConst(FileLine* fl, uint32_t num)
|
AstConst(FileLine* fl, uint32_t num)
|
||||||
:AstNodeMath(fl)
|
:AstNodeMath(fl)
|
||||||
,m_num(V3Number(fl,32,num)) { width(m_num.width(), m_num.sized()?0:m_num.minWidth()); }
|
,m_num(V3Number(fl,32,num)) { width(m_num.width(), m_num.sized()?0:m_num.minWidth()); }
|
||||||
|
class Unsized32 {}; // for creator type-overload selection
|
||||||
AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value
|
AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value
|
||||||
:AstNodeMath(fl)
|
:AstNodeMath(fl)
|
||||||
,m_num(V3Number(fl,32,num)) { m_num.width(32,false); width(32,m_num.minWidth()); }
|
,m_num(V3Number(fl,32,num)) { m_num.width(32,false); width(32,m_num.minWidth()); }
|
||||||
|
class RealDouble {}; // for creator type-overload selection
|
||||||
|
AstConst(FileLine* fl, RealDouble, double num)
|
||||||
|
:AstNodeMath(fl)
|
||||||
|
,m_num(V3Number(fl,64)) { m_num.setDouble(num); numeric(AstNumeric::DOUBLE); }
|
||||||
class LogicFalse {};
|
class LogicFalse {};
|
||||||
AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1
|
AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1
|
||||||
:AstNodeMath(fl)
|
:AstNodeMath(fl)
|
||||||
@@ -258,7 +264,8 @@ private:
|
|||||||
m_keyword = AstBasicDTypeKwd::LOGIC;
|
m_keyword = AstBasicDTypeKwd::LOGIC;
|
||||||
}
|
}
|
||||||
if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED;
|
if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED;
|
||||||
setSignedState(signst);
|
if (keyword().isDouble()) numeric(AstNumeric::DOUBLE);
|
||||||
|
else setSignedState(signst);
|
||||||
if (!rangep) { // Set based on keyword properties
|
if (!rangep) { // Set based on keyword properties
|
||||||
// V3Width will pull from this width
|
// V3Width will pull from this width
|
||||||
if (keyword().width() > 1 && !isOpaque()) rangep = new AstRange(fileline(), keyword().width()-1, 0);
|
if (keyword().width() > 1 && !isOpaque()) rangep = new AstRange(fileline(), keyword().width()-1, 0);
|
||||||
@@ -278,7 +285,8 @@ public:
|
|||||||
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
|
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
|
||||||
void rangep(AstRange* nodep) { setNOp1p(nodep); }
|
void rangep(AstRange* nodep) { setNOp1p(nodep); }
|
||||||
void setSignedState(AstSignedState signst) {
|
void setSignedState(AstSignedState signst) {
|
||||||
if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED);
|
if (signst==signedst_UNSIGNED) numeric(AstNumeric::UNSIGNED);
|
||||||
|
else if (signst==signedst_SIGNED) numeric(AstNumeric::SIGNED);
|
||||||
}
|
}
|
||||||
// METHODS
|
// METHODS
|
||||||
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
|
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
|
||||||
@@ -300,6 +308,25 @@ public:
|
|||||||
void implicit(bool flag) { m_implicit = flag; }
|
void implicit(bool flag) { m_implicit = flag; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstConstDType : public AstNodeDType {
|
||||||
|
// const data type, ie "const some_dtype var_name [2:0]"
|
||||||
|
// ConstDType are removed in V3LinkLValue and become AstVar::isConst.
|
||||||
|
// When more generic types are supported AstConstDType will be propagated further.
|
||||||
|
AstConstDType(FileLine* fl, AstNodeDType* dtypep)
|
||||||
|
: AstNodeDType(fl) {
|
||||||
|
setOp1p(dtypep);
|
||||||
|
widthSignedFrom(dtypep);
|
||||||
|
}
|
||||||
|
ASTNODE_NODE_FUNCS(ConstDType, CONSTDTYPE)
|
||||||
|
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||||
|
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||||
|
// METHODS
|
||||||
|
virtual AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||||
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
||||||
|
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstRefDType : public AstNodeDType {
|
struct AstRefDType : public AstNodeDType {
|
||||||
private:
|
private:
|
||||||
AstTypedef* m_defp;
|
AstTypedef* m_defp;
|
||||||
@@ -364,9 +391,10 @@ public:
|
|||||||
struct AstEnumItemRef : public AstNodeMath {
|
struct AstEnumItemRef : public AstNodeMath {
|
||||||
private:
|
private:
|
||||||
AstEnumItem* m_itemp; // [AfterLink] Pointer to item
|
AstEnumItem* m_itemp; // [AfterLink] Pointer to item
|
||||||
|
AstPackage* m_packagep; // Package hierarchy
|
||||||
public:
|
public:
|
||||||
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp)
|
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstPackage* packagep)
|
||||||
: AstNodeMath(fl), m_itemp(itemp) {
|
: AstNodeMath(fl), m_itemp(itemp), m_packagep(packagep) {
|
||||||
if (m_itemp) widthSignedFrom(m_itemp);
|
if (m_itemp) widthSignedFrom(m_itemp);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(EnumItemRef, ENUMITEMREF)
|
ASTNODE_NODE_FUNCS(EnumItemRef, ENUMITEMREF)
|
||||||
@@ -381,6 +409,8 @@ public:
|
|||||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
virtual bool cleanOut() { return true; }
|
virtual bool cleanOut() { return true; }
|
||||||
|
AstPackage* packagep() const { return m_packagep; }
|
||||||
|
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstEnumDType : public AstNodeDType {
|
struct AstEnumDType : public AstNodeDType {
|
||||||
@@ -431,10 +461,10 @@ public:
|
|||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
virtual bool same(AstNode* samep) const { return true; }
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
virtual int instrCount() const { return widthInstrs(); }
|
virtual int instrCount() const { return widthInstrs(); }
|
||||||
unsigned length() { return m_length; }
|
unsigned length() const { return m_length; }
|
||||||
void length(unsigned length) { m_length = length; }
|
void length(unsigned length) { m_length = length; }
|
||||||
void start(unsigned start) { m_start = start; }
|
void start(unsigned start) { m_start = start; }
|
||||||
unsigned start() { return m_start; }
|
unsigned start() const { return m_start; }
|
||||||
// Special operators
|
// Special operators
|
||||||
static int dimension(AstNode* nodep); ///< How many dimensions is this reference from the base variable?
|
static int dimension(AstNode* nodep); ///< How many dimensions is this reference from the base variable?
|
||||||
static AstNode* baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences?
|
static AstNode* baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences?
|
||||||
@@ -553,9 +583,11 @@ private:
|
|||||||
bool m_sigUserRWPublic:1; // User C code accesses this signal, read-write
|
bool m_sigUserRWPublic:1; // User C code accesses this signal, read-write
|
||||||
bool m_usedClock:1; // Signal used as a clock
|
bool m_usedClock:1; // Signal used as a clock
|
||||||
bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup)
|
bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup)
|
||||||
|
bool m_usedLoopIdx:1; // Variable subject of for unrolling
|
||||||
bool m_funcLocal:1; // Local variable for a function
|
bool m_funcLocal:1; // Local variable for a function
|
||||||
bool m_funcReturn:1; // Return variable for a function
|
bool m_funcReturn:1; // Return variable for a function
|
||||||
bool m_attrClockEn:1;// User clock enable attribute
|
bool m_attrClockEn:1;// User clock enable attribute
|
||||||
|
bool m_attrScBv:1; // User force bit vector attribute
|
||||||
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
|
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
|
||||||
bool m_attrSFormat:1;// User sformat attribute
|
bool m_attrSFormat:1;// User sformat attribute
|
||||||
bool m_fileDescr:1; // File descriptor
|
bool m_fileDescr:1; // File descriptor
|
||||||
@@ -567,10 +599,10 @@ private:
|
|||||||
m_input=false; m_output=false; m_tristate=false;
|
m_input=false; m_output=false; m_tristate=false;
|
||||||
m_primaryIO=false;
|
m_primaryIO=false;
|
||||||
m_sc=false; m_scClocked=false; m_scSensitive=false;
|
m_sc=false; m_scClocked=false; m_scSensitive=false;
|
||||||
m_usedClock=false; m_usedParam=false;
|
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
|
||||||
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
|
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
|
||||||
m_funcLocal=false; m_funcReturn=false;
|
m_funcLocal=false; m_funcReturn=false;
|
||||||
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrSFormat=false;
|
m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false;
|
||||||
m_fileDescr=false; m_isConst=false; m_isStatic=false;
|
m_fileDescr=false; m_isConst=false; m_isStatic=false;
|
||||||
m_trace=false;
|
m_trace=false;
|
||||||
}
|
}
|
||||||
@@ -581,6 +613,7 @@ public:
|
|||||||
init();
|
init();
|
||||||
combineType(type); setOp1p(dtypep);
|
combineType(type); setOp1p(dtypep);
|
||||||
if (dtypep && dtypep->basicp()) {
|
if (dtypep && dtypep->basicp()) {
|
||||||
|
numericFrom(dtypep);
|
||||||
width(dtypep->basicp()->width(), 0);
|
width(dtypep->basicp()->width(), 0);
|
||||||
} else width(1, 0);
|
} else width(1, 0);
|
||||||
}
|
}
|
||||||
@@ -600,6 +633,7 @@ public:
|
|||||||
if (examplep->dtypep()) {
|
if (examplep->dtypep()) {
|
||||||
setOp1p(examplep->dtypep()->cloneTree(true));
|
setOp1p(examplep->dtypep()->cloneTree(true));
|
||||||
}
|
}
|
||||||
|
numericFrom(examplep);
|
||||||
width(examplep->width(), examplep->widthMin());
|
width(examplep->width(), examplep->widthMin());
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Var, VAR)
|
ASTNODE_NODE_FUNCS(Var, VAR)
|
||||||
@@ -631,10 +665,12 @@ public:
|
|||||||
void attrClockEn(bool flag) { m_attrClockEn = flag; }
|
void attrClockEn(bool flag) { m_attrClockEn = flag; }
|
||||||
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
||||||
void attrScClocked(bool flag) { m_scClocked = flag; }
|
void attrScClocked(bool flag) { m_scClocked = flag; }
|
||||||
|
void attrScBv(bool flag) { m_attrScBv = flag; }
|
||||||
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
||||||
void attrSFormat(bool flag) { m_attrSFormat = flag; }
|
void attrSFormat(bool flag) { m_attrSFormat = flag; }
|
||||||
void usedClock(bool flag) { m_usedClock = flag; }
|
void usedClock(bool flag) { m_usedClock = flag; }
|
||||||
void usedParam(bool flag) { m_usedParam = flag; }
|
void usedParam(bool flag) { m_usedParam = flag; }
|
||||||
|
void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; }
|
||||||
void sigPublic(bool flag) { m_sigPublic = flag; }
|
void sigPublic(bool flag) { m_sigPublic = flag; }
|
||||||
void sigModPublic(bool flag) { m_sigModPublic = flag; }
|
void sigModPublic(bool flag) { m_sigModPublic = flag; }
|
||||||
void sigUserRdPublic(bool flag) { m_sigUserRdPublic = flag; if (flag) sigPublic(true); }
|
void sigUserRdPublic(bool flag) { m_sigUserRdPublic = flag; if (flag) sigPublic(true); }
|
||||||
@@ -665,7 +701,7 @@ public:
|
|||||||
bool isToggleCoverable() const { return ((isIO() || isSignal())
|
bool isToggleCoverable() const { return ((isIO() || isSignal())
|
||||||
&& (isIO() || isBitLogic())
|
&& (isIO() || isBitLogic())
|
||||||
// Wrapper would otherwise duplicate wrapped module's coverage
|
// Wrapper would otherwise duplicate wrapped module's coverage
|
||||||
&& !isSc() && !isPrimaryIO()); }
|
&& !isSc() && !isPrimaryIO() && !isConst()); }
|
||||||
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
|
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
|
||||||
bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); }
|
bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); }
|
||||||
bool isPure() const { return (varType()==AstVarType::XTEMP); }
|
bool isPure() const { return (varType()==AstVarType::XTEMP); }
|
||||||
@@ -675,6 +711,7 @@ public:
|
|||||||
bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); }
|
bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); }
|
||||||
bool isUsedClock() const { return m_usedClock; }
|
bool isUsedClock() const { return m_usedClock; }
|
||||||
bool isUsedParam() const { return m_usedParam; }
|
bool isUsedParam() const { return m_usedParam; }
|
||||||
|
bool isUsedLoopIdx() const { return m_usedLoopIdx; }
|
||||||
bool isSc() const { return m_sc; }
|
bool isSc() const { return m_sc; }
|
||||||
bool isScQuad() const;
|
bool isScQuad() const;
|
||||||
bool isScBv() const;
|
bool isScBv() const;
|
||||||
@@ -689,6 +726,7 @@ public:
|
|||||||
bool isFuncLocal() const { return m_funcLocal; }
|
bool isFuncLocal() const { return m_funcLocal; }
|
||||||
bool isFuncReturn() const { return m_funcReturn; }
|
bool isFuncReturn() const { return m_funcReturn; }
|
||||||
bool attrClockEn() const { return m_attrClockEn; }
|
bool attrClockEn() const { return m_attrClockEn; }
|
||||||
|
bool attrScBv() const { return m_attrScBv; }
|
||||||
bool attrFileDescr() const { return m_fileDescr; }
|
bool attrFileDescr() const { return m_fileDescr; }
|
||||||
bool attrScClocked() const { return m_scClocked; }
|
bool attrScClocked() const { return m_scClocked; }
|
||||||
bool attrSFormat() const { return m_attrSFormat; }
|
bool attrSFormat() const { return m_attrSFormat; }
|
||||||
@@ -909,7 +947,9 @@ public:
|
|||||||
,m_name(name), m_svImplicit(false) {
|
,m_name(name), m_svImplicit(false) {
|
||||||
m_pinNum = pinNum;
|
m_pinNum = pinNum;
|
||||||
m_modVarp = NULL;
|
m_modVarp = NULL;
|
||||||
setNOp1p(exprp); }
|
setNOp1p(exprp);
|
||||||
|
if (exprp) widthSignedFrom(exprp);
|
||||||
|
}
|
||||||
ASTNODE_NODE_FUNCS(Pin, PIN)
|
ASTNODE_NODE_FUNCS(Pin, PIN)
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
virtual bool broken() const { return (m_modVarp && !m_modVarp->brokeExists()); }
|
virtual bool broken() const { return (m_modVarp && !m_modVarp->brokeExists()); }
|
||||||
@@ -918,7 +958,7 @@ public:
|
|||||||
bool dotStar() const { return name() == ".*"; } // Special fake name for .* connections until linked
|
bool dotStar() const { return name() == ".*"; } // Special fake name for .* connections until linked
|
||||||
int pinNum() const { return m_pinNum; }
|
int pinNum() const { return m_pinNum; }
|
||||||
void exprp(AstNode* nodep) { addOp1p(nodep); }
|
void exprp(AstNode* nodep) { addOp1p(nodep); }
|
||||||
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
|
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin, NULL if unconnected
|
||||||
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
|
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
|
||||||
void modVarp(AstVar* varp) { m_modVarp=varp; }
|
void modVarp(AstVar* varp) { m_modVarp=varp; }
|
||||||
bool svImplicit() const { return m_svImplicit; }
|
bool svImplicit() const { return m_svImplicit; }
|
||||||
@@ -933,6 +973,14 @@ struct AstModule : public AstNodeModule {
|
|||||||
virtual string verilogKwd() const { return "module"; }
|
virtual string verilogKwd() const { return "module"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstNotFoundModule : public AstNodeModule {
|
||||||
|
// A missing module declaration
|
||||||
|
AstNotFoundModule(FileLine* fl, const string& name)
|
||||||
|
: AstNodeModule (fl,name) {}
|
||||||
|
ASTNODE_NODE_FUNCS(NotFoundModule, NOTFOUNDMODULE)
|
||||||
|
virtual string verilogKwd() const { return "/*not-found-*/ module"; }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstPackage : public AstNodeModule {
|
struct AstPackage : public AstNodeModule {
|
||||||
// A package declaration
|
// A package declaration
|
||||||
AstPackage(FileLine* fl, const string& name)
|
AstPackage(FileLine* fl, const string& name)
|
||||||
@@ -1538,11 +1586,15 @@ private:
|
|||||||
AstCaseType m_casex; // 0=case, 1=casex, 2=casez
|
AstCaseType m_casex; // 0=case, 1=casex, 2=casez
|
||||||
bool m_fullPragma; // Synthesis full_case
|
bool m_fullPragma; // Synthesis full_case
|
||||||
bool m_parallelPragma; // Synthesis parallel_case
|
bool m_parallelPragma; // Synthesis parallel_case
|
||||||
|
bool m_uniquePragma; // unique case
|
||||||
|
bool m_unique0Pragma; // unique0 case
|
||||||
|
bool m_priorityPragma; // priority case
|
||||||
public:
|
public:
|
||||||
AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp)
|
AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp)
|
||||||
: AstNodeCase(fileline, exprp, casesp) {
|
: AstNodeCase(fileline, exprp, casesp) {
|
||||||
m_casex=casex;
|
m_casex=casex;
|
||||||
m_fullPragma=false; m_parallelPragma=false;
|
m_fullPragma=false; m_parallelPragma=false;
|
||||||
|
m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false;
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Case, CASE)
|
ASTNODE_NODE_FUNCS(Case, CASE)
|
||||||
virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; }
|
virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; }
|
||||||
@@ -1554,6 +1606,12 @@ public:
|
|||||||
void fullPragma(bool flag) { m_fullPragma=flag; }
|
void fullPragma(bool flag) { m_fullPragma=flag; }
|
||||||
bool parallelPragma() const { return m_parallelPragma; }
|
bool parallelPragma() const { return m_parallelPragma; }
|
||||||
void parallelPragma(bool flag) { m_parallelPragma=flag; }
|
void parallelPragma(bool flag) { m_parallelPragma=flag; }
|
||||||
|
bool uniquePragma() const { return m_uniquePragma; }
|
||||||
|
void uniquePragma(bool flag) { m_uniquePragma=flag; }
|
||||||
|
bool unique0Pragma() const { return m_unique0Pragma; }
|
||||||
|
void unique0Pragma(bool flag) { m_unique0Pragma=flag; }
|
||||||
|
bool priorityPragma() const { return m_priorityPragma; }
|
||||||
|
void priorityPragma(bool flag) { m_priorityPragma=flag; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstCaseItem : public AstNode {
|
struct AstCaseItem : public AstNode {
|
||||||
@@ -1580,7 +1638,7 @@ public:
|
|||||||
void ignoreOverlap(bool flag) { m_ignoreOverlap = flag; }
|
void ignoreOverlap(bool flag) { m_ignoreOverlap = flag; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstSFormatF : public AstNode {
|
struct AstSFormatF : public AstNode {
|
||||||
// Convert format to string, generally under a AstDisplay or AstSFormat
|
// Convert format to string, generally under a AstDisplay or AstSFormat
|
||||||
// Also used as "real" function for /*verilator sformat*/ functions
|
// Also used as "real" function for /*verilator sformat*/ functions
|
||||||
string m_text;
|
string m_text;
|
||||||
@@ -1669,6 +1727,22 @@ struct AstSFormat : public AstNode {
|
|||||||
void lhsp(AstNode* nodep) { setOp3p(nodep); }
|
void lhsp(AstNode* nodep) { setOp3p(nodep); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstSysIgnore : public AstNode {
|
||||||
|
// Parents: stmtlist
|
||||||
|
// Children: varrefs or exprs
|
||||||
|
AstSysIgnore(FileLine* fileline, AstNode* exprsp)
|
||||||
|
: AstNode (fileline) { addNOp1p(exprsp); }
|
||||||
|
ASTNODE_NODE_FUNCS(SysIgnore, SYSIGNORE)
|
||||||
|
virtual string verilogKwd() const { return "$ignored"; }
|
||||||
|
virtual bool isGateOptimizable() const { return false; } // Though deleted before opt
|
||||||
|
virtual bool isPredictOptimizable() const { return false; } // Though deleted before opt
|
||||||
|
virtual bool isSplittable() const { return false; } // Though deleted before opt
|
||||||
|
virtual bool isOutputter() const { return true; } // Though deleted before opt
|
||||||
|
virtual int instrCount() const { return instrCountPli(); }
|
||||||
|
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
|
||||||
|
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
||||||
|
};
|
||||||
|
|
||||||
struct AstFClose : public AstNodeStmt {
|
struct AstFClose : public AstNodeStmt {
|
||||||
// Parents: stmtlist
|
// Parents: stmtlist
|
||||||
// Children: file which must be a varref
|
// Children: file which must be a varref
|
||||||
@@ -1821,6 +1895,45 @@ public:
|
|||||||
AstNode* msbp() const { return op4p()->castNode(); }
|
AstNode* msbp() const { return op4p()->castNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstSystemT : public AstNodeStmt {
|
||||||
|
// $system used as task
|
||||||
|
AstSystemT(FileLine* fileline, AstNode* lhsp)
|
||||||
|
: AstNodeStmt (fileline) {
|
||||||
|
setOp1p(lhsp);
|
||||||
|
}
|
||||||
|
ASTNODE_NODE_FUNCS(SystemT, SYSTEMT)
|
||||||
|
virtual string verilogKwd() const { return "$system"; }
|
||||||
|
virtual bool isGateOptimizable() const { return false; }
|
||||||
|
virtual bool isPredictOptimizable() const { return false; }
|
||||||
|
virtual bool isSplittable() const { return false; }
|
||||||
|
virtual bool isOutputter() const { return true; }
|
||||||
|
virtual bool isUnlikely() const { return true; }
|
||||||
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
|
AstNode* lhsp() const { return op1p(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstSystemF : public AstNodeMath {
|
||||||
|
// $system used as function
|
||||||
|
AstSystemF(FileLine* fileline, AstNode* lhsp)
|
||||||
|
: AstNodeMath (fileline) {
|
||||||
|
setOp1p(lhsp);
|
||||||
|
}
|
||||||
|
ASTNODE_NODE_FUNCS(SystemF, SYSTEMF)
|
||||||
|
virtual string verilogKwd() const { return "$system"; }
|
||||||
|
virtual string emitVerilog() { return verilogKwd(); }
|
||||||
|
virtual string emitC() { return "VL_SYSTEM_%nq(%lw, %P)"; }
|
||||||
|
virtual bool isGateOptimizable() const { return false; }
|
||||||
|
virtual bool isPredictOptimizable() const { return false; }
|
||||||
|
virtual bool isSplittable() const { return false; }
|
||||||
|
virtual bool isOutputter() const { return true; }
|
||||||
|
virtual bool isUnlikely() const { return true; }
|
||||||
|
virtual bool cleanOut() { return true; }
|
||||||
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
|
AstNode* lhsp() const { return op1p(); }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstValuePlusArgs : public AstNodeMath {
|
struct AstValuePlusArgs : public AstNodeMath {
|
||||||
// Parents: expr
|
// Parents: expr
|
||||||
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
|
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
|
||||||
@@ -1932,6 +2045,18 @@ struct AstContinue : public AstNodeStmt {
|
|||||||
virtual bool isSplittable() const { return false; } // SPECIAL: We don't process code after breaks
|
virtual bool isSplittable() const { return false; } // SPECIAL: We don't process code after breaks
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstDisable : public AstNodeStmt {
|
||||||
|
private:
|
||||||
|
string m_name; // Name of block
|
||||||
|
public:
|
||||||
|
AstDisable(FileLine* fileline, const string& name)
|
||||||
|
: AstNodeStmt(fileline), m_name(name) {}
|
||||||
|
ASTNODE_NODE_FUNCS(Disable, DISABLE)
|
||||||
|
virtual string name() const { return m_name; } // * = Block name
|
||||||
|
void name(const string& flag) { m_name=flag; }
|
||||||
|
virtual bool isSplittable() const { return false; } // SPECIAL: We don't process code after breaks
|
||||||
|
};
|
||||||
|
|
||||||
struct AstReturn : public AstNodeStmt {
|
struct AstReturn : public AstNodeStmt {
|
||||||
AstReturn(FileLine* fileline, AstNode* lhsp=NULL)
|
AstReturn(FileLine* fileline, AstNode* lhsp=NULL)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt (fileline) {
|
||||||
@@ -1952,10 +2077,22 @@ struct AstGenIf : public AstNodeIf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AstIf : public AstNodeIf {
|
struct AstIf : public AstNodeIf {
|
||||||
|
private:
|
||||||
|
bool m_uniquePragma; // unique case
|
||||||
|
bool m_unique0Pragma; // unique0 case
|
||||||
|
bool m_priorityPragma; // priority case
|
||||||
|
public:
|
||||||
AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp)
|
AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp)
|
||||||
: AstNodeIf(fileline, condp, ifsp, elsesp) {
|
: AstNodeIf(fileline, condp, ifsp, elsesp) {
|
||||||
|
m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false;
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(If, IF)
|
ASTNODE_NODE_FUNCS(If, IF)
|
||||||
|
bool uniquePragma() const { return m_uniquePragma; }
|
||||||
|
void uniquePragma(bool flag) { m_uniquePragma=flag; }
|
||||||
|
bool unique0Pragma() const { return m_unique0Pragma; }
|
||||||
|
void unique0Pragma(bool flag) { m_unique0Pragma=flag; }
|
||||||
|
bool priorityPragma() const { return m_priorityPragma; }
|
||||||
|
void priorityPragma(bool flag) { m_priorityPragma=flag; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstJumpLabel : public AstNodeStmt {
|
struct AstJumpLabel : public AstNodeStmt {
|
||||||
@@ -2363,6 +2500,20 @@ struct AstTime : public AstNodeTermop {
|
|||||||
virtual bool same(AstNode* samep) const { return true; }
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstTimeD : public AstNodeTermop {
|
||||||
|
AstTimeD(FileLine* fl) : AstNodeTermop(fl) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(TimeD, TIMED)
|
||||||
|
virtual string emitVerilog() { return "%f$realtime"; }
|
||||||
|
virtual string emitC() { return "VL_TIME_D()"; }
|
||||||
|
virtual bool cleanOut() { return true; }
|
||||||
|
virtual bool isGateOptimizable() const { return false; }
|
||||||
|
virtual bool isPredictOptimizable() const { return false; }
|
||||||
|
virtual int instrCount() const { return instrCountTime(); }
|
||||||
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstUCFunc : public AstNodeMath {
|
struct AstUCFunc : public AstNodeMath {
|
||||||
// User's $c function
|
// User's $c function
|
||||||
// Perhaps this should be a AstNodeListop; but there's only one list math right now
|
// Perhaps this should be a AstNodeListop; but there's only one list math right now
|
||||||
@@ -2388,19 +2539,32 @@ struct AstUCFunc : public AstNodeMath {
|
|||||||
//======================================================================
|
//======================================================================
|
||||||
// Unary ops
|
// Unary ops
|
||||||
|
|
||||||
struct AstUnaryMin : public AstNodeUniop {
|
struct AstNegate : public AstNodeUniop {
|
||||||
AstUnaryMin(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstNegate(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
if (lhsp) widthSignedFrom(lhsp); }
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
ASTNODE_NODE_FUNCS(UnaryMin, UNARYMIN)
|
ASTNODE_NODE_FUNCS(Negate, NEGATE)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opUnaryMin(lhs); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegate(lhs); }
|
||||||
virtual string emitVerilog() { return "%f(- %l)"; }
|
virtual string emitVerilog() { return "%f(- %l)"; }
|
||||||
virtual string emitC() { return "VL_UNARYMIN_%lq(%lW, %P, %li)"; }
|
virtual string emitC() { return "VL_NEGATE_%lq(%lW, %P, %li)"; }
|
||||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
|
||||||
virtual bool sizeMattersLhs() {return true;}
|
virtual bool sizeMattersLhs() {return true;}
|
||||||
};
|
};
|
||||||
|
struct AstNegateD : public AstNodeUniop {
|
||||||
|
AstNegateD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(NegateD, NEGATED)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegateD(lhs); }
|
||||||
|
virtual string emitVerilog() { return "%f(- %l)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "-"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstRedAnd : public AstNodeUniop {
|
struct AstRedAnd : public AstNodeUniop {
|
||||||
AstRedAnd(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstRedAnd(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
width(1,1); }
|
width(1,1); numeric(AstNumeric::UNSIGNED); }
|
||||||
ASTNODE_NODE_FUNCS(RedAnd, REDAND)
|
ASTNODE_NODE_FUNCS(RedAnd, REDAND)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); }
|
||||||
virtual string emitVerilog() { return "%f(& %l)"; }
|
virtual string emitVerilog() { return "%f(& %l)"; }
|
||||||
@@ -2410,7 +2574,7 @@ struct AstRedAnd : public AstNodeUniop {
|
|||||||
};
|
};
|
||||||
struct AstRedOr : public AstNodeUniop {
|
struct AstRedOr : public AstNodeUniop {
|
||||||
AstRedOr(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstRedOr(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
width(1,1); }
|
width(1,1); numeric(AstNumeric::UNSIGNED); }
|
||||||
ASTNODE_NODE_FUNCS(RedOr, REDOR)
|
ASTNODE_NODE_FUNCS(RedOr, REDOR)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); }
|
||||||
virtual string emitVerilog() { return "%f(| %l)"; }
|
virtual string emitVerilog() { return "%f(| %l)"; }
|
||||||
@@ -2420,7 +2584,7 @@ struct AstRedOr : public AstNodeUniop {
|
|||||||
};
|
};
|
||||||
struct AstRedXor : public AstNodeUniop {
|
struct AstRedXor : public AstNodeUniop {
|
||||||
AstRedXor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstRedXor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
width(1,1); }
|
width(1,1); numeric(AstNumeric::UNSIGNED); }
|
||||||
ASTNODE_NODE_FUNCS(RedXor, REDXOR)
|
ASTNODE_NODE_FUNCS(RedXor, REDXOR)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); }
|
||||||
virtual string emitVerilog() { return "%f(^ %l)"; }
|
virtual string emitVerilog() { return "%f(^ %l)"; }
|
||||||
@@ -2434,7 +2598,7 @@ struct AstRedXor : public AstNodeUniop {
|
|||||||
struct AstRedXnor : public AstNodeUniop {
|
struct AstRedXnor : public AstNodeUniop {
|
||||||
// AstRedXnors are replaced with AstRedXors in V3Const.
|
// AstRedXnors are replaced with AstRedXors in V3Const.
|
||||||
AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
width(1,1); }
|
width(1,1); numeric(AstNumeric::UNSIGNED); }
|
||||||
ASTNODE_NODE_FUNCS(RedXnor, REDXNOR)
|
ASTNODE_NODE_FUNCS(RedXnor, REDXNOR)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); }
|
||||||
virtual string emitVerilog() { return "%f(~^ %l)"; }
|
virtual string emitVerilog() { return "%f(~^ %l)"; }
|
||||||
@@ -2492,7 +2656,7 @@ struct AstExtendS : public AstNodeUniop {
|
|||||||
struct AstSigned : public AstNodeUniop {
|
struct AstSigned : public AstNodeUniop {
|
||||||
// $signed(lhs)
|
// $signed(lhs)
|
||||||
AstSigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstSigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
isSigned(true);
|
numeric(AstNumeric::SIGNED);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Signed, SIGNED)
|
ASTNODE_NODE_FUNCS(Signed, SIGNED)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
|
||||||
@@ -2505,7 +2669,7 @@ struct AstSigned : public AstNodeUniop {
|
|||||||
struct AstUnsigned : public AstNodeUniop {
|
struct AstUnsigned : public AstNodeUniop {
|
||||||
// $unsigned(lhs)
|
// $unsigned(lhs)
|
||||||
AstUnsigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
AstUnsigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
isSigned(false);
|
numeric(AstNumeric::UNSIGNED);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Unsigned, UNSIGNED)
|
ASTNODE_NODE_FUNCS(Unsigned, UNSIGNED)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
|
||||||
@@ -2515,6 +2679,63 @@ struct AstUnsigned : public AstNodeUniop {
|
|||||||
virtual bool sizeMattersLhs() {return true;} // Eliminated before matters
|
virtual bool sizeMattersLhs() {return true;} // Eliminated before matters
|
||||||
virtual int instrCount() const { return 0; }
|
virtual int instrCount() const { return 0; }
|
||||||
};
|
};
|
||||||
|
struct AstRToIS : public AstNodeUniop {
|
||||||
|
// $rtoi(lhs)
|
||||||
|
AstRToIS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
width(32,32); }
|
||||||
|
ASTNODE_NODE_FUNCS(RToIS, RTOIS)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIS(lhs); }
|
||||||
|
virtual string emitVerilog() { return "%f$rtoi(%l)"; }
|
||||||
|
virtual string emitC() { return "VL_RTOI_I_D(%li)"; }
|
||||||
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual bool sizeMattersLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
};
|
||||||
|
struct AstRToIRoundS : public AstNodeUniop {
|
||||||
|
AstRToIRoundS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
width(32,32); }
|
||||||
|
ASTNODE_NODE_FUNCS(RToIRoundS, RTOIROUNDS)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIRoundS(lhs); }
|
||||||
|
virtual string emitVerilog() { return "%f$rtoi_rounded(%l)"; }
|
||||||
|
virtual string emitC() { return "VL_RTOIROUND_I_D(%li)"; }
|
||||||
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual bool sizeMattersLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
};
|
||||||
|
struct AstIToRD : public AstNodeUniop {
|
||||||
|
AstIToRD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(IToRD, ITORD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIToRD(lhs); }
|
||||||
|
virtual string emitVerilog() { return "%f$itor(%l)"; }
|
||||||
|
virtual string emitC() { return "VL_ITOR_D_I(%li)"; }
|
||||||
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual bool sizeMattersLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
};
|
||||||
|
struct AstRealToBits : public AstNodeUniop {
|
||||||
|
AstRealToBits(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
width(64,64); }
|
||||||
|
ASTNODE_NODE_FUNCS(RealToBits, REALTOBITS)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRealToBits(lhs); }
|
||||||
|
virtual string emitVerilog() { return "%f$realtobits(%l)"; }
|
||||||
|
virtual string emitC() { return "VL_CVT_Q_D(%li)"; }
|
||||||
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual bool sizeMattersLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
};
|
||||||
|
struct AstBitsToRealD : public AstNodeUniop {
|
||||||
|
AstBitsToRealD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(BitsToRealD, BITSTOREALD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opBitsToRealD(lhs); }
|
||||||
|
virtual string emitVerilog() { return "%f$bitstoreal(%l)"; }
|
||||||
|
virtual string emitC() { return "VL_CVT_D_Q(%li)"; }
|
||||||
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual bool sizeMattersLhs() {return false;} // Eliminated before matters
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstCLog2 : public AstNodeUniop {
|
struct AstCLog2 : public AstNodeUniop {
|
||||||
AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
||||||
ASTNODE_NODE_FUNCS(CLog2, CLOG2)
|
ASTNODE_NODE_FUNCS(CLog2, CLOG2)
|
||||||
@@ -2572,27 +2793,42 @@ struct AstOneHot0 : public AstNodeUniop {
|
|||||||
virtual int instrCount() const { return widthInstrs()*3; }
|
virtual int instrCount() const { return widthInstrs()*3; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstCast : public AstNodeUniop {
|
struct AstCast : public AstNode {
|
||||||
// Cast to appropriate data type
|
// Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc
|
||||||
|
AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtypep) : AstNode(fl) {
|
||||||
|
setOp1p(lhsp); setOp2p(dtypep);
|
||||||
|
if (dtypep) { widthSignedFrom(dtypep); }
|
||||||
|
}
|
||||||
|
ASTNODE_NODE_FUNCS(Cast, CAST)
|
||||||
|
virtual string emitVerilog() { return "((%r)'(%l))"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
AstNode* lhsp() const { return op1p(); }
|
||||||
|
AstNodeDType* dtypep() const { return op2p()->castNodeDType(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstCCast : public AstNodeUniop {
|
||||||
|
// Cast to C-based data type
|
||||||
private:
|
private:
|
||||||
int m_size;
|
int m_size;
|
||||||
public:
|
public:
|
||||||
AstCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
|
AstCCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
|
||||||
m_size=setwidth;
|
m_size=setwidth;
|
||||||
if (setwidth) { width(setwidth,setwidth); }
|
if (setwidth) { width(setwidth,setwidth); }
|
||||||
}
|
}
|
||||||
AstCast(FileLine* fl, AstNode* lhsp, AstNode* widthFromp) : AstNodeUniop(fl, lhsp) {
|
AstCCast(FileLine* fl, AstNode* lhsp, AstNode* widthFromp) : AstNodeUniop(fl, lhsp) {
|
||||||
if (widthFromp) { widthSignedFrom(widthFromp); }
|
if (widthFromp) { widthSignedFrom(widthFromp); }
|
||||||
m_size=width();
|
m_size=width();
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Cast, CAST)
|
ASTNODE_NODE_FUNCS(CCast, CCAST)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
|
||||||
virtual string emitVerilog() { return "%f$_CAST(%l)"; }
|
virtual string emitVerilog() { return "%f$_CAST(%l)"; }
|
||||||
virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
|
virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast
|
virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast
|
||||||
virtual V3Hash sameHash() const { return V3Hash(size()); }
|
virtual V3Hash sameHash() const { return V3Hash(size()); }
|
||||||
virtual bool same(AstNode* samep) const { return size()==samep->castCast()->size(); }
|
virtual bool same(AstNode* samep) const { return size()==samep->castCCast()->size(); }
|
||||||
virtual void dump(ostream& str=cout);
|
virtual void dump(ostream& str=cout);
|
||||||
//
|
//
|
||||||
int size() const { return m_size; }
|
int size() const { return m_size; }
|
||||||
@@ -2617,7 +2853,7 @@ struct AstFEof : public AstNodeUniop {
|
|||||||
ASTNODE_NODE_FUNCS(FEof, FEOF)
|
ASTNODE_NODE_FUNCS(FEof, FEOF)
|
||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
||||||
virtual string emitVerilog() { return "%f$feof(%l)"; }
|
virtual string emitVerilog() { return "%f$feof(%l)"; }
|
||||||
virtual string emitC() { return "(%li ? feof(VL_CVT_Q_FP(%li)) : true)"; }
|
virtual string emitC() { return "(%li ? feof(VL_CVT_I_FP(%li)) : true)"; }
|
||||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
virtual int instrCount() const { return widthInstrs()*16; }
|
virtual int instrCount() const { return widthInstrs()*16; }
|
||||||
@@ -2630,13 +2866,97 @@ struct AstFGetC : public AstNodeUniop {
|
|||||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
||||||
virtual string emitVerilog() { return "%f$fgetc(%l)"; }
|
virtual string emitVerilog() { return "%f$fgetc(%l)"; }
|
||||||
// Non-existent filehandle returns EOF
|
// Non-existent filehandle returns EOF
|
||||||
virtual string emitC() { return "(%li ? fgetc(VL_CVT_Q_FP(%li)) : -1)"; }
|
virtual string emitC() { return "(%li ? fgetc(VL_CVT_I_FP(%li)) : -1)"; }
|
||||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
virtual int instrCount() const { return widthInstrs()*64; }
|
virtual int instrCount() const { return widthInstrs()*64; }
|
||||||
AstNode* filep() const { return lhsp(); }
|
AstNode* filep() const { return lhsp(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstCeilD : public AstNodeUniop {
|
||||||
|
AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(CeilD, CEILD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||||
|
out.setDouble(ceil(lhs.toDouble())); }
|
||||||
|
virtual string emitVerilog() { return "%f$ceil(%l)"; }
|
||||||
|
virtual string emitC() { return "ceil(%li)"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleTrig(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstExpD : public AstNodeUniop {
|
||||||
|
AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(ExpD, EXPD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||||
|
out.setDouble(exp(lhs.toDouble())); }
|
||||||
|
virtual string emitVerilog() { return "%f$exp(%l)"; }
|
||||||
|
virtual string emitC() { return "exp(%li)"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleTrig(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstFloorD : public AstNodeUniop {
|
||||||
|
AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(FloorD, FLOORD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||||
|
out.setDouble(floor(lhs.toDouble())); }
|
||||||
|
virtual string emitVerilog() { return "%f$floor(%l)"; }
|
||||||
|
virtual string emitC() { return "floor(%li)"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleTrig(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstLogD : public AstNodeUniop {
|
||||||
|
AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(LogD, LOGD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||||
|
out.setDouble(log(lhs.toDouble())); }
|
||||||
|
virtual string emitVerilog() { return "%f$ln(%l)"; }
|
||||||
|
virtual string emitC() { return "log(%li)"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleTrig(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstLog10D : public AstNodeUniop {
|
||||||
|
AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(Log10D, LOG10D)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||||
|
out.setDouble(log10(lhs.toDouble())); }
|
||||||
|
virtual string emitVerilog() { return "%f$log10(%l)"; }
|
||||||
|
virtual string emitC() { return "log10(%li)"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleTrig(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstSqrtD : public AstNodeUniop {
|
||||||
|
AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(SqrtD, SQRTD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||||
|
out.setDouble(sqrt(lhs.toDouble())); }
|
||||||
|
virtual string emitVerilog() { return "%f$sqrt(%l)"; }
|
||||||
|
virtual string emitC() { return "sqrt(%li)"; }
|
||||||
|
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleTrig(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Binary ops
|
// Binary ops
|
||||||
|
|
||||||
@@ -2752,6 +3072,20 @@ struct AstEq : public AstNodeBiCom {
|
|||||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
};
|
};
|
||||||
|
struct AstEqD : public AstNodeBiCom {
|
||||||
|
AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||||
|
width(1,1); }
|
||||||
|
ASTNODE_NODE_FUNCS(EqD, EQD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f== %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "=="; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstNeq : public AstNodeBiCom {
|
struct AstNeq : public AstNodeBiCom {
|
||||||
AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||||
width(1,1); }
|
width(1,1); }
|
||||||
@@ -2764,6 +3098,20 @@ struct AstNeq : public AstNodeBiCom {
|
|||||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
};
|
};
|
||||||
|
struct AstNeqD : public AstNodeBiCom {
|
||||||
|
AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||||
|
width(1,1); }
|
||||||
|
ASTNODE_NODE_FUNCS(NeqD, NEQD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "!="; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstLt : public AstNodeBiop {
|
struct AstLt : public AstNodeBiop {
|
||||||
AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
width(1,1); }
|
width(1,1); }
|
||||||
@@ -2776,6 +3124,20 @@ struct AstLt : public AstNodeBiop {
|
|||||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
};
|
};
|
||||||
|
struct AstLtD : public AstNodeBiop {
|
||||||
|
AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
width(1,1); }
|
||||||
|
ASTNODE_NODE_FUNCS(LtD, LTD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "<"; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstLtS : public AstNodeBiop {
|
struct AstLtS : public AstNodeBiop {
|
||||||
AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
width(1,1); }
|
width(1,1); }
|
||||||
@@ -2801,6 +3163,20 @@ struct AstGt : public AstNodeBiop {
|
|||||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
};
|
};
|
||||||
|
struct AstGtD : public AstNodeBiop {
|
||||||
|
AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
width(1,1); }
|
||||||
|
ASTNODE_NODE_FUNCS(GtD, GTD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return ">"; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstGtS : public AstNodeBiop {
|
struct AstGtS : public AstNodeBiop {
|
||||||
AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
width(1,1); }
|
width(1,1); }
|
||||||
@@ -2826,6 +3202,20 @@ struct AstGte : public AstNodeBiop {
|
|||||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
};
|
};
|
||||||
|
struct AstGteD : public AstNodeBiop {
|
||||||
|
AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
width(1,1); }
|
||||||
|
ASTNODE_NODE_FUNCS(GteD, GTED)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return ">="; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstGteS : public AstNodeBiop {
|
struct AstGteS : public AstNodeBiop {
|
||||||
AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
width(1,1); }
|
width(1,1); }
|
||||||
@@ -2851,6 +3241,20 @@ struct AstLte : public AstNodeBiop {
|
|||||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
};
|
};
|
||||||
|
struct AstLteD : public AstNodeBiop {
|
||||||
|
AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
width(1,1); }
|
||||||
|
ASTNODE_NODE_FUNCS(LteD, LTED)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "<="; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstLteS : public AstNodeBiop {
|
struct AstLteS : public AstNodeBiop {
|
||||||
AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
width(1,1); }
|
width(1,1); }
|
||||||
@@ -2919,6 +3323,20 @@ struct AstAdd : public AstNodeBiComAsv {
|
|||||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||||
};
|
};
|
||||||
|
struct AstAddD : public AstNodeBiComAsv {
|
||||||
|
AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(AddD, ADDD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAddD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f+ %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "+"; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstSub : public AstNodeBiop {
|
struct AstSub : public AstNodeBiop {
|
||||||
AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
if (lhsp) widthSignedFrom(lhsp); }
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
@@ -2931,6 +3349,20 @@ struct AstSub : public AstNodeBiop {
|
|||||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||||
};
|
};
|
||||||
|
struct AstSubD : public AstNodeBiop {
|
||||||
|
AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(SubD, SUBD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSubD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f- %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "-"; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstMul : public AstNodeBiComAsv {
|
struct AstMul : public AstNodeBiComAsv {
|
||||||
AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||||
if (lhsp) widthSignedFrom(lhsp); }
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
@@ -2944,6 +3376,20 @@ struct AstMul : public AstNodeBiComAsv {
|
|||||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||||
virtual int instrCount() const { return widthInstrs()*instrCountMul(); }
|
virtual int instrCount() const { return widthInstrs()*instrCountMul(); }
|
||||||
};
|
};
|
||||||
|
struct AstMulD : public AstNodeBiComAsv {
|
||||||
|
AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(MulD, MULD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f* %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "*"; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||||
|
virtual int instrCount() const { return instrCountDouble(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstMulS : public AstNodeBiComAsv {
|
struct AstMulS : public AstNodeBiComAsv {
|
||||||
AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||||
if (lhsp) widthSignedFrom(lhsp); }
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
@@ -2970,6 +3416,20 @@ struct AstDiv : public AstNodeBiop {
|
|||||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||||
virtual int instrCount() const { return widthInstrs()*instrCountDiv(); }
|
virtual int instrCount() const { return widthInstrs()*instrCountDiv(); }
|
||||||
};
|
};
|
||||||
|
struct AstDivD : public AstNodeBiop {
|
||||||
|
AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(DivD, DIVD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f/ %r)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitSimpleOperator() { return "/"; }
|
||||||
|
virtual bool cleanOut() {return true;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleDiv(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstDivS : public AstNodeBiop {
|
struct AstDivS : public AstNodeBiop {
|
||||||
AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
if (lhsp) widthSignedFrom(lhsp); }
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
@@ -3020,6 +3480,19 @@ struct AstPow : public AstNodeBiop {
|
|||||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
|
||||||
virtual int instrCount() const { return widthInstrs()*instrCountMul(); }
|
virtual int instrCount() const { return widthInstrs()*instrCountMul(); }
|
||||||
};
|
};
|
||||||
|
struct AstPowD : public AstNodeBiop {
|
||||||
|
AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
numeric(AstNumeric::DOUBLE); }
|
||||||
|
ASTNODE_NODE_FUNCS(PowD, POWD)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowD(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
|
||||||
|
virtual string emitC() { return "pow(%li,%ri)"; }
|
||||||
|
virtual bool cleanOut() {return false;}
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
virtual int instrCount() const { return instrCountDoubleDiv(); }
|
||||||
|
virtual bool doubleFlavor() const { return true; }
|
||||||
|
};
|
||||||
struct AstPowS : public AstNodeBiop {
|
struct AstPowS : public AstNodeBiop {
|
||||||
AstPowS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
AstPowS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
if (lhsp) widthSignedFrom(lhsp); }
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
@@ -3109,6 +3582,19 @@ struct AstReplicate : public AstNodeBiop {
|
|||||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
virtual int instrCount() const { return widthInstrs()*2; }
|
virtual int instrCount() const { return widthInstrs()*2; }
|
||||||
};
|
};
|
||||||
|
struct AstBufIf1 : public AstNodeBiop {
|
||||||
|
// lhs is enable, rhs is data to drive
|
||||||
|
AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||||
|
if (lhsp) widthSignedFrom(lhsp); }
|
||||||
|
ASTNODE_NODE_FUNCS(BufIf1, BUFIF1)
|
||||||
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); }
|
||||||
|
virtual string emitVerilog() { return "bufif(%r,%l)"; }
|
||||||
|
virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean
|
||||||
|
virtual string emitSimpleOperator() { V3ERROR_NA; return "";} // Lclean || Rclean
|
||||||
|
virtual bool cleanOut() {V3ERROR_NA; return "";} // Lclean || Rclean
|
||||||
|
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||||
|
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||||
|
};
|
||||||
struct AstFGetS : public AstNodeBiop {
|
struct AstFGetS : public AstNodeBiop {
|
||||||
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
|
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
|
||||||
ASTNODE_NODE_FUNCS(FGetS, FGETS)
|
ASTNODE_NODE_FUNCS(FGetS, FGETS)
|
||||||
@@ -3543,25 +4029,6 @@ struct AstCReturn : public AstNodeStmt {
|
|||||||
AstNode* lhsp() const { return op1p(); }
|
AstNode* lhsp() const { return op1p(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstCInclude : public AstNode {
|
|
||||||
// C++ use of another class
|
|
||||||
// Parents: MODULE
|
|
||||||
// Children: None
|
|
||||||
private:
|
|
||||||
AstNodeModule* m_modp;
|
|
||||||
public:
|
|
||||||
AstCInclude(FileLine* fl, AstNodeModule* modp)
|
|
||||||
: AstNode(fl) {
|
|
||||||
m_modp = modp;
|
|
||||||
}
|
|
||||||
ASTNODE_NODE_FUNCS(CInclude, CINCLUDE)
|
|
||||||
virtual bool broken() const { return (m_modp && !m_modp->brokeExists()); }
|
|
||||||
virtual void cloneRelink() { if (m_modp && m_modp->clonep()) {
|
|
||||||
m_modp = m_modp->clonep()->castNodeModule();
|
|
||||||
}}
|
|
||||||
AstNodeModule* modp() const { return m_modp; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AstCMath : public AstNodeMath {
|
struct AstCMath : public AstNodeMath {
|
||||||
private:
|
private:
|
||||||
bool m_cleanOut;
|
bool m_cleanOut;
|
||||||
|
|||||||
+18
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -53,6 +53,7 @@ private:
|
|||||||
string m_namedScope; // Name of begin blocks above us
|
string m_namedScope; // Name of begin blocks above us
|
||||||
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
|
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
|
||||||
int m_repeatNum; // Repeat counter
|
int m_repeatNum; // Repeat counter
|
||||||
|
int m_ifDepth; // Current if depth
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static int debug() {
|
static int debug() {
|
||||||
@@ -152,6 +153,21 @@ private:
|
|||||||
// any BEGINs, but V3Coverage adds them all under the module itself.
|
// any BEGINs, but V3Coverage adds them all under the module itself.
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
// VISITORS - LINT CHECK
|
||||||
|
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
|
||||||
|
// Check IFDEPTH warning - could be in other transform files if desire
|
||||||
|
int prevIfDepth = m_ifDepth;
|
||||||
|
if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off
|
||||||
|
} else if (nodep->uniquePragma() || nodep->unique0Pragma() || nodep->priorityPragma()) {
|
||||||
|
m_ifDepth = -1;
|
||||||
|
} else if (++m_ifDepth > v3Global.opt.ifDepth()) {
|
||||||
|
nodep->v3warn(IFDEPTH,"Deep 'if' statement; suggest unique/priority to avoid slow logic");
|
||||||
|
nodep->fileline()->modifyWarnOff(V3ErrorCode::IFDEPTH, true); // Warn only once
|
||||||
|
m_ifDepth = -1;
|
||||||
|
}
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
m_ifDepth = prevIfDepth;
|
||||||
|
}
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
@@ -161,6 +177,7 @@ public:
|
|||||||
m_modp = NULL;
|
m_modp = NULL;
|
||||||
m_ftaskp = NULL;
|
m_ftaskp = NULL;
|
||||||
m_repeatNum = 0;
|
m_repeatNum = 0;
|
||||||
|
m_ifDepth = 0;
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
virtual ~BeginVisitor() {}
|
virtual ~BeginVisitor() {}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+9
-5
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -148,17 +148,19 @@ private:
|
|||||||
|
|
||||||
bool isCaseTreeFast(AstCase* nodep) {
|
bool isCaseTreeFast(AstCase* nodep) {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
bool opaque = false;
|
||||||
m_caseItems = 0;
|
m_caseItems = 0;
|
||||||
m_caseNoOverlapsAllCovered = true;
|
m_caseNoOverlapsAllCovered = true;
|
||||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||||
if (icondp->width() > width) width = icondp->width();
|
if (icondp->width() > width) width = icondp->width();
|
||||||
|
if (icondp->isDouble()) opaque = true;
|
||||||
if (!icondp->castConst()) width = CASE_BARF; // Can't parse; not a constant
|
if (!icondp->castConst()) width = CASE_BARF; // Can't parse; not a constant
|
||||||
m_caseItems++;
|
m_caseItems++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_caseWidth = width;
|
m_caseWidth = width;
|
||||||
if (width==0 || width > CASE_OVERLAP_WIDTH) {
|
if (width==0 || width > CASE_OVERLAP_WIDTH || opaque) {
|
||||||
m_caseNoOverlapsAllCovered = false;
|
m_caseNoOverlapsAllCovered = false;
|
||||||
return false; // Too wide for analysis
|
return false; // Too wide for analysis
|
||||||
}
|
}
|
||||||
@@ -348,7 +350,9 @@ private:
|
|||||||
and1p = cexprp->cloneTree(false);
|
and1p = cexprp->cloneTree(false);
|
||||||
and2p = icondp;
|
and2p = icondp;
|
||||||
}
|
}
|
||||||
AstEq* condp = new AstEq(itemp->fileline(), and1p, and2p);
|
AstNodeBiop* condp = (and1p->isDouble()
|
||||||
|
? (new AstEqD(itemp->fileline(), and1p, and2p))->castNodeBiop()
|
||||||
|
: (new AstEq(itemp->fileline(), and1p, and2p))->castNodeBiop());
|
||||||
if (!ifexprp) {
|
if (!ifexprp) {
|
||||||
ifexprp = condp;
|
ifexprp = condp;
|
||||||
} else {
|
} else {
|
||||||
@@ -448,10 +452,10 @@ private:
|
|||||||
if (isCaseTreeFast(nodep) && v3Global.opt.oCase()) {
|
if (isCaseTreeFast(nodep) && v3Global.opt.oCase()) {
|
||||||
// It's a simple priority encoder or complete statement
|
// It's a simple priority encoder or complete statement
|
||||||
// we can make a tree of statements to avoid extra comparisons
|
// we can make a tree of statements to avoid extra comparisons
|
||||||
m_statCaseFast++;
|
++m_statCaseFast;
|
||||||
replaceCaseFast(nodep); nodep=NULL;
|
replaceCaseFast(nodep); nodep=NULL;
|
||||||
} else {
|
} else {
|
||||||
m_statCaseSlow++;
|
++m_statCaseSlow;
|
||||||
replaceCaseComplicated(nodep); nodep=NULL;
|
replaceCaseComplicated(nodep); nodep=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+7
-7
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -77,7 +77,7 @@ private:
|
|||||||
AstNRelinker relinkHandle;
|
AstNRelinker relinkHandle;
|
||||||
nodep->unlinkFrBack(&relinkHandle);
|
nodep->unlinkFrBack(&relinkHandle);
|
||||||
//
|
//
|
||||||
AstCast* castp = new AstCast (nodep->fileline(), nodep, needsize);
|
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize);
|
||||||
castp->width(needsize, nodep->widthMin());
|
castp->width(needsize, nodep->widthMin());
|
||||||
relinkHandle.relink(castp);
|
relinkHandle.relink(castp);
|
||||||
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
|
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
|
||||||
@@ -97,13 +97,13 @@ private:
|
|||||||
insertCast(nodep, castSize(nodep->backp()));
|
insertCast(nodep, castSize(nodep->backp()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void insureLower32Cast(AstCast* nodep) {
|
void insureLower32Cast(AstCCast* nodep) {
|
||||||
// If we have uint64 = CAST(uint64(x)) then the upcasting
|
// If we have uint64 = CAST(uint64(x)) then the upcasting
|
||||||
// really needs to be CAST(uint64(CAST(uint32(x))).
|
// really needs to be CAST(uint64(CAST(uint32(x))).
|
||||||
// Otherwise a (uint64)(a>b) would return wrong value, as
|
// Otherwise a (uint64)(a>b) would return wrong value, as
|
||||||
// less than has undeterministic signedness.
|
// less than has undeterministic signedness.
|
||||||
if (nodep->isQuad() && !nodep->lhsp()->isQuad()
|
if (nodep->isQuad() && !nodep->lhsp()->isQuad()
|
||||||
&& !nodep->lhsp()->castCast()) {
|
&& !nodep->lhsp()->castCCast()) {
|
||||||
insertCast(nodep->lhsp(), VL_WORDSIZE);
|
insertCast(nodep->lhsp(), VL_WORDSIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,12 +130,12 @@ private:
|
|||||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||||
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
|
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstCast* nodep, AstNUser*) {
|
virtual void visit(AstCCast* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
insureLower32Cast(nodep);
|
insureLower32Cast(nodep);
|
||||||
nodep->user1(1);
|
nodep->user1(1);
|
||||||
}
|
}
|
||||||
virtual void visit(AstUnaryMin* nodep, AstNUser*) {
|
virtual void visit(AstNegate* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
nodep->user1(nodep->lhsp()->user1());
|
nodep->user1(nodep->lhsp()->user1());
|
||||||
if (nodep->lhsp()->widthMin()==1) {
|
if (nodep->lhsp()->widthMin()==1) {
|
||||||
@@ -149,7 +149,7 @@ private:
|
|||||||
}
|
}
|
||||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
if (!nodep->lvalue()
|
if (!nodep->lvalue()
|
||||||
&& !nodep->backp()->castCast()
|
&& !nodep->backp()->castCCast()
|
||||||
&& nodep->backp()->castNodeMath()
|
&& nodep->backp()->castNodeMath()
|
||||||
&& nodep->backp()->width()
|
&& nodep->backp()->width()
|
||||||
&& castSize(nodep) != castSize(nodep->varp())) {
|
&& castSize(nodep) != castSize(nodep->varp())) {
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+46
-17
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -46,6 +46,8 @@
|
|||||||
#include "V3EmitV.h"
|
#include "V3EmitV.h"
|
||||||
#include "V3File.h"
|
#include "V3File.h"
|
||||||
|
|
||||||
|
#define CDC_WEIGHT_ASYNC 0x1000 // Weight for edges that feed async logic
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
class CdcBaseVisitor : public AstNVisitor {
|
class CdcBaseVisitor : public AstNVisitor {
|
||||||
@@ -65,9 +67,9 @@ class CdcEitherVertex : public V3GraphVertex {
|
|||||||
AstNode* m_nodep;
|
AstNode* m_nodep;
|
||||||
AstSenTree* m_srcDomainp;
|
AstSenTree* m_srcDomainp;
|
||||||
AstSenTree* m_dstDomainp;
|
AstSenTree* m_dstDomainp;
|
||||||
bool m_srcDomainSet;
|
bool m_srcDomainSet:1;
|
||||||
bool m_dstDomainSet;
|
bool m_dstDomainSet:1;
|
||||||
bool m_asyncPath;
|
bool m_asyncPath:1;
|
||||||
public:
|
public:
|
||||||
CdcEitherVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep)
|
CdcEitherVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep)
|
||||||
: V3GraphVertex(graphp), m_scopep(scopep), m_nodep(nodep)
|
: V3GraphVertex(graphp), m_scopep(scopep), m_nodep(nodep)
|
||||||
@@ -109,11 +111,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class CdcLogicVertex : public CdcEitherVertex {
|
class CdcLogicVertex : public CdcEitherVertex {
|
||||||
bool m_hazard;
|
bool m_hazard:1;
|
||||||
bool m_isFlop;
|
bool m_isFlop:1;
|
||||||
public:
|
public:
|
||||||
CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep)
|
CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep)
|
||||||
: CdcEitherVertex(graphp,scopep,nodep), m_hazard(false), m_isFlop(false)
|
: CdcEitherVertex(graphp,scopep,nodep)
|
||||||
|
, m_hazard(false), m_isFlop(false)
|
||||||
{ srcDomainp(sensenodep); dstDomainp(sensenodep); }
|
{ srcDomainp(sensenodep); dstDomainp(sensenodep); }
|
||||||
virtual ~CdcLogicVertex() {}
|
virtual ~CdcLogicVertex() {}
|
||||||
// Accessors
|
// Accessors
|
||||||
@@ -132,7 +135,7 @@ class CdcDumpVisitor : public CdcBaseVisitor {
|
|||||||
private:
|
private:
|
||||||
// NODE STATE
|
// NODE STATE
|
||||||
//Entire netlist:
|
//Entire netlist:
|
||||||
// {statement}Node::user3p -> bool, indicating not hazard
|
// {statement}Node::user3 -> bool, indicating not hazard
|
||||||
ofstream* m_ofp; // Output file
|
ofstream* m_ofp; // Output file
|
||||||
string m_prefix;
|
string m_prefix;
|
||||||
|
|
||||||
@@ -290,9 +293,12 @@ private:
|
|||||||
void setNodeHazard(AstNode* nodep) {
|
void setNodeHazard(AstNode* nodep) {
|
||||||
// Need to not clear if warnings are off (rather than when report it)
|
// Need to not clear if warnings are off (rather than when report it)
|
||||||
// as bypassing this warning may turn up another path that isn't warning off'ed.
|
// as bypassing this warning may turn up another path that isn't warning off'ed.
|
||||||
|
// We can't modifyWarnOff here, as one instantiation might not be an issue until we find a hitting flop
|
||||||
|
// Furthermore, a module like a "Or" module would only get flagged once,
|
||||||
|
// even though the signals feeding it are radically different.
|
||||||
if (!m_domainp || m_domainp->hasCombo()) { // Source flop logic in a posedge block is OK for reset (not async though)
|
if (!m_domainp || m_domainp->hasCombo()) { // Source flop logic in a posedge block is OK for reset (not async though)
|
||||||
if (m_logicVertexp && !nodep->fileline()->warnIsOff(V3ErrorCode::CDCRSTLOGIC)) {
|
if (m_logicVertexp && !nodep->fileline()->warnIsOff(V3ErrorCode::CDCRSTLOGIC)) {
|
||||||
UINFO(9,"Set hazard "<<nodep<<endl);
|
UINFO(8,"Set hazard "<<nodep<<endl);
|
||||||
m_logicVertexp->setHazard(nodep);
|
m_logicVertexp->setHazard(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,7 +316,9 @@ private:
|
|||||||
UINFO(3,__FUNCTION__<<": "<<endl);
|
UINFO(3,__FUNCTION__<<": "<<endl);
|
||||||
//if (debug()>6) m_graph.dump();
|
//if (debug()>6) m_graph.dump();
|
||||||
if (debug()>6) m_graph.dumpDotFilePrefixed("cdc_pre");
|
if (debug()>6) m_graph.dumpDotFilePrefixed("cdc_pre");
|
||||||
m_graph.removeRedundantEdgesSum(&V3GraphEdge::followAlwaysTrue);
|
//
|
||||||
|
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // This will MAX across edge weights
|
||||||
|
//
|
||||||
m_graph.dumpDotFilePrefixed("cdc_simp");
|
m_graph.dumpDotFilePrefixed("cdc_simp");
|
||||||
//
|
//
|
||||||
analyzeReset();
|
analyzeReset();
|
||||||
@@ -335,7 +343,7 @@ private:
|
|||||||
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||||
if (vvertexp->cntAsyncRst()) {
|
if (vvertexp->cntAsyncRst()) {
|
||||||
m_userGeneration++; // Effectively a userClearVertices()
|
m_userGeneration++; // Effectively a userClearVertices()
|
||||||
UINFO(9, " Trace One async: "<<vvertexp<<endl);
|
UINFO(8, " Trace One async: "<<vvertexp<<endl);
|
||||||
// Twice, as we need to detect, then propagate
|
// Twice, as we need to detect, then propagate
|
||||||
CdcEitherVertex* markp = traceAsyncRecurse(vvertexp, false);
|
CdcEitherVertex* markp = traceAsyncRecurse(vvertexp, false);
|
||||||
if (markp) { // Mark is non-NULL if something bad on this path
|
if (markp) { // Mark is non-NULL if something bad on this path
|
||||||
@@ -351,7 +359,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CdcEitherVertex* traceAsyncRecurse(CdcEitherVertex* vertexp, bool mark) {
|
CdcEitherVertex* traceAsyncRecurse(CdcEitherVertex* vertexp, bool mark) {
|
||||||
// Return vertex of any hazardous stuff attached, or NULL if OK
|
// First pass: Return vertex of any hazardous stuff attached, or NULL if OK
|
||||||
|
// If first pass returns true, second pass calls asyncPath() on appropriate nodes
|
||||||
if (vertexp->user()>=m_userGeneration) return false; // Processed - prevent loop
|
if (vertexp->user()>=m_userGeneration) return false; // Processed - prevent loop
|
||||||
vertexp->user(m_userGeneration);
|
vertexp->user(m_userGeneration);
|
||||||
|
|
||||||
@@ -406,12 +415,15 @@ private:
|
|||||||
CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top();
|
CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top();
|
||||||
if (!eToVertexp) targetp = eToVertexp;
|
if (!eToVertexp) targetp = eToVertexp;
|
||||||
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
|
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
|
||||||
if (vvertexp->isFlop()) {
|
if (vvertexp->isFlop() // IE the target flop that is upsetting us
|
||||||
|
&& edgep->weight() >= CDC_WEIGHT_ASYNC) { // And this signal feeds an async reset line
|
||||||
targetp = eToVertexp;
|
targetp = eToVertexp;
|
||||||
|
//UINFO(9," targetasync "<<targetp->name()<<" "<<" from "<<vertexp->name()<<endl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // else it might be random logic that's not relevant
|
} // else it might be random logic that's not relevant
|
||||||
}
|
}
|
||||||
|
//UINFO(9," finalflop "<<targetp->name()<<" "<<targetp->nodep()->fileline()<<endl);
|
||||||
warnAndFile(markp->nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName());
|
warnAndFile(markp->nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName());
|
||||||
dumpAsyncRecurse(targetp, "", " ",0);
|
dumpAsyncRecurse(targetp, "", " ",0);
|
||||||
}
|
}
|
||||||
@@ -464,6 +476,12 @@ private:
|
|||||||
|
|
||||||
void edgeReport() {
|
void edgeReport() {
|
||||||
// Make report of all signal names and what clock edges they have
|
// Make report of all signal names and what clock edges they have
|
||||||
|
//
|
||||||
|
// Due to flattening, many interesting direct-connect signals are
|
||||||
|
// lost, so we can't make a report showing I/Os for a low level
|
||||||
|
// module. Disabling flattening though makes us consider each
|
||||||
|
// signal in it's own unique clock domain.
|
||||||
|
|
||||||
UINFO(3,__FUNCTION__<<": "<<endl);
|
UINFO(3,__FUNCTION__<<": "<<endl);
|
||||||
|
|
||||||
// Trace all sources and sinks
|
// Trace all sources and sinks
|
||||||
@@ -493,6 +511,10 @@ private:
|
|||||||
|
|
||||||
ostringstream os;
|
ostringstream os;
|
||||||
os.setf(ios::left);
|
os.setf(ios::left);
|
||||||
|
// Module name - doesn't work due to flattening having lost the original
|
||||||
|
// so we assume the modulename matches the filebasename
|
||||||
|
string fname = vvertexp->varScp()->fileline()->filebasename() + ":";
|
||||||
|
os<<" "<<setw(20)<<fname;
|
||||||
os<<" "<<setw(8)<<whatp;
|
os<<" "<<setw(8)<<whatp;
|
||||||
os<<" "<<setw(40)<<vvertexp->varScp()->prettyName();
|
os<<" "<<setw(40)<<vvertexp->varScp()->prettyName();
|
||||||
os<<" SRC=";
|
os<<" SRC=";
|
||||||
@@ -613,8 +635,9 @@ private:
|
|||||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
||||||
CdcVarVertex* varvertexp = makeVarVertex(varscp);
|
CdcVarVertex* varvertexp = makeVarVertex(varscp);
|
||||||
UINFO(5," VARREF to "<<varscp<<endl);
|
UINFO(5," VARREF to "<<varscp<<endl);
|
||||||
// We use weight of one; if we ref the var more than once, when we simplify,
|
// We use weight of one for normal edges,
|
||||||
// the weight will increase
|
// Weight of CDC_WEIGHT_ASYNC to indicate feeds async (for reporting)
|
||||||
|
// When simplify we'll take the MAX weight
|
||||||
if (nodep->lvalue()) {
|
if (nodep->lvalue()) {
|
||||||
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
|
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
|
||||||
if (m_inDly) {
|
if (m_inDly) {
|
||||||
@@ -623,7 +646,13 @@ private:
|
|||||||
varvertexp->srcDomainSet(true);
|
varvertexp->srcDomainSet(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
|
if (varvertexp->cntAsyncRst()) {
|
||||||
|
//UINFO(9," edgeasync "<<varvertexp->name()<<" to "<<m_logicVertexp<<endl);
|
||||||
|
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, CDC_WEIGHT_ASYNC);
|
||||||
|
} else {
|
||||||
|
//UINFO(9," edgena "<<varvertexp->name()<<" to "<<m_logicVertexp<<endl);
|
||||||
|
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -720,7 +749,7 @@ public:
|
|||||||
|
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
analyze();
|
analyze();
|
||||||
//edgeReport(); // Not useful at the moment
|
if (debug()>=1) edgeReport(); // Not useful to users at the moment
|
||||||
|
|
||||||
if (0) { *m_ofp<<"\nDBG-test-dumper\n"; V3EmitV::verilogPrefixedTree(nodep, *m_ofp, "DBG ",40,NULL,true); *m_ofp<<endl; }
|
if (0) { *m_ofp<<"\nDBG-test-dumper\n"; V3EmitV::verilogPrefixedTree(nodep, *m_ofp, "DBG ",40,NULL,true); *m_ofp<<endl; }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2008-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2008-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -315,6 +315,7 @@ public:
|
|||||||
m_exprp = exprp;
|
m_exprp = exprp;
|
||||||
m_original = original;
|
m_original = original;
|
||||||
m_state = STATE_UNKNOWN;
|
m_state = STATE_UNKNOWN;
|
||||||
|
m_cloning = false;
|
||||||
if (debug()>=9) nodep->dumpTree(cout," GateBodyIn: ");
|
if (debug()>=9) nodep->dumpTree(cout," GateBodyIn: ");
|
||||||
nodep->bodysp()->iterateAndNext(*this);
|
nodep->bodysp()->iterateAndNext(*this);
|
||||||
if (debug()>=9) nodep->dumpTree(cout," GateBodyOut: ");
|
if (debug()>=9) nodep->dumpTree(cout," GateBodyOut: ");
|
||||||
@@ -696,7 +697,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||||||
// Blow old statements from new body
|
// Blow old statements from new body
|
||||||
GaterBodyVisitor(alwp,exprp,false);
|
GaterBodyVisitor(alwp,exprp,false);
|
||||||
|
|
||||||
m_statGaters++;
|
++m_statGaters;
|
||||||
if (debug()>=9) alwp->dumpTree(cout," new: ");
|
if (debug()>=9) alwp->dumpTree(cout," new: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+7
-5
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -70,8 +70,8 @@ protected:
|
|||||||
virtual ~CombBaseVisitor() {}
|
virtual ~CombBaseVisitor() {}
|
||||||
|
|
||||||
//***** optimization levels
|
//***** optimization levels
|
||||||
bool emptyFunctionDeletion() { return true; }
|
static bool emptyFunctionDeletion() { return true; }
|
||||||
bool duplicateFunctionCombine() { return true; }
|
static bool duplicateFunctionCombine() { return true; }
|
||||||
// Note this is disabled, it still needed work
|
// Note this is disabled, it still needed work
|
||||||
// Also repair it for DPI functions; when make __common need to insure proper
|
// Also repair it for DPI functions; when make __common need to insure proper
|
||||||
// flags get inherited from the old to new AstCFunc, and that AstText doesn't
|
// flags get inherited from the old to new AstCFunc, and that AstText doesn't
|
||||||
@@ -146,7 +146,9 @@ private:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
CombCallVisitor() {}
|
CombCallVisitor() {
|
||||||
|
m_find = false;
|
||||||
|
}
|
||||||
virtual ~CombCallVisitor() {}
|
virtual ~CombCallVisitor() {}
|
||||||
void main(AstNetlist* nodep) {
|
void main(AstNetlist* nodep) {
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
@@ -257,7 +259,7 @@ private:
|
|||||||
UINFO(5," DupFunc "<<hex<<V3Hash(newfuncp->user4p())<<" "<<newfuncp<<endl);
|
UINFO(5," DupFunc "<<hex<<V3Hash(newfuncp->user4p())<<" "<<newfuncp<<endl);
|
||||||
UINFO(5," and "<<hex<<V3Hash(oldfuncp->user4p())<<" "<<oldfuncp<<endl);
|
UINFO(5," and "<<hex<<V3Hash(oldfuncp->user4p())<<" "<<oldfuncp<<endl);
|
||||||
// Mark user3p on entire old tree, so we don't process it more
|
// Mark user3p on entire old tree, so we don't process it more
|
||||||
m_statCombs++;
|
++m_statCombs;
|
||||||
CombMarkVisitor visitor(oldfuncp);
|
CombMarkVisitor visitor(oldfuncp);
|
||||||
m_call.replaceFunc(oldfuncp, newfuncp);
|
m_call.replaceFunc(oldfuncp, newfuncp);
|
||||||
oldfuncp->unlinkFrBack();
|
oldfuncp->unlinkFrBack();
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+30
-17
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2010-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -60,7 +60,8 @@ class V3ConfigIgnores {
|
|||||||
IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number
|
IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number
|
||||||
IgnLines::const_iterator m_lastEnd; // Point with end()
|
IgnLines::const_iterator m_lastEnd; // Point with end()
|
||||||
|
|
||||||
IgnFiles m_ignFiles; // Ignores for each filename
|
IgnFiles m_ignWilds; // Ignores for each wildcarded filename
|
||||||
|
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename
|
||||||
|
|
||||||
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
|
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
|
||||||
|
|
||||||
@@ -68,13 +69,13 @@ class V3ConfigIgnores {
|
|||||||
~V3ConfigIgnores() {}
|
~V3ConfigIgnores() {}
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
inline IgnLines* findLines(const string& filename) {
|
inline IgnLines* findWilds(const string& wildname) {
|
||||||
IgnFiles::iterator it = m_ignFiles.find(filename);
|
IgnFiles::iterator it = m_ignWilds.find(wildname);
|
||||||
if (it != m_ignFiles.end()) {
|
if (it != m_ignWilds.end()) {
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
} else {
|
} else {
|
||||||
m_ignFiles.insert(make_pair(filename, IgnLines()));
|
m_ignWilds.insert(make_pair(wildname, IgnLines()));
|
||||||
it = m_ignFiles.find(filename);
|
it = m_ignWilds.find(wildname);
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,23 +83,35 @@ class V3ConfigIgnores {
|
|||||||
// Given a filename, find all wildcard matches against it and build
|
// Given a filename, find all wildcard matches against it and build
|
||||||
// hash with the specific filename. This avoids having to wildmatch
|
// hash with the specific filename. This avoids having to wildmatch
|
||||||
// more than once against any filename.
|
// more than once against any filename.
|
||||||
IgnLines* linesp = findLines(filename);
|
IgnFiles::iterator it = m_ignFiles.find(filename);
|
||||||
m_lastIt = linesp->begin();
|
if (it == m_ignFiles.end()) {
|
||||||
m_lastEnd = linesp->end();
|
// Haven't seen this filename before
|
||||||
|
m_ignFiles.insert(make_pair(filename, IgnLines()));
|
||||||
|
it = m_ignFiles.find(filename);
|
||||||
|
// Make new list for this file of all matches
|
||||||
|
for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) {
|
||||||
|
if (V3Options::wildmatch(filename.c_str(), fnit->first.c_str())) {
|
||||||
|
for (IgnLines::iterator lit = fnit->second.begin(); lit != fnit->second.end(); ++lit) {
|
||||||
|
it->second.insert(*lit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_lastIt = it->second.begin();
|
||||||
|
m_lastEnd = it->second.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline static V3ConfigIgnores& singleton() { return s_singleton; }
|
inline static V3ConfigIgnores& singleton() { return s_singleton; }
|
||||||
|
|
||||||
void addIgnore(V3ErrorCode code, string filename, int lineno, bool on) {
|
void addIgnore(V3ErrorCode code, string wildname, int lineno, bool on) {
|
||||||
// Insert
|
// Insert
|
||||||
IgnLines* linesp = findLines(filename);
|
IgnLines* linesp = findWilds(wildname);
|
||||||
UINFO(9,"config addIgnore "<<filename<<":"<<lineno<<", "<<code<<", "<<on<<endl);
|
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl);
|
||||||
linesp->insert(V3ConfigLine(code, lineno, on));
|
linesp->insert(V3ConfigLine(code, lineno, on));
|
||||||
if (m_lastFilename == filename) {
|
// Flush the match cache, due to a change in the rules.
|
||||||
// Flush the match cache, due to a change in the rules.
|
m_ignFiles.clear();
|
||||||
m_lastFilename = " ";
|
m_lastFilename = " ";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
inline void applyIgnores(FileLine* filelinep) {
|
inline void applyIgnores(FileLine* filelinep) {
|
||||||
// HOT routine, called each parsed token line
|
// HOT routine, called each parsed token line
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2010-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+381
-219
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -37,7 +37,6 @@
|
|||||||
#include "V3Const.h"
|
#include "V3Const.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
#include "V3Width.h"
|
#include "V3Width.h"
|
||||||
#include "V3Signed.h"
|
|
||||||
#include "V3Simulate.h"
|
#include "V3Simulate.h"
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
@@ -93,7 +92,7 @@ public:
|
|||||||
class ConstVisitor : public AstNVisitor {
|
class ConstVisitor : public AstNVisitor {
|
||||||
private:
|
private:
|
||||||
// NODE STATE
|
// NODE STATE
|
||||||
// ** only when m_warn/m_expensive is set. If state is needed other times,
|
// ** only when m_warn/m_doExpensive is set. If state is needed other times,
|
||||||
// ** must track down everywhere V3Const is called and make sure no overlaps.
|
// ** must track down everywhere V3Const is called and make sure no overlaps.
|
||||||
// AstVar::user4p -> Used by ConstVarMarkVisitor/ConstVarFindVisitor
|
// AstVar::user4p -> Used by ConstVarMarkVisitor/ConstVarFindVisitor
|
||||||
// AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label
|
// AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label
|
||||||
@@ -103,8 +102,9 @@ private:
|
|||||||
bool m_required; // If true, must become a constant
|
bool m_required; // If true, must become a constant
|
||||||
bool m_wremove; // Inside scope, no assignw removal
|
bool m_wremove; // Inside scope, no assignw removal
|
||||||
bool m_warn; // Output warnings
|
bool m_warn; // Output warnings
|
||||||
bool m_cpp; // C++ conversions only
|
bool m_doExpensive; // Enable computationally expensive optimizations
|
||||||
bool m_expensive; // Enable computationally expensive optimizations
|
bool m_doNConst; // Enable non-constant-child simplifications
|
||||||
|
bool m_doV; // Verilog, not C++ conversion
|
||||||
AstNodeModule* m_modp; // Current module
|
AstNodeModule* m_modp; // Current module
|
||||||
AstNode* m_scopep; // Current scope
|
AstNode* m_scopep; // Current scope
|
||||||
|
|
||||||
@@ -289,13 +289,61 @@ private:
|
|||||||
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
|
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
|
||||||
// Since select's return unsigned, this is always an extend
|
// Since select's return unsigned, this is always an extend
|
||||||
AstExtend* extendp = nodep->fromp()->castExtend();
|
AstExtend* extendp = nodep->fromp()->castExtend();
|
||||||
return (!m_cpp
|
if (!(m_doV
|
||||||
&& extendp
|
&& extendp
|
||||||
&& nodep->lsbp()->castConst()
|
&& nodep->lsbp()->castConst()
|
||||||
&& nodep->widthp()->castConst()
|
&& nodep->widthp()->castConst()
|
||||||
&& nodep->lsbConst()==0
|
&& nodep->lsbConst()==0
|
||||||
&& (int)nodep->widthConst()==extendp->lhsp()->width()
|
&& (int)nodep->widthConst()==extendp->lhsp()->width()
|
||||||
);
|
)) return false;
|
||||||
|
replaceWChild(nodep, extendp->lhsp()); nodep=NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool operandSelBiLower(AstSel* nodep) {
|
||||||
|
// SEL(ADD(a,b),(width-1),0) -> ADD(SEL(a),SEL(b))
|
||||||
|
// Add or any operation which doesn't care if we discard top bits
|
||||||
|
AstNodeBiop* bip = nodep->fromp()->castNodeBiop();
|
||||||
|
if (!(m_doV
|
||||||
|
&& bip
|
||||||
|
&& nodep->lsbp()->castConst()
|
||||||
|
&& nodep->widthp()->castConst()
|
||||||
|
&& nodep->lsbConst()==0
|
||||||
|
)) return false;
|
||||||
|
if (debug()>=9) nodep->dumpTree(cout,"SEL(BI)-in:");
|
||||||
|
AstNode* bilhsp = bip->lhsp()->unlinkFrBack();
|
||||||
|
AstNode* birhsp = bip->rhsp()->unlinkFrBack();
|
||||||
|
bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst()));
|
||||||
|
bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst()));
|
||||||
|
if (debug()>=9) bip->dumpTree(cout,"SEL(BI)-ou:");
|
||||||
|
replaceWChild(nodep, bip); nodep=NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operandBiExtendConst(AstNodeBiop* nodep) {
|
||||||
|
// Loop unrolling likes standalone compares
|
||||||
|
// EQ(EXTEND(xx{width3}), const{width32}) -> EQ(xx{3},const{3})
|
||||||
|
// Beware that the constant must have zero bits (+ 1 if signed) or compare
|
||||||
|
// would be incorrect
|
||||||
|
AstExtend* extendp = nodep->lhsp()->castExtend();
|
||||||
|
if (!extendp) return false;
|
||||||
|
AstNode* smallerp = extendp->lhsp();
|
||||||
|
int subsize = smallerp->width();
|
||||||
|
AstConst* constp = nodep->rhsp()->castConst();
|
||||||
|
if (!constp) return false;
|
||||||
|
if (!constp->num().isBitsZero(constp->width()-1, subsize)) return false;
|
||||||
|
//
|
||||||
|
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-in:");
|
||||||
|
smallerp->unlinkFrBack();
|
||||||
|
extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp.
|
||||||
|
nodep->lhsp(smallerp);
|
||||||
|
|
||||||
|
constp->unlinkFrBack();
|
||||||
|
V3Number num (constp->fileline(), subsize);
|
||||||
|
num.opAssign(constp->num());
|
||||||
|
nodep->rhsp(new AstConst(constp->fileline(), num));
|
||||||
|
constp->deleteTree(); constp=NULL;
|
||||||
|
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* afterComment(AstNode* nodep) {
|
AstNode* afterComment(AstNode* nodep) {
|
||||||
@@ -724,7 +772,7 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!m_cpp && nodep->lhsp()->castConcat()) {
|
else if (m_doV && nodep->lhsp()->castConcat()) {
|
||||||
bool need_temp = false;
|
bool need_temp = false;
|
||||||
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
|
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
|
||||||
// Note only do this (need user4) when m_warn, which is
|
// Note only do this (need user4) when m_warn, which is
|
||||||
@@ -773,7 +821,9 @@ private:
|
|||||||
AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
|
AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
|
||||||
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
|
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
|
||||||
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
|
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
|
||||||
|
// cppcheck-suppress nullPointer // addNext deals with it
|
||||||
newp = newp->addNext(asn1ap);
|
newp = newp->addNext(asn1ap);
|
||||||
|
// cppcheck-suppress nullPointer // addNext deals with it
|
||||||
newp = newp->addNext(asn2ap);
|
newp = newp->addNext(asn2ap);
|
||||||
} else {
|
} else {
|
||||||
if (!m_modp) nodep->v3fatalSrc("Not under module");
|
if (!m_modp) nodep->v3fatalSrc("Not under module");
|
||||||
@@ -804,12 +854,16 @@ private:
|
|||||||
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
|
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
|
||||||
asn2bp->width(msb2-lsb2+1,msb2-lsb2+1);
|
asn2bp->width(msb2-lsb2+1,msb2-lsb2+1);
|
||||||
// This order matters
|
// This order matters
|
||||||
|
// cppcheck-suppress nullPointer // addNext deals with it
|
||||||
newp = newp->addNext(asn1ap);
|
newp = newp->addNext(asn1ap);
|
||||||
|
// cppcheck-suppress nullPointer // addNext deals with it
|
||||||
newp = newp->addNext(asn2ap);
|
newp = newp->addNext(asn2ap);
|
||||||
|
// cppcheck-suppress nullPointer // addNext deals with it
|
||||||
newp = newp->addNext(asn1bp);
|
newp = newp->addNext(asn1bp);
|
||||||
|
// cppcheck-suppress nullPointer // addNext deals with it
|
||||||
newp = newp->addNext(asn2bp);
|
newp = newp->addNext(asn2bp);
|
||||||
}
|
}
|
||||||
if (debug()>=9) newp->dumpTreeAndNext(cout," _new: ");
|
if (debug()>=9 && newp) newp->dumpTreeAndNext(cout," _new: ");
|
||||||
nodep->addNextHere(newp);
|
nodep->addNextHere(newp);
|
||||||
// Cleanup
|
// Cleanup
|
||||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
@@ -855,10 +909,10 @@ private:
|
|||||||
// Run it - may be unoptimizable due to large for loop, etc
|
// Run it - may be unoptimizable due to large for loop, etc
|
||||||
simvis.mainParamEmulate(nodep);
|
simvis.mainParamEmulate(nodep);
|
||||||
if (!simvis.optimizable()) {
|
if (!simvis.optimizable()) {
|
||||||
AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep;
|
AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep;
|
||||||
nodep->v3error("Expecting expression to be constant, but can't determine constant for "
|
nodep->v3error("Expecting expression to be constant, but can't determine constant for "
|
||||||
<<nodep->prettyTypeName()<<endl
|
<<nodep->prettyTypeName()<<endl
|
||||||
<<V3Error::msgPrefix()<<errorp->fileline()<<"... Location of non-constant "
|
<<V3Error::msgPrefix(V3ErrorCode::EC_ERROR,false)<<errorp->fileline()<<"... Location of non-constant "
|
||||||
<<errorp->prettyTypeName()<<": "<<simvis.whyNotMessage());
|
<<errorp->prettyTypeName()<<": "<<simvis.whyNotMessage());
|
||||||
replaceZero(nodep); nodep=NULL;
|
replaceZero(nodep); nodep=NULL;
|
||||||
} else {
|
} else {
|
||||||
@@ -1060,16 +1114,50 @@ private:
|
|||||||
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
|
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void replaceSelIntoBiop(AstSel* nodep) {
|
||||||
|
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
|
||||||
|
AstNodeBiop* fromp = nodep->fromp()->unlinkFrBack()->castNodeBiop();
|
||||||
|
if (!fromp) nodep->v3fatalSrc("Called on non biop");
|
||||||
|
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
||||||
|
AstNode* widthp = nodep->widthp()->unlinkFrBack();
|
||||||
|
//
|
||||||
|
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
|
||||||
|
AstNode* birhsp = fromp->rhsp()->unlinkFrBack();
|
||||||
|
//
|
||||||
|
fromp->lhsp(new AstSel(nodep->fileline(),
|
||||||
|
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
|
||||||
|
fromp->rhsp(new AstSel(nodep->fileline(),
|
||||||
|
birhsp, lsbp, widthp));
|
||||||
|
fromp->widthSignedFrom(nodep);
|
||||||
|
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
void replaceSelIntoUniop(AstSel* nodep) {
|
||||||
|
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
|
||||||
|
AstNodeUniop* fromp = nodep->fromp()->unlinkFrBack()->castNodeUniop();
|
||||||
|
if (!fromp) nodep->v3fatalSrc("Called on non biop");
|
||||||
|
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
||||||
|
AstNode* widthp = nodep->widthp()->unlinkFrBack();
|
||||||
|
//
|
||||||
|
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
|
||||||
|
//
|
||||||
|
fromp->lhsp(new AstSel(nodep->fileline(),
|
||||||
|
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
|
||||||
|
fromp->widthSignedFrom(nodep);
|
||||||
|
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
|
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
|
||||||
bool did=false;
|
bool did=false;
|
||||||
if (!m_cpp && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
|
if (m_doV && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
|
||||||
//if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: ");
|
//if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: ");
|
||||||
nodep->varp()->valuep()->iterateAndNext(*this);
|
nodep->varp()->valuep()->iterateAndNext(*this);
|
||||||
if (operandConst(nodep->varp()->valuep())
|
if (operandConst(nodep->varp()->valuep())
|
||||||
&& !nodep->lvalue()
|
&& !nodep->lvalue()
|
||||||
&& ((v3Global.opt.oConst() && !m_params // Can reduce constant wires into equations
|
&& ((!m_params // Can reduce constant wires into equations
|
||||||
|
&& m_doNConst
|
||||||
|
&& v3Global.opt.oConst()
|
||||||
&& !nodep->varp()->isSigPublic())
|
&& !nodep->varp()->isSigPublic())
|
||||||
|| nodep->varp()->isParam())) {
|
|| nodep->varp()->isParam())) {
|
||||||
AstConst* constp = nodep->varp()->valuep()->castConst();
|
AstConst* constp = nodep->varp()->valuep()->castConst();
|
||||||
@@ -1121,8 +1209,9 @@ private:
|
|||||||
}
|
}
|
||||||
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (nodep->sensp()->castConst()
|
if (m_doNConst
|
||||||
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
|
&& (nodep->sensp()->castConst()
|
||||||
|
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam()))) {
|
||||||
// Constants in sensitivity lists may be removed (we'll simplify later)
|
// Constants in sensitivity lists may be removed (we'll simplify later)
|
||||||
if (nodep->isClocked()) { // A constant can never get a pos/negexge
|
if (nodep->isClocked()) { // A constant can never get a pos/negexge
|
||||||
if (onlySenItemInSenTree(nodep)) {
|
if (onlySenItemInSenTree(nodep)) {
|
||||||
@@ -1135,7 +1224,7 @@ private:
|
|||||||
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
|
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
|
||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
} else if (nodep->sensp()->castNot()) {
|
} else if (m_doNConst && nodep->sensp()->castNot()) {
|
||||||
// V3Gate may propagate NOTs into clocks... Just deal with it
|
// V3Gate may propagate NOTs into clocks... Just deal with it
|
||||||
AstNode* sensp = nodep->sensp();
|
AstNode* sensp = nodep->sensp();
|
||||||
AstNode* lastSensp = sensp;
|
AstNode* lastSensp = sensp;
|
||||||
@@ -1202,7 +1291,7 @@ private:
|
|||||||
|
|
||||||
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (m_expensive) {
|
if (m_doExpensive) {
|
||||||
//cout<<endl; nodep->dumpTree(cout,"ssin: ");
|
//cout<<endl; nodep->dumpTree(cout,"ssin: ");
|
||||||
// Optimize ideas for the future:
|
// Optimize ideas for the future:
|
||||||
// SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b))
|
// SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b))
|
||||||
@@ -1305,22 +1394,21 @@ private:
|
|||||||
// Zero elimination
|
// Zero elimination
|
||||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
replaceNodeAssign(nodep);
|
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||||
}
|
}
|
||||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||||
// Don't perform any optimizations, keep the alias around
|
// Don't perform any optimizations, keep the alias around
|
||||||
}
|
}
|
||||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (replaceNodeAssign(nodep)) return;
|
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||||
AstNodeVarRef* varrefp = nodep->lhsp()->castVarRef(); // Not VarXRef, as different refs may set different values to each hierarchy
|
AstNodeVarRef* varrefp = nodep->lhsp()->castVarRef(); // Not VarXRef, as different refs may set different values to each hierarchy
|
||||||
if (m_wremove
|
if (m_wremove && !m_params && m_doNConst
|
||||||
&& m_modp && operandConst(nodep->rhsp())
|
&& m_modp && operandConst(nodep->rhsp())
|
||||||
&& !nodep->rhsp()->castConst()->num().isFourState()
|
&& !nodep->rhsp()->castConst()->num().isFourState()
|
||||||
&& varrefp // Don't do messes with BITREFs/ARRAYREFs
|
&& varrefp // Don't do messes with BITREFs/ARRAYREFs
|
||||||
&& !varrefp->varp()->valuep() // Not already constified
|
&& !varrefp->varp()->valuep() // Not already constified
|
||||||
&& !varrefp->varScopep() // Not scoped (or each scope may have different initial value)
|
&& !varrefp->varScopep()) { // Not scoped (or each scope may have different initial value)
|
||||||
&& !m_params) {
|
|
||||||
// ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) )
|
// ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) )
|
||||||
UINFO(4,"constAssignW "<<nodep<<endl);
|
UINFO(4,"constAssignW "<<nodep<<endl);
|
||||||
// Make a initial assignment
|
// Make a initial assignment
|
||||||
@@ -1340,77 +1428,79 @@ private:
|
|||||||
|
|
||||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (AstConst* constp = nodep->condp()->castConst()) {
|
if (m_doNConst) {
|
||||||
AstNode* keepp = NULL;
|
if (AstConst* constp = nodep->condp()->castConst()) {
|
||||||
if (constp->isZero()) {
|
AstNode* keepp = NULL;
|
||||||
UINFO(4,"IF(0,{any},{x}) => {x}: "<<nodep<<endl);
|
if (constp->isZero()) {
|
||||||
keepp = nodep->elsesp();
|
UINFO(4,"IF(0,{any},{x}) => {x}: "<<nodep<<endl);
|
||||||
} else {
|
keepp = nodep->elsesp();
|
||||||
UINFO(4,"IF(!0,{x},{any}) => {x}: "<<nodep<<endl);
|
} else {
|
||||||
keepp = nodep->ifsp();
|
UINFO(4,"IF(!0,{x},{any}) => {x}: "<<nodep<<endl);
|
||||||
|
keepp = nodep->ifsp();
|
||||||
|
}
|
||||||
|
if (keepp) {
|
||||||
|
keepp->unlinkFrBackWithNext();
|
||||||
|
nodep->replaceWith(keepp);
|
||||||
|
} else {
|
||||||
|
nodep->unlinkFrBack();
|
||||||
|
}
|
||||||
|
nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
if (keepp) {
|
else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) {
|
||||||
keepp->unlinkFrBackWithNext();
|
// Empty block, remove it
|
||||||
nodep->replaceWith(keepp);
|
// Note if we support more C++ then there might be side effects in the condition itself
|
||||||
} else {
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
nodep->unlinkFrBack();
|
}
|
||||||
|
else if (!afterComment(nodep->ifsp())) {
|
||||||
|
UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<<nodep<<endl);
|
||||||
|
AstNode* condp = nodep->condp();
|
||||||
|
AstNode* elsesp = nodep->elsesp();
|
||||||
|
condp->unlinkFrBackWithNext();
|
||||||
|
elsesp->unlinkFrBackWithNext();
|
||||||
|
if (nodep->ifsp()) { nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); } // Must have been comment
|
||||||
|
nodep->condp(new AstLogNot(condp->fileline(), condp)); // LogNot, as C++ optimization also possible
|
||||||
|
nodep->addIfsp(elsesp);
|
||||||
|
}
|
||||||
|
else if (((nodep->condp()->castNot() && nodep->condp()->width()==1)
|
||||||
|
|| (nodep->condp()->castLogNot()))
|
||||||
|
&& nodep->ifsp() && nodep->elsesp()) {
|
||||||
|
UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl);
|
||||||
|
AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext();
|
||||||
|
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
|
||||||
|
AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext();
|
||||||
|
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
|
||||||
|
ifp->branchPred(nodep->branchPred().invert());
|
||||||
|
nodep->replaceWith(ifp);
|
||||||
|
nodep->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
else if (ifSameAssign(nodep)) {
|
||||||
|
UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<<endl);
|
||||||
|
AstNodeAssign* ifp = nodep->ifsp()->castNodeAssign();
|
||||||
|
AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign();
|
||||||
|
ifp->unlinkFrBack();
|
||||||
|
AstNode* condp = nodep->condp()->unlinkFrBack();
|
||||||
|
AstNode* truep = ifp->rhsp()->unlinkFrBack();
|
||||||
|
AstNode* falsep = elsep->rhsp()->unlinkFrBack();
|
||||||
|
ifp->rhsp(new AstCond(truep->fileline(),
|
||||||
|
condp, truep, falsep));
|
||||||
|
nodep->replaceWith(ifp);
|
||||||
|
nodep->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
|
||||||
|
&& operandIfIf(nodep)) {
|
||||||
|
UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl);
|
||||||
|
AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf();
|
||||||
|
AstNode* condp = nodep->condp()->unlinkFrBack();
|
||||||
|
AstNode* lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext();
|
||||||
|
AstNode* lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
|
||||||
|
nodep->condp(new AstLogAnd(lowerIfp->fileline(),
|
||||||
|
condp, lowerCondp));
|
||||||
|
lowerIfp->replaceWith(lowerIfsp);
|
||||||
|
lowerIfp->deleteTree(); lowerIfp=NULL;
|
||||||
|
}
|
||||||
|
else if (operandBoolShift(nodep->condp())) {
|
||||||
|
replaceBoolShift(nodep->condp());
|
||||||
}
|
}
|
||||||
nodep->deleteTree(); nodep=NULL;
|
|
||||||
}
|
|
||||||
else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) {
|
|
||||||
// Empty block, remove it
|
|
||||||
// Note if we support more C++ then there might be side effects in the condition itself
|
|
||||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
|
||||||
}
|
|
||||||
else if (!afterComment(nodep->ifsp())) {
|
|
||||||
UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<<nodep<<endl);
|
|
||||||
AstNode* condp = nodep->condp();
|
|
||||||
AstNode* elsesp = nodep->elsesp();
|
|
||||||
condp->unlinkFrBackWithNext();
|
|
||||||
elsesp->unlinkFrBackWithNext();
|
|
||||||
if (nodep->ifsp()) { nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); } // Must have been comment
|
|
||||||
nodep->condp(new AstLogNot(condp->fileline(), condp)); // LogNot, as C++ optimization also possible
|
|
||||||
nodep->addIfsp(elsesp);
|
|
||||||
}
|
|
||||||
else if (((nodep->condp()->castNot() && nodep->condp()->width()==1)
|
|
||||||
|| (nodep->condp()->castLogNot()))
|
|
||||||
&& nodep->ifsp() && nodep->elsesp()) {
|
|
||||||
UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl);
|
|
||||||
AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext();
|
|
||||||
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
|
|
||||||
AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext();
|
|
||||||
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
|
|
||||||
ifp->branchPred(nodep->branchPred().invert());
|
|
||||||
nodep->replaceWith(ifp);
|
|
||||||
nodep->deleteTree(); nodep=NULL;
|
|
||||||
}
|
|
||||||
else if (ifSameAssign(nodep)) {
|
|
||||||
UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<<endl);
|
|
||||||
AstNodeAssign* ifp = nodep->ifsp()->castNodeAssign();
|
|
||||||
AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign();
|
|
||||||
ifp->unlinkFrBack();
|
|
||||||
AstNode* condp = nodep->condp()->unlinkFrBack();
|
|
||||||
AstNode* truep = ifp->rhsp()->unlinkFrBack();
|
|
||||||
AstNode* falsep = elsep->rhsp()->unlinkFrBack();
|
|
||||||
ifp->rhsp(new AstCond(truep->fileline(),
|
|
||||||
condp, truep, falsep));
|
|
||||||
nodep->replaceWith(ifp);
|
|
||||||
nodep->deleteTree(); nodep=NULL;
|
|
||||||
}
|
|
||||||
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
|
|
||||||
&& operandIfIf(nodep)) {
|
|
||||||
UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl);
|
|
||||||
AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf();
|
|
||||||
AstNode* condp = nodep->condp()->unlinkFrBack();
|
|
||||||
AstNode* lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext();
|
|
||||||
AstNode* lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
|
|
||||||
nodep->condp(new AstLogAnd(lowerIfp->fileline(),
|
|
||||||
condp, lowerCondp));
|
|
||||||
lowerIfp->replaceWith(lowerIfsp);
|
|
||||||
lowerIfp->deleteTree(); lowerIfp=NULL;
|
|
||||||
}
|
|
||||||
else if (operandBoolShift(nodep->condp())) {
|
|
||||||
replaceBoolShift(nodep->condp());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1423,7 +1513,7 @@ private:
|
|||||||
for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) {
|
for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) {
|
||||||
if (argp->castConst()) { anyconst=true; break; }
|
if (argp->castConst()) { anyconst=true; break; }
|
||||||
}
|
}
|
||||||
if (anyconst) {
|
if (m_doNConst && anyconst) {
|
||||||
//UINFO(9," Display in "<<nodep->text()<<endl);
|
//UINFO(9," Display in "<<nodep->text()<<endl);
|
||||||
string dispout = "";
|
string dispout = "";
|
||||||
string fmt = "";
|
string fmt = "";
|
||||||
@@ -1434,7 +1524,7 @@ private:
|
|||||||
if (!inPct && ch=='%') {
|
if (!inPct && ch=='%') {
|
||||||
inPct = true;
|
inPct = true;
|
||||||
fmt = ch;
|
fmt = ch;
|
||||||
} else if (inPct && isdigit(ch)) {
|
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
||||||
fmt += ch;
|
fmt += ch;
|
||||||
} else if (inPct) {
|
} else if (inPct) {
|
||||||
inPct = false;
|
inPct = false;
|
||||||
@@ -1450,7 +1540,7 @@ private:
|
|||||||
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
|
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
|
||||||
{ // fmt = out w/ replace % with %% as it must be literal.
|
{ // fmt = out w/ replace % with %% as it must be literal.
|
||||||
fmt = "";
|
fmt = "";
|
||||||
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
|
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
|
||||||
if (*pos == '%') fmt += '%';
|
if (*pos == '%') fmt += '%';
|
||||||
fmt += *pos;
|
fmt += *pos;
|
||||||
}
|
}
|
||||||
@@ -1486,14 +1576,16 @@ private:
|
|||||||
|
|
||||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (nodep->condp()->isZero()) {
|
if (m_doNConst) {
|
||||||
UINFO(4,"WHILE(0) => nop "<<nodep<<endl);
|
if (nodep->condp()->isZero()) {
|
||||||
if (nodep->precondsp()) nodep->replaceWith(nodep->precondsp());
|
UINFO(4,"WHILE(0) => nop "<<nodep<<endl);
|
||||||
else nodep->unlinkFrBack();
|
if (nodep->precondsp()) nodep->replaceWith(nodep->precondsp());
|
||||||
nodep->deleteTree(); nodep=NULL;
|
else nodep->unlinkFrBack();
|
||||||
}
|
nodep->deleteTree(); nodep=NULL;
|
||||||
else if (operandBoolShift(nodep->condp())) {
|
}
|
||||||
replaceBoolShift(nodep->condp());
|
else if (operandBoolShift(nodep->condp())) {
|
||||||
|
replaceBoolShift(nodep->condp());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1501,12 +1593,20 @@ private:
|
|||||||
// If output of a presel didn't get consted, chances are V3Param didn't visit properly
|
// If output of a presel didn't get consted, chances are V3Param didn't visit properly
|
||||||
virtual void visit(AstNodePreSel* nodep, AstNUser*) {}
|
virtual void visit(AstNodePreSel* nodep, AstNUser*) {}
|
||||||
|
|
||||||
|
// Ignored, can eliminate early
|
||||||
|
virtual void visit(AstSysIgnore* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
if (m_doNConst) {
|
||||||
|
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----
|
//-----
|
||||||
// Jump elimination
|
// Jump elimination
|
||||||
|
|
||||||
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (m_expensive) { nodep->labelp()->user4(true); }
|
if (m_doExpensive) { nodep->labelp()->user4(true); }
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstJumpLabel* nodep, AstNUser*) {
|
virtual void visit(AstJumpLabel* nodep, AstNUser*) {
|
||||||
@@ -1515,7 +1615,7 @@ private:
|
|||||||
// Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
|
// Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
// AstJumpGo's below here that point to this node will set user4
|
// AstJumpGo's below here that point to this node will set user4
|
||||||
if (m_expensive && !nodep->user4()) {
|
if (m_doExpensive && !nodep->user4()) {
|
||||||
UINFO(4,"JUMPLABEL => unused "<<nodep<<endl);
|
UINFO(4,"JUMPLABEL => unused "<<nodep<<endl);
|
||||||
AstNode* underp = NULL;
|
AstNode* underp = NULL;
|
||||||
if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext();
|
if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||||
@@ -1546,78 +1646,81 @@ private:
|
|||||||
|
|
||||||
// Lint Checks
|
// Lint Checks
|
||||||
// v--- *1* These ops are always first, as we warn before replacing
|
// v--- *1* These ops are always first, as we warn before replacing
|
||||||
// v--- *V* This op is a verilog op, ignore when in m_cpp mode
|
// v--- *V* This op is a verilog op, only in m_doV mode
|
||||||
|
// v--- *C* This op works on all constant children, allowed in m_doConst mode
|
||||||
TREEOP1("AstSel{warnSelect(nodep)}", "NEVER");
|
TREEOP1("AstSel{warnSelect(nodep)}", "NEVER");
|
||||||
// Generic constants on both side. Do this first to avoid other replacements
|
// Generic constants on both side. Do this first to avoid other replacements
|
||||||
TREEOP("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)");
|
TREEOPC("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)");
|
||||||
TREEOP("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)");
|
TREEOPC("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)");
|
||||||
// Zero on one side or the other
|
// Zero on one side or the other
|
||||||
TREEOP("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstAnd {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstAnd {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstDiv {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstDivS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstMul {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstMulS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstPow {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstPow {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstPowS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstPowS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
TREEOP ("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
|
||||||
TREEOP("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
|
TREEOP ("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
|
||||||
TREEOP("AstSub {$lhsp.isZero, $rhsp}", "AstUnaryMin{$rhsp}");
|
TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstNegate{$rhsp}");
|
||||||
TREEOP("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstAnd {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
||||||
TREEOP("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
||||||
TREEOP("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstMul {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
||||||
TREEOP("AstMulS {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
|
||||||
TREEOP("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}");
|
TREEOP ("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}");
|
||||||
// Non-zero on one side or the other
|
// Non-zero on one side or the other
|
||||||
TREEOP("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstOr {$lhsp.isAllOnes, $rhsp}", "replaceWLhs(nodep)"); //->allOnes
|
TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp}", "replaceWLhs(nodep)"); //->allOnes
|
||||||
TREEOP("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)");
|
TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
|
TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)");
|
TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstOr {$lhsp, $rhsp.isAllOnes}", "replaceWRhs(nodep)"); //->allOnes
|
TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes}", "replaceWRhs(nodep)"); //->allOnes
|
||||||
TREEOP("AstLogOr {$lhsp, $rhsp.isNeqZero}", "replaceNum(nodep,1)");
|
TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
|
TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
|
||||||
TREEOP("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
|
TREEOP ("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
|
||||||
TREEOP("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
|
TREEOP ("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
|
TREEOP ("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
|
TREEOP ("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
|
||||||
TREEOP("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
|
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
|
||||||
TREEOP("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
||||||
TREEOP("AstPowS {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
TREEOP ("AstPowS {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
||||||
// Trinary ops
|
// Trinary ops
|
||||||
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
|
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
|
||||||
TREEOP("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");
|
TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");
|
||||||
TREEOP("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)");
|
TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)");
|
||||||
TREEOP("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)");
|
TREEOPC("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)");
|
||||||
TREEOP("AstCond{$condp->castNot(), $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}");
|
TREEOPC("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)");
|
||||||
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstOr {$condp, $expr2p}"); // a?1:b == a|b
|
TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)");
|
||||||
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstAnd{$condp, $expr1p}"); // a?b:0 == a&b
|
TREEOP ("AstCond{$condp->castNot(), $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}");
|
||||||
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a|b
|
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstOr {$condp, $expr2p}"); // a?1:b == a|b
|
||||||
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&b
|
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstAnd{$condp, $expr1p}"); // a?b:0 == a&b
|
||||||
TREEOP("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
|
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a|b
|
||||||
|
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&b
|
||||||
|
TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
|
||||||
// Prefer constants on left, since that often needs a shift, it lets constant red remove the shift
|
// Prefer constants on left, since that often needs a shift, it lets constant red remove the shift
|
||||||
TREEOP("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
|
TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
|
||||||
TREEOP("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
|
TREEOP ("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
|
||||||
TREEOP("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
|
TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
|
||||||
TREEOP("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
|
TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
|
||||||
TREEOP("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
|
TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
|
||||||
// v--- *1* as These ops are always first, as we warn before replacing
|
// v--- *1* as These ops are always first, as we warn before replacing
|
||||||
TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)");
|
TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)");
|
||||||
TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)");
|
TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)");
|
||||||
@@ -1666,33 +1769,46 @@ private:
|
|||||||
TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
|
TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
|
||||||
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
|
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
|
||||||
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
|
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
|
||||||
|
// Compress out EXTENDs to appease loop unroller
|
||||||
|
TREEOPV("AstEq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstNeq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstGt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstGte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstLt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstLte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||||
// Identical operands on both sides
|
// Identical operands on both sides
|
||||||
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
|
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
|
||||||
// AstAdd->ShiftL(#,1) but uncommon
|
// AstAdd->ShiftL(#,1) but uncommon
|
||||||
TREEOP("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
|
TREEOP ("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
|
TREEOP ("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
|
||||||
TREEOP("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)");
|
TREEOP ("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)");
|
||||||
TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
|
TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
|
||||||
TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstEqD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
|
||||||
TREEOP("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstGtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstGteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstLtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
TREEOP("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
|
TREEOP ("AstLteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
|
TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP ("AstNeqD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
|
||||||
|
TREEOP ("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
|
||||||
///=== Verilog operators
|
///=== Verilog operators
|
||||||
// Comparison against 1'b0/1'b1; must be careful about widths.
|
// Comparison against 1'b0/1'b1; must be careful about widths.
|
||||||
// These use Not, so must be Verilog only
|
// These use Not, so must be Verilog only
|
||||||
@@ -1743,18 +1859,33 @@ private:
|
|||||||
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
|
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
|
||||||
// Next rule because AUTOINST puts the width of bits in
|
// Next rule because AUTOINST puts the width of bits in
|
||||||
// to pins, even when the widths are exactly the same across the hierarchy.
|
// to pins, even when the widths are exactly the same across the hierarchy.
|
||||||
TREEOPV("AstSel{operandSelExtend(nodep)}", "replaceWChild(nodep, nodep->fromp()->castExtend()->lhsp())");
|
TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE");
|
||||||
TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())");
|
TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())");
|
||||||
TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)");
|
TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)");
|
||||||
TREEOPV("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
|
TREEOPV("AstSel{$fromp.castAdd, operandSelBiLower(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstSel{$fromp.castAnd, operandSelBiLower(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstSel{$fromp.castOr, operandSelBiLower(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstSel{$fromp.castXnor,operandSelBiLower(nodep)}", "DONE");
|
||||||
|
TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE");
|
||||||
|
TREEOPC("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
|
||||||
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
|
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
|
||||||
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)");
|
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)");
|
||||||
|
// V3Tristate requires selects below BufIf1.
|
||||||
|
// Also do additional operators that are bit-independent, but only definite
|
||||||
|
// win if bit select is a constant (otherwise we may need to compute bit index several times)
|
||||||
|
TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)");
|
||||||
|
TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)");
|
||||||
|
TREEOPV("AstSel{$fromp.castAnd,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||||
|
TREEOPV("AstSel{$fromp.castOr,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||||
|
TREEOPV("AstSel{$fromp.castXor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||||
|
TREEOPV("AstSel{$fromp.castXnor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||||
// Conversions
|
// Conversions
|
||||||
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
|
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
|
||||||
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
|
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
|
||||||
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
|
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
|
||||||
// Strings
|
// Strings
|
||||||
TREEOP ("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())");
|
TREEOPC("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())");
|
||||||
|
|
||||||
|
|
||||||
// Possible futures:
|
// Possible futures:
|
||||||
@@ -1781,15 +1912,37 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Processing Mode Enum
|
||||||
|
enum ProcMode {
|
||||||
|
PROC_PARAMS,
|
||||||
|
PROC_LIVE,
|
||||||
|
PROC_V_WARN,
|
||||||
|
PROC_V_NOWARN,
|
||||||
|
PROC_V_EXPENSIVE,
|
||||||
|
PROC_CPP
|
||||||
|
};
|
||||||
|
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
ConstVisitor(bool params, bool expensive, bool warn, bool cpp) {
|
ConstVisitor(ProcMode pmode) {
|
||||||
m_params = params; m_required = params;
|
m_params = false;
|
||||||
m_expensive = expensive;
|
m_required = false;
|
||||||
m_warn = warn;
|
m_doExpensive = false;
|
||||||
m_cpp = cpp;
|
m_doNConst = false;
|
||||||
m_wremove = true;
|
m_doV = false;
|
||||||
|
m_warn = false;
|
||||||
|
m_wremove = true; // Overridden in visitors
|
||||||
m_modp = NULL;
|
m_modp = NULL;
|
||||||
m_scopep = NULL;
|
m_scopep = NULL;
|
||||||
|
//
|
||||||
|
switch (pmode) {
|
||||||
|
case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true; m_required = true; break;
|
||||||
|
case PROC_LIVE: break;
|
||||||
|
case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; break;
|
||||||
|
case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break;
|
||||||
|
case PROC_V_EXPENSIVE: m_doV = true; m_doNConst = true; m_doExpensive = true; break;
|
||||||
|
case PROC_CPP: m_doV = false; m_doNConst = true; break;
|
||||||
|
default: v3fatalSrc("Bad case"); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
virtual ~ConstVisitor() {}
|
virtual ~ConstVisitor() {}
|
||||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||||
@@ -1806,7 +1959,7 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
|
|||||||
// Resize even if the node already has a width, because burried in the treee we may
|
// Resize even if the node already has a width, because burried in the treee we may
|
||||||
// have a node we just created with signing, etc, that isn't sized yet.
|
// have a node we just created with signing, etc, that isn't sized yet.
|
||||||
nodep = V3Width::widthParamsEdit(nodep); // Make sure we've sized everything first
|
nodep = V3Width::widthParamsEdit(nodep); // Make sure we've sized everything first
|
||||||
ConstVisitor visitor (true,false,false,false);
|
ConstVisitor visitor (ConstVisitor::PROC_PARAMS);
|
||||||
if (AstVar* varp=nodep->castVar()) {
|
if (AstVar* varp=nodep->castVar()) {
|
||||||
// If a var wants to be constified, it's really a param, and
|
// If a var wants to be constified, it's really a param, and
|
||||||
// we want the value to be constant. We aren't passed just the
|
// we want the value to be constant. We aren't passed just the
|
||||||
@@ -1820,34 +1973,43 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
|
|||||||
return nodep;
|
return nodep;
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3Const::constifyAll(AstNetlist* nodep) {
|
|
||||||
// Only call from Verilator.cpp, as it uses user#'s
|
|
||||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
|
||||||
ConstVisitor visitor (false,true,false,false);
|
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void V3Const::constifyAllLint(AstNetlist* nodep) {
|
void V3Const::constifyAllLint(AstNetlist* nodep) {
|
||||||
// Only call from Verilator.cpp, as it uses user#'s
|
// Only call from Verilator.cpp, as it uses user#'s
|
||||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
ConstVisitor visitor (false,false,true,false);
|
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3Const::constifyCpp(AstNetlist* nodep) {
|
void V3Const::constifyCpp(AstNetlist* nodep) {
|
||||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
ConstVisitor visitor (false,false,false,true);
|
ConstVisitor visitor (ConstVisitor::PROC_CPP);
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* V3Const::constifyEdit(AstNode* nodep) {
|
AstNode* V3Const::constifyEdit(AstNode* nodep) {
|
||||||
ConstVisitor visitor (false,false,false,false);
|
ConstVisitor visitor (ConstVisitor::PROC_V_NOWARN);
|
||||||
nodep = visitor.mainAcceptEdit(nodep);
|
nodep = visitor.mainAcceptEdit(nodep);
|
||||||
return nodep;
|
return nodep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void V3Const::constifyAllLive(AstNetlist* nodep) {
|
||||||
|
// Only call from Verilator.cpp, as it uses user#'s
|
||||||
|
// This only pushes constants up, doesn't make any other edits
|
||||||
|
// IE doesn't prune dead statements, as we need to do some usability checks after this
|
||||||
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
|
ConstVisitor visitor (ConstVisitor::PROC_LIVE);
|
||||||
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void V3Const::constifyAll(AstNetlist* nodep) {
|
||||||
|
// Only call from Verilator.cpp, as it uses user#'s
|
||||||
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
|
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
|
||||||
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
|
}
|
||||||
|
|
||||||
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
|
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
|
||||||
ConstVisitor visitor (false,true,false,false);
|
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
|
||||||
nodep = visitor.mainAcceptEdit(nodep);
|
nodep = visitor.mainAcceptEdit(nodep);
|
||||||
return nodep;
|
return nodep;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -34,6 +34,8 @@ public:
|
|||||||
// Force this cell node's parameter list to become a constant
|
// Force this cell node's parameter list to become a constant
|
||||||
// Return new node that may have replaced nodep
|
// Return new node that may have replaced nodep
|
||||||
static AstNode* constifyParamsEdit(AstNode* nodep);
|
static AstNode* constifyParamsEdit(AstNode* nodep);
|
||||||
|
// Only do constant pushing, without removing dead logic
|
||||||
|
static void constifyAllLive(AstNetlist* nodep);
|
||||||
// Everything that's possible
|
// Everything that's possible
|
||||||
static void constifyAll(AstNetlist* nodep);
|
static void constifyAll(AstNetlist* nodep);
|
||||||
// Also, warn
|
// Also, warn
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -97,7 +97,7 @@ private:
|
|||||||
removep->unlinkFrBack(); pushDeletep(removep); removep=NULL;
|
removep->unlinkFrBack(); pushDeletep(removep); removep=NULL;
|
||||||
// Remove node from comparison so don't hit it again
|
// Remove node from comparison so don't hit it again
|
||||||
hashed.erase(dupit);
|
hashed.erase(dupit);
|
||||||
m_statToggleJoins++;
|
++m_statToggleJoins;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+7
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -122,6 +122,12 @@ private:
|
|||||||
nodep->packagep()->user1Inc();
|
nodep->packagep()->user1Inc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
if (nodep->packagep()) {
|
||||||
|
nodep->packagep()->user1Inc();
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
m_vscsp.push_back(nodep);
|
m_vscsp.push_back(nodep);
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+3
-7
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -224,7 +224,6 @@ private:
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
//=== Setting/not setting boolean: __Vdlyvset__
|
//=== Setting/not setting boolean: __Vdlyvset__
|
||||||
bool sharedVset = false;
|
|
||||||
AstVarScope* setvscp;
|
AstVarScope* setvscp;
|
||||||
|
|
||||||
if (nodep->user3p()) {
|
if (nodep->user3p()) {
|
||||||
@@ -232,9 +231,8 @@ private:
|
|||||||
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
|
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
|
||||||
// This is good for code like:
|
// This is good for code like:
|
||||||
// for (i=0; i<5; i++) vector[i] <= something;
|
// for (i=0; i<5; i++) vector[i] <= something;
|
||||||
sharedVset = true;
|
|
||||||
setvscp = nodep->user3p()->castNode()->castVarScope();
|
setvscp = nodep->user3p()->castNode()->castVarScope();
|
||||||
m_statSharedSet++;
|
++m_statSharedSet;
|
||||||
} else { // Create new one
|
} else { // Create new one
|
||||||
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||||
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1);
|
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1);
|
||||||
@@ -345,9 +343,7 @@ private:
|
|||||||
m_nextDlyp = NULL;
|
m_nextDlyp = NULL;
|
||||||
}
|
}
|
||||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
if (!nodep->user2()) { // Not done yet
|
if (!nodep->user2Inc()) { // Not done yet
|
||||||
nodep->user2(true);
|
|
||||||
|
|
||||||
if (m_inDly && nodep->lvalue()) {
|
if (m_inDly && nodep->lvalue()) {
|
||||||
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
|
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
|
||||||
markVarUsage(nodep->varScopep(), VU_DLY);
|
markVarUsage(nodep->varScopep(), VU_DLY);
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+57
-14
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -55,9 +55,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
int splitFilenum() { return m_splitFilenum; }
|
int splitFilenum() const { return m_splitFilenum; }
|
||||||
int splitFilenumInc() { m_splitSize = 0; return ++m_splitFilenum; }
|
int splitFilenumInc() { m_splitSize = 0; return ++m_splitFilenum; }
|
||||||
int splitSize() { return m_splitSize; }
|
int splitSize() const { return m_splitSize; }
|
||||||
void splitSizeInc(AstNode* nodep) { m_splitSize += EmitCBaseCounterVisitor(nodep).count(); }
|
void splitSizeInc(AstNode* nodep) { m_splitSize += EmitCBaseCounterVisitor(nodep).count(); }
|
||||||
bool splitNeeded() { return (splitSize() && v3Global.opt.outputSplit() > 1
|
bool splitNeeded() { return (splitSize() && v3Global.opt.outputSplit() > 1
|
||||||
&& v3Global.opt.outputSplit() < splitSize()); }
|
&& v3Global.opt.outputSplit() < splitSize()); }
|
||||||
@@ -127,6 +127,7 @@ public:
|
|||||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||||
} else if (nodep->isWide()
|
} else if (nodep->isWide()
|
||||||
&& nodep->lhsp()->castVarRef()
|
&& nodep->lhsp()->castVarRef()
|
||||||
|
&& !nodep->rhsp()->castCMath()
|
||||||
&& !nodep->rhsp()->castVarRef()
|
&& !nodep->rhsp()->castVarRef()
|
||||||
&& !nodep->rhsp()->castArraySel()) {
|
&& !nodep->rhsp()->castArraySel()) {
|
||||||
// Wide functions assign into the array directly, don't need separate assign statement
|
// Wide functions assign into the array directly, don't need separate assign statement
|
||||||
@@ -343,13 +344,11 @@ public:
|
|||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstFClose* nodep, AstNUser*) {
|
virtual void visit(AstFClose* nodep, AstNUser*) {
|
||||||
puts("if (");
|
puts("VL_FCLOSE_I(");
|
||||||
nodep->filep()->iterateAndNext(*this);
|
nodep->filep()->iterateAndNext(*this);
|
||||||
puts(") { fclose (VL_CVT_Q_FP(");
|
puts("); ");
|
||||||
nodep->filep()->iterateAndNext(*this);
|
|
||||||
puts(")); ");
|
|
||||||
nodep->filep()->iterateAndNext(*this); // For saftey, so user doesn't later WRITE with it.
|
nodep->filep()->iterateAndNext(*this); // For saftey, so user doesn't later WRITE with it.
|
||||||
puts("=0; }\n");
|
puts("=0;\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||||
if (!nodep->filep()) {
|
if (!nodep->filep()) {
|
||||||
@@ -357,11 +356,35 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
puts("if (");
|
puts("if (");
|
||||||
nodep->filep()->iterateAndNext(*this);
|
nodep->filep()->iterateAndNext(*this);
|
||||||
puts(") { fflush (VL_CVT_Q_FP(");
|
puts(") { fflush (VL_CVT_I_FP(");
|
||||||
nodep->filep()->iterateAndNext(*this);
|
nodep->filep()->iterateAndNext(*this);
|
||||||
puts(")); }\n");
|
puts(")); }\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstSystemT* nodep, AstNUser*) {
|
||||||
|
puts("(void)VL_SYSTEM_I");
|
||||||
|
emitIQW(nodep->lhsp());
|
||||||
|
puts("(");
|
||||||
|
if (nodep->lhsp()->isWide()) {
|
||||||
|
puts(cvtToStr(nodep->lhsp()->widthWords()));
|
||||||
|
putbs(", ");
|
||||||
|
}
|
||||||
|
checkMaxWords(nodep->lhsp());
|
||||||
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
|
puts(");\n");
|
||||||
|
}
|
||||||
|
virtual void visit(AstSystemF* nodep, AstNUser*) {
|
||||||
|
puts("VL_SYSTEM_I");
|
||||||
|
emitIQW(nodep->lhsp());
|
||||||
|
puts("(");
|
||||||
|
if (nodep->lhsp()->isWide()) {
|
||||||
|
puts(cvtToStr(nodep->lhsp()->widthWords()));
|
||||||
|
putbs(", ");
|
||||||
|
}
|
||||||
|
checkMaxWords(nodep->lhsp());
|
||||||
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
|
puts(")");
|
||||||
|
}
|
||||||
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
||||||
puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n");
|
puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n");
|
||||||
}
|
}
|
||||||
@@ -475,7 +498,7 @@ public:
|
|||||||
}
|
}
|
||||||
visit(nodep->castNodeBiop(), vup);
|
visit(nodep->castNodeBiop(), vup);
|
||||||
}
|
}
|
||||||
virtual void visit(AstCast* nodep, AstNUser*) {
|
virtual void visit(AstCCast* nodep, AstNUser*) {
|
||||||
// Extending a value of the same word width is just a NOP.
|
// Extending a value of the same word width is just a NOP.
|
||||||
if (nodep->size()>VL_WORDSIZE) {
|
if (nodep->size()>VL_WORDSIZE) {
|
||||||
puts("(QData)(");
|
puts("(QData)(");
|
||||||
@@ -546,6 +569,8 @@ public:
|
|||||||
ofp()->printf(",0x%08" VL_PRI64 "x", (vluint64_t)(nodep->num().dataWord(word)));
|
ofp()->printf(",0x%08" VL_PRI64 "x", (vluint64_t)(nodep->num().dataWord(word)));
|
||||||
}
|
}
|
||||||
ofp()->printf(",0x%08" VL_PRI64 "x)", (vluint64_t)(nodep->num().dataWord(0)));
|
ofp()->printf(",0x%08" VL_PRI64 "x)", (vluint64_t)(nodep->num().dataWord(0)));
|
||||||
|
} else if (nodep->isDouble()) {
|
||||||
|
ofp()->printf("%.17g", nodep->num().toDouble());
|
||||||
} else if (nodep->isQuad()) {
|
} else if (nodep->isQuad()) {
|
||||||
vluint64_t num = nodep->toUQuad();
|
vluint64_t num = nodep->toUQuad();
|
||||||
if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "d)", num);
|
if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "d)", num);
|
||||||
@@ -829,6 +854,8 @@ class EmitCImp : EmitCStmts {
|
|||||||
public:
|
public:
|
||||||
EmitCImp() {
|
EmitCImp() {
|
||||||
m_modp = NULL;
|
m_modp = NULL;
|
||||||
|
m_slow = false;
|
||||||
|
m_fast = false;
|
||||||
}
|
}
|
||||||
virtual ~EmitCImp() {}
|
virtual ~EmitCImp() {}
|
||||||
void main(AstNodeModule* modp, bool slow, bool fast);
|
void main(AstNodeModule* modp, bool slow, bool fast);
|
||||||
@@ -1211,6 +1238,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
|||||||
switch (tolower(pos[0])) {
|
switch (tolower(pos[0])) {
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
case '.':
|
||||||
// Digits, like %5d, etc.
|
// Digits, like %5d, etc.
|
||||||
vfmt += pos[0];
|
vfmt += pos[0];
|
||||||
inPct = true; // Get more digits
|
inPct = true; // Get more digits
|
||||||
@@ -1229,6 +1257,9 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
|||||||
case 'h':
|
case 'h':
|
||||||
case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break;
|
case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break;
|
||||||
case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break;
|
case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break;
|
||||||
|
case 'e': displayArg(nodep,&elistp,isScan, vfmt,'e'); break;
|
||||||
|
case 'f': displayArg(nodep,&elistp,isScan, vfmt,'f'); break;
|
||||||
|
case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break;
|
||||||
case 'm': {
|
case 'm': {
|
||||||
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||||
string suffix = scopenamep->scopePrettyName();
|
string suffix = scopenamep->scopePrettyName();
|
||||||
@@ -1419,6 +1450,7 @@ void EmitCImp::emitStaticDecl(AstNodeModule* modp) {
|
|||||||
// Need implementation here. Be careful of alignment code; needs to be uniquified
|
// Need implementation here. Be careful of alignment code; needs to be uniquified
|
||||||
// with module name to avoid multiple symbols.
|
// with module name to avoid multiple symbols.
|
||||||
//emitVarList(modp->stmtsp(), EVL_ALL, modp->name());
|
//emitVarList(modp->stmtsp(), EVL_ALL, modp->name());
|
||||||
|
puts(""); // NOP for cppcheck, otherwise const function
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCImp::emitTextSection(AstType type) {
|
void EmitCImp::emitTextSection(AstType type) {
|
||||||
@@ -1619,7 +1651,12 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
|||||||
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
|
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
|
||||||
puts("#include \""+topClassName()+"__Inlines.h\"\n");
|
puts("#include \""+topClassName()+"__Inlines.h\"\n");
|
||||||
}
|
}
|
||||||
// No __Dpi.h needed, we've shimmed it all into the interface
|
if (v3Global.dpi()) {
|
||||||
|
// do this before including our main .h file so that any references to
|
||||||
|
// types defined in svdpi.h are available
|
||||||
|
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
|
||||||
|
puts("\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Declare foreign instances up front to make C++ happy
|
// Declare foreign instances up front to make C++ happy
|
||||||
puts("class "+symClassName()+";\n");
|
puts("class "+symClassName()+";\n");
|
||||||
@@ -1797,8 +1834,10 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
|||||||
|
|
||||||
// Us
|
// Us
|
||||||
puts("#include \""+ symClassName() +".h\"\n");
|
puts("#include \""+ symClassName() +".h\"\n");
|
||||||
|
|
||||||
if (v3Global.dpi()) {
|
if (v3Global.dpi()) {
|
||||||
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
|
puts("\n");
|
||||||
|
puts("#include \"verilated_dpi.h\"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optSystemPerl() && (splitFilenum() || !m_fast)) {
|
if (optSystemPerl() && (splitFilenum() || !m_fast)) {
|
||||||
@@ -2003,7 +2042,9 @@ class EmitCTrace : EmitCStmts {
|
|||||||
return varp->isSc() && varp->isScBv();
|
return varp->isSc() && varp->isScBv();
|
||||||
}
|
}
|
||||||
void emitTraceInitOne(AstTraceDecl* nodep) {
|
void emitTraceInitOne(AstTraceDecl* nodep) {
|
||||||
if (nodep->isWide()) {
|
if (nodep->isDouble()) {
|
||||||
|
puts("vcdp->declDouble");
|
||||||
|
} else if (nodep->isWide()) {
|
||||||
puts("vcdp->declArray");
|
puts("vcdp->declArray");
|
||||||
} else if (nodep->isQuad()) {
|
} else if (nodep->isQuad()) {
|
||||||
puts("vcdp->declQuad ");
|
puts("vcdp->declQuad ");
|
||||||
@@ -2032,7 +2073,9 @@ class EmitCTrace : EmitCStmts {
|
|||||||
string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL
|
string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL
|
||||||
|| m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB)
|
|| m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB)
|
||||||
? "full":"chg");
|
? "full":"chg");
|
||||||
if (nodep->isWide() || emitTraceIsScBv(nodep)) {
|
if (nodep->isDouble()) {
|
||||||
|
puts("vcdp->"+full+"Double");
|
||||||
|
} else if (nodep->isWide() || emitTraceIsScBv(nodep)) {
|
||||||
puts("vcdp->"+full+"Array");
|
puts("vcdp->"+full+"Array");
|
||||||
} else if (nodep->isQuad()) {
|
} else if (nodep->isQuad()) {
|
||||||
puts("vcdp->"+full+"Quad ");
|
puts("vcdp->"+full+"Quad ");
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+5
-3
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -519,13 +519,15 @@ void EmitCSyms::emitDpiHdr() {
|
|||||||
puts("// Manually include this file where DPI .c import functions are declared to insure\n");
|
puts("// Manually include this file where DPI .c import functions are declared to insure\n");
|
||||||
puts("// the C functions match the expectations of the DPI imports.\n");
|
puts("// the C functions match the expectations of the DPI imports.\n");
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
puts("#include \"svdpi.h\"\n");
|
||||||
|
puts("\n");
|
||||||
puts("#ifdef __cplusplus\n");
|
puts("#ifdef __cplusplus\n");
|
||||||
puts("extern \"C\" {\n");
|
puts("extern \"C\" {\n");
|
||||||
puts("#endif\n");
|
puts("#endif\n");
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
|
||||||
bool firstExp = false;
|
int firstExp = 0;
|
||||||
bool firstImp = false;
|
int firstImp = 0;
|
||||||
for (vector<AstCFunc*>::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) {
|
for (vector<AstCFunc*>::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) {
|
||||||
AstCFunc* nodep = *it;
|
AstCFunc* nodep = *it;
|
||||||
if (nodep->dpiExportWrapper()) {
|
if (nodep->dpiExportWrapper()) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user