mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 17:43:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eae1f380cd | ||
|
|
e7280d7237 | ||
|
|
78997ee13c | ||
|
|
79ab50d84f | ||
|
|
98282114c9 | ||
|
|
d6cb175f96 | ||
|
|
b4d9eb6ec4 | ||
|
|
fabbfbc46e | ||
|
|
c7d80f8cf8 | ||
|
|
c70add7d0f | ||
|
|
44fe8741f3 | ||
|
|
f8680cf5c2 | ||
|
|
24c3424e51 | ||
|
|
bd264006ef | ||
|
|
bec3daa79f | ||
|
|
ead01ba0b9 | ||
|
|
8e7267f0e2 | ||
|
|
5dbae27f01 | ||
|
|
ecb938f20e | ||
|
|
f1a2ee3273 | ||
|
|
eb2eb14297 | ||
|
|
da07cc6ed1 | ||
|
|
3ff10b40d6 | ||
|
|
7f515e6033 | ||
|
|
a583592cd4 | ||
|
|
b6f2b5b46a | ||
|
|
895a3264a3 | ||
|
|
8738a51449 | ||
|
|
8ca6901f1f | ||
|
|
c14818ebb3 | ||
|
|
58dc91605b | ||
|
|
b5b1d94d4a | ||
|
|
5a65f6debb | ||
|
|
58b1ad1439 | ||
|
|
94d0aa2058 | ||
|
|
1d6495e2dc | ||
|
|
42883e7b6a | ||
|
|
dc6a164e01 | ||
|
|
26bab12257 | ||
|
|
8714ee591f | ||
|
|
11335fae5f | ||
|
|
ce531c5a67 | ||
|
|
52e36fb434 | ||
|
|
100d5b386c | ||
|
|
699563c9bd | ||
|
|
a599fbea18 | ||
|
|
c5f0ed9c99 | ||
|
|
2ce30e78a1 | ||
|
|
3b554f4c5b | ||
|
|
cf40fd356f | ||
|
|
8848469bf9 | ||
|
|
4100417f83 | ||
|
|
bd6d743f9c | ||
|
|
857ac24ba7 | ||
|
|
5672b99203 | ||
|
|
3d8de3194c | ||
|
|
8b91a9f898 | ||
|
|
038ee69a96 | ||
|
|
8986d1f16f | ||
|
|
86c8e7b3e6 | ||
|
|
9026118a7c | ||
|
|
58fc922737 | ||
|
|
3b5c791332 | ||
|
|
6e16bc1b7b | ||
|
|
1aba0f6379 | ||
|
|
11cfa3c072 | ||
|
|
59141b1678 | ||
|
|
2083c071ce | ||
|
|
3ad5872d30 | ||
|
|
ea6bb21cdc | ||
|
|
3d4fe0364a | ||
|
|
710d7c0ee5 | ||
|
|
1c8fd37745 | ||
|
|
956c854662 | ||
|
|
318a6e348c | ||
|
|
e471a34323 | ||
|
|
95c5b85e88 | ||
|
|
a46a556a64 | ||
|
|
fa3e03e071 | ||
|
|
74d7c55f1b | ||
|
|
79e02858cb | ||
|
|
7738b202ac | ||
|
|
b4d4917c6c | ||
|
|
5c93520b27 | ||
|
|
94f0809d33 | ||
|
|
ca4e3c1737 | ||
|
|
ba7b4f261a | ||
|
|
4f42c25c7c | ||
|
|
621ef70c31 | ||
|
|
e3f17e7853 | ||
|
|
73c897ac69 | ||
|
|
a4db880809 | ||
|
|
f9697463cc | ||
|
|
f283076570 | ||
|
|
e15228498d |
@@ -3,7 +3,121 @@ Revision history for Verilator
|
|||||||
The contributors that suggested a given feature are shown in []. [by ...]
|
The contributors that suggested a given feature are shown in []. [by ...]
|
||||||
indicates the contributor was also the author of the fix; Thanks!
|
indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
* Verilator 3.602 09/11/2006
|
* Verilator 3.640 3/12/2007
|
||||||
|
|
||||||
|
*** Support Verilog 2005 `begin_keywords and `end_keywords.
|
||||||
|
|
||||||
|
*** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2005.
|
||||||
|
|
||||||
|
*** Add /*verilator public_flat*/. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Try all +libext's in the exact order given. [Michael Shinkarovsky]
|
||||||
|
|
||||||
|
**** Fix elimination of public signals assigned to constants. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Fix internal error when public for loop has empty body. [David Addison]
|
||||||
|
|
||||||
|
**** Fix "Loops detected" assertion when model exceeds 4GB. [David Hewson]
|
||||||
|
|
||||||
|
**** Fix display %m names inside named blocks.
|
||||||
|
|
||||||
|
* Verilator 3.633 2/7/2007
|
||||||
|
|
||||||
|
*** Add --trace-depth option for minimizing VCD file size. [Emerson Suguimoto]
|
||||||
|
|
||||||
|
*** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky]
|
||||||
|
|
||||||
|
**** Fix isolate_assignments when many signals per always. [Mike Shinkarovsky]
|
||||||
|
|
||||||
|
**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
|
||||||
|
|
||||||
|
**** Fix $display's with array select followed by wide AND. [David Hewson]
|
||||||
|
|
||||||
|
* Verilator 3.632 1/17/2007
|
||||||
|
|
||||||
|
*** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky]
|
||||||
|
|
||||||
|
* Verilator 3.631 1/2/2007
|
||||||
|
|
||||||
|
** Support standard NAME[#] for cells created by arraying or generate for.
|
||||||
|
This replaces the non-standard name__# syntax used in earlier versions.
|
||||||
|
|
||||||
|
**** Fix again dotted references into generate cells. [David Hewson]
|
||||||
|
Verilator no longer accepts duplicated variables inside unique
|
||||||
|
generate blocks as this is illegal according to the specification.
|
||||||
|
|
||||||
|
**** Fix $readmem* with filenames < 8 characters. [Emerson Suguimoto]
|
||||||
|
|
||||||
|
* Verilator 3.630 12/19/2006
|
||||||
|
|
||||||
|
** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich]
|
||||||
|
|
||||||
|
*** Fixed configure and compiling under Solaris. [Bob Farrell]
|
||||||
|
|
||||||
|
*** When dotted signal lookup fails, help the user by showing known scopes.
|
||||||
|
|
||||||
|
*** Reduce depth of priority encoded case statements. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Fix dotted references inside generated cells. [David Hewson]
|
||||||
|
|
||||||
|
**** Fix missed split optimization points underneath other re-split blocks.
|
||||||
|
|
||||||
|
* Verilator 3.623 12/05/2006
|
||||||
|
|
||||||
|
*** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Fix $signed mis-extending when input has a WIDTH violation. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Add M32 make variable to support -m32 compiles. [Eugene Weber]
|
||||||
|
|
||||||
|
* Verilator 3.622 10/17/2006 Stable
|
||||||
|
|
||||||
|
**** Fix --skip-identical without --debug, broken in 3.621. [Andy Meier]
|
||||||
|
|
||||||
|
* Verilator 3.621 10/11/2006 Beta
|
||||||
|
|
||||||
|
** Add /*verilator no_inline_task*/ to prevent over-expansion. [Eugene Weber]
|
||||||
|
|
||||||
|
*** Public functions now allow > 64 bit arguments.
|
||||||
|
|
||||||
|
**** Remove .vpp intermediate files when not under --debug.
|
||||||
|
|
||||||
|
**** Fix link error when using --exe with --trace. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Fix mis-optimization of wide concats with constants.
|
||||||
|
|
||||||
|
**** Fix core dump on printing error when not under --debug. [Allan Cochrane]
|
||||||
|
|
||||||
|
* Verilator 3.620 10/04/2006 Stable
|
||||||
|
|
||||||
|
*** Support simple inout task ports. [Eugene Weber]
|
||||||
|
|
||||||
|
*** Allow overriding Perl, Flex and Bison versions. [by Robert Farrell]
|
||||||
|
|
||||||
|
*** Optimize variables set to constants within basic blocks for ~3%.
|
||||||
|
|
||||||
|
**** Default make no longer makes the docs; if you edit the documentation.
|
||||||
|
sources, run "make info" to get them.
|
||||||
|
|
||||||
|
**** Optimize additional boolean identities (a|a = a, etc.)
|
||||||
|
|
||||||
|
**** Fix coredump when dotted cross-ref inside task call. [Eugene Weber]
|
||||||
|
|
||||||
|
**** Fix dotted variables in always sensitivity lists. [Allan Cochrane]
|
||||||
|
|
||||||
|
* Verilator 3.610 09/20/2006 Stable
|
||||||
|
|
||||||
|
*** Verilator now works under DJGPP (Pentium GCC). [John Stroebel]
|
||||||
|
|
||||||
|
**** Add default define for VL_PRINTF. [John Stroebel]
|
||||||
|
|
||||||
|
**** Removed coverage request variable; see Coverage limitations in docs.
|
||||||
|
|
||||||
|
**** Fix DOS carriage returns in multiline defines. [Ralf Karge]
|
||||||
|
|
||||||
|
**** Fix printf format warnings on 64-bit linux.
|
||||||
|
|
||||||
|
* Verilator 3.602 09/11/2006 Stable
|
||||||
|
|
||||||
**** Fix function references under top inlined module. [David Hewson]
|
**** Fix function references under top inlined module. [David Hewson]
|
||||||
|
|
||||||
@@ -11,7 +125,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
|
|
||||||
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
|
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
|
||||||
|
|
||||||
*** Added `systemc_dtor for destructor extentions. [Allan Cochrane]
|
*** Added `systemc_dtor for destructor extensions. [Allan Cochrane]
|
||||||
|
|
||||||
*** Added -MP to make phony dependencies, ala GCC's.
|
*** Added -MP to make phony dependencies, ala GCC's.
|
||||||
|
|
||||||
@@ -46,7 +160,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
|
|
||||||
**** Fix extraneous UNSIGNED warning when comparing genvars. [David Hewson]
|
**** Fix extraneous UNSIGNED warning when comparing genvars. [David Hewson]
|
||||||
|
|
||||||
**** Fix extra whitespace in $display %c. [by David Addison]
|
**** Fix extra white space in $display %c. [by David Addison]
|
||||||
|
|
||||||
**** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout.
|
**** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout.
|
||||||
|
|
||||||
@@ -149,7 +263,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
|
|
||||||
**** Fix functions where regs are declared before inputs. [Danny Ding]
|
**** Fix functions where regs are declared before inputs. [Danny Ding]
|
||||||
|
|
||||||
**** Fix bad deep expressions with bitselects and rotate. [Prabhat Gupta]
|
**** Fix bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
|
||||||
|
|
||||||
* Verilator 3.500 10/30/2005 Stable
|
* Verilator 3.500 10/30/2005 Stable
|
||||||
|
|
||||||
@@ -397,7 +511,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
**** Added NC Verilog as alternative to VCS for reference tests.
|
**** Added NC Verilog as alternative to VCS for reference tests.
|
||||||
|
|
||||||
**** Support implicit wire declarations on input-only signals.
|
**** Support implicit wire declarations on input-only signals.
|
||||||
(Dangerous, as leads to wires without drivers, but allowed by spec.)
|
(Dangerous, as leads to wires without drivers, but allowed by spec.)
|
||||||
|
|
||||||
**** Fixed compile warnings on Suse 9.1
|
**** Fixed compile warnings on Suse 9.1
|
||||||
|
|
||||||
@@ -933,7 +1047,7 @@ $Id$
|
|||||||
|
|
||||||
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
||||||
|
|
||||||
Copyright 2001-2006 by Wilson Snyder. This program is free software;
|
Copyright 2001-2007 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
|
||||||
General Public License or the Perl Artistic License.
|
General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
|
|||||||
+15
-16
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 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
|
||||||
# General Public License or the Perl Artistic License.
|
# General Public License or the Perl Artistic License.
|
||||||
#
|
#
|
||||||
@@ -78,7 +78,6 @@ datadir = @datadir@
|
|||||||
infodir = @infodir@
|
infodir = @infodir@
|
||||||
|
|
||||||
# Directory in which to install package specific files
|
# Directory in which to install package specific files
|
||||||
# Note this gets coded into v3c/config.h also
|
|
||||||
pkgdatadir = @pkgdatadir@
|
pkgdatadir = @pkgdatadir@
|
||||||
|
|
||||||
#### End of system configuration section. ####
|
#### End of system configuration section. ####
|
||||||
@@ -91,11 +90,11 @@ SUBDIRS = src test_verilated test_c test_sc test_sp test_regress test_vcs
|
|||||||
INFOS = README verilator.txt verilator.html verilator.1 verilator.pdf
|
INFOS = README verilator.txt verilator.html verilator.1 verilator.pdf
|
||||||
|
|
||||||
# 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 = $(INFOS) Makefile
|
DISTDEP = info Makefile
|
||||||
# Files to distribute.
|
# Files to distribute.
|
||||||
DISTBIN = $(wildcard bin/verilator-*)
|
DISTBIN = $(wildcard bin/verilator-*)
|
||||||
|
|
||||||
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in \
|
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \
|
||||||
Changes README TODO \
|
Changes README TODO \
|
||||||
bin/* \
|
bin/* \
|
||||||
install-sh configure mkinstalldirs *.texi \
|
install-sh configure mkinstalldirs *.texi \
|
||||||
@@ -126,7 +125,7 @@ INST_PROJ_BIN_FILES = \
|
|||||||
DISTFILES := $(DISTFILES_INC)
|
DISTFILES := $(DISTFILES_INC)
|
||||||
|
|
||||||
all: all_nomsg msg_test
|
all: all_nomsg msg_test
|
||||||
all_nomsg: verilator_exe info
|
all_nomsg: verilator_exe
|
||||||
|
|
||||||
.PHONY:verilator_exe
|
.PHONY:verilator_exe
|
||||||
verilator_exe verilator_bin verilator_bin_dbg:
|
verilator_exe verilator_bin verilator_bin_dbg:
|
||||||
@@ -156,15 +155,15 @@ test_vcs: all_nomsg
|
|||||||
test_c: all_nomsg
|
test_c: all_nomsg
|
||||||
@(cd test_c && $(MAKE))
|
@(cd test_c && $(MAKE))
|
||||||
test_c_debug: all_nomsg
|
test_c_debug: all_nomsg
|
||||||
@(cd test_c && $(MAKE) debug)
|
@(cd test_c && $(MAKE) test_debug)
|
||||||
test_sc: all_nomsg
|
test_sc: all_nomsg
|
||||||
@(cd test_sc && $(MAKE))
|
@(cd test_sc && $(MAKE))
|
||||||
test_sc_debug: all_nomsg
|
test_sc_debug: all_nomsg
|
||||||
@(cd test_sc && $(MAKE) debug)
|
@(cd test_sc && $(MAKE) test_debug)
|
||||||
test_sp: all_nomsg
|
test_sp: all_nomsg
|
||||||
@(cd test_sp && $(MAKE))
|
@(cd test_sp && $(MAKE))
|
||||||
test_sp_debug: all_nomsg
|
test_sp_debug: all_nomsg
|
||||||
@(cd test_sp && $(MAKE) debug)
|
@(cd test_sp && $(MAKE) test_debug)
|
||||||
test_verilated: all_nomsg
|
test_verilated: all_nomsg
|
||||||
@(cd test_verilated && $(MAKE))
|
@(cd test_verilated && $(MAKE))
|
||||||
test_regress: all_nomsg
|
test_regress: all_nomsg
|
||||||
@@ -218,7 +217,7 @@ installman:
|
|||||||
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \
|
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \
|
||||||
done
|
done
|
||||||
|
|
||||||
install: all_nomsg info installdirs installbin installman install-msg
|
install: all_nomsg installdirs installbin installman install-msg
|
||||||
|
|
||||||
install-here: installman ftp
|
install-here: installman ftp
|
||||||
|
|
||||||
@@ -265,16 +264,16 @@ uninstall:
|
|||||||
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||||
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES)
|
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||||
|
|
||||||
# autoheader might not change config.h.in, so touch a stamp file.
|
# autoheader might not change config_build.h.in, so touch a stamp file.
|
||||||
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
|
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
|
||||||
*.in */*.in */*.in
|
*.in */*.in */*.in
|
||||||
|
|
||||||
${srcdir}/config.h.in: stamp-h.in
|
${srcdir}/config_build.h.in: stamp-h.in
|
||||||
${srcdir}/stamp-h.in: configure.in $(wildcard $(IN_WILD))
|
${srcdir}/stamp-h.in: configure.ac $(wildcard $(IN_WILD))
|
||||||
cd ${srcdir} && autoheader
|
cd ${srcdir} && autoheader
|
||||||
echo timestamp > ${srcdir}/stamp-h.in
|
echo timestamp > ${srcdir}/stamp-h.in
|
||||||
config.h: stamp-h
|
config_build.h: stamp-h
|
||||||
stamp-h: config.h.in config.status
|
stamp-h: config_build.h.in config.status
|
||||||
./config.status
|
./config.status
|
||||||
Makefile: Makefile.in config.status
|
Makefile: Makefile.in config.status
|
||||||
./config.status
|
./config.status
|
||||||
@@ -282,7 +281,7 @@ src/Makefile: src/Makefile.in config.status
|
|||||||
./config.status
|
./config.status
|
||||||
config.status: configure
|
config.status: configure
|
||||||
./config.status --recheck
|
./config.status --recheck
|
||||||
configure: configure.in
|
configure: configure.ac
|
||||||
autoconf
|
autoconf
|
||||||
|
|
||||||
maintainer-clean::
|
maintainer-clean::
|
||||||
@@ -317,7 +316,7 @@ TAGS: $(TAGFILES)
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Distributions
|
# Distributions
|
||||||
|
|
||||||
DISTCONFIG = src/config.h.in
|
DISTCONFIG = src/config_build.h.in
|
||||||
|
|
||||||
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
|
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
|
||||||
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
|
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ This is the Verilator Package.
|
|||||||
1.1 Copyright
|
1.1 Copyright
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This package is Copyright 2003-2006 by Wilson Snyder
|
This package is Copyright 2003-2007 by Wilson Snyder
|
||||||
<[email protected]>.
|
<[email protected]>.
|
||||||
|
|
||||||
You may distribute under the terms of either the GNU General Public
|
You may distribute under the terms of either the GNU General Public
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// $Id$
|
// $Id$
|
||||||
// DESCRIPTION: Verilator: List of To Do issues.
|
// DESCRIPTION: Verilator: List of To Do issues.
|
||||||
//
|
//
|
||||||
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
@@ -47,6 +47,10 @@ Testing:
|
|||||||
Better graph viewer with search and zoom
|
Better graph viewer with search and zoom
|
||||||
Port and test against opencores.org code
|
Port and test against opencores.org code
|
||||||
|
|
||||||
|
Usability:
|
||||||
|
Better reporting of unopt problems, including what lines of code
|
||||||
|
Report more errors (all of them?) before exiting [Eugene Weber]
|
||||||
|
|
||||||
Performance:
|
Performance:
|
||||||
Constant propagation
|
Constant propagation
|
||||||
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
|
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
|
||||||
@@ -97,6 +101,7 @@ Performance:
|
|||||||
Track recirculation and convert into clock-enables
|
Track recirculation and convert into clock-enables
|
||||||
Clock enables should become new clocking domains for speed
|
Clock enables should become new clocking domains for speed
|
||||||
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
|
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
|
||||||
|
Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
|
||||||
|
|
||||||
//**********************************************************************
|
//**********************************************************************
|
||||||
//* Detailed notes on 'todo' features
|
//* Detailed notes on 'todo' features
|
||||||
|
|||||||
+485
-156
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
|||||||
# $Id$
|
# $Id$
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 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
|
||||||
# General Public License or the Perl Artistic License.
|
# General Public License or the Perl Artistic License.
|
||||||
#
|
#
|
||||||
@@ -104,16 +104,16 @@ if ($Opt_Sp) {
|
|||||||
}
|
}
|
||||||
if ($Opt_Sp eq 'sp' || $Opt_Trace) {
|
if ($Opt_Sp eq 'sp' || $Opt_Trace) {
|
||||||
if (!defined $ENV{SYSTEMPERL}) {
|
if (!defined $ENV{SYSTEMPERL}) {
|
||||||
my $try = "$ENV{W}/hw/utils/perltools/SystemC/src";
|
my $try = "$ENV{W}/hw/utils/perltools/SystemC";
|
||||||
$ENV{SYSTEMPERL} = $try if -d $try;
|
$ENV{SYSTEMPERL} = $try if -d $try;
|
||||||
}
|
}
|
||||||
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
|
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
|
||||||
|
(-d "$ENV{SYSTEMPERL}/src") or die "%Error: verilator: \$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determine runtime flags
|
# Determine runtime flags
|
||||||
my $vcmd =(($opt_gdb?"$opt_gdb ":"")
|
my $vcmd =(($opt_gdb?"$opt_gdb ":"")
|
||||||
.verilator_bin()
|
.verilator_bin()
|
||||||
." --bin ".verilator_bin() # So we get binary name into .d file
|
|
||||||
." ".join(' ',@Opt_Verilator_Sw)
|
." ".join(' ',@Opt_Verilator_Sw)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ sub run {
|
|||||||
warn "%Error: export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
|
warn "%Error: export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
|
||||||
warn "%Error: $command\n";
|
warn "%Error: $command\n";
|
||||||
}
|
}
|
||||||
die "%Error: Command Failed $command, $status, stopped";
|
die "%Error: Command Failed $command\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,6 +234,13 @@ linking with make rules you write yourself.
|
|||||||
Enable all assertions, includes enabling the --psl flag. (If psl is not
|
Enable all assertions, includes enabling the --psl flag. (If psl is not
|
||||||
desired, but other assertions are, use --assert --nopsl.)
|
desired, but other assertions are, use --assert --nopsl.)
|
||||||
|
|
||||||
|
=item --bin I<filename>
|
||||||
|
|
||||||
|
Rarely needed. Override the default filename for Verilator itself. When a
|
||||||
|
dependency (.d) file is created, this filename will become a source
|
||||||
|
dependency, such that a change in this binary will have make rebuild the
|
||||||
|
output files.
|
||||||
|
|
||||||
=item --cc
|
=item --cc
|
||||||
|
|
||||||
Specifies C++ without SystemC output mode; see also --sc and --sp.
|
Specifies C++ without SystemC output mode; see also --sc and --sp.
|
||||||
@@ -247,10 +254,10 @@ Enables all forms of coverage, alias for --coverage-line, --coverage-user
|
|||||||
Specifies basic block line coverage analysis code should be inserted.
|
Specifies basic block line coverage analysis code should be inserted.
|
||||||
|
|
||||||
Coverage analysis adds statements at each code flow change point, which are
|
Coverage analysis adds statements at each code flow change point, which are
|
||||||
the branches of IF and CASE statements, a superset of normal Verilog Line
|
the branches of IF and CASE statements, a super-set of normal Verilog Line
|
||||||
Coverage. At each such branch a C++ macro is called, which SystemPerl uses
|
Coverage. At each such branch a unique counter is incremented. At the end
|
||||||
to increment an array. At the end of a test, logs/coverage.pl is written
|
of a test, the counters along with the filename and line number
|
||||||
with the data from the array.
|
corresponding to each counter are written into logs/coverage.pl.
|
||||||
|
|
||||||
After running multiple tests, the vcoverage utility (from the SystemPerl
|
After running multiple tests, the vcoverage utility (from the SystemPerl
|
||||||
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
|
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
|
||||||
@@ -261,6 +268,10 @@ them, as it is assumed $stop branches contain an error check that should
|
|||||||
not occur. A /*verilator coverage_block_off*/ comment will perform a
|
not occur. A /*verilator coverage_block_off*/ comment will perform a
|
||||||
similar function on any code in that block or below.
|
similar function on any code in that block or below.
|
||||||
|
|
||||||
|
Note Verilator may over-count combinatorial (non-clocked) blocks when those
|
||||||
|
blocks receive signals which have had the UNOPTFLAT warning disabled; for
|
||||||
|
most accurate results do not disable this warning when using coverage.
|
||||||
|
|
||||||
For an example, after running 'make test' in the Verilator distribution,
|
For an example, after running 'make test' in the Verilator distribution,
|
||||||
see the test_sp/logs/coverage_source directory. Grep for lines starting
|
see the test_sp/logs/coverage_source directory. Grep for lines starting
|
||||||
with '%' to see what lines Verilator believes need more coverage.
|
with '%' to see what lines Verilator believes need more coverage.
|
||||||
@@ -279,8 +290,13 @@ the comment "DefaultClock":
|
|||||||
|
|
||||||
=item --debug
|
=item --debug
|
||||||
|
|
||||||
Select the debug built image of Verilator (if available), and enable
|
Select the debug built image of Verilator (if available), and enable more
|
||||||
debugging messages and intermediate form dump files.
|
internal assertions, debugging messages, and intermediate form dump files.
|
||||||
|
|
||||||
|
=item --debug-check
|
||||||
|
|
||||||
|
Rarely needed. Enable internal debugging assertion checks, without
|
||||||
|
changing debug verbosity. Enabled automatically when --debug specified.
|
||||||
|
|
||||||
=item -E
|
=item -E
|
||||||
|
|
||||||
@@ -299,10 +315,10 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=item --inhibit-sim
|
=item --inhibit-sim
|
||||||
|
|
||||||
Create a "inhibitSim(bool)" function to enable and disable evaluation.
|
Rarely needed. Create a "inhibitSim(bool)" function to enable and disable
|
||||||
This allows a upper level testbench to disable modules that are not
|
evaluation. This allows a upper level testbench to disable modules that
|
||||||
important in a given simulation, without needing to recompile or change the
|
are not important in a given simulation, without needing to recompile or
|
||||||
SystemC modules instantiated.
|
change the SystemC modules instantiated.
|
||||||
|
|
||||||
=item --inline-mult I<value>
|
=item --inline-mult I<value>
|
||||||
|
|
||||||
@@ -335,8 +351,8 @@ the same as --prefix.
|
|||||||
|
|
||||||
=item --no-skip-identical
|
=item --no-skip-identical
|
||||||
|
|
||||||
Disables skipping execution of Verilator if all source files are identical,
|
Rarely needed. Disables skipping execution of Verilator if all source
|
||||||
and all output files exist with newer dates.
|
files are identical, and all output files exist with newer dates.
|
||||||
|
|
||||||
=item -O0
|
=item -O0
|
||||||
|
|
||||||
@@ -349,11 +365,11 @@ cost of compile time. This currently sets --inline-mult -1.
|
|||||||
|
|
||||||
=item -OI<optimization-letter>
|
=item -OI<optimization-letter>
|
||||||
|
|
||||||
Enables or disables a specific optimizations, with the optimization
|
Rarely needed. Enables or disables a specific optimizations, with the
|
||||||
selected based on the letter passed. A lowercase letter disables an
|
optimization selected based on the letter passed. A lowercase letter
|
||||||
optimization, an upper case letter enables it. This is intended for
|
disables an optimization, an upper case letter enables it. This is
|
||||||
debugging use only; see the source code for version-dependent mappings of
|
intended for debugging use only; see the source code for version-dependent
|
||||||
optimizations to -O letters.
|
mappings of optimizations to -O letters.
|
||||||
|
|
||||||
=item --output-split I<bytes>
|
=item --output-split I<bytes>
|
||||||
|
|
||||||
@@ -362,9 +378,18 @@ C++ file exceeds the specified number of operations, a new file will be
|
|||||||
created. In addition, any slow routines will be placed into __Slow files.
|
created. In addition, any slow routines will be placed into __Slow files.
|
||||||
This accelerates compilation by as optimization can be disabled on the slow
|
This accelerates compilation by as optimization can be disabled on the slow
|
||||||
routines, and the remaining files can be compiled on parallel machines.
|
routines, and the remaining files can be compiled on parallel machines.
|
||||||
|
Using --output-split should have only a trivial impact on performance.
|
||||||
With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in
|
With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in
|
||||||
splitting into approximately one-minute-compile chunks.
|
splitting into approximately one-minute-compile chunks.
|
||||||
|
|
||||||
|
=item --output-split-cfuncs I<statements>
|
||||||
|
|
||||||
|
Enables splitting functions in the output .cpp/.sp files into multiple
|
||||||
|
functions. When a generated function exceeds the specified number of
|
||||||
|
operations, a new function will be created. With --output-split, this will
|
||||||
|
enable GCC to compile faster, at a small loss in performance that increases
|
||||||
|
with smaller statement values.
|
||||||
|
|
||||||
=item --pins64
|
=item --pins64
|
||||||
|
|
||||||
Specifies SystemC outputs of 33-64 bits wide should use uint64_t instead of
|
Specifies SystemC outputs of 33-64 bits wide should use uint64_t instead of
|
||||||
@@ -392,17 +417,20 @@ compatibility.
|
|||||||
|
|
||||||
=item --psl
|
=item --psl
|
||||||
|
|
||||||
Enable PSL parsing. Without this switch, psl meta-comments are ignored.
|
Enable PSL parsing. Without this switch, PSL meta-comments are ignored.
|
||||||
See the --assert flag to enable all assertions, and --coverage-user to
|
See the --assert flag to enable all assertions, and --coverage-user to
|
||||||
enable functional coverage.
|
enable functional coverage.
|
||||||
|
|
||||||
=item --public
|
=item --public
|
||||||
|
|
||||||
|
This is only for historical debug use. Using it may result in
|
||||||
|
mis-simulation of generated clocks.
|
||||||
|
|
||||||
Declares all signals and modules public. This will turn off signal
|
Declares all signals and modules public. This will turn off signal
|
||||||
optimizations as if all signals had a /*verilator public*/ comments. This
|
optimizations as if all signals had a /*verilator public*/ comments and
|
||||||
will also turn off inlining as if all modules had a /*verilator
|
inlining. This will also turn off inlining as if all modules had a
|
||||||
public_module*/, unless the module specifically enabled it with /*verilator
|
/*verilator public_module*/, unless the module specifically enabled it with
|
||||||
inline_module*/.
|
/*verilator inline_module*/.
|
||||||
|
|
||||||
=item --sc
|
=item --sc
|
||||||
|
|
||||||
@@ -422,12 +450,19 @@ Adds waveform tracing code to the model. Having tracing compiled in may
|
|||||||
result in some small performance losses, even when waveforms are not turned
|
result in some small performance losses, even when waveforms are not turned
|
||||||
on during model execution.
|
on during model execution.
|
||||||
|
|
||||||
|
=item --trace-depth I<levels>
|
||||||
|
|
||||||
|
Specify the number of levels deep to enable tracing, for example
|
||||||
|
--trace-level 1 to only see the top level's signals. Defaults to the
|
||||||
|
entire model. Using a small number will decrease visibility, but greatly
|
||||||
|
improve runtime and trace file size.
|
||||||
|
|
||||||
=item --underline-zero
|
=item --underline-zero
|
||||||
|
|
||||||
Signals starting with a underline should be initialized to zero, as was
|
Rarely needed. Signals starting with a underline should be initialized to
|
||||||
done in Verilator 2. Default is for all signals including those with
|
zero, as was done in Verilator 2. Default is for all signals including
|
||||||
underlines being randomized. This option may be depreciated in future
|
those with underlines being randomized. This option may be depreciated in
|
||||||
versions.
|
future versions.
|
||||||
|
|
||||||
=item -Werror-I<message>
|
=item -Werror-I<message>
|
||||||
|
|
||||||
@@ -548,7 +583,7 @@ And we get as output
|
|||||||
Hello World
|
Hello World
|
||||||
- our.v:2: Verilog $finish
|
- our.v:2: Verilog $finish
|
||||||
|
|
||||||
Really, you're better off using a Makefile to do all this for you. Then,
|
Really, you're better off writing a Makefile to do all this for you. Then,
|
||||||
when your source changes it will automatically run all of these steps. See
|
when your source changes it will automatically run all of these steps. See
|
||||||
the test_c directory in the distribution for an example.
|
the test_c directory in the distribution for an example.
|
||||||
|
|
||||||
@@ -591,7 +626,7 @@ Then we convert the SystemPerl output to SystemC.
|
|||||||
$SYSTEMPERL/sp_preproc --preproc *.sp
|
$SYSTEMPERL/sp_preproc --preproc *.sp
|
||||||
|
|
||||||
(You can also skip the above sp_preproc by getting pure SystemC from
|
(You can also skip the above sp_preproc by getting pure SystemC from
|
||||||
verilator by replacing the verilator --sp flag in the previous step with
|
Verilator by replacing the verilator --sp flag in the previous step with
|
||||||
-sc.)
|
-sc.)
|
||||||
|
|
||||||
We then can compile it
|
We then can compile it
|
||||||
@@ -702,7 +737,7 @@ In certain optimization modes, it also creates:
|
|||||||
|
|
||||||
It also creates internal files that can be mostly ignored:
|
It also creates internal files that can be mostly ignored:
|
||||||
|
|
||||||
{each_verilog_module}.vpp // Post-processed verilog source code
|
{each_verilog_module}.vpp // Post-processed verilog (--debug)
|
||||||
{prefix}.flags_vbin // Verilator dependencies
|
{prefix}.flags_vbin // Verilator dependencies
|
||||||
{prefix}.flags_vpp // Pre-processor dependencies
|
{prefix}.flags_vpp // Pre-processor dependencies
|
||||||
{prefix}{misc}.d // Make dependencies (-MMD)
|
{prefix}{misc}.d // Make dependencies (-MMD)
|
||||||
@@ -828,30 +863,73 @@ Lower modules are not pure SystemC code. This is a feature, as using the
|
|||||||
SystemC pin interconnect scheme everywhere would reduce performance by an
|
SystemC pin interconnect scheme everywhere would reduce performance by an
|
||||||
order of magnitude.
|
order of magnitude.
|
||||||
|
|
||||||
=head1 VERILOG 2001 SUPPORT
|
=head1 CROSS COMPILATION
|
||||||
|
|
||||||
|
Verilator supports cross-compiling Verilated code. This is generally used
|
||||||
|
to run Verilator on a Linux system and produce C++ code that is then compiled
|
||||||
|
on Windows.
|
||||||
|
|
||||||
|
Cross compilation involves up to three different OSes. The build system is
|
||||||
|
where you configured and compiled Verilator, the host system where you run
|
||||||
|
Verilator, and the target system where you compile the Verilated code and
|
||||||
|
run the simulation.
|
||||||
|
|
||||||
|
Currently, Verilator requires the build and host system type to be the
|
||||||
|
same, though the target system type may be different. To support this,
|
||||||
|
./configure and make Verilator on the build system. Then, run Verilator on
|
||||||
|
the host system. Finally, the output of Verilator may be compiled on the
|
||||||
|
different target system.
|
||||||
|
|
||||||
|
To support this, none of the files that Verilator produces will reference
|
||||||
|
any configure generated build-system specific files, such as config.h
|
||||||
|
(which is renamed in Verilator to config_build.h to reduce confusion.) The
|
||||||
|
disadvantage of this approach is that include/verilatedos.h must
|
||||||
|
self-detect the requirements of the target system, rather then using
|
||||||
|
configure.
|
||||||
|
|
||||||
|
The target system may also require edits to the Makefiles, the simple
|
||||||
|
Makefiles produced by Verilator presume the target system is the same type
|
||||||
|
as the build system.
|
||||||
|
|
||||||
|
=head1 VERILOG 2001 (IEEE 1364-2001) SUPPORT
|
||||||
|
|
||||||
Verilator supports the more common Verilog 2001 language features. This
|
Verilator supports the more common Verilog 2001 language features. This
|
||||||
includes signed numbers, "always @*", comma separated sensitivity lists,
|
includes signed numbers, "always @*", comma separated sensitivity lists,
|
||||||
generate statements, multidimensional arrays, localparam, and C-style
|
generate statements, multidimensional arrays, localparam, and C-style
|
||||||
declarations inside port lists.
|
declarations inside port lists.
|
||||||
|
|
||||||
=head1 SYSTEMVERILOG 3.1 SUPPORT
|
=head1 VERILOG 2005 (IEEE 1364-2005) SUPPORT
|
||||||
|
|
||||||
Verilator currently has very minimal support for SystemVerilog.
|
Verilator supports the `begin_keywords and `end_keywords compiler
|
||||||
|
directives.
|
||||||
|
|
||||||
Verilator implement the full SystemVerilog 3.1 preprocessor subset,
|
Verilator partially supports the uwire keyword.
|
||||||
including function call-like preprocessor defines. Verilator also
|
|
||||||
implements $bits, $countones, $isunknown, $onehot, and $onehot0,
|
=head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT
|
||||||
always_comb, always_ff, always_latch, and final.
|
|
||||||
|
Verilator currently has very minimal support for SystemVerilog as they
|
||||||
|
become more common, contact the author if a feature you need is missing.
|
||||||
|
|
||||||
|
Verilator implements the full SystemVerilog 1800-2005 preprocessor subset,
|
||||||
|
including function call-like preprocessor defines.
|
||||||
|
|
||||||
|
Verilator supports $bits, $countones, $error, $fatal, $info, $isunknown,
|
||||||
|
$onehot, $onehot0, $warning, always_comb, always_ff, always_latch, and
|
||||||
|
final.
|
||||||
|
|
||||||
|
Verilator partially supports assert.
|
||||||
|
|
||||||
=head1 SUGAR/PSL SUPPORT
|
=head1 SUGAR/PSL SUPPORT
|
||||||
|
|
||||||
With the --assert switch, Verilator is just beginning to support the
|
Most future work is being directed towards improving SystemVerilog
|
||||||
Property Specification Language (PSL), specifically the simple subset
|
assertions instead of PSL. If you are using these PSL features, please
|
||||||
without time-branching primitives. Verilator currently only converts PSL
|
contact the author as they may be depreciated in future versions.
|
||||||
|
|
||||||
|
With the --assert switch, Verilator enables support of the Property
|
||||||
|
Specification Language (PSL), specifically the simple PSL subset without
|
||||||
|
time-branching primitives. Verilator currently only converts PSL
|
||||||
assertions to simple "if (...) error" statements, and coverage statements
|
assertions to simple "if (...) error" statements, and coverage statements
|
||||||
to increment the line counters described in the coverage section. If you
|
to increment the line counters described in the coverage section.
|
||||||
need additional features please contact the author.
|
|
||||||
|
|
||||||
Verilator implements these keywords: assert, assume (same as assert),
|
Verilator implements these keywords: assert, assume (same as assert),
|
||||||
default (for clocking), countones, cover, isunknown, onehot, onehot0,
|
default (for clocking), countones, cover, isunknown, onehot, onehot0,
|
||||||
@@ -860,18 +938,16 @@ report, true.
|
|||||||
Verilator implements these operators: -> (logical if).
|
Verilator implements these operators: -> (logical if).
|
||||||
|
|
||||||
Verilator does not support SEREs yet. All assertion and coverage
|
Verilator does not support SEREs yet. All assertion and coverage
|
||||||
statements must be simple expressions that complete in one cycle.
|
statements must be simple expressions that complete in one cycle. PSL
|
||||||
(Arguably SEREs are the whole point of PSL, but one must start somewhere.)
|
vmode/vprop/vunits are not supported. PSL statements must be in the module
|
||||||
|
they reference, at the module level where you would put an
|
||||||
PSL vmode/vprop/vunits are not supported. PSL statements must be in the
|
|
||||||
module they reference, at the module level where you would put an
|
|
||||||
initial... statement.
|
initial... statement.
|
||||||
|
|
||||||
Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the
|
Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the
|
||||||
name of a one bit signal. You may not use arbitrary expressions as
|
name of a one bit signal. You may not use arbitrary expressions as
|
||||||
assertion clocks.
|
assertion clocks.
|
||||||
|
|
||||||
=head1 SYNTHESIS DIRECTIVE ASSERTIONS
|
=head1 SYNTHESIS DIRECTIVE ASSERTION SUPPORT
|
||||||
|
|
||||||
With the --assert switch, Verilator reads any "//synopsys full_case" or "//
|
With the --assert switch, Verilator reads any "//synopsys full_case" or "//
|
||||||
synopsys parallel_case" directives. The same applies to any "//cadence" or
|
synopsys parallel_case" directives. The same applies to any "//cadence" or
|
||||||
@@ -920,7 +996,7 @@ call C++ functions from your Verilog code.
|
|||||||
String arguments will be put directly into the output C++ code. Expression
|
String arguments will be put directly into the output C++ code. Expression
|
||||||
arguments will have the code to evaluate the expression inserted. Thus to
|
arguments will have the code to evaluate the expression inserted. Thus to
|
||||||
call a C++ function, $c("func(",a,")") will result in 'func(a)' in the
|
call a C++ function, $c("func(",a,")") will result in 'func(a)' in the
|
||||||
output C++ code. For input arguments, rather then hardcoding variable
|
output C++ code. For input arguments, rather then hard-coding variable
|
||||||
names in the string $c("func(a)"), instead pass the variable as an
|
names in the string $c("func(a)"), instead pass the variable as an
|
||||||
expression $c("func(",a,")"). This will allow the call to work inside
|
expression $c("func(",a,")"). This will allow the call to work inside
|
||||||
Verilog functions where the variable is flattened out, and also enable
|
Verilog functions where the variable is flattened out, and also enable
|
||||||
@@ -936,21 +1012,11 @@ each different output width.
|
|||||||
|
|
||||||
=item $display, $write, $fdisplay, $fwrite
|
=item $display, $write, $fdisplay, $fwrite
|
||||||
|
|
||||||
$display format arguments may use C fprintf sizes after the % escape. Per
|
Format arguments may use C fprintf sizes after the % escape. Per the
|
||||||
the Verilog standard, %x prints a number with the natural width, %0x prints
|
Verilog standard, %x prints a number with the natural width, %0x prints a
|
||||||
a number with minimum width, however %5x prints 5 digits per the C standard
|
number with minimum width, however %5x prints 5 digits per the C standard
|
||||||
(it's unspecified in Verilog).
|
(it's unspecified in Verilog).
|
||||||
|
|
||||||
=item $fopen, $fclose, $fdisplay, $fwrite
|
|
||||||
|
|
||||||
File descriptors passed to the file PLI calls must be file descriptors, not
|
|
||||||
MCDs, which includes the mode parameter to $fopen being mandatory.
|
|
||||||
Verilator will convert the integer used to hold the file descriptor into a
|
|
||||||
internal FILE*. To prevent core dumps due to mis-use, and because integers
|
|
||||||
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
|
|
||||||
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
|
|
||||||
verilated.v can be used to hide this difference.
|
|
||||||
|
|
||||||
=item `coverage_block_off
|
=item `coverage_block_off
|
||||||
|
|
||||||
Specifies the entire begin/end block should be ignored for coverage analysis.
|
Specifies the entire begin/end block should be ignored for coverage analysis.
|
||||||
@@ -1030,6 +1096,41 @@ submodules will be named I<submodule>__DOT__I<subsignal> as C++ does not
|
|||||||
allow "." in signal names. SystemPerl when tracing such signals will
|
allow "." in signal names. SystemPerl when tracing such signals will
|
||||||
replace the __DOT__ with the period.
|
replace the __DOT__ with the period.
|
||||||
|
|
||||||
|
=item /*verilator isolate_assignments*/
|
||||||
|
|
||||||
|
Used after a signal declaration to indicate the assignments to this signal
|
||||||
|
in any blocks should be isolated into new blocks. When there is a large
|
||||||
|
combinatorial block that is resulting in a UNOPTFLAT warning, attaching
|
||||||
|
this to the signal causing a false loop may clear up the problem.
|
||||||
|
|
||||||
|
IE, with the following
|
||||||
|
|
||||||
|
reg splitme /* verilator isolate_assignments*/;
|
||||||
|
always @* begin
|
||||||
|
if (....) begin
|
||||||
|
splitme = ....;
|
||||||
|
other assignments
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Verilator will internally split the block that assigns to "splitme" into
|
||||||
|
two blocks:
|
||||||
|
|
||||||
|
It would then internally break it into (sort of):
|
||||||
|
|
||||||
|
// All assignments excluding those to splitme
|
||||||
|
always @* begin
|
||||||
|
if (....) begin
|
||||||
|
other assignments
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// All assignments to splitme
|
||||||
|
always @* begin
|
||||||
|
if (....) begin
|
||||||
|
splitme = ....;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
=item /*verilator lint_off I<msg>*/
|
=item /*verilator lint_off I<msg>*/
|
||||||
|
|
||||||
Disable the specified warning message for any warnings following the comment.
|
Disable the specified warning message for any warnings following the comment.
|
||||||
@@ -1038,6 +1139,57 @@ Disable the specified warning message for any warnings following the comment.
|
|||||||
|
|
||||||
Re-enable the specified warning message for any warnings following the comment.
|
Re-enable the specified warning message for any warnings following the comment.
|
||||||
|
|
||||||
|
=item /*verilator no_inline_task*/
|
||||||
|
|
||||||
|
Used in a function or task variable definition section to specify the
|
||||||
|
function or task should not be inlined into where it is used. This may
|
||||||
|
reduce the size of the final executable when a task is used a very large
|
||||||
|
number of times. For this flag to work, the task and tasks below it must
|
||||||
|
be pure; they cannot reference any variables outside the task itself.
|
||||||
|
|
||||||
|
=item /*verilator public*/ (variable)
|
||||||
|
|
||||||
|
Used after a input, output, register, or wire declaration to indicate the
|
||||||
|
signal should be declared so that C code may read or write the value
|
||||||
|
of the signal. This will also declare this module public, otherwise use
|
||||||
|
/*verilator public_flat*/.
|
||||||
|
|
||||||
|
=item /*verilator public*/ (task/function)
|
||||||
|
|
||||||
|
Used inside the declaration section of a function or task declaration to
|
||||||
|
indicate the function or task should be made into a C++ function, public to
|
||||||
|
outside callers. Public tasks will be declared as a void C++ function,
|
||||||
|
public functions will get the appropriate non-void (bool, uint32_t, etc)
|
||||||
|
return type. Any input arguments will become C++ arguments to the
|
||||||
|
function. Any output arguments will become C++ reference arguments. Any
|
||||||
|
local registers/integers will become function automatic variables on the
|
||||||
|
stack.
|
||||||
|
|
||||||
|
Wide variables over 64 bits cannot be function returns, to avoid exposing
|
||||||
|
complexities. However, wide variables can be input/outputs; they will be
|
||||||
|
passed as references to an array of 32 bit numbers.
|
||||||
|
|
||||||
|
This feature is still somewhat experimental. Generally, only the values of
|
||||||
|
stored state (flops) should be written, as the model will NOT notice
|
||||||
|
changes made to variables in these functions. (Same as when a signal is
|
||||||
|
declared public.)
|
||||||
|
|
||||||
|
=item /*verilator public_flat*/ (variable)
|
||||||
|
|
||||||
|
Used after a input, output, register, or wire declaration to indicate the
|
||||||
|
signal should be declared so that C code may read or write the value of the
|
||||||
|
signal. This will not declare this module public, which means the name of
|
||||||
|
the signal or path to it may change based upon the module inlining which
|
||||||
|
takes place.
|
||||||
|
|
||||||
|
=item /*verilator public_module*/
|
||||||
|
|
||||||
|
Used after a module statement to indicate the module should not be inlined
|
||||||
|
(unless specifically requested) so that C code may access the module.
|
||||||
|
Verilator automatically sets this attribute when the module contains any
|
||||||
|
public signals or `systemc_ directives. Also set for all modules when
|
||||||
|
using the --public switch.
|
||||||
|
|
||||||
=item /*verilator sc_clock*/
|
=item /*verilator sc_clock*/
|
||||||
|
|
||||||
Used after a input declaration to indicate the signal should be declared in
|
Used after a input declaration to indicate the signal should be declared in
|
||||||
@@ -1053,40 +1205,6 @@ that the entire module is not traced.
|
|||||||
|
|
||||||
Re-enable waveform tracing for all future signals that are declared.
|
Re-enable waveform tracing for all future signals that are declared.
|
||||||
|
|
||||||
=item /*verilator public*/ (variable)
|
|
||||||
|
|
||||||
Used after a input, output, register, or wire declaration to indicate the
|
|
||||||
signal should be declared so that C code may read or write the value
|
|
||||||
of the signal. Set for all signals when using the --public switch.
|
|
||||||
|
|
||||||
=item /*verilator public*/ (task/function)
|
|
||||||
|
|
||||||
Used inside the declaration section of a function or task declaration to
|
|
||||||
indicate the function or task should be made into a C++ function, public to
|
|
||||||
outside callers. Public tasks will be declared as a void C++ function,
|
|
||||||
public functions will get the appropriate non-void (bool, uint32_t, etc)
|
|
||||||
return type. Any input arguments will become C++ arguments to the
|
|
||||||
function. Any output arguments will become C++ reference arguments. Any
|
|
||||||
local registers/integers will become function automatic variables on the
|
|
||||||
stack.
|
|
||||||
|
|
||||||
Wide variables over 64 bits cannot be I/O to the module, to avoid exposing
|
|
||||||
complexities; generally the cleanest technique is to pass a word number to
|
|
||||||
the function, and do appropriate bit selection.
|
|
||||||
|
|
||||||
This feature is still somewhat experimental. Generally, only the values of
|
|
||||||
stored state (flops) should be written, as the model will NOT notice
|
|
||||||
changes made to variables in these functions. (Same as when a signal is
|
|
||||||
declared public.)
|
|
||||||
|
|
||||||
=item /*verilator public_module*/
|
|
||||||
|
|
||||||
Used after a module statement to indicate the module should not be inlined
|
|
||||||
(unless specifically requested) so that C code may access the module.
|
|
||||||
Verilator automatically sets this attribute when the module contains any
|
|
||||||
public signals or `systemc_ directives. Also set for all modules when
|
|
||||||
using the --public switch.
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 LANGUAGE LIMITATIONS
|
=head1 LANGUAGE LIMITATIONS
|
||||||
@@ -1116,25 +1234,21 @@ always @* to prevent these issues.)
|
|||||||
|
|
||||||
Verilator supports dotted references to variables, functions and tasks in
|
Verilator supports dotted references to variables, functions and tasks in
|
||||||
different modules. However, references into named blocks and function-local
|
different modules. However, references into named blocks and function-local
|
||||||
variables are not supported. References into arrayed and generated
|
variables are not supported. The portion before the dot must have a
|
||||||
instances work, but still require some work-arounds in the Verilog code:
|
constant value; for example a[2].b is acceptable, while a[x].b is not.
|
||||||
|
|
||||||
References into arrayed instances use different names from the Verilog
|
References into generated and arrayed instances use the instance names
|
||||||
standard; arrayed instances are named {cellName}__{instanceNumber}. For
|
specified in the Verilog standard; arrayed instances are named
|
||||||
example a[2] is instead a__2. Thus you cannot use a parameter or variable
|
{cellName}[{instanceNumber}] in Verilog, which becomes
|
||||||
to select the index number; expand it into a case statement manually.
|
{cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code.
|
||||||
|
|
||||||
References into generate statements also use different names from the
|
Verilator creates numbered "genblk" when a begin: name is not specified
|
||||||
Verilog standard; the top level generate, any begin statement, and any
|
around a block inside a generate statement. These numbers may differ
|
||||||
place where there is a implied begin statement (under each generate-if or
|
between other simulators, but the Verilog specification does not allow
|
||||||
generate-case) adds a hierarchy level named genblkI<instanceNumber>. And
|
users to use these names, so it should not matter.
|
||||||
each generate-for adds genforI<loopCount>. The best bet is to comment out
|
|
||||||
the references and run with --debug and look in the at the _begin.tree
|
If you are having trouble determining where a dotted path goes wrong, note
|
||||||
file, and see the hierarchy by looking at the names of all of the CELLs in
|
that Verilator will print a list of known scopes to help your debugging.
|
||||||
question. Replace __DOT__ with . in your program. For example most cells
|
|
||||||
under a for loop would be something like
|
|
||||||
"genblk__DOT__genfor0__DOT__I<cellname>"; so use genblk.genfor0.I<cellname> to
|
|
||||||
see inside that cell.
|
|
||||||
|
|
||||||
=head2 Latches
|
=head2 Latches
|
||||||
|
|
||||||
@@ -1188,12 +1302,6 @@ prepended. (If you don't know what this means, Verilator will do what you
|
|||||||
probably expect -- what C does. The default behavior of Verilog is
|
probably expect -- what C does. The default behavior of Verilog is
|
||||||
different.)
|
different.)
|
||||||
|
|
||||||
=head2 Generate Statements
|
|
||||||
|
|
||||||
All instantiations and variables in generate blocks will be placed under
|
|
||||||
hierarchy that has a name different from that required in the language
|
|
||||||
specification.
|
|
||||||
|
|
||||||
=head2 Generated Clocks
|
=head2 Generated Clocks
|
||||||
|
|
||||||
Verilator attempts to deal with generated clocks correctly, however new
|
Verilator attempts to deal with generated clocks correctly, however new
|
||||||
@@ -1248,7 +1356,84 @@ will give a width warning and wrap around the power-of-2 size. For
|
|||||||
non-power-of-2 sizes, it will return a unspecified constant of the
|
non-power-of-2 sizes, it will return a unspecified constant of the
|
||||||
appropriate width.
|
appropriate width.
|
||||||
|
|
||||||
=head1 ERRORS
|
=head2 Assertions
|
||||||
|
|
||||||
|
Verilator is beginning to add support for assertions. Verilator currently
|
||||||
|
only converts assertions to simple "if (...) error" statements, and
|
||||||
|
coverage statements to increment the line counters described in the
|
||||||
|
coverage section.
|
||||||
|
|
||||||
|
Verilator does not support SEREs yet. All assertion and coverage
|
||||||
|
statements must be simple expressions that complete in one cycle.
|
||||||
|
(Arguably SEREs are much of the point, but one must start somewhere.)
|
||||||
|
|
||||||
|
=head1 LANGUAGE KEYWORD LIMITATIONS
|
||||||
|
|
||||||
|
This section describes specific limitations for each language keyword.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item always always_comb always_ff always_latch and assign begin buf case
|
||||||
|
casex casez default defparam else end endcase endfunction endgenerate
|
||||||
|
endmodule endspecify endtask final for function generate genvar if initial
|
||||||
|
inout input integer localparam macromodule module nand negedge nor not or
|
||||||
|
output parameter posedge reg scalared signed supply0 supply1 task tri
|
||||||
|
vectored wire xnor xor
|
||||||
|
|
||||||
|
Generally supported.
|
||||||
|
|
||||||
|
=item specify specparam
|
||||||
|
|
||||||
|
All specify blocks and timing checks are ignored.
|
||||||
|
|
||||||
|
=item uwire
|
||||||
|
|
||||||
|
Verilator does not perform warning checking on uwires, it treats the uwire
|
||||||
|
keyword as if it were the normal wire keyword.
|
||||||
|
|
||||||
|
=item $bits, $countones, $finish, $isunknown, $onehot, $onehot0, $readmemb,
|
||||||
|
$readmemh, $signed, $stop, $time, $unsigned
|
||||||
|
|
||||||
|
Generally supported.
|
||||||
|
|
||||||
|
=item $display, $write, $fdisplay, $fwrite
|
||||||
|
|
||||||
|
$display and friends must have a constant format string as the first
|
||||||
|
argument (as with C's printf), you cannot simply list variables standalone.
|
||||||
|
|
||||||
|
=item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc
|
||||||
|
|
||||||
|
The sized display functions are rarely used and so not supported. Replace
|
||||||
|
them with a $write with the appropriate format specifier.
|
||||||
|
|
||||||
|
=item $fopen, $fclose, $fdisplay, $fwrite
|
||||||
|
|
||||||
|
File descriptors passed to the file PLI calls must be file descriptors, not
|
||||||
|
MCDs, which includes the mode parameter to $fopen being mandatory.
|
||||||
|
Verilator will convert the integer used to hold the file descriptor into a
|
||||||
|
internal FILE*. To prevent core dumps due to mis-use, and because integers
|
||||||
|
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
|
||||||
|
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
|
||||||
|
verilated.v can be used to hide this difference.
|
||||||
|
|
||||||
|
=item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
|
||||||
|
$setup, $setuphold, $skew, $timeskew, $width
|
||||||
|
|
||||||
|
All specify blocks and timing checks are ignored.
|
||||||
|
|
||||||
|
=item $readmemb, $readmemh
|
||||||
|
|
||||||
|
Read memory commands should work properly. Note Verilator and the Verilog
|
||||||
|
specification does not include support for readmem to multi-dimensional
|
||||||
|
arrays.
|
||||||
|
|
||||||
|
=item $realtime
|
||||||
|
|
||||||
|
Treated as $time.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 ERRORS AND WARNINGS
|
||||||
|
|
||||||
Warnings may be disabled in two ways. First, when the warning is
|
Warnings may be disabled in two ways. First, when the warning is
|
||||||
printed it will include a warning code. Simply surround the offending
|
printed it will include a warning code. Simply surround the offending
|
||||||
@@ -1258,16 +1443,36 @@ line with a warn_off/warn_on pair:
|
|||||||
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
|
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
|
||||||
// verilator lint_on UNSIGNED
|
// verilator lint_on UNSIGNED
|
||||||
|
|
||||||
They may also be globally disabled by invoking Verilator with the
|
Warnings may also be globally disabled by invoking Verilator with the
|
||||||
C<-Wno-I<warning>> switch. This should be avoided, as it removes
|
C<-Wno-I<warning>> switch. This should be avoided, as it removes all
|
||||||
all checking across the designs, and prevents other users from
|
checking across the designs, and prevents other users from compiling your
|
||||||
compiling your code without knowing the magic set of disables needed
|
code without knowing the magic set of disables needed to successfully
|
||||||
to successfully compile your design.
|
compile your design.
|
||||||
|
|
||||||
Warnings:
|
List of all warnings:
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
|
=item BLKANDNBLK
|
||||||
|
|
||||||
|
Error that a variable comes from a mix of blocked and non-blocking
|
||||||
|
assignments. Generally, this is caused by a register driven by both combo
|
||||||
|
logic and a flop:
|
||||||
|
|
||||||
|
always @ (posedge clk) foo[0] <= ...
|
||||||
|
always @* foo[1] = ...
|
||||||
|
|
||||||
|
Simply use a different register for the flop:
|
||||||
|
|
||||||
|
always @ (posedge clk) foo_flopped[0] <= ...
|
||||||
|
always @* foo[0] = foo_flopped[0];
|
||||||
|
always @* foo[1] = ...
|
||||||
|
|
||||||
|
This is good coding practice anyways.
|
||||||
|
|
||||||
|
It is also possible to disable this error when one of the assignments is
|
||||||
|
inside a public task.
|
||||||
|
|
||||||
=item CASEINCOMPLETE
|
=item CASEINCOMPLETE
|
||||||
|
|
||||||
Warns that inside a case statement there is a stimulus pattern for which
|
Warns that inside a case statement there is a stimulus pattern for which
|
||||||
@@ -1321,12 +1526,52 @@ signal before it is implicitly declared by a cell, and can lead to dangling
|
|||||||
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
|
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
|
||||||
Emacs, available from L<http://www.veripool.com/>
|
Emacs, available from L<http://www.veripool.com/>
|
||||||
|
|
||||||
|
=item IMPURE
|
||||||
|
|
||||||
|
Warns that a task or function that has been marked with /*verilator
|
||||||
|
no_inline_task*/ references variables that are not local to the task.
|
||||||
|
Verilator cannot schedule these variables correctly.
|
||||||
|
|
||||||
=item MULTIDRIVEN
|
=item MULTIDRIVEN
|
||||||
|
|
||||||
Warns that the specified signal comes from multiple always blocks. This is
|
Warns that the specified signal comes from multiple always blocks. This is
|
||||||
often unsupported by synthesis tools, and is considered bad style. It will
|
often unsupported by synthesis tools, and is considered bad style. It will
|
||||||
also cause longer runtimes due to reduced optimizations.
|
also cause longer runtimes due to reduced optimizations.
|
||||||
|
|
||||||
|
=item MULTITOP
|
||||||
|
|
||||||
|
Error that there are multiple top level modules, that is modules not
|
||||||
|
instantiated by any other module. Verilator only supports a single top
|
||||||
|
level, if you need more, create a module that wraps all of the top modules.
|
||||||
|
|
||||||
|
Often this error is because some low level cell is being read in, but is
|
||||||
|
not really needed. The best solution is to insure that each module is in a
|
||||||
|
unique file by the same name. Otherwise, make sure all library files are
|
||||||
|
read in as libraries with -v, instead of automatically with -y.
|
||||||
|
|
||||||
|
=item TASKNSVAR
|
||||||
|
|
||||||
|
Error when a call to a task or function has a output from that task tied to
|
||||||
|
a non-simple signal. Instead connect the task output to a temporary signal
|
||||||
|
of the appropriate width, and use that signal to set the appropriate
|
||||||
|
expression as the next statement. For example:
|
||||||
|
|
||||||
|
task foo; output sig; ... endtask
|
||||||
|
always @* begin
|
||||||
|
foo(bus_we_select_from[2]); // Will get TASKNSVAR error
|
||||||
|
end
|
||||||
|
|
||||||
|
Change this to:
|
||||||
|
|
||||||
|
reg foo_temp_out;
|
||||||
|
always @* begin
|
||||||
|
foo(foo_temp_out);
|
||||||
|
bus_we_select_from[2] = foo_temp_out;
|
||||||
|
end
|
||||||
|
|
||||||
|
Verilator doesn't do this conversion for you, as some more complicated
|
||||||
|
cases would result in simulator mismatches.
|
||||||
|
|
||||||
=item UNDRIVEN
|
=item UNDRIVEN
|
||||||
|
|
||||||
Warns that the specified signal is never sourced.
|
Warns that the specified signal is never sourced.
|
||||||
@@ -1352,11 +1597,11 @@ may be only one particular usage of a multiply instantiated block. The
|
|||||||
construct should be cleaned up to improve runtime; two times better
|
construct should be cleaned up to improve runtime; two times better
|
||||||
performance may be possible by fixing these warnings.
|
performance may be possible by fixing these warnings.
|
||||||
|
|
||||||
Unlike UNOPT this occurs after netlist flattening, and indicates a more
|
Unlike the UNOPT warning, this occurs after netlist flattening, and
|
||||||
basic problem, as the less obvious case described under UNOPT does not
|
indicates a more basic problem, as the less obvious case described under
|
||||||
apply.
|
UNOPT does not apply.
|
||||||
|
|
||||||
Often this is caused by logic that isn't truly circular as viewed by
|
Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by
|
||||||
synthesis which analyzes interconnection per-bit, but is circular to
|
synthesis which analyzes interconnection per-bit, but is circular to
|
||||||
simulation which analyzes per-bus:
|
simulation which analyzes per-bus:
|
||||||
|
|
||||||
@@ -1364,14 +1609,37 @@ simulation which analyzes per-bus:
|
|||||||
|
|
||||||
This statement needs to be evaluated multiple times, as a change in
|
This statement needs to be evaluated multiple times, as a change in
|
||||||
"shift_in" requires "x" to be computed 3 times before it becomes stable.
|
"shift_in" requires "x" to be computed 3 times before it becomes stable.
|
||||||
|
This is because a change in "x" requires "x" itself to change value, which
|
||||||
|
causes the warning.
|
||||||
|
|
||||||
For significantly better performance, split this into 2 separate signals:
|
For significantly better performance, split this into 2 separate signals:
|
||||||
|
|
||||||
wire [2:1] x_21 = x[1:0];
|
wire [2:0] xout = {x[1:0],shift_in};
|
||||||
wire [0:0] x_0 = shift_in;
|
|
||||||
|
|
||||||
This warning may also be due to clock enables. To fix these, use the
|
and change all receiving logic to instead receive "xout". Alternatively,
|
||||||
|
change it to
|
||||||
|
|
||||||
|
wire [2:0] x = {xin[1:0],shift_in};
|
||||||
|
|
||||||
|
and change all driving logic to instead drive "xin".
|
||||||
|
|
||||||
|
With this change this assignment needs to be evaluated only once. These
|
||||||
|
sort of changes may also speed up your traditional event driven simulator,
|
||||||
|
as it will result in fewer events per cycle.
|
||||||
|
|
||||||
|
The most complicated UNOPTFLAT path we've seen was due to low bits of a bus
|
||||||
|
being generated from an always statement that consumed high bits of the
|
||||||
|
same bus processed by another series of always blocks. The fix is the
|
||||||
|
same; split it into two separate signals generated from each block.
|
||||||
|
|
||||||
|
The UNOPTFLAT warning may also be due to clock enables, identified from the
|
||||||
|
reported path going through a clock gating cell. To fix these, use the
|
||||||
clock_enable meta comment described above.
|
clock_enable meta comment described above.
|
||||||
|
|
||||||
|
The UNOPTFLAT warning may also occur where outputs from a block of logic
|
||||||
|
are independent, but occur in the same always block. To fix this, use the
|
||||||
|
isolate_assignments meta comment described above.
|
||||||
|
|
||||||
=item UNSIGNED
|
=item UNSIGNED
|
||||||
|
|
||||||
Warns that you are comparing a unsigned value in a way that implies it is
|
Warns that you are comparing a unsigned value in a way that implies it is
|
||||||
@@ -1427,19 +1695,25 @@ that is not yet supported in Verilator. See the Limitations chapter.
|
|||||||
=item Verilated model didn't converge
|
=item Verilated model didn't converge
|
||||||
|
|
||||||
Verilator sometimes has to evaluate combinatorial logic multiple times,
|
Verilator sometimes has to evaluate combinatorial logic multiple times,
|
||||||
usually around code where a UNOPT warning was issued, but disabled. For
|
usually around code where a UNOPTFLAT warning was issued, but disabled.
|
||||||
example:
|
For example:
|
||||||
|
|
||||||
always @ (a) b=~a;
|
always @ (a) b=~a;
|
||||||
always @ (b) a=b
|
always @ (b) a=b
|
||||||
|
|
||||||
will toggle forever and thus the executable will give the didn't converge
|
will toggle forever and thus the executable will give the didn't converge
|
||||||
error to prevent an infinite loop. To debug this, compile the Verilated
|
error to prevent an infinite loop.
|
||||||
.cpp files with -DVL_DEBUG, then call Verilated::debug(1) in your main.cpp.
|
|
||||||
This will cause each module to print a message when it's invoked. From
|
To debug this, run Verilator with --profile-cfuncs. Run make on the
|
||||||
that it should be obvious what routine(s) are part of the infinite loop.
|
generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in
|
||||||
Then in Gdb, add a break point at the routine entry point and "print *this"
|
your main.cpp.
|
||||||
on each loop so you can see what variables are changing each invocation.
|
|
||||||
|
This will cause each change in a variable to print a message. Near the
|
||||||
|
bottom you'll see the code and variable that causes the problem. For the
|
||||||
|
program above:
|
||||||
|
|
||||||
|
CHANGE: filename.v:1: b
|
||||||
|
CHANGE: filename.v:2: a
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
@@ -1474,18 +1748,38 @@ so your simulator shouldn't have to be -- and Verilator is closer to the
|
|||||||
synthesis interpretation, so this is a good thing for getting working
|
synthesis interpretation, so this is a good thing for getting working
|
||||||
silicon.
|
silicon.
|
||||||
|
|
||||||
=item How do I generate waveforms (traces)?
|
=item How do I generate waveforms (traces) in C++?
|
||||||
|
|
||||||
|
See the next question for SystemC mode.
|
||||||
|
|
||||||
Add the --trace switch to Verilator, and make sure the SystemPerl package
|
Add the --trace switch to Verilator, and make sure the SystemPerl package
|
||||||
is installed (SystemC itself isn't required for C++ only tracing.) In your
|
is installed. SystemC itself does not need to be installed for C++ only
|
||||||
top level C code, call Verilated::traceEverOn(true).
|
tracing. You do not even need to compile SystemPerl; you may simply untar
|
||||||
|
the SystemPerl kit and point the SYSTEMPERL environment variable to the
|
||||||
|
untarred directory.
|
||||||
|
|
||||||
Then, in SystemC mode, create a SpTraceFile object. For an example, see
|
In your top level C code, call Verilated::traceEverOn(true). Then create a
|
||||||
the call to SpTraceFile in the test_sp/sc_main.cpp file of the
|
SpTraceVcdC object. For an example, see the call to SpTraceVcdC in the
|
||||||
distribution.
|
test_c/sc_main.cpp file of the distribution.
|
||||||
|
|
||||||
Or, in C++ mode, create a SpTraceVcdCFile object, and see
|
You also need to compile SpTraceVcdC.cpp and add it to your link. This is
|
||||||
test_c/sim_main.cpp.
|
done for you if using the Verilator --exe flag.
|
||||||
|
|
||||||
|
=item How do I generate waveforms (traces) in SystemC?
|
||||||
|
|
||||||
|
Add the --trace switch to Verilator, and make sure the SystemPerl package
|
||||||
|
is installed.
|
||||||
|
|
||||||
|
In your top level C sc_main code, call Verilated::traceEverOn(true). Then
|
||||||
|
create a SpTraceFile object as you would create a normal SystemC trace
|
||||||
|
file. For an example, see the call to SpTraceFile in the
|
||||||
|
test_sp/sc_main.cpp file of the distribution.
|
||||||
|
|
||||||
|
=item How do I view waveforms (traces)?
|
||||||
|
|
||||||
|
Verilator makes standard VCD (Value Change Dump) files. They are viewable
|
||||||
|
with the public domain Dinotrace or GtkWave programs, or any of the many
|
||||||
|
commercial offerings.
|
||||||
|
|
||||||
=item Where is the translate_off command? (How do I ignore a construct?)
|
=item Where is the translate_off command? (How do I ignore a construct?)
|
||||||
|
|
||||||
@@ -1504,6 +1798,16 @@ Call Verilated::assertOn(false) before you first call the model, then turn
|
|||||||
it back on after reset. It defaults to true. When false, all assertions
|
it back on after reset. It defaults to true. When false, all assertions
|
||||||
controlled by --assert are disabled.
|
controlled by --assert are disabled.
|
||||||
|
|
||||||
|
=item Why do I get "undefined reference to `sc_time_stamp()'"?
|
||||||
|
|
||||||
|
In C++ (non SystemC) code you need to define this function so that the
|
||||||
|
simulator knows the current time. See the "CONNECTING TO C++" examples.
|
||||||
|
|
||||||
|
=item Why do I get "undefined reference to `VL_RAND_RESET_I' or `Verilated::...'"?
|
||||||
|
|
||||||
|
You need to link your compiled Verilated code against the verilated.cpp
|
||||||
|
file found in the include directory of the Verilator kit.
|
||||||
|
|
||||||
=item Is the PLI supported?
|
=item Is the PLI supported?
|
||||||
|
|
||||||
No.
|
No.
|
||||||
@@ -1514,6 +1818,12 @@ complex, since Verilator emits standard C++ code, you can simply write your
|
|||||||
own C++ routines that can access and modify signal values without needing
|
own C++ routines that can access and modify signal values without needing
|
||||||
any PLI interface code, and call it with $c("{any_c++_statement}").
|
any PLI interface code, and call it with $c("{any_c++_statement}").
|
||||||
|
|
||||||
|
=item How do I make a Verilog module that contain a C++ object?
|
||||||
|
|
||||||
|
You need to add the object to the structure that Verilator creates, then
|
||||||
|
use $c to call a method inside your object. The
|
||||||
|
test_regress/t/t_extend_class files show an example of how to do this.
|
||||||
|
|
||||||
=item How do I get faster build times?
|
=item How do I get faster build times?
|
||||||
|
|
||||||
Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can
|
Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can
|
||||||
@@ -1563,6 +1873,25 @@ In this example, clk is a bool you can read or set as any other variable.
|
|||||||
The value of normal signals may be set, though clocks shouldn't be changed
|
The value of normal signals may be set, though clocks shouldn't be changed
|
||||||
by your code or you'll get strange results.
|
by your code or you'll get strange results.
|
||||||
|
|
||||||
|
=item Should a module be in Verilog or SystemC?
|
||||||
|
|
||||||
|
Sometimes there is a block that just interconnects cells, and have a choice
|
||||||
|
as to if you write it in Verilog or SystemC. Everything else being equal,
|
||||||
|
best performance is when Verilator sees all of the design. So, look at the
|
||||||
|
hierarchy of your design, labeling cells as to if they are SystemC or
|
||||||
|
Verilog. Then:
|
||||||
|
|
||||||
|
A module with only SystemC cells below must be SystemC.
|
||||||
|
|
||||||
|
A module with a mix of Verilog and SystemC cells below must be SystemC. (As
|
||||||
|
Verilator cannot connect to lower-level SystemC cells.)
|
||||||
|
|
||||||
|
A module with only Verilog cells below can be either, but for best
|
||||||
|
performance should be Verilog. (The exception is if you have a design that
|
||||||
|
is instantiated many times; in this case Verilating one of the lower
|
||||||
|
modules and instantiating that Verilated cells multiple times into a
|
||||||
|
SystemC module *may* be faster.)
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 BUGS
|
=head1 BUGS
|
||||||
@@ -1587,7 +1916,7 @@ outputs. Now, the following should fail:
|
|||||||
cd test_regress
|
cd test_regress
|
||||||
t/t_BUG.pl
|
t/t_BUG.pl
|
||||||
|
|
||||||
Finally, Mail the bug report to C<[email protected]>
|
Finally, Mail the bug report to C<[email protected]>.
|
||||||
|
|
||||||
=head1 HISTORY
|
=head1 HISTORY
|
||||||
|
|
||||||
@@ -1614,8 +1943,8 @@ scratch in C++. This added many optimizations, yielding about a 2-5x
|
|||||||
performance gain.
|
performance gain.
|
||||||
|
|
||||||
Currently, various language features and performance enhancements are added
|
Currently, various language features and performance enhancements are added
|
||||||
as the need arises. Verilator is now about 2x faster then in 2002, and
|
as the need arises. Verilator is now about 2x faster then in 2002, and is
|
||||||
as fast as most popular commercial simulators.
|
faster then many popular commercial simulators.
|
||||||
|
|
||||||
=head1 CONTRIBUTORS
|
=head1 CONTRIBUTORS
|
||||||
|
|
||||||
@@ -1642,7 +1971,7 @@ Eugene Weber, Leon Wildman, and Mat Zeno.
|
|||||||
|
|
||||||
The latest version is available from L<http://www.veripool.com/>.
|
The latest version is available from L<http://www.veripool.com/>.
|
||||||
|
|
||||||
Copyright 2003-2006 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2003-2007 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 or the Perl Artistic License.
|
General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
|||||||
# $Id$
|
# $Id$
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2005-2006 by Wilson Snyder <[email protected]>. This
|
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||||
# program is free software; you can redistribute it and/or modify it under
|
# program is free software; you can redistribute it and/or modify it under
|
||||||
# the terms of either the GNU Lesser General Public License or the Perl
|
# the terms of either the GNU Lesser General Public License or the Perl
|
||||||
# Artistic License.
|
# Artistic License.
|
||||||
@@ -46,6 +46,9 @@ if (! GetOptions (
|
|||||||
defined $Opt_A or die "%Error: No old diff filename\n";
|
defined $Opt_A or die "%Error: No old diff filename\n";
|
||||||
defined $Opt_B or die "%Error: No new diff filename\n";
|
defined $Opt_B or die "%Error: No new diff filename\n";
|
||||||
|
|
||||||
|
-e $Opt_A or die "%Error: No old diff filename found: $Opt_A\n";
|
||||||
|
-e $Opt_B or die "%Error: No new diff filename found: $Opt_B\n";
|
||||||
|
|
||||||
if (-d $Opt_A && -d $Opt_B) {
|
if (-d $Opt_A && -d $Opt_B) {
|
||||||
diff_dir ($Opt_A, $Opt_B);
|
diff_dir ($Opt_A, $Opt_B);
|
||||||
} elsif (-f $Opt_A && -f $Opt_B) {
|
} elsif (-f $Opt_A && -f $Opt_B) {
|
||||||
@@ -176,7 +179,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
The latest version is available from L<http://www.veripool.com/>.
|
The latest version is available from L<http://www.veripool.com/>.
|
||||||
|
|
||||||
Copyright 2005-2006 by Wilson Snyder. This package is free software; you
|
Copyright 2005-2007 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 or the Perl Artistic License.
|
Lesser General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
@@ -192,5 +195,5 @@ C<verilator>
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
### Local Variables:
|
### Local Variables:
|
||||||
### compile-command: "$V4/bin/verilator_difftree ~/SandBox/workwsnyder/verilator/test_c/obj_dir/V*_03_*.tree $V4/test_c/obj_dir/V*_03_*.tree"
|
### compile-command: "$V4/bin/verilator_difftree $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
|
||||||
### End:
|
### End:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
|||||||
# $Id$
|
# $Id$
|
||||||
# DESCRIPTION: Print include statements for each ARGV
|
# DESCRIPTION: Print include statements for each ARGV
|
||||||
#
|
#
|
||||||
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 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
|
||||||
# General Public License or the Perl Artistic License.
|
# General Public License or the Perl Artistic License.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
dnl $Id$
|
dnl $Id$
|
||||||
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
|
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||||
dnl Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
dnl Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||||
dnl redistribute it and/or modify it under the terms of either the GNU
|
dnl redistribute it and/or modify it under the terms of either the GNU
|
||||||
dnl General Public License or the Perl Artistic License.
|
dnl General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
AC_REVISION($Revision$)dnl
|
AC_REVISION($Revision$)dnl
|
||||||
AC_INIT(src/Verilator.cpp)
|
AC_INIT(src/Verilator.cpp)
|
||||||
AC_CONFIG_HEADER(src/config.h)
|
AC_CONFIG_HEADER(src/config_build.h)
|
||||||
|
|
||||||
dnl Special Substitutions
|
dnl Special Substitutions
|
||||||
|
|
||||||
@@ -16,13 +16,15 @@ AC_PROG_CC
|
|||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PATH_PROG(PERL,perl)
|
AC_PATH_PROG(PERL,perl)
|
||||||
|
AC_PATH_PROG(YACC,bison)
|
||||||
|
AC_PATH_PROG(LEX,flex)
|
||||||
|
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_HEADER_SYS_WAIT
|
AC_HEADER_SYS_WAIT
|
||||||
AC_CHECK_HEADERS(fcntl.h unistd.h sys/file.h sys/time.h sys/un.h math.h stdint.h mingw/stdint.h)
|
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
|
dnl Checks for typedefs, structures
|
||||||
AC_CHECK_TYPE(size_t,unsigned int)
|
AC_CHECK_TYPE(size_t,unsigned int)
|
||||||
+109
-1
@@ -1,7 +1,7 @@
|
|||||||
// $Id$ -*- C++ -*-
|
// $Id$ -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
@@ -238,6 +239,113 @@ QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
|||||||
return VL_CVT_FP_Q(fopen(filenamez,modez));
|
return VL_CVT_FP_Q(fopen(filenamez,modez));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
|
||||||
|
QData ofilename, void* memp, IData start, IData end) {
|
||||||
|
IData fnw[2]; VL_SET_WQ(fnw, ofilename);
|
||||||
|
return VL_READMEM_W(hex,width,depth,array_lsb,2, fnw,memp,start,end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||||
|
WDataInP ofilenamep, void* memp, IData start, IData end) {
|
||||||
|
char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||||
|
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep);
|
||||||
|
FILE* fp = fopen(ofilenamez, "r");
|
||||||
|
if (!fp) {
|
||||||
|
// We don't report the Verilog source filename as it slow to have to pass it down
|
||||||
|
vl_fatal (ofilenamez, 0, "", "$readmem file not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Prep for reading
|
||||||
|
IData addr = start;
|
||||||
|
int linenum = 1;
|
||||||
|
bool innum = false;
|
||||||
|
bool ignore_to_eol = false;
|
||||||
|
bool ignore_to_cmt = false;
|
||||||
|
bool needinc = false;
|
||||||
|
bool reading_addr = false;
|
||||||
|
int lastc = ' ';
|
||||||
|
// Read the data
|
||||||
|
// We process a character at a time, as then we don't need to deal
|
||||||
|
// with changing buffer sizes dynamically, etc.
|
||||||
|
while (1) {
|
||||||
|
int c = fgetc(fp);
|
||||||
|
if (c==EOF) break;
|
||||||
|
//printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n", linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc);
|
||||||
|
if (c=='\n') { linenum++; ignore_to_eol=false; if (innum) reading_addr=false; innum=false; }
|
||||||
|
else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; }
|
||||||
|
// Skip // comments and detect /* comments
|
||||||
|
else if (ignore_to_cmt && lastc=='*' && c=='/') {
|
||||||
|
ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
|
||||||
|
} else if (!ignore_to_eol && !ignore_to_cmt) {
|
||||||
|
if (lastc=='/' && c=='*') { ignore_to_cmt = true; }
|
||||||
|
else if (lastc=='/' && c=='/') { ignore_to_eol = true; }
|
||||||
|
else if (c=='/') {} // Part of /* or //
|
||||||
|
else if (c=='_') {}
|
||||||
|
else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
|
||||||
|
// Check for hex or binary digits as file format requests
|
||||||
|
else if (isxdigit(c)) {
|
||||||
|
c = tolower(c);
|
||||||
|
int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
|
||||||
|
if (!innum) { // Prep for next number
|
||||||
|
if (needinc) { addr++; needinc=false; }
|
||||||
|
}
|
||||||
|
if (reading_addr) {
|
||||||
|
// Decode @ addresses
|
||||||
|
if (!innum) addr=0;
|
||||||
|
addr = (addr<<4) + value;
|
||||||
|
} else {
|
||||||
|
needinc = true;
|
||||||
|
//printf(" Value width=%d @%x = %c\n", width, addr, c);
|
||||||
|
if (addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb)) {
|
||||||
|
vl_fatal (ofilenamez, linenum, "", "$readmem file address beyond bounds of array");
|
||||||
|
} else {
|
||||||
|
int entry = addr - array_lsb;
|
||||||
|
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
|
||||||
|
// Shift value in
|
||||||
|
if (width<=8) {
|
||||||
|
CData* datap = &((CData*)(memp))[entry];
|
||||||
|
if (!innum) { *datap = 0; }
|
||||||
|
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
|
||||||
|
} else if (width<=16) {
|
||||||
|
SData* datap = &((SData*)(memp))[entry];
|
||||||
|
if (!innum) { *datap = 0; }
|
||||||
|
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
|
||||||
|
} else if (width<=VL_WORDSIZE) {
|
||||||
|
IData* datap = &((IData*)(memp))[entry];
|
||||||
|
if (!innum) { *datap = 0; }
|
||||||
|
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
|
||||||
|
} else if (width<=VL_QUADSIZE) {
|
||||||
|
QData* datap = &((QData*)(memp))[entry];
|
||||||
|
if (!innum) { *datap = 0; }
|
||||||
|
*datap = ((*datap << (QData)(shift)) + (QData)(value)) & VL_MASK_Q(width);
|
||||||
|
} else {
|
||||||
|
WDataOutP datap = &((WDataOutP)(memp))[ entry*VL_WORDS_I(width) ];
|
||||||
|
if (!innum) { VL_ZERO_RESET_W(width, datap); }
|
||||||
|
_VL_SHIFTL_INPLACE_W(width, datap, shift);
|
||||||
|
datap[0] |= value;
|
||||||
|
}
|
||||||
|
if (value>=(1<<shift)) {
|
||||||
|
vl_fatal (ofilenamez, linenum, "", "$readmemb (binary) file contains hex characters");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
innum = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vl_fatal (ofilenamez, linenum, "", "$readmem file syntax error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastc = c;
|
||||||
|
}
|
||||||
|
if (needinc) { addr++; needinc=false; }
|
||||||
|
|
||||||
|
// Final checks
|
||||||
|
fclose(fp);
|
||||||
|
if (end != (IData)(~ VL_ULL(0)) && addr != (end+1)) {
|
||||||
|
vl_fatal (ofilenamez, linenum, "", "$readmem file ended before specified ending-address");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Verilated:: Methods
|
// Verilated:: Methods
|
||||||
|
|
||||||
|
|||||||
+75
-9
@@ -1,7 +1,7 @@
|
|||||||
// $Id$ -*- C++ -*-
|
// $Id$ -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -40,11 +40,11 @@ using namespace std;
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Basic types
|
// Basic types
|
||||||
|
|
||||||
typedef uint8_t CData; ///< Verilated data, 1-8 bits
|
typedef vluint8_t CData; ///< Verilated data, 1-8 bits
|
||||||
typedef uint16_t SData; ///< Verilated data, 9-16 bits
|
typedef vluint16_t SData; ///< Verilated data, 9-16 bits
|
||||||
typedef uint32_t IData; ///< Verilated data, 17-32 bits
|
typedef vluint32_t IData; ///< Verilated data, 17-32 bits
|
||||||
typedef vluint64_t QData; ///< Verilated data, 33-64 bits
|
typedef vluint64_t QData; ///< Verilated data, 33-64 bits
|
||||||
typedef uint32_t WData; ///< Verilated data, >64 bits, as an array
|
typedef vluint32_t WData; ///< Verilated data, >64 bits, as an array
|
||||||
|
|
||||||
typedef const WData* WDataInP; ///< Array input to a function
|
typedef const WData* WDataInP; ///< Array input to a function
|
||||||
typedef WData* WDataOutP; ///< Array output from a function
|
typedef WData* WDataOutP; ///< Array output from a function
|
||||||
@@ -115,6 +115,13 @@ public:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// Functions overridable by user defines
|
||||||
|
|
||||||
|
#ifndef VL_PRINTF
|
||||||
|
# define VL_PRINTF printf ///< Print ala printf; may redefine if desired
|
||||||
|
#endif
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
/// Verilator global static information class
|
/// Verilator global static information class
|
||||||
|
|
||||||
@@ -187,9 +194,17 @@ inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData l
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// File I/O
|
/// File I/O
|
||||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP filename, IData mode);
|
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||||
extern QData VL_FOPEN_QI(QData filename, IData mode);
|
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||||
inline QData VL_FOPEN_II(IData filename, IData mode) { return VL_FOPEN_QI(filename,mode); }
|
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||||
|
|
||||||
|
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||||
|
WDataInP ofilename, void* memp, IData start, IData end);
|
||||||
|
extern void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||||
|
QData ofilename, void* memp, IData start, IData end);
|
||||||
|
inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||||
|
IData ofilename, void* memp, IData start, IData end) {
|
||||||
|
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Base macros
|
// Base macros
|
||||||
@@ -219,6 +234,13 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q
|
|||||||
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); }
|
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); }
|
||||||
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
|
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
|
||||||
|
|
||||||
|
// Debugging prints
|
||||||
|
static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
|
||||||
|
printf(" Data: w%d: ", lbits);
|
||||||
|
for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { printf("%08x ",iwp[i]); }
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Pli macros
|
// Pli macros
|
||||||
|
|
||||||
@@ -1028,6 +1050,18 @@ static inline WDataOutP VL_CONCAT_WWW(int obits,int lbits,int rbits,WDataOutP ow
|
|||||||
//===================================================================
|
//===================================================================
|
||||||
// Shifts
|
// Shifts
|
||||||
|
|
||||||
|
// Static shift, used by internal functions
|
||||||
|
// The output is the same as the input - it overlaps!
|
||||||
|
static inline void _VL_SHIFTL_INPLACE_W(int obits,WDataOutP iowp,IData rd/*1 or 4*/) {
|
||||||
|
int words = VL_WORDS_I(obits);
|
||||||
|
IData linsmask = VL_MASK_I(rd);
|
||||||
|
for (int i=words-1; i>=1; i--) {
|
||||||
|
iowp[i] = ((iowp[i]<<rd) & ~linsmask) | ((iowp[i-1] >> (32-rd)) & linsmask);
|
||||||
|
}
|
||||||
|
iowp[0] = ((iowp[0]<<rd) & ~linsmask);
|
||||||
|
iowp[VL_WORDS_I(obits)-1] &= VL_MASK_I(obits);
|
||||||
|
}
|
||||||
|
|
||||||
// EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
|
// EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
|
||||||
// Important: Unlike most other funcs, the shift might well be a computed
|
// Important: Unlike most other funcs, the shift might well be a computed
|
||||||
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
|
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
|
||||||
@@ -1321,6 +1355,38 @@ static inline WDataOutP VL_CONST_W_16X(int obits, WDataOutP o,
|
|||||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
_END(obits,16); }
|
_END(obits,16); }
|
||||||
|
static inline WDataOutP VL_CONST_W_17X(int obits, WDataOutP o,
|
||||||
|
I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16;
|
||||||
|
_END(obits,17); }
|
||||||
|
static inline WDataOutP VL_CONST_W_18X(int obits, WDataOutP o,
|
||||||
|
I d17,I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16; o[17]=d17;
|
||||||
|
_END(obits,18); }
|
||||||
|
static inline WDataOutP VL_CONST_W_19X(int obits, WDataOutP o,
|
||||||
|
I d18,I d17,I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16; o[17]=d17; o[18]=d18;
|
||||||
|
_END(obits,19); }
|
||||||
|
static inline WDataOutP VL_CONST_W_20X(int obits, WDataOutP o,
|
||||||
|
I d19,I d18,I d17,I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16; o[17]=d17; o[18]=d18; o[19]=d19;
|
||||||
|
_END(obits,20); }
|
||||||
static inline WDataOutP VL_CONST_W_24X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_24X(int obits, WDataOutP o,
|
||||||
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
|
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
|
||||||
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
######################################################################
|
######################################################################
|
||||||
# DESCRIPTION: Makefile commands for all verilated target files
|
# DESCRIPTION: Makefile commands for all verilated target files
|
||||||
#
|
#
|
||||||
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 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
|
||||||
# General Public License or the Perl Artistic License.
|
# General Public License or the Perl Artistic License.
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -48,6 +48,9 @@ VPATH += $(VERILATOR_ROOT)/include
|
|||||||
#OPT = -ggdb -DPRINTINITSTR
|
#OPT = -ggdb -DPRINTINITSTR
|
||||||
CPPFLAGS += $(OPT)
|
CPPFLAGS += $(OPT)
|
||||||
|
|
||||||
|
CPPFLAGS += $(M32)
|
||||||
|
LDFLAGS += $(M32)
|
||||||
|
|
||||||
# See the benchmarking section of bin/verilator.
|
# See the benchmarking section of bin/verilator.
|
||||||
# Support class optimizations. This includes the tracing and symbol table.
|
# Support class optimizations. This includes the tracing and symbol table.
|
||||||
# SystemC takes minutes to optimize, thus it is off by default.
|
# SystemC takes minutes to optimize, thus it is off by default.
|
||||||
@@ -81,8 +84,8 @@ endif
|
|||||||
##### SystemPerl builds
|
##### SystemPerl builds
|
||||||
|
|
||||||
ifeq ($(VM_SP),1)
|
ifeq ($(VM_SP),1)
|
||||||
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src -DSYSTEMPERL
|
CPPFLAGS += -I$(SYSTEMPERL)/src -DSYSTEMPERL
|
||||||
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src
|
VPATH += $(SYSTEMPERL)/src
|
||||||
|
|
||||||
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
||||||
|
|
||||||
@@ -101,8 +104,8 @@ endif
|
|||||||
ifeq ($(VM_PCLI),1)
|
ifeq ($(VM_PCLI),1)
|
||||||
LIBS += -lm -lstdc++
|
LIBS += -lm -lstdc++
|
||||||
ifeq ($(VM_TRACE),1)
|
ifeq ($(VM_TRACE),1)
|
||||||
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src
|
CPPFLAGS += -I$(SYSTEMPERL)/src
|
||||||
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src
|
VPATH += $(SYSTEMPERL)/src
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
|
|||||||
+32
-16
@@ -1,7 +1,7 @@
|
|||||||
// $Id$ -*- C++ -*-
|
// $Id$ -*- C++ -*-
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -15,9 +15,11 @@
|
|||||||
/// \file
|
/// \file
|
||||||
/// \brief Verilator: Common include for OS portability (verilated & verilator)
|
/// \brief Verilator: Common include for OS portability (verilated & verilator)
|
||||||
///
|
///
|
||||||
/// This header is used by both verilated code, and the verilator
|
/// This header is used by both the Verilator source code (run on the
|
||||||
/// program itself Code needed by only one goes into verilated.h or
|
/// build and host system), and the Verilated output (run on the target
|
||||||
/// config.h.in respectively.
|
/// system). Code needed by only the host system goes into
|
||||||
|
/// config_build.h.in, code needed by Verilated code only goes into
|
||||||
|
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.com/verilator
|
/// Code available from: http://www.veripool.com/verilator
|
||||||
///
|
///
|
||||||
@@ -37,6 +39,8 @@
|
|||||||
# define VL_ATTR_UNUSED __attribute__ ((unused))
|
# define VL_ATTR_UNUSED __attribute__ ((unused))
|
||||||
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||||
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||||
|
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
|
||||||
|
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
|
||||||
#else
|
#else
|
||||||
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
|
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
|
||||||
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
|
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
|
||||||
@@ -44,6 +48,8 @@
|
|||||||
# define VL_ATTR_UNUSED ///< Function that may be never used
|
# define VL_ATTR_UNUSED ///< Function that may be never used
|
||||||
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true then false
|
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true then false
|
||||||
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false then true
|
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false then true
|
||||||
|
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
|
||||||
|
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
@@ -68,24 +74,34 @@
|
|||||||
#ifdef VL_UINTS_DEFINED
|
#ifdef VL_UINTS_DEFINED
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
typedef unsigned char uint8_t; ///< 8-bit basic type
|
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned short int uint16_t; ///< 16-bit basic type
|
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned long uint32_t; ///< 32-bit basic type
|
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned long long vluint64_t; ///< 64-bit basic type
|
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||||
|
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||||
typedef long vlsint32_t; ///< 32-bit signed type
|
typedef long vlsint32_t; ///< 32-bit signed type
|
||||||
|
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
|
||||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||||
|
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
typedef unsigned char uint8_t; ///< 8-bit basic type
|
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned short int uint16_t; ///< 16-bit basic type
|
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned int uint32_t; ///< 32-bit basic type
|
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned __int64 vluint64_t; ///< 64-bit basic type
|
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||||
|
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||||
typedef int vlsint32_t; ///< 32-bit signed type
|
typedef int vlsint32_t; ///< 32-bit signed type
|
||||||
|
typedef unsigned int vluint32_t; ///< 32-bit unsigned type
|
||||||
typedef __int64 vlsint64_t; ///< 64-bit signed type
|
typedef __int64 vlsint64_t; ///< 64-bit signed type
|
||||||
#else // Linux or compliant Unix flavors
|
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
|
||||||
# include <stdint.h>
|
#else // Linux or compliant Unix flavors, -m64
|
||||||
typedef unsigned long long vluint64_t; ///< 64-bit basic type
|
# include <stdint.h> // Linux and most flavors
|
||||||
typedef long vlsint32_t; ///< 32-bit signed type
|
# include <inttypes.h> // Solaris
|
||||||
|
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
|
||||||
|
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
|
||||||
|
typedef int vlsint32_t; ///< 32-bit signed type
|
||||||
|
typedef uint32_t vluint32_t; ///< 32-bit signed type
|
||||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||||
|
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|||||||
Executable
+174
@@ -0,0 +1,174 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
# $Id$
|
||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||||
|
# program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of either the GNU Lesser General Public License or the Perl
|
||||||
|
# Artistic License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
require 5.006_001;
|
||||||
|
use Getopt::Long;
|
||||||
|
use IO::File;
|
||||||
|
use Pod::Usage;
|
||||||
|
use Data::Dumper; $Data::Dumper::Indent=1;
|
||||||
|
use strict;
|
||||||
|
use vars qw ($Debug);
|
||||||
|
|
||||||
|
#======================================================================
|
||||||
|
|
||||||
|
our @Header;
|
||||||
|
our %Vertexes;
|
||||||
|
our @Edges;
|
||||||
|
our %Edges;
|
||||||
|
|
||||||
|
#======================================================================
|
||||||
|
# main
|
||||||
|
|
||||||
|
$Debug = 0;
|
||||||
|
my $opt_filename;
|
||||||
|
autoflush STDOUT 1;
|
||||||
|
autoflush STDERR 1;
|
||||||
|
if (! GetOptions (
|
||||||
|
"help" => \&usage,
|
||||||
|
"debug" => \&debug,
|
||||||
|
"<>" => \¶meter,
|
||||||
|
)) {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
dotread ($opt_filename);
|
||||||
|
cwrite ("graph_export.cpp");
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
sub usage {
|
||||||
|
print '$Id$ ', "\n";
|
||||||
|
pod2usage(-verbose=>2, -exitval => 2);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub debug {
|
||||||
|
$Debug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parameter {
|
||||||
|
my $param = shift;
|
||||||
|
if (!$opt_filename) {
|
||||||
|
$opt_filename = $param;
|
||||||
|
} else {
|
||||||
|
die "%Error: Unknown parameter: $param\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
sub dotread {
|
||||||
|
my $filename = shift;
|
||||||
|
|
||||||
|
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
|
||||||
|
my $header = 1;
|
||||||
|
my $vnum = 0;
|
||||||
|
while (defined (my $line = $fh->getline)) {
|
||||||
|
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
|
||||||
|
next if $1 eq 'nTITLE';
|
||||||
|
$header = 0;
|
||||||
|
$Vertexes{$1} = {num => $vnum++,
|
||||||
|
line => $line,
|
||||||
|
name => $1,};
|
||||||
|
}
|
||||||
|
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
|
||||||
|
my $from=$1; my $to=$2;
|
||||||
|
my $weight = 1; $weight = $1 if $line =~ /weight=(\d+)/;
|
||||||
|
my $cutable = undef; $cutable = $1 if $line =~ /style=(\S+)/;
|
||||||
|
my $edge = {num => $vnum++,
|
||||||
|
line => $line,
|
||||||
|
weight => $weight,
|
||||||
|
cutable => $cutable,
|
||||||
|
from => $from,
|
||||||
|
to => $to,};
|
||||||
|
push @Edges, $edge;
|
||||||
|
$Edges{$from}{$to} = $edge;
|
||||||
|
}
|
||||||
|
elsif ($header) {
|
||||||
|
push @Header, $line;
|
||||||
|
print "IGNORE: $line";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
sub cwrite {
|
||||||
|
my $filename = shift;
|
||||||
|
|
||||||
|
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
|
||||||
|
$fh->print("void V3GraphTestImport::dotImport() {\n");
|
||||||
|
$fh->print(" DfaGraph* gp = &m_graph;\n");
|
||||||
|
foreach my $ver (sort {$a->{num} <=> $b->{num}} (values %Vertexes)) {
|
||||||
|
$fh->printf(" V3GraphTestVertex* %s = new V3GraphTestVertex(gp, \"%s\"); if (%s) {}\n",
|
||||||
|
$ver->{name}, $ver->{name}, $ver->{name});
|
||||||
|
}
|
||||||
|
$fh->print("\n");
|
||||||
|
foreach my $edge (@Edges) {
|
||||||
|
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
|
||||||
|
$edge->{from}, $edge->{to},
|
||||||
|
$edge->{weight}, $edge->{cutable}?"true":"false");
|
||||||
|
}
|
||||||
|
$fh->print("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
dot_importer - Take graph .dot file and convert into .cpp file
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
dot_importer a.dot
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Dot_importer takes a graphvis .dot file and converts into .cpp file. This
|
||||||
|
.cpp file is then manually included in V3GraphTest.cpp to verify various
|
||||||
|
sub-algorithms.
|
||||||
|
|
||||||
|
=head1 ARGUMENTS
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item --help
|
||||||
|
|
||||||
|
Displays this message and program version and exits.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
|
Copyright 2005-2007 by Wilson Snyder. This package is free software; you
|
||||||
|
can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
Lesser General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
|
=head1 AUTHORS
|
||||||
|
|
||||||
|
Wilson Snyder <[email protected]>
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
### Local Variables:
|
||||||
|
### compile-command: "./dot_importer | tee ~/d/a.dot"
|
||||||
|
### End:
|
||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2005-2006 by Wilson Snyder <[email protected]>. This
|
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||||
# program is free software; you can redistribute it and/or modify it under
|
# program is free software; you can redistribute it and/or modify it under
|
||||||
# the terms of either the GNU Lesser General Public License or the Perl
|
# the terms of either the GNU Lesser General Public License or the Perl
|
||||||
# Artistic License.
|
# Artistic License.
|
||||||
@@ -197,7 +197,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2006 by Wilson Snyder. This package is free software; you
|
Copyright 2005-2007 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 or the Perl Artistic License.
|
Lesser General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2005-2006 by Wilson Snyder <[email protected]>. This
|
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||||
# program is free software; you can redistribute it and/or modify it under
|
# program is free software; you can redistribute it and/or modify it under
|
||||||
# the terms of either the GNU Lesser General Public License or the Perl
|
# the terms of either the GNU Lesser General Public License or the Perl
|
||||||
# Artistic License.
|
# Artistic License.
|
||||||
@@ -344,7 +344,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
Copyright 2005-2006 by Wilson Snyder. This package is free software; you
|
Copyright 2005-2007 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 or the Perl Artistic License.
|
Lesser General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,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-2006 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
|
This package is Copyright 2003-2007 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
|
||||||
|
|
||||||
You may distribute under the terms of either the GNU General Public License
|
You may distribute under the terms of either the GNU General Public License
|
||||||
or the Artistic License, as specified in the Perl README file.
|
or the Artistic License, as specified in the Perl README file.
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
*.old
|
*.old
|
||||||
config.h
|
config_build.h
|
||||||
Makefile
|
Makefile
|
||||||
Makefile_obj
|
Makefile_obj
|
||||||
.objcache*
|
.objcache*
|
||||||
|
|||||||
+4
-1
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 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
|
||||||
# General Public License or the Perl Artistic License.
|
# General Public License or the Perl Artistic License.
|
||||||
#
|
#
|
||||||
@@ -85,3 +85,6 @@ clean mostlyclean distclean maintainer-clean::
|
|||||||
-rm -f *__gen*
|
-rm -f *__gen*
|
||||||
-rm -f *.yy.* y.output y.tab.[cho] *_test
|
-rm -f *.yy.* y.output y.tab.[cho] *_test
|
||||||
-rm -f .objcache*
|
-rm -f .objcache*
|
||||||
|
|
||||||
|
distclean maintainer-clean::
|
||||||
|
-rm -f Makefile Makefile_obj config_build.h
|
||||||
|
|||||||
+10
-8
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 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
|
||||||
# General Public License or the Perl Artistic License.
|
# General Public License or the Perl Artistic License.
|
||||||
#
|
#
|
||||||
@@ -28,6 +28,8 @@ CC = @CC@
|
|||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
LINK = @CXX@
|
LINK = @CXX@
|
||||||
|
|
||||||
|
LDFLAGS += @LDFLAGS@
|
||||||
|
|
||||||
#### End of system configuration section. ####
|
#### End of system configuration section. ####
|
||||||
|
|
||||||
VPATH += . $(srcdir)
|
VPATH += . $(srcdir)
|
||||||
@@ -36,22 +38,20 @@ TGT = ../../verilator_bin
|
|||||||
#################
|
#################
|
||||||
ifeq ($(VL_DEBUG),)
|
ifeq ($(VL_DEBUG),)
|
||||||
# Optimize
|
# Optimize
|
||||||
LDFLAGS =
|
|
||||||
COPT = -O
|
COPT = -O
|
||||||
else
|
else
|
||||||
# Debug
|
# Debug
|
||||||
LDFLAGS =
|
|
||||||
COPT = -ggdb -DVL_DEBUG
|
COPT = -ggdb -DVL_DEBUG
|
||||||
# Debug & Profile:
|
# Debug & Profile:
|
||||||
#LDFLAGS = -pg -g
|
#LDFLAGS += -pg -g
|
||||||
#COPT = -ggdb -pg -g
|
#COPT = -ggdb -pg -g
|
||||||
endif
|
endif
|
||||||
#################
|
#################
|
||||||
|
|
||||||
LEX = flex
|
LEX = @LEX@
|
||||||
LFLAGS = -d
|
LFLAGS = -d
|
||||||
YACC = bison -y
|
YACC = @YACC@
|
||||||
YFLAGS = -d -v
|
YFLAGS = -y -d -v
|
||||||
|
|
||||||
#LIBS += -ldl
|
#LIBS += -ldl
|
||||||
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl
|
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl
|
||||||
@@ -89,7 +89,6 @@ clean mostlyclean distclean maintainer-clean::
|
|||||||
-rm -f obj_* .objcache*
|
-rm -f obj_* .objcache*
|
||||||
|
|
||||||
distclean maintainer-clean:: clean
|
distclean maintainer-clean:: clean
|
||||||
rm -f Makefile config.h
|
|
||||||
|
|
||||||
maintainer-clean::
|
maintainer-clean::
|
||||||
|
|
||||||
@@ -143,6 +142,8 @@ RAW_OBJS = \
|
|||||||
V3LinkCells.o \
|
V3LinkCells.o \
|
||||||
V3LinkDot.o \
|
V3LinkDot.o \
|
||||||
V3LinkLevel.o \
|
V3LinkLevel.o \
|
||||||
|
V3LinkLValue.o \
|
||||||
|
V3LinkParse.o \
|
||||||
V3LinkResolve.o \
|
V3LinkResolve.o \
|
||||||
V3Localize.o \
|
V3Localize.o \
|
||||||
V3Name.o \
|
V3Name.o \
|
||||||
@@ -155,6 +156,7 @@ RAW_OBJS = \
|
|||||||
V3Scope.o \
|
V3Scope.o \
|
||||||
V3Signed.o \
|
V3Signed.o \
|
||||||
V3Split.o \
|
V3Split.o \
|
||||||
|
V3SplitAs.o \
|
||||||
V3Stats.o \
|
V3Stats.o \
|
||||||
V3StatsReport.o \
|
V3StatsReport.o \
|
||||||
V3Subst.o \
|
V3Subst.o \
|
||||||
|
|||||||
+5
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -31,7 +31,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -298,8 +299,10 @@ private:
|
|||||||
// OPTIMIZE: We could substitute a constant for things in the sense list, for example
|
// OPTIMIZE: We could substitute a constant for things in the sense list, for example
|
||||||
// always (posedge RESET) { if (RESET).... } we know RESET is true.
|
// always (posedge RESET) { if (RESET).... } we know RESET is true.
|
||||||
// Summarize a long list of combo inputs as just "combo"
|
// Summarize a long list of combo inputs as just "combo"
|
||||||
|
#ifndef __COVERITY__ // Else dead code on next line.
|
||||||
if (combo) nodep->sensesp()->addSensesp
|
if (combo) nodep->sensesp()->addSensesp
|
||||||
(new AstSenItem(nodep->fileline(),AstSenItem::Combo()));
|
(new AstSenItem(nodep->fileline(),AstSenItem::Combo()));
|
||||||
|
#endif
|
||||||
wantactivep = m_namer.getActive(nodep->fileline(), nodep->sensesp());
|
wantactivep = m_namer.getActive(nodep->fileline(), nodep->sensesp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3ACTIVE_H_
|
#ifndef _V3ACTIVE_H_
|
||||||
#define _V3ACTIVE_H_ 1
|
#define _V3ACTIVE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -28,7 +28,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3ACTIVETOP_H_
|
#ifndef _V3ACTIVETOP_H_
|
||||||
#define _V3ACTIVETOP_H_ 1
|
#define _V3ACTIVETOP_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+91
-19
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -46,28 +47,58 @@ private:
|
|||||||
V3Double0 m_statAsCover; // Statistic tracking
|
V3Double0 m_statAsCover; // Statistic tracking
|
||||||
V3Double0 m_statAsPsl; // Statistic tracking
|
V3Double0 m_statAsPsl; // Statistic tracking
|
||||||
V3Double0 m_statAsFull; // Statistic tracking
|
V3Double0 m_statAsFull; // Statistic tracking
|
||||||
|
V3Double0 m_statAsSV; // Statistic tracking
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
AstNode* newFireAssert(AstNode* nodep, const string& message) {
|
string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) {
|
||||||
AstNode* bodysp = new AstDisplay
|
return (string("[%0t] "+prefix+": ")+nodep->fileline()->filebasename()
|
||||||
(nodep->fileline(), '\0',
|
+":"+cvtToStr(nodep->fileline()->lineno())
|
||||||
(string("[%0t] %%Error: ")+nodep->fileline()->filebasename()
|
+": Assertion failed in %m"
|
||||||
+":"+cvtToStr(nodep->fileline()->lineno())
|
+((message != "")?": ":"")+message
|
||||||
+": Assertion failed in %m"
|
+"\\n");
|
||||||
+((message != "")?": ":"")+message
|
}
|
||||||
+"\\n"),
|
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
|
||||||
NULL,
|
nodep->displayType(AstDisplayType::WRITE);
|
||||||
new AstTime(nodep->fileline()));
|
nodep->text(assertDisplayMessage(nodep, prefix, nodep->text()));
|
||||||
bodysp->addNext(new AstStop (nodep->fileline()));
|
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
|
||||||
|
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
||||||
|
nodep->exprsp(timesp);
|
||||||
|
}
|
||||||
|
|
||||||
|
AstNode* newIfAssertOn(AstNode* nodep) {
|
||||||
// Add a internal if to check assertions are on.
|
// Add a internal if to check assertions are on.
|
||||||
// Don't make this a AND term, as it's unlikely to need to test this.
|
// Don't make this a AND term, as it's unlikely to need to test this.
|
||||||
bodysp = new AstIf (nodep->fileline(),
|
return new AstIf (nodep->fileline(),
|
||||||
new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1),
|
// If assertions are off, have constant propagation rip them out later
|
||||||
bodysp, NULL);
|
// This allows syntax errors and such to be detected normally.
|
||||||
|
(v3Global.opt.assertOn()
|
||||||
|
? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1))
|
||||||
|
: (AstNode*)(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), 1, 0)))),
|
||||||
|
nodep, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
AstNode* newIfCoverageOn(AstNode* nodep) {
|
||||||
|
// Add a internal if to check coverage is on
|
||||||
|
// Don't make this a AND term, as it's unlikely to need to test this.
|
||||||
|
return new AstIf (nodep->fileline(),
|
||||||
|
// If assertions are off, have constant propagation rip them out later
|
||||||
|
// This allows syntax errors and such to be detected normally.
|
||||||
|
(v3Global.opt.coverage()
|
||||||
|
? (AstNode*)(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), 1, 1)))
|
||||||
|
: (AstNode*)(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), 1, 0)))),
|
||||||
|
nodep, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
AstNode* newFireAssert(AstNode* nodep, const string& message) {
|
||||||
|
AstDisplay* dispp = new AstDisplay (nodep->fileline(), AstDisplayType::ERROR, message, NULL, NULL);
|
||||||
|
AstNode* bodysp = dispp;
|
||||||
|
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
|
||||||
|
bodysp->addNext(new AstStop (nodep->fileline()));
|
||||||
|
bodysp = newIfAssertOn(bodysp);
|
||||||
return bodysp;
|
return bodysp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void newAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, const string& message) {
|
void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, const string& message) {
|
||||||
propp->unlinkFrBack();
|
propp->unlinkFrBack();
|
||||||
sentreep->unlinkFrBack();
|
sentreep->unlinkFrBack();
|
||||||
//
|
//
|
||||||
@@ -113,6 +144,28 @@ private:
|
|||||||
pushDeletep(nodep); nodep=NULL;
|
pushDeletep(nodep); nodep=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void newVAssertion(AstVAssert* nodep, AstNode* propp) {
|
||||||
|
propp->unlinkFrBackWithNext();
|
||||||
|
AstNode* passsp = nodep->passsp(); if (passsp) passsp->unlinkFrBackWithNext();
|
||||||
|
AstNode* failsp = nodep->failsp(); if (failsp) failsp->unlinkFrBackWithNext();
|
||||||
|
//
|
||||||
|
if (nodep->castVAssert()) {
|
||||||
|
if (passsp) passsp = newIfAssertOn(passsp);
|
||||||
|
if (failsp) failsp = newIfAssertOn(failsp);
|
||||||
|
} else {
|
||||||
|
nodep->v3fatalSrc("Unknown node type");
|
||||||
|
}
|
||||||
|
|
||||||
|
AstIf* ifp = new AstIf (nodep->fileline(), propp, passsp, failsp);
|
||||||
|
AstNode* newp = ifp;
|
||||||
|
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::UNLIKELY);
|
||||||
|
//
|
||||||
|
// Install it
|
||||||
|
nodep->replaceWith(newp);
|
||||||
|
// Bye
|
||||||
|
pushDeletep(nodep); nodep=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// VISITORS //========== Case assertions
|
// VISITORS //========== Case assertions
|
||||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
@@ -162,16 +215,34 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS //========== Statements
|
// VISITORS //========== Statements
|
||||||
|
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
// Replace the special types with standard text
|
||||||
|
if (nodep->displayType()==AstDisplayType::INFO) {
|
||||||
|
replaceDisplay(nodep, "-Info");
|
||||||
|
} else if (nodep->displayType()==AstDisplayType::WARNING) {
|
||||||
|
replaceDisplay(nodep, "%%Warning");
|
||||||
|
} else if (nodep->displayType()==AstDisplayType::ERROR
|
||||||
|
|| nodep->displayType()==AstDisplayType::FATAL) {
|
||||||
|
replaceDisplay(nodep, "%%Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
newAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
|
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), 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);
|
||||||
newAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
|
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
|
||||||
m_statAsPsl++;
|
m_statAsPsl++;
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
newVAssertion(nodep, nodep->propp()); nodep=NULL;
|
||||||
|
m_statAsSV++;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||||
m_modp = nodep;
|
m_modp = nodep;
|
||||||
@@ -202,6 +273,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual ~AssertVisitor() {
|
virtual ~AssertVisitor() {
|
||||||
V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl);
|
V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl);
|
||||||
|
V3Stats::addStat("Assertions, SystemVerilog asserts", m_statAsSV);
|
||||||
V3Stats::addStat("Assertions, cover statements", m_statAsCover);
|
V3Stats::addStat("Assertions, cover statements", m_statAsCover);
|
||||||
V3Stats::addStat("Assertions, full/parallel case", m_statAsFull);
|
V3Stats::addStat("Assertions, full/parallel case", m_statAsFull);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3ASSERT_H_
|
#ifndef _V3ASSERT_H_
|
||||||
#define _V3ASSERT_H_ 1
|
#define _V3ASSERT_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -22,7 +22,8 @@
|
|||||||
// Attach clocks to each assertion
|
// Attach clocks to each assertion
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3ASSERTPRE_H_
|
#ifndef _V3ASSERTPRE_H_
|
||||||
#define _V3ASSERTPRE_H_ 1
|
#define _V3ASSERTPRE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+23
-9
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
//======================================================================
|
//======================================================================
|
||||||
// Statics
|
// Statics
|
||||||
|
|
||||||
uint64_t AstNode::s_editCntGbl=0;
|
vluint64_t AstNode::s_editCntGbl=0;
|
||||||
uint64_t AstNode::s_editCntLast=0;
|
vluint64_t AstNode::s_editCntLast=0;
|
||||||
|
|
||||||
// To allow for fast clearing of all user pointers, we keep a "timestamp"
|
// To allow for fast clearing of all user pointers, we keep a "timestamp"
|
||||||
// along with each userp, and thus by bumping this count we can make it look
|
// along with each userp, and thus by bumping this count we can make it look
|
||||||
@@ -92,17 +92,29 @@ string AstNode::shortName() const {
|
|||||||
return pretty;
|
return pretty;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AstNode::prettyName(const string& namein) {
|
string AstNode::dedotName(const string& namein) {
|
||||||
string pretty = namein;
|
string pretty = namein;
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
while ((pos=pretty.find("__DOT__")) != string::npos) {
|
while ((pos=pretty.find("__DOT__")) != string::npos) {
|
||||||
pretty.replace(pos, 7, ".");
|
pretty.replace(pos, 7, ".");
|
||||||
}
|
}
|
||||||
|
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||||
|
return pretty;
|
||||||
|
}
|
||||||
|
|
||||||
|
string AstNode::prettyName(const string& namein) {
|
||||||
|
string pretty = namein;
|
||||||
|
string::size_type pos;
|
||||||
|
while ((pos=pretty.find("__BRA__")) != string::npos) {
|
||||||
|
pretty.replace(pos, 7, "[");
|
||||||
|
}
|
||||||
|
while ((pos=pretty.find("__KET__")) != string::npos) {
|
||||||
|
pretty.replace(pos, 7, "]");
|
||||||
|
}
|
||||||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
||||||
pretty.replace(pos, 7, "");
|
pretty.replace(pos, 7, "");
|
||||||
}
|
}
|
||||||
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
return AstNode::dedotName(pretty);
|
||||||
return pretty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AstNode::widthPow2() const {
|
int AstNode::widthPow2() const {
|
||||||
@@ -777,21 +789,23 @@ void AstNode::dumpTreeFile(const string& filename, bool append) {
|
|||||||
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
|
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
|
||||||
*logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">";
|
*logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">";
|
||||||
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
|
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
|
||||||
if (editCountGbl()==editCountLast() && 0) { // Off, as messes up tree diffing
|
if (editCountGbl()==editCountLast() && 1) { // Off, as messes up tree diffing
|
||||||
*logsp<<endl;
|
*logsp<<endl;
|
||||||
*logsp<<"No changes since last dump!\n";
|
*logsp<<"No changes since last dump!\n";
|
||||||
} else {
|
} else {
|
||||||
dumpTree(*logsp);
|
dumpTree(*logsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (v3Global.opt.debugCheck() || v3Global.opt.dumpTree()) {
|
||||||
// Error check
|
// Error check
|
||||||
checkTree();
|
checkTree();
|
||||||
// Broken isn't part of check tree because it can munge iterp's
|
// Broken isn't part of check tree because it can munge iterp's
|
||||||
// set by other steps if it is called in the middle of other operations
|
// set by other steps if it is called in the middle of other operations
|
||||||
if (AstNetlist* netp=this->castNetlist()) V3Broken::brokenAll(netp);
|
if (AstNetlist* netp=this->castNetlist()) V3Broken::brokenAll(netp);
|
||||||
// Next dump can indicate start from here
|
|
||||||
editCountSetLast();
|
|
||||||
}
|
}
|
||||||
|
// Next dump can indicate start from here
|
||||||
|
editCountSetLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstNode::v3errorEnd(ostringstream& str) {
|
void AstNode::v3errorEnd(ostringstream& str) {
|
||||||
|
|||||||
+80
-14
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3AST_H_
|
#ifndef _V3AST_H_
|
||||||
#define _V3AST_H_ 1
|
#define _V3AST_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Number.h"
|
#include "V3Number.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -57,6 +58,7 @@ public:
|
|||||||
COVERAGE_BLOCK_OFF,
|
COVERAGE_BLOCK_OFF,
|
||||||
INLINE_MODULE,
|
INLINE_MODULE,
|
||||||
NO_INLINE_MODULE,
|
NO_INLINE_MODULE,
|
||||||
|
NO_INLINE_TASK,
|
||||||
PUBLIC_MODULE,
|
PUBLIC_MODULE,
|
||||||
PUBLIC_TASK
|
PUBLIC_TASK
|
||||||
};
|
};
|
||||||
@@ -246,6 +248,61 @@ public:
|
|||||||
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
|
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
|
||||||
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
|
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
|
class AstDisplayType {
|
||||||
|
public:
|
||||||
|
enum en {
|
||||||
|
DISPLAY,
|
||||||
|
WRITE,
|
||||||
|
INFO,
|
||||||
|
ERROR,
|
||||||
|
WARNING,
|
||||||
|
FATAL
|
||||||
|
};
|
||||||
|
enum en m_e;
|
||||||
|
inline AstDisplayType () {};
|
||||||
|
inline AstDisplayType (en _e) : m_e(_e) {};
|
||||||
|
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {};
|
||||||
|
operator en () const { return m_e; };
|
||||||
|
bool addNewline() const { return m_e!=WRITE; }
|
||||||
|
bool needScopeTracking() const { return m_e!=DISPLAY && m_e!=WRITE; }
|
||||||
|
const char* ascii() const {
|
||||||
|
static const char* names[] = {
|
||||||
|
"display","write","info","error","warning","fatal"};
|
||||||
|
return names[m_e];};
|
||||||
|
};
|
||||||
|
inline bool operator== (AstDisplayType lhs, AstDisplayType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
|
inline bool operator== (AstDisplayType lhs, AstDisplayType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
inline bool operator== (AstDisplayType::en lhs, AstDisplayType rhs) { return (lhs == rhs.m_e); }
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
|
class AstParseRefExp {
|
||||||
|
public:
|
||||||
|
enum en {
|
||||||
|
NONE, // Used in V3LinkParse only
|
||||||
|
VAR_MEM,
|
||||||
|
VAR_ANY,
|
||||||
|
TASK,
|
||||||
|
FUNC,
|
||||||
|
_ENUM_END
|
||||||
|
};
|
||||||
|
enum en m_e;
|
||||||
|
inline AstParseRefExp() : m_e(NONE) {};
|
||||||
|
inline AstParseRefExp (en _e) : m_e(_e) {};
|
||||||
|
explicit inline AstParseRefExp (int _e) : m_e(static_cast<en>(_e)) {};
|
||||||
|
operator en () const { return m_e; };
|
||||||
|
const char* ascii() const {
|
||||||
|
static const char* names[] = {
|
||||||
|
"","VAR_MEM","VAR_ANY","TASK","FUNC"};
|
||||||
|
return names[m_e];};
|
||||||
|
};
|
||||||
|
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
|
inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); }
|
||||||
|
inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<<rhs.ascii(); }
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// AstNUser - Generic pointer base class for AST User nodes.
|
// AstNUser - Generic pointer base class for AST User nodes.
|
||||||
// - Also used to allow parameter passing up/down iterate calls
|
// - Also used to allow parameter passing up/down iterate calls
|
||||||
@@ -391,9 +448,9 @@ private:
|
|||||||
static int s_cloneCntGbl; // Count of which userp is set
|
static int s_cloneCntGbl; // Count of which userp is set
|
||||||
|
|
||||||
FileLine* m_fileline; // Where it was declared
|
FileLine* m_fileline; // Where it was declared
|
||||||
uint64_t m_editCount; // When it was last edited
|
vluint64_t m_editCount; // When it was last edited
|
||||||
static uint64_t s_editCntGbl;// Global edit counter
|
static vluint64_t s_editCntGbl; // Global edit counter
|
||||||
static uint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s
|
static vluint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
bool m_signed; // Node is signed
|
bool m_signed; // Node is signed
|
||||||
@@ -476,6 +533,7 @@ public:
|
|||||||
AstNode* op3p() const { return m_op3p; }
|
AstNode* op3p() const { return m_op3p; }
|
||||||
AstNode* op4p() const { return m_op4p; }
|
AstNode* op4p() const { return m_op4p; }
|
||||||
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); }
|
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); }
|
||||||
|
AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list
|
||||||
bool brokeExists() const;
|
bool brokeExists() const;
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
@@ -494,6 +552,7 @@ public:
|
|||||||
virtual string name() const { return ""; }
|
virtual string name() const { return ""; }
|
||||||
virtual string verilogKwd() const { return ""; }
|
virtual string verilogKwd() const { return ""; }
|
||||||
string shortName() const; // Name with __PVT__ removed for concatenating scopes
|
string shortName() const; // Name with __PVT__ removed for concatenating scopes
|
||||||
|
static string dedotName(const string& namein); // Name with dots removed
|
||||||
static string prettyName(const string& namein); // Name for printing out to the user
|
static string prettyName(const string& namein); // Name for printing out to the user
|
||||||
string prettyName() const { return prettyName(name()); }
|
string prettyName() const { return prettyName(name()); }
|
||||||
FileLine* fileline() const { return m_fileline; }
|
FileLine* fileline() const { return m_fileline; }
|
||||||
@@ -539,10 +598,10 @@ public:
|
|||||||
void user5(int val) { user5p(AstNUser::fromInt(val)); }
|
void user5(int val) { user5p(AstNUser::fromInt(val)); }
|
||||||
static void user5ClearTree() { s_user5CntGbl++; } // Clear userp()'s across the entire tree
|
static void user5ClearTree() { s_user5CntGbl++; } // Clear userp()'s across the entire tree
|
||||||
|
|
||||||
uint64_t editCount() const { return m_editCount; }
|
vluint64_t editCount() const { return m_editCount; }
|
||||||
void editCountInc() { m_editCount = s_editCntGbl++; }
|
void editCountInc() { m_editCount = s_editCntGbl++; }
|
||||||
static uint64_t editCountLast() { return s_editCntLast; }
|
static vluint64_t editCountLast() { return s_editCntLast; }
|
||||||
static uint64_t editCountGbl() { return s_editCntGbl; }
|
static vluint64_t editCountGbl() { return s_editCntGbl; }
|
||||||
static void editCountSetLast() { s_editCntLast = editCountGbl(); }
|
static void editCountSetLast() { s_editCntLast = editCountGbl(); }
|
||||||
|
|
||||||
// ACCESSORS for specific types
|
// ACCESSORS for specific types
|
||||||
@@ -585,6 +644,7 @@ public:
|
|||||||
virtual int instrCount() const { return 0; }
|
virtual int instrCount() const { return 0; }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it
|
virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it
|
||||||
virtual bool same(AstNode* otherp) const { return true; }
|
virtual bool same(AstNode* otherp) const { return true; }
|
||||||
|
virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc.
|
||||||
virtual bool broken() const { return false; }
|
virtual bool broken() const { return false; }
|
||||||
virtual bool emitWordForm() { return false; }
|
virtual bool emitWordForm() { return false; }
|
||||||
|
|
||||||
@@ -874,6 +934,7 @@ public:
|
|||||||
virtual ~AstNodePli() {}
|
virtual ~AstNodePli() {}
|
||||||
virtual string name() const { return m_text; }
|
virtual string name() const { return m_text; }
|
||||||
virtual int instrCount() const { return instrCountPli(); }
|
virtual int instrCount() const { return instrCountPli(); }
|
||||||
|
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
||||||
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
|
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
|
||||||
string text() const { return m_text; } // * = Text to display
|
string text() const { return m_text; } // * = Text to display
|
||||||
void text(const string& text) { m_text=text; }
|
void text(const string& text) { m_text=text; }
|
||||||
@@ -922,6 +983,7 @@ public:
|
|||||||
virtual ~AstNodeFTask() {}
|
virtual ~AstNodeFTask() {}
|
||||||
virtual void dump(ostream& str=cout);
|
virtual void dump(ostream& str=cout);
|
||||||
virtual string name() const { return m_name; } // * = Var name
|
virtual string name() const { return m_name; } // * = Var name
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
// {AstFunc only} op1 = Range output variable
|
// {AstFunc only} op1 = Range output variable
|
||||||
// op3 = Statements/Ports/Vars
|
// op3 = Statements/Ports/Vars
|
||||||
void name(const string& name) { m_name = name; }
|
void name(const string& name) { m_name = name; }
|
||||||
@@ -939,10 +1001,10 @@ private:
|
|||||||
string m_dotted; // Dotted part of scope to task or ""
|
string m_dotted; // Dotted part of scope to task or ""
|
||||||
string m_inlinedDots; // Dotted hiearchy flattened out
|
string m_inlinedDots; // Dotted hiearchy flattened out
|
||||||
public:
|
public:
|
||||||
AstNodeFTaskRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp)
|
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
|
||||||
:AstNode(fl)
|
:AstNode(fl)
|
||||||
, m_taskp(NULL), m_name(name), m_dotted(dotted) {
|
, m_taskp(NULL) {
|
||||||
addNOp1p(pinsp);
|
setOp1p(namep); addNOp2p(pinsp);
|
||||||
}
|
}
|
||||||
virtual ~AstNodeFTaskRef() {}
|
virtual ~AstNodeFTaskRef() {}
|
||||||
virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); }
|
virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); }
|
||||||
@@ -957,9 +1019,13 @@ public:
|
|||||||
void inlinedDots(const string& flag) { m_inlinedDots = flag; }
|
void inlinedDots(const string& flag) { m_inlinedDots = flag; }
|
||||||
AstNodeFTask* taskp() const { return m_taskp; } // [After Link] Pointer to variable
|
AstNodeFTask* taskp() const { return m_taskp; } // [After Link] Pointer to variable
|
||||||
void taskp(AstNodeFTask* taskp) { m_taskp=taskp; }
|
void taskp(AstNodeFTask* taskp) { m_taskp=taskp; }
|
||||||
// op1 = Pin interconnection list
|
void name(const string& name) { m_name = name; }
|
||||||
AstNode* pinsp() const { return op1p()->castNode(); }
|
void dotted(const string& name) { m_dotted = name; }
|
||||||
void addPinsp(AstNode* nodep) { addOp1p(nodep); }
|
// op1 = namep
|
||||||
|
AstNode* namep() const { return op1p(); }
|
||||||
|
// op2 = Pin interconnection list
|
||||||
|
AstNode* pinsp() const { return op2p()->castNode(); }
|
||||||
|
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|||||||
+34
-8
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -85,7 +87,7 @@ int AstVar::widthTotalBytes() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string AstVar::verilogKwd() const {
|
string AstVar::verilogKwd() const {
|
||||||
if (isTristate()) {
|
if (isInout()) {
|
||||||
return "inout";
|
return "inout";
|
||||||
} else if (isInput()) {
|
} else if (isInput()) {
|
||||||
return "input";
|
return "input";
|
||||||
@@ -93,6 +95,8 @@ string AstVar::verilogKwd() const {
|
|||||||
return "output";
|
return "output";
|
||||||
} else if (isInteger()) {
|
} else if (isInteger()) {
|
||||||
return "integer";
|
return "integer";
|
||||||
|
} else if (isTristate()) {
|
||||||
|
return "tri";
|
||||||
} else if (varType()==AstVarType::WIRE) {
|
} else if (varType()==AstVarType::WIRE) {
|
||||||
return "wire";
|
return "wire";
|
||||||
} else {
|
} else {
|
||||||
@@ -101,6 +105,18 @@ string AstVar::verilogKwd() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string AstVar::cType() const {
|
string AstVar::cType() const {
|
||||||
|
if (widthMin() == 1) {
|
||||||
|
return "bool";
|
||||||
|
} else if (widthMin() <= VL_WORDSIZE) {
|
||||||
|
return "uint32_t";
|
||||||
|
} else if (isScWide()) {
|
||||||
|
return "uint32_t"; // []'s added later
|
||||||
|
} else {
|
||||||
|
return "uint64_t";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string AstVar::scType() const {
|
||||||
if (widthMin() == 1) {
|
if (widthMin() == 1) {
|
||||||
return "bool";
|
return "bool";
|
||||||
} else if (widthMin() <= VL_WORDSIZE) {
|
} else if (widthMin() <= VL_WORDSIZE) {
|
||||||
@@ -130,7 +146,7 @@ uint32_t AstVar::arrayElements() const {
|
|||||||
bool AstScope::broken() const {
|
bool AstScope::broken() const {
|
||||||
return ((m_aboveScopep && !m_aboveScopep->brokeExists())
|
return ((m_aboveScopep && !m_aboveScopep->brokeExists())
|
||||||
|| (m_aboveCellp && !m_aboveCellp->brokeExists())
|
|| (m_aboveCellp && !m_aboveCellp->brokeExists())
|
||||||
|| !m_modp || !((AstNode*)m_modp)->brokeExists());
|
|| !m_modp || !m_modp->brokeExists());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstScope::cloneRelink() {
|
void AstScope::cloneRelink() {
|
||||||
@@ -325,14 +341,19 @@ void AstVarRef::dump(ostream& str) {
|
|||||||
void AstVar::dump(ostream& str) {
|
void AstVar::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
if (isSc()) str<<" [SC]";
|
if (isSc()) str<<" [SC]";
|
||||||
if (isInput()) str<<" [I]";
|
if (isPrimaryIO()) str<<(isInout()?" [PIO]":(isInput()?" [PI]":" [PO]"));
|
||||||
if (isPrimaryIO()) str<<(isInput()?" [PI]":" [PO]");
|
else {
|
||||||
if (isOutput()) str<<" [O]";
|
if (isInout()) str<<" [IO]";
|
||||||
|
else if (isInput()) str<<" [I]";
|
||||||
|
else if (isOutput()) str<<" [O]";
|
||||||
|
}
|
||||||
if (isUsedClock()) str<<" [C]";
|
if (isUsedClock()) str<<" [C]";
|
||||||
if (isSigPublic()) str<<" [P]";
|
if (isSigPublic()) str<<" [P]";
|
||||||
if (attrClockEn()) str<<" [aCLKEN]";
|
if (attrClockEn()) str<<" [aCLKEN]";
|
||||||
|
if (attrIsolateAssign()) str<<" [aISO]";
|
||||||
if (attrFileDescr()) str<<" [aFD]";
|
if (attrFileDescr()) str<<" [aFD]";
|
||||||
if (isFuncLocal() || isFuncReturn()) str<<" [FUNC]";
|
if (isFuncReturn()) str<<" [FUNCRTN]";
|
||||||
|
else if (isFuncLocal()) str<<" [FUNC]";
|
||||||
str<<" "<<varType();
|
str<<" "<<varType();
|
||||||
}
|
}
|
||||||
void AstSenTree::dump(ostream& str) {
|
void AstSenTree::dump(ostream& str) {
|
||||||
@@ -341,7 +362,11 @@ void AstSenTree::dump(ostream& str) {
|
|||||||
}
|
}
|
||||||
void AstSenItem::dump(ostream& str) {
|
void AstSenItem::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
str<<" ["<<m_edgeType.ascii()<<"]";
|
str<<" ["<<edgeType().ascii()<<"]";
|
||||||
|
}
|
||||||
|
void AstParseRef::dump(ostream& str) {
|
||||||
|
this->AstNode::dump(str);
|
||||||
|
str<<" ["<<expect().ascii()<<"]";
|
||||||
}
|
}
|
||||||
void AstActive::dump(ostream& str) {
|
void AstActive::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
@@ -358,6 +383,7 @@ void AstNodeFTaskRef::dump(ostream& str) {
|
|||||||
}
|
}
|
||||||
void AstNodeFTask::dump(ostream& str) {
|
void AstNodeFTask::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
|
if (taskPublic()) str<<" [PUBLIC]";
|
||||||
}
|
}
|
||||||
void AstCoverDecl::dump(ostream& str) {
|
void AstCoverDecl::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
|
|||||||
+165
-26
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -236,11 +236,13 @@ private:
|
|||||||
bool m_scClocked:1; // SystemC sc_clk<> needed
|
bool m_scClocked:1; // SystemC sc_clk<> needed
|
||||||
bool m_scSensitive:1;// SystemC sensitive() needed
|
bool m_scSensitive:1;// SystemC sensitive() needed
|
||||||
bool m_sigPublic:1; // User C code accesses this signal
|
bool m_sigPublic:1; // User C code accesses this signal
|
||||||
|
bool m_sigModPublic:1;// User C code accesses this signal and module
|
||||||
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_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_attrIsolateAssign:1;// User isolate_assignments attribute
|
||||||
bool m_fileDescr:1; // File descriptor
|
bool m_fileDescr:1; // File descriptor
|
||||||
bool m_isConst:1; // Table contains constant data
|
bool m_isConst:1; // Table contains constant data
|
||||||
bool m_isStatic:1; // Static variable
|
bool m_isStatic:1; // Static variable
|
||||||
@@ -251,8 +253,10 @@ private:
|
|||||||
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_sigPublic=false; m_funcLocal=false; m_funcReturn=false;
|
m_sigPublic=false; m_sigModPublic=false;
|
||||||
m_attrClockEn=false; m_fileDescr=false; m_isConst=false; m_isStatic=false;
|
m_funcLocal=false; m_funcReturn=false;
|
||||||
|
m_attrClockEn=false; m_attrIsolateAssign=false;
|
||||||
|
m_fileDescr=false; m_isConst=false; m_isStatic=false;
|
||||||
m_trace=false;
|
m_trace=false;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@@ -286,8 +290,10 @@ public:
|
|||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
virtual string name() const { return m_name; } // * = Var name
|
virtual string name() const { return m_name; } // * = Var name
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
AstVarType varType() const { return m_varType; } // * = Type of variable
|
AstVarType varType() const { return m_varType; } // * = Type of variable
|
||||||
string cType() const; // Return C type: bool, uint32_t, uint64_t, etc.
|
string cType() const; // Return C type for declaration: bool, uint32_t, uint64_t, etc.
|
||||||
|
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
|
||||||
void combineType(AstVarType type);
|
void combineType(AstVarType type);
|
||||||
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
|
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
|
||||||
AstRange* arraysp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
AstRange* arraysp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
||||||
@@ -299,9 +305,11 @@ 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 attrIsolateAssign(bool flag) { m_attrIsolateAssign = 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 sigPublic(bool flag) { m_sigPublic = flag; }
|
void sigPublic(bool flag) { m_sigPublic = flag; }
|
||||||
|
void sigModPublic(bool flag) { m_sigModPublic = flag; }
|
||||||
void sc(bool flag) { m_sc = flag; }
|
void sc(bool flag) { m_sc = flag; }
|
||||||
void scSensitive(bool flag) { m_scSensitive = flag; }
|
void scSensitive(bool flag) { m_scSensitive = flag; }
|
||||||
void primaryIO(bool flag) { m_primaryIO = flag; }
|
void primaryIO(bool flag) { m_primaryIO = flag; }
|
||||||
@@ -314,10 +322,13 @@ public:
|
|||||||
void name(const string& name) { m_name = name; }
|
void name(const string& name) { m_name = name; }
|
||||||
bool isInput() const { return m_input; }
|
bool isInput() const { return m_input; }
|
||||||
bool isOutput() const { return m_output; }
|
bool isOutput() const { return m_output; }
|
||||||
bool isTristate() const { return (m_tristate); }
|
bool isInOnly() const { return m_input && !m_output; }
|
||||||
|
bool isOutOnly() const { return m_output && !m_input; }
|
||||||
|
bool isInout() const { return m_input && m_output; }
|
||||||
|
bool isTristate() const { return m_tristate; }
|
||||||
bool isPrimaryIO() const { return m_primaryIO; }
|
bool isPrimaryIO() const { return m_primaryIO; }
|
||||||
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
|
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
|
||||||
bool isIO() const { return (m_input||m_output||m_tristate); }
|
bool isIO() const { return (m_input||m_output); }
|
||||||
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|
||||||
|| varType()==AstVarType::REG || varType()==AstVarType::INTEGER); }
|
|| varType()==AstVarType::REG || varType()==AstVarType::INTEGER); }
|
||||||
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|
||||||
@@ -335,6 +346,7 @@ public:
|
|||||||
bool isScWide() const;
|
bool isScWide() const;
|
||||||
bool isScSensitive() const { return m_scSensitive; }
|
bool isScSensitive() const { return m_scSensitive; }
|
||||||
bool isSigPublic() const;
|
bool isSigPublic() const;
|
||||||
|
bool isSigModPublic() const { return m_sigModPublic; }
|
||||||
bool isTrace() const { return m_trace; }
|
bool isTrace() const { return m_trace; }
|
||||||
bool isConst() const { return m_isConst; }
|
bool isConst() const { return m_isConst; }
|
||||||
bool isStatic() const { return m_isStatic; }
|
bool isStatic() const { return m_isStatic; }
|
||||||
@@ -343,6 +355,7 @@ public:
|
|||||||
bool attrClockEn() const { return m_attrClockEn; }
|
bool attrClockEn() const { return m_attrClockEn; }
|
||||||
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 attrIsolateAssign() const { return m_attrIsolateAssign; }
|
||||||
int widthAlignBytes() const; // Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
int widthAlignBytes() const; // Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||||
int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,...
|
int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,...
|
||||||
uint32_t msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
uint32_t msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
||||||
@@ -354,6 +367,7 @@ public:
|
|||||||
// Note the method below too
|
// Note the method below too
|
||||||
if (fromp->attrClockEn()) attrClockEn(true);
|
if (fromp->attrClockEn()) attrClockEn(true);
|
||||||
if (fromp->attrFileDescr()) attrFileDescr(true);
|
if (fromp->attrFileDescr()) attrFileDescr(true);
|
||||||
|
if (fromp->attrIsolateAssign()) attrIsolateAssign(true);
|
||||||
}
|
}
|
||||||
bool gateMultiInputOptimizable() const {
|
bool gateMultiInputOptimizable() const {
|
||||||
// Ok to gate optimize; must return false if propagateAttrFrom would do anything
|
// Ok to gate optimize; must return false if propagateAttrFrom would do anything
|
||||||
@@ -364,6 +378,7 @@ public:
|
|||||||
propagateAttrFrom(typevarp);
|
propagateAttrFrom(typevarp);
|
||||||
combineType(typevarp->varType());
|
combineType(typevarp->varType());
|
||||||
if (typevarp->isSigPublic()) sigPublic(true);
|
if (typevarp->isSigPublic()) sigPublic(true);
|
||||||
|
if (typevarp->isSigModPublic()) sigModPublic(true);
|
||||||
if (typevarp->attrScClocked()) attrScClocked(true);
|
if (typevarp->attrScClocked()) attrScClocked(true);
|
||||||
}
|
}
|
||||||
void inlineAttrReset(const string& name) {
|
void inlineAttrReset(const string& name) {
|
||||||
@@ -419,6 +434,7 @@ public:
|
|||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual void cloneRelink();
|
virtual void cloneRelink();
|
||||||
virtual bool broken() const;
|
virtual bool broken() const;
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
virtual string name() const { return m_name; } // * = Scope name
|
virtual string name() const { return m_name; } // * = Scope name
|
||||||
void name(const string& name) { m_name = name; }
|
void name(const string& name) { m_name = name; }
|
||||||
string nameDotless() const;
|
string nameDotless() const;
|
||||||
@@ -480,6 +496,7 @@ public:
|
|||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual bool broken() const { return ( (m_varp && !m_varp->brokeExists())
|
virtual bool broken() const { return ( (m_varp && !m_varp->brokeExists())
|
||||||
|| (m_scopep && !m_scopep->brokeExists())); }
|
|| (m_scopep && !m_scopep->brokeExists())); }
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
virtual string name() const {return scopep()->name()+"->"+varp()->name();} // * = Var name
|
virtual string name() const {return scopep()->name()+"->"+varp()->name();} // * = Var name
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
|
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
|
||||||
@@ -604,6 +621,7 @@ public:
|
|||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
virtual bool broken() const { return (m_clkReqVarp && !m_clkReqVarp->brokeExists()); }
|
virtual bool broken() const { return (m_clkReqVarp && !m_clkReqVarp->brokeExists()); }
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
virtual string name() const { return m_name; }
|
virtual string name() const { return m_name; }
|
||||||
AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements
|
AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements
|
||||||
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
|
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
|
||||||
@@ -648,6 +666,7 @@ public:
|
|||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
virtual bool broken() const { return (m_modp && !m_modp->brokeExists()); }
|
virtual bool broken() const { return (m_modp && !m_modp->brokeExists()); }
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
virtual string name() const { return m_name; } // * = Cell name
|
virtual string name() const { return m_name; } // * = Cell name
|
||||||
void name(const string& name) { m_name = name; }
|
void name(const string& name) { m_name = name; }
|
||||||
@@ -747,6 +766,46 @@ struct AstGenerate : public AstNode {
|
|||||||
void addStmtp(AstNode* nodep) { addOp1p(nodep); }
|
void addStmtp(AstNode* nodep) { addOp1p(nodep); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstParseRef : public AstNode {
|
||||||
|
// A reference to a variable, function or task
|
||||||
|
// We don't know which at parse time due to bison constraints
|
||||||
|
// The link stages will replace this with AstVarRef, or AstTaskRef, etc.
|
||||||
|
// Parents: math|stmt
|
||||||
|
// Children: TEXT|DOT|SEL* (or expression under sel)
|
||||||
|
private:
|
||||||
|
AstParseRefExp m_expect; // Type we think it should resolve to
|
||||||
|
public:
|
||||||
|
AstParseRef(FileLine* fl, AstParseRefExp expect, AstNode* lhsp)
|
||||||
|
:AstNode(fl), m_expect(expect) { setOp1p(lhsp); }
|
||||||
|
virtual ~AstParseRef() {}
|
||||||
|
virtual AstType type() const { return AstType::PARSEREF;}
|
||||||
|
virtual AstNode* clone() { return new AstParseRef(*this);}
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual void dump(ostream& str);
|
||||||
|
virtual V3Hash sameHash() const { return V3Hash(m_expect); }
|
||||||
|
virtual bool same(AstNode* samep) const { return expect() == samep->castParseRef()->expect(); }
|
||||||
|
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||||
|
AstParseRefExp expect() const { return m_expect; }
|
||||||
|
// op1 = Components
|
||||||
|
AstNode* lhsp() const { return op1p(); } // op1 = List of statements
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AstDot : public AstNode {
|
||||||
|
// A dot separating paths in a AstXRef, AstFuncRef or AstTaskRef
|
||||||
|
// These are elimiated in the link stage
|
||||||
|
AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
||||||
|
:AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); }
|
||||||
|
virtual ~AstDot() {}
|
||||||
|
virtual AstType type() const { return AstType::DOT;}
|
||||||
|
virtual AstNode* clone() { return new AstDot(*this);}
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||||
|
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||||
|
AstNode* lhsp() const { return op1p(); }
|
||||||
|
AstNode* rhsp() const { return op2p(); }
|
||||||
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
struct AstTask : public AstNodeFTask {
|
struct AstTask : public AstNodeFTask {
|
||||||
@@ -760,10 +819,13 @@ struct AstTask : public AstNodeFTask {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AstFunc : public AstNodeFTask {
|
struct AstFunc : public AstNodeFTask {
|
||||||
|
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
|
||||||
|
public:
|
||||||
// A function inside a module
|
// A function inside a module
|
||||||
AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
|
AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
|
||||||
:AstNodeFTask(fl, name, stmtp) {
|
:AstNodeFTask(fl, name, stmtp) {
|
||||||
addNOp1p(fvarsp);
|
addNOp1p(fvarsp);
|
||||||
|
m_attrIsolateAssign = false;
|
||||||
}
|
}
|
||||||
virtual ~AstFunc() {}
|
virtual ~AstFunc() {}
|
||||||
virtual AstType type() const { return AstType::FUNC;}
|
virtual AstType type() const { return AstType::FUNC;}
|
||||||
@@ -772,12 +834,14 @@ struct AstFunc : public AstNodeFTask {
|
|||||||
// op1 = Range output variable (functions only)
|
// op1 = Range output variable (functions only)
|
||||||
AstNode* fvarp() const { return op1p()->castNode(); }
|
AstNode* fvarp() const { return op1p()->castNode(); }
|
||||||
void addFvarp(AstNode* nodep) { addOp1p(nodep); }
|
void addFvarp(AstNode* nodep) { addOp1p(nodep); }
|
||||||
|
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
||||||
|
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstTaskRef : public AstNodeFTaskRef {
|
struct AstTaskRef : public AstNodeFTaskRef {
|
||||||
// A reference to a task
|
// A reference to a task
|
||||||
AstTaskRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp)
|
AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
|
||||||
:AstNodeFTaskRef(fl, name, dotted, pinsp) {}
|
:AstNodeFTaskRef(fl, namep, pinsp) {}
|
||||||
virtual ~AstTaskRef() {}
|
virtual ~AstTaskRef() {}
|
||||||
virtual AstType type() const { return AstType::TASKREF;}
|
virtual AstType type() const { return AstType::TASKREF;}
|
||||||
virtual AstNode* clone() { return new AstTaskRef(*this);}
|
virtual AstNode* clone() { return new AstTaskRef(*this);}
|
||||||
@@ -786,8 +850,8 @@ struct AstTaskRef : public AstNodeFTaskRef {
|
|||||||
|
|
||||||
struct AstFuncRef : public AstNodeFTaskRef {
|
struct AstFuncRef : public AstNodeFTaskRef {
|
||||||
// A reference to a function
|
// A reference to a function
|
||||||
AstFuncRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp)
|
AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
|
||||||
:AstNodeFTaskRef(fl, name, dotted, pinsp) {}
|
:AstNodeFTaskRef(fl, namep, pinsp) {}
|
||||||
virtual ~AstFuncRef() {}
|
virtual ~AstFuncRef() {}
|
||||||
virtual AstType type() const { return AstType::FUNCREF;}
|
virtual AstType type() const { return AstType::FUNCREF;}
|
||||||
virtual AstNode* clone() { return new AstFuncRef(*this);}
|
virtual AstNode* clone() { return new AstFuncRef(*this);}
|
||||||
@@ -806,9 +870,12 @@ public:
|
|||||||
class Initial {}; // for creator type-overload selection
|
class Initial {}; // for creator type-overload selection
|
||||||
class Settle {}; // for creator type-overload selection
|
class Settle {}; // for creator type-overload selection
|
||||||
class Never {}; // for creator type-overload selection
|
class Never {}; // for creator type-overload selection
|
||||||
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstVarRef* varrefp)
|
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNodeVarRef* varrefp)
|
||||||
: AstNode(fl) {
|
: AstNode(fl), m_edgeType(edgeType) {
|
||||||
m_edgeType = edgeType;
|
setOp1p(varrefp);
|
||||||
|
}
|
||||||
|
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstParseRef* varrefp)
|
||||||
|
: AstNode(fl), m_edgeType(edgeType) {
|
||||||
setOp1p(varrefp);
|
setOp1p(varrefp);
|
||||||
}
|
}
|
||||||
AstSenItem(FileLine* fl, Combo)
|
AstSenItem(FileLine* fl, Combo)
|
||||||
@@ -839,7 +906,7 @@ public:
|
|||||||
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
|
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
|
||||||
void edgeType(AstEdgeType type) { m_edgeType=type; editCountInc(); }// * = Posedge/negedge
|
void edgeType(AstEdgeType type) { m_edgeType=type; editCountInc(); }// * = Posedge/negedge
|
||||||
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
|
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
|
||||||
AstVarRef* varrefp() const { return op1p()->castVarRef(); } // op1 = Signal sensitized
|
AstNodeVarRef* varrefp() const { return op1p()->castNodeVarRef(); } // op1 = Signal sensitized
|
||||||
//
|
//
|
||||||
bool isClocked() const { return edgeType().clockedStmt(); }
|
bool isClocked() const { return edgeType().clockedStmt(); }
|
||||||
bool isCombo() const { return edgeType()==AstEdgeType::COMBO; }
|
bool isCombo() const { return edgeType()==AstEdgeType::COMBO; }
|
||||||
@@ -865,6 +932,7 @@ public:
|
|||||||
virtual AstNode* clone() { return new AstSenTree(*this); }
|
virtual AstNode* clone() { return new AstSenTree(*this); }
|
||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
bool isMulti() const { return m_multi; }
|
bool isMulti() const { return m_multi; }
|
||||||
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
|
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
|
||||||
void addSensesp(AstSenItem* nodep) { addOp1p(nodep); }
|
void addSensesp(AstSenItem* nodep) { addOp1p(nodep); }
|
||||||
@@ -1050,6 +1118,7 @@ public:
|
|||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual void dump(ostream& str);
|
virtual void dump(ostream& str);
|
||||||
virtual int instrCount() const { return 1+2*instrCountLd(); }
|
virtual int instrCount() const { return 1+2*instrCountLd(); }
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
int column() const { return m_column; }
|
int column() const { return m_column; }
|
||||||
const string& comment() const { return m_text; } // text to insert in code
|
const string& comment() const { return m_text; } // text to insert in code
|
||||||
const string& typeText() const { return m_typeText; }
|
const string& typeText() const { return m_typeText; }
|
||||||
@@ -1156,6 +1225,7 @@ public:
|
|||||||
virtual int instrCount() const { return widthInstrs()+instrCountBranch(); }
|
virtual int instrCount() const { return widthInstrs()+instrCountBranch(); }
|
||||||
AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions
|
AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions
|
||||||
AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do
|
AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do
|
||||||
|
void condsp(AstNode* nodep) { setOp1p(nodep); }
|
||||||
void addBodysp(AstNode* newp) { addOp2p(newp); }
|
void addBodysp(AstNode* newp) { addOp2p(newp); }
|
||||||
bool isDefault() const { return condsp()==NULL; }
|
bool isDefault() const { return condsp()==NULL; }
|
||||||
bool ignoreOverlap() const { return m_ignoreOverlap; }
|
bool ignoreOverlap() const { return m_ignoreOverlap; }
|
||||||
@@ -1163,20 +1233,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AstDisplay : public AstNodePli {
|
struct AstDisplay : public AstNodePli {
|
||||||
|
// Parents: stmtlist
|
||||||
|
// Children: file which must be a varref, MATH to print
|
||||||
private:
|
private:
|
||||||
char m_newline;
|
AstDisplayType m_displayType;
|
||||||
public:
|
public:
|
||||||
AstDisplay(FileLine* fileline, char newln, const string& text, AstNodeVarRef* filep, AstNode* exprsp)
|
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
|
||||||
: AstNodePli (fileline, text, exprsp) {
|
: AstNodePli (fileline, text, exprsp) {
|
||||||
setNOp2p(filep);
|
setNOp2p(filep);
|
||||||
m_newline = newln;
|
m_displayType = dispType;
|
||||||
}
|
}
|
||||||
virtual ~AstDisplay() {}
|
virtual ~AstDisplay() {}
|
||||||
virtual AstType type() const { return AstType::DISPLAY;}
|
virtual AstType type() const { return AstType::DISPLAY;}
|
||||||
virtual AstNode* clone() { return new AstDisplay(*this); }
|
virtual AstNode* clone() { return new AstDisplay(*this); }
|
||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual string verilogKwd() const { return (filep() ? ((newline() == '\n')?"$fdisplay":"$fwrite")
|
virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
|
||||||
: ((newline() == '\n')?"$display":"$write")); };
|
: (string)"$"+(string)displayType().ascii()); }
|
||||||
virtual bool isGateOptimizable() const { return false; }
|
virtual bool isGateOptimizable() const { return false; }
|
||||||
virtual bool isPredictOptimizable() const { return false; }
|
virtual bool isPredictOptimizable() const { return false; }
|
||||||
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
|
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
|
||||||
@@ -1184,19 +1256,25 @@ public:
|
|||||||
virtual bool isUnlikely() const { return true; }
|
virtual bool isUnlikely() const { return true; }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(text()); }
|
virtual V3Hash sameHash() const { return V3Hash(text()); }
|
||||||
virtual bool same(AstNode* samep) const {
|
virtual bool same(AstNode* samep) const {
|
||||||
return newline()==samep->castDisplay()->newline()
|
return displayType()==samep->castDisplay()->displayType()
|
||||||
&& text()==samep->castDisplay()->text(); }
|
&& text()==samep->castDisplay()->text(); }
|
||||||
// op1 used by AstNodePli
|
// op1 used by AstNodePli
|
||||||
char newline() const { return m_newline; } // * = Add a newline for $display
|
AstDisplayType displayType() const { return m_displayType; }
|
||||||
AstNodeVarRef* filep() const { return op2p()->castVarRef(); }
|
void displayType(AstDisplayType type) { m_displayType = type; }
|
||||||
|
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
|
||||||
|
AstNode* filep() const { return op2p(); }
|
||||||
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
||||||
AstNode* scopeAttrp() const { return op3p(); }
|
AstNode* scopeAttrp() const { return op3p(); }
|
||||||
AstText* scopeTextp() const { return op3p()->castText(); }
|
AstText* scopeTextp() const { return op3p()->castText(); }
|
||||||
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
|
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
|
||||||
|
bool needScopeTracking() { return (displayType().needScopeTracking()
|
||||||
|
|| name().find("%m") != string::npos); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstFClose : public AstNodeStmt {
|
struct AstFClose : public AstNodeStmt {
|
||||||
AstFClose(FileLine* fileline, AstNodeVarRef* filep)
|
// Parents: stmtlist
|
||||||
|
// Children: file which must be a varref
|
||||||
|
AstFClose(FileLine* fileline, AstNode* filep)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt (fileline) {
|
||||||
setNOp2p(filep);
|
setNOp2p(filep);
|
||||||
}
|
}
|
||||||
@@ -1212,7 +1290,7 @@ struct AstFClose : public AstNodeStmt {
|
|||||||
virtual bool isUnlikely() const { return true; }
|
virtual bool isUnlikely() const { return true; }
|
||||||
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; }
|
||||||
AstNodeVarRef* filep() const { return op2p()->castVarRef(); }
|
AstNode* filep() const { return op2p(); }
|
||||||
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1235,11 +1313,39 @@ struct AstFOpen : public AstNodeStmt {
|
|||||||
virtual bool isUnlikely() const { return true; }
|
virtual bool isUnlikely() const { return true; }
|
||||||
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; }
|
||||||
AstNodeVarRef* filep() const { return op1p()->castVarRef(); }
|
AstNode* filep() const { return op1p(); }
|
||||||
AstNode* filenamep() const { return op2p(); }
|
AstNode* filenamep() const { return op2p(); }
|
||||||
AstNode* modep() const { return op3p(); }
|
AstNode* modep() const { return op3p(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstReadMem : public AstNodeStmt {
|
||||||
|
private:
|
||||||
|
bool m_isHex; // readmemh, not readmemb
|
||||||
|
public:
|
||||||
|
AstReadMem(FileLine* fileline, bool hex,
|
||||||
|
AstNode* filenamep, AstNode* memp, AstNode* lsbp, AstNode* msbp)
|
||||||
|
: AstNodeStmt (fileline), m_isHex(hex) {
|
||||||
|
setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp);
|
||||||
|
}
|
||||||
|
virtual ~AstReadMem() {}
|
||||||
|
virtual AstType type() const { return AstType::READMEM;}
|
||||||
|
virtual AstNode* clone() { return new AstReadMem(*this); }
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual string verilogKwd() const { return (isHex()?"$readmemh":"$readmemb"); };
|
||||||
|
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 isHex()==samep->castReadMem()->isHex(); }
|
||||||
|
bool isHex() const { return m_isHex; }
|
||||||
|
AstNode* filenamep() const { return op1p()->castNode(); }
|
||||||
|
AstNode* memp() const { return op2p()->castNode(); }
|
||||||
|
AstNode* lsbp() const { return op3p()->castNode(); }
|
||||||
|
AstNode* msbp() const { return op4p()->castNode(); }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstGenFor : public AstNodeFor {
|
struct AstGenFor : public AstNodeFor {
|
||||||
AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
|
AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
|
||||||
AstNode* incsp, AstNode* bodysp)
|
AstNode* incsp, AstNode* bodysp)
|
||||||
@@ -1503,6 +1609,7 @@ public:
|
|||||||
virtual AstNode* clone() { return new AstTraceDecl(*this); }
|
virtual AstNode* clone() { return new AstTraceDecl(*this); }
|
||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual string name() const { return m_showname; }
|
virtual string name() const { return m_showname; }
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
string showname() const { return m_showname; } // * = Var name
|
string showname() const { return m_showname; } // * = Var name
|
||||||
virtual bool same(AstNode* samep) const { return false; }
|
virtual bool same(AstNode* samep) const { return false; }
|
||||||
// Details on what we're tracing
|
// Details on what we're tracing
|
||||||
@@ -1594,7 +1701,8 @@ public:
|
|||||||
bool hasClocked() const { return m_sensesp->hasClocked(); }
|
bool hasClocked() const { return m_sensesp->hasClocked(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstAttrOf : public AstNode {
|
struct AstAttrOf : public AstNode {
|
||||||
|
private:
|
||||||
// Return a value of a attribute, for example a LSB or array LSB of a signal
|
// Return a value of a attribute, for example a LSB or array LSB of a signal
|
||||||
AstAttrType m_attrType; // What sort of extraction
|
AstAttrType m_attrType; // What sort of extraction
|
||||||
int m_dimension; // Dimension number (0 is leftmost), for ARRAY_LSB extractions
|
int m_dimension; // Dimension number (0 is leftmost), for ARRAY_LSB extractions
|
||||||
@@ -1736,6 +1844,7 @@ struct AstRedXor : public AstNodeUniop {
|
|||||||
virtual int instrCount() const { return 1+V3Number::log2b(width()); }
|
virtual int instrCount() const { return 1+V3Number::log2b(width()); }
|
||||||
};
|
};
|
||||||
struct AstRedXnor : public AstNodeUniop {
|
struct AstRedXnor : public AstNodeUniop {
|
||||||
|
// 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); }
|
||||||
virtual ~AstRedXnor() {}
|
virtual ~AstRedXnor() {}
|
||||||
@@ -2511,6 +2620,30 @@ struct AstReplicate : public AstNodeBiop {
|
|||||||
virtual int instrCount() const { return widthInstrs()*2; }
|
virtual int instrCount() const { return widthInstrs()*2; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// SysVerilog assertions
|
||||||
|
|
||||||
|
struct AstVAssert : public AstNodeStmt {
|
||||||
|
// Verilog Assertion
|
||||||
|
// Parents: {statement list}
|
||||||
|
// Children: expression, if pass statements, if fail statements
|
||||||
|
AstVAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp)
|
||||||
|
: AstNodeStmt(fl) {
|
||||||
|
addOp1p(propp);
|
||||||
|
addNOp2p(passsp);
|
||||||
|
addNOp3p(failsp);
|
||||||
|
}
|
||||||
|
virtual ~AstVAssert() {}
|
||||||
|
virtual AstType type() const { return AstType::VASSERT;}
|
||||||
|
virtual AstNode* clone() { return new AstVAssert(*this); }
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
|
AstNode* propp() const { return op1p(); } // op1 = property
|
||||||
|
AstNode* passsp() const { return op2p(); } // op2 = if passes
|
||||||
|
AstNode* failsp() const { return op3p(); } // op3 = if fails
|
||||||
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// PSL
|
// PSL
|
||||||
|
|
||||||
@@ -2773,6 +2906,7 @@ private:
|
|||||||
bool m_funcPublic:1; // From user public task/function
|
bool m_funcPublic:1; // From user public task/function
|
||||||
bool m_isStatic:1; // Function is declared static (no this)
|
bool m_isStatic:1; // Function is declared static (no this)
|
||||||
bool m_symProlog:1; // Setup symbol table for later instructions
|
bool m_symProlog:1; // Setup symbol table for later instructions
|
||||||
|
bool m_entryPoint:1; // User may call into this top level function
|
||||||
public:
|
public:
|
||||||
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="")
|
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="")
|
||||||
: AstNode(fl) {
|
: AstNode(fl) {
|
||||||
@@ -2788,12 +2922,15 @@ public:
|
|||||||
m_funcPublic = false;
|
m_funcPublic = false;
|
||||||
m_isStatic = true; // Note defaults to static, later we see where thisp is needed
|
m_isStatic = true; // Note defaults to static, later we see where thisp is needed
|
||||||
m_symProlog = false;
|
m_symProlog = false;
|
||||||
|
m_entryPoint = false;
|
||||||
}
|
}
|
||||||
virtual ~AstCFunc() {}
|
virtual ~AstCFunc() {}
|
||||||
virtual AstType type() const { return AstType::CFUNC;}
|
virtual AstType type() const { return AstType::CFUNC;}
|
||||||
virtual AstNode* clone() { return new AstCFunc(*this); }
|
virtual AstNode* clone() { return new AstCFunc(*this); }
|
||||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
virtual string name() const { return m_name; }
|
virtual string name() const { return m_name; }
|
||||||
|
virtual bool broken() const { return ( (m_scopep && !m_scopep->brokeExists())); }
|
||||||
|
virtual bool maybePointedTo() const { return true; }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
|
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
|
||||||
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())
|
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())
|
||||||
@@ -2823,6 +2960,8 @@ public:
|
|||||||
void isStatic(bool flag) { m_isStatic = flag; }
|
void isStatic(bool flag) { m_isStatic = flag; }
|
||||||
bool symProlog() const { return m_symProlog; }
|
bool symProlog() const { return m_symProlog; }
|
||||||
void symProlog(bool flag) { m_symProlog = flag; }
|
void symProlog(bool flag) { m_symProlog = flag; }
|
||||||
|
bool entryPoint() const { return m_entryPoint; }
|
||||||
|
void entryPoint(bool flag) { m_entryPoint = flag; }
|
||||||
//
|
//
|
||||||
// If adding node accessors, see below
|
// If adding node accessors, see below
|
||||||
AstNode* argsp() const { return op1p()->castNode(); }
|
AstNode* argsp() const { return op1p()->castNode(); }
|
||||||
|
|||||||
+15
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -27,7 +27,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -130,6 +131,18 @@ private:
|
|||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||||
|
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||||
|
// Similar code in V3Inline
|
||||||
|
if (m_beginScope != "" && nodep->needScopeTracking()) {
|
||||||
|
// To keep correct visual order, must add before other Text's
|
||||||
|
AstNode* afterp = nodep->scopeAttrp();
|
||||||
|
if (afterp) afterp->unlinkFrBackWithNext();
|
||||||
|
nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"."+AstNode::prettyName(m_beginScope)));
|
||||||
|
if (afterp) nodep->scopeAttrp(afterp);
|
||||||
|
}
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3BEGIN_H_
|
#ifndef _V3BEGIN_H_
|
||||||
#define _V3BEGIN_H_ 1
|
#define _V3BEGIN_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3BRANCH_H_
|
#ifndef _V3BRANCH_H_
|
||||||
#define _V3BRANCH_H_ 1
|
#define _V3BRANCH_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -81,13 +82,15 @@ private:
|
|||||||
// // so userp and friends may not be used
|
// // so userp and friends may not be used
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
BrokenTable::add(nodep);
|
if (nodep->maybePointedTo()) {
|
||||||
|
BrokenTable::add(nodep);
|
||||||
|
}
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
BrokenMarkVisitor(AstNode* nodep) {
|
BrokenMarkVisitor(AstNetlist* nodep) {
|
||||||
nodep->iterateAndNext(*this, NULL);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
virtual ~BrokenMarkVisitor() {}
|
virtual ~BrokenMarkVisitor() {}
|
||||||
};
|
};
|
||||||
@@ -99,7 +102,7 @@ class BrokenCheckVisitor : public AstNVisitor {
|
|||||||
private:
|
private:
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
if (nodep->broken()) {
|
if (nodep->broken()) {
|
||||||
nodep->v3fatalSrc("Broken link in node\n");
|
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo)\n");
|
||||||
}
|
}
|
||||||
if (v3Global.assertWidthsSame()) {
|
if (v3Global.assertWidthsSame()) {
|
||||||
if (nodep->width() != nodep->widthMin()) {
|
if (nodep->width() != nodep->widthMin()) {
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3BROKEN_H_
|
#ifndef _V3BROKEN_H_
|
||||||
#define _V3BROKEN_H_ 1
|
#define _V3BROKEN_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+82
-42
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -29,16 +29,17 @@
|
|||||||
// (other items))
|
// (other items))
|
||||||
// body
|
// body
|
||||||
// Or, converts to a if/else tree.
|
// Or, converts to a if/else tree.
|
||||||
// Constants:
|
// FUTURES:
|
||||||
// RHS, Replace 5'bx_1_x with a module global we init to a random value
|
// Large 16+ bit tables with constants and no masking (address muxes)
|
||||||
// CONST(5'bx_1_x) -> VARREF(_{numberedtemp})
|
// Enter all into multimap, sort by value and use a tree of < and == compares.
|
||||||
// -> VAR(_{numberedtemp})
|
// "Diagonal" find of {rightmost,leftmost} bit {set,clear}
|
||||||
// -> INITIAL(VARREF(_{numberedtemp}), OR(5'bx_1_x,AND(random,5'b0_1_x))
|
// Ignoring mask, check each value is unique (using multimap as above?)
|
||||||
// OPTIMIZE: Must not collapse this initial back into the equation.
|
// Each branch is then mask-and-compare operation (IE <000000001_000000000 at midpoint.)
|
||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -49,7 +50,9 @@
|
|||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
#include "V3Stats.h"
|
#include "V3Stats.h"
|
||||||
|
|
||||||
#define CASE_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in
|
#define CASE_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in
|
||||||
|
#define CASE_BARF 999999 // Magic width when non-constant
|
||||||
|
#define CASE_ENCODER_GROUP_DEPTH 8 // Levels of priority to be ORed together in top IF tree
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
@@ -126,22 +129,22 @@ private:
|
|||||||
//int debug() { return 9; }
|
//int debug() { return 9; }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
bool checkCaseTree(AstCase* nodep) {
|
bool isCaseTreeFast(AstCase* nodep) {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
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->castConst()) width = 999; // 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;
|
||||||
if (width==0 || width > CASE_OVERLAP_WIDTH) {
|
if (width==0 || width > CASE_OVERLAP_WIDTH) {
|
||||||
m_caseNoOverlapsAllCovered = false;
|
m_caseNoOverlapsAllCovered = false;
|
||||||
return false; // Too wide for analysis
|
return false; // Too wide for analysis
|
||||||
}
|
}
|
||||||
m_caseWidth = width;
|
|
||||||
UINFO(8,"Simple case statement: "<<nodep<<endl);
|
UINFO(8,"Simple case statement: "<<nodep<<endl);
|
||||||
// Zero list of items for each value
|
// Zero list of items for each value
|
||||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) m_valueItem[i] = NULL;
|
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) m_valueItem[i] = NULL;
|
||||||
@@ -172,7 +175,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Defaults were moved to last in the caseitem list by V3Link
|
// Defaults were moved to last in the caseitem list by V3Link
|
||||||
if (!itemp->condsp()) { // Case statement's default... Fill the table
|
if (itemp->isDefault()) { // Case statement's default... Fill the table
|
||||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
||||||
if (!m_valueItem[i]) m_valueItem[i] = itemp;
|
if (!m_valueItem[i]) m_valueItem[i] = itemp;
|
||||||
}
|
}
|
||||||
@@ -207,7 +210,7 @@ private:
|
|||||||
AstNode* tree1p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | (1UL<<msb));
|
AstNode* tree1p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | (1UL<<msb));
|
||||||
|
|
||||||
if (tree0p == tree1p) {
|
if (tree0p == tree1p) {
|
||||||
// Same logic on both sides, so we can just return one of em
|
// Same logic on both sides, so we can just return one of 'em
|
||||||
return tree0p;
|
return tree0p;
|
||||||
}
|
}
|
||||||
// We could have a "checkerboard" with A B A B, we can use the same IF on both edges
|
// We could have a "checkerboard" with A B A B, we can use the same IF on both edges
|
||||||
@@ -273,21 +276,15 @@ private:
|
|||||||
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
|
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
|
||||||
// ,istmts2, istmts3
|
// ,istmts2, istmts3
|
||||||
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
|
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
|
||||||
AstNode* ifrootp = NULL;
|
// We'll do this in two stages. First stage, convert the conditions to
|
||||||
AstNode* ifnextp = NULL;
|
// the appropriate IF AND terms.
|
||||||
|
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
|
||||||
|
bool hadDefault = false;
|
||||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||||
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
|
||||||
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
|
||||||
if (!itemp->condsp()) {
|
if (!itemp->condsp()) {
|
||||||
// Default clause. We reordered in link, so default is always last
|
// Default clause. Just make true, we'll optimize it away later
|
||||||
if (ifnextp) {
|
itemp->condsp(new AstConst(itemp->fileline(), V3Number(itemp->fileline(), 1,1)));
|
||||||
if (istmtsp) ifnextp->castIf()->addElsesp(istmtsp);
|
hadDefault = true;
|
||||||
} else { // Just a empty case default: endcase
|
|
||||||
ifnextp = istmtsp;
|
|
||||||
}
|
|
||||||
if (!ifrootp) ifrootp = istmtsp;
|
|
||||||
ifnextp = istmtsp;
|
|
||||||
itemp = NULL; break;
|
|
||||||
} else {
|
} else {
|
||||||
// Expressioned clause
|
// Expressioned clause
|
||||||
AstNode* icondNextp = NULL;
|
AstNode* icondNextp = NULL;
|
||||||
@@ -322,24 +319,67 @@ private:
|
|||||||
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
|
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Replace expression in tree
|
||||||
// Make the new IF and attach in the tree
|
itemp->condsp(ifexprp);
|
||||||
if (ifexprp) {
|
|
||||||
AstIf* newp = new AstIf(itemp->fileline(), ifexprp, istmtsp, NULL);
|
|
||||||
if (ifnextp) {
|
|
||||||
ifnextp->castIf()->addElsesp(newp);
|
|
||||||
}
|
|
||||||
if (!ifrootp) ifrootp = newp;
|
|
||||||
ifnextp = newp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!hadDefault) {
|
||||||
|
// If there was no default, add a empty one, this greatly simplifies below code
|
||||||
|
// and constant propagation will just eliminate it for us later.
|
||||||
|
nodep->addItemsp(new AstCaseItem(nodep->fileline(),
|
||||||
|
new AstConst(nodep->fileline(), V3Number(nodep->fileline(),1,1)),
|
||||||
|
NULL));
|
||||||
|
}
|
||||||
|
if (debug()>=9) nodep->dumpTree(cout," _comp_COND: ");
|
||||||
|
// Now build the IF statement tree
|
||||||
|
// The tree can be quite huge. Pull ever group of 8 out, and make a OR tree.
|
||||||
|
// This reduces the depth for the bottom elements, at the cost of some of the top elements.
|
||||||
|
// If we ever have profiling data, we should pull out the most common item from here and
|
||||||
|
// instead make it the first IF branch.
|
||||||
|
int depth = 0;
|
||||||
|
AstNode* grouprootp = NULL;
|
||||||
|
AstIf* groupnextp = NULL;
|
||||||
|
AstIf* itemnextp = NULL;
|
||||||
|
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||||
|
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||||
|
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
||||||
|
// Expressioned clause
|
||||||
|
AstNode* ifexprp = itemp->condsp()->unlinkFrBack();
|
||||||
|
{ // Prepare for next group
|
||||||
|
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
|
||||||
|
if (depth == 1) { // First group or starting new group
|
||||||
|
itemnextp = NULL;
|
||||||
|
AstIf* newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true), NULL, NULL);
|
||||||
|
if (groupnextp) groupnextp->addElsesp(newp);
|
||||||
|
else grouprootp = newp;
|
||||||
|
groupnextp = newp;
|
||||||
|
} else { // Continue group, modify if condition to OR in this new condition
|
||||||
|
AstNode* condp = groupnextp->condp()->unlinkFrBack();
|
||||||
|
groupnextp->condp(new AstOr(ifexprp->fileline(),
|
||||||
|
condp,
|
||||||
|
ifexprp->cloneTree(true)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ // Make the new lower IF and attach in the tree
|
||||||
|
AstNode* itemexprp = ifexprp; ifexprp=NULL;
|
||||||
|
if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition
|
||||||
|
itemexprp->deleteTree(); itemexprp=NULL;
|
||||||
|
itemexprp = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,1));
|
||||||
|
}
|
||||||
|
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL);
|
||||||
|
if (itemnextp) itemnextp->addElsesp(newp);
|
||||||
|
else groupnextp->addIfsp(newp); // First in a new group
|
||||||
|
itemnextp = newp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug()>=9) nodep->dumpTree(cout," _comp_TREE: ");
|
||||||
// Handle any assertions
|
// Handle any assertions
|
||||||
replaceCaseParallel(nodep, false);
|
replaceCaseParallel(nodep, false);
|
||||||
// Replace the CASE... with IF...
|
// Replace the CASE... with IF...
|
||||||
if (ifrootp) nodep->replaceWith(ifrootp);
|
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
|
||||||
|
if (grouprootp) nodep->replaceWith(grouprootp);
|
||||||
else nodep->unlinkFrBack();
|
else nodep->unlinkFrBack();
|
||||||
if (debug()>=9) ifrootp->dumpTree(cout," _new: ");
|
nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
|
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
|
||||||
@@ -357,7 +397,7 @@ private:
|
|||||||
V3Case::caseLint(nodep);
|
V3Case::caseLint(nodep);
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (debug()>=9) nodep->dumpTree(cout," case_old: ");
|
if (debug()>=9) nodep->dumpTree(cout," case_old: ");
|
||||||
if (checkCaseTree(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++;
|
||||||
@@ -375,13 +415,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
CaseVisitor(AstNode* nodep) {
|
CaseVisitor(AstNetlist* nodep) {
|
||||||
m_caseNoOverlapsAllCovered = false;
|
m_caseNoOverlapsAllCovered = false;
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
virtual ~CaseVisitor() {
|
virtual ~CaseVisitor() {
|
||||||
V3Stats::addStat("Optimizations, Cases parallelized", m_statCaseFast);
|
V3Stats::addStat("Optimizations, Cases parallelized", m_statCaseFast);
|
||||||
V3Stats::addStat("Optimizations, Cases priority-encoded", m_statCaseSlow);
|
V3Stats::addStat("Optimizations, Cases complex", m_statCaseSlow);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3CASE_H_
|
#ifndef _V3CASE_H_
|
||||||
#define _V3CASE_H_ 1
|
#define _V3CASE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -42,7 +42,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3CAST_H_
|
#ifndef _V3CAST_H_
|
||||||
#define _V3CAST_H_ 1
|
#define _V3CAST_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -31,7 +31,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3CHANGED_H_
|
#ifndef _V3CHANGED_H_
|
||||||
#define _V3CHANGED_H_ 1
|
#define _V3CHANGED_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -28,7 +28,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -103,11 +104,8 @@ private:
|
|||||||
nodep->unlinkFrBack(&relinkHandle);
|
nodep->unlinkFrBack(&relinkHandle);
|
||||||
//
|
//
|
||||||
computeCppWidth(nodep);
|
computeCppWidth(nodep);
|
||||||
V3Number zero (nodep->fileline(), nodep->widthMin(),0);
|
|
||||||
V3Number masksmall (nodep->fileline(), nodep->widthMin());
|
|
||||||
masksmall.opNot(zero);
|
|
||||||
V3Number mask (nodep->fileline(), cppWidth(nodep));
|
V3Number mask (nodep->fileline(), cppWidth(nodep));
|
||||||
mask.opAssign(masksmall);
|
mask.setMask(nodep->widthMin());
|
||||||
AstNode* cleanp = new AstAnd (nodep->fileline(),
|
AstNode* cleanp = new AstAnd (nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), mask),
|
new AstConst (nodep->fileline(), mask),
|
||||||
nodep);
|
nodep);
|
||||||
@@ -239,6 +237,10 @@ private:
|
|||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
insureCleanAndNext (nodep->bodysp());
|
insureCleanAndNext (nodep->bodysp());
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
insureCleanAndNext (nodep->argsp());
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3CLEAN_H_
|
#ifndef _V3CLEAN_H_
|
||||||
#define _V3CLEAN_H_ 1
|
#define _V3CLEAN_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -32,7 +32,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -192,6 +193,7 @@ private:
|
|||||||
funcp->dontCombine(true);
|
funcp->dontCombine(true);
|
||||||
funcp->symProlog(true);
|
funcp->symProlog(true);
|
||||||
funcp->isStatic(true);
|
funcp->isStatic(true);
|
||||||
|
funcp->entryPoint(true);
|
||||||
m_scopep->addActivep(funcp);
|
m_scopep->addActivep(funcp);
|
||||||
m_evalFuncp = funcp;
|
m_evalFuncp = funcp;
|
||||||
}
|
}
|
||||||
@@ -202,6 +204,7 @@ private:
|
|||||||
funcp->slow(true);
|
funcp->slow(true);
|
||||||
funcp->symProlog(true);
|
funcp->symProlog(true);
|
||||||
funcp->isStatic(true);
|
funcp->isStatic(true);
|
||||||
|
funcp->entryPoint(true);
|
||||||
m_scopep->addActivep(funcp);
|
m_scopep->addActivep(funcp);
|
||||||
m_initFuncp = funcp;
|
m_initFuncp = funcp;
|
||||||
}
|
}
|
||||||
@@ -211,6 +214,7 @@ private:
|
|||||||
funcp->dontCombine(true);
|
funcp->dontCombine(true);
|
||||||
funcp->slow(true);
|
funcp->slow(true);
|
||||||
funcp->isStatic(false);
|
funcp->isStatic(false);
|
||||||
|
funcp->entryPoint(true);
|
||||||
funcp->addInitsp(
|
funcp->addInitsp(
|
||||||
new AstCStmt(nodep->fileline(),
|
new AstCStmt(nodep->fileline(),
|
||||||
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
|
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
|
||||||
@@ -225,6 +229,7 @@ private:
|
|||||||
funcp->slow(true);
|
funcp->slow(true);
|
||||||
funcp->isStatic(true);
|
funcp->isStatic(true);
|
||||||
funcp->symProlog(true);
|
funcp->symProlog(true);
|
||||||
|
funcp->entryPoint(true);
|
||||||
m_scopep->addActivep(funcp);
|
m_scopep->addActivep(funcp);
|
||||||
m_settleFuncp = funcp;
|
m_settleFuncp = funcp;
|
||||||
}
|
}
|
||||||
@@ -360,8 +365,7 @@ private:
|
|||||||
// Move statements to if
|
// Move statements to if
|
||||||
m_lastIfp->addIfsp(stmtsp);
|
m_lastIfp->addIfsp(stmtsp);
|
||||||
} else if (nodep->hasSettle()) {
|
} else if (nodep->hasSettle()) {
|
||||||
// Settlement
|
// Don't need to: clearLastSen();, as we're adding it to different cfunc
|
||||||
clearLastSen();
|
|
||||||
// Move statements to function
|
// Move statements to function
|
||||||
addToSettleLoop(stmtsp);
|
addToSettleLoop(stmtsp);
|
||||||
} else {
|
} else {
|
||||||
@@ -468,7 +472,8 @@ private:
|
|||||||
ifstmtp->addNext(new AstIf(fl,
|
ifstmtp->addNext(new AstIf(fl,
|
||||||
new AstLt (fl, new AstConst(fl, 100),
|
new AstLt (fl, new AstConst(fl, 100),
|
||||||
new AstVarRef(fl, countVarp, false)),
|
new AstVarRef(fl, countVarp, false)),
|
||||||
(new AstDisplay (fl, '\n', "%%Error: Verilated model didn't converge", NULL, NULL))
|
(new AstDisplay (fl, AstDisplayType::DISPLAY,
|
||||||
|
"%%Error: Verilated model didn't converge", NULL, NULL))
|
||||||
->addNext(new AstStop (fl)),
|
->addNext(new AstStop (fl)),
|
||||||
NULL));
|
NULL));
|
||||||
untilp->addBodysp(new AstIf(fl, new AstNeq(fl, new AstConst(fl, 0),
|
untilp->addBodysp(new AstIf(fl, new AstNeq(fl, new AstConst(fl, 0),
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3CLOCK_H_
|
#ifndef _V3CLOCK_H_
|
||||||
#define _V3CLOCK_H_ 1
|
#define _V3CLOCK_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -35,7 +35,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3COMBINE_H_
|
#ifndef _V3COMBINE_H_
|
||||||
#define _V3COMBINE_H_ 1
|
#define _V3COMBINE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+65
-20
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
// If operands are constant, replace this node with constant.
|
// If operands are constant, replace this node with constant.
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -70,6 +71,16 @@ private:
|
|||||||
if (!rnodep->lhsp()->castConst()) return false;
|
if (!rnodep->lhsp()->castConst()) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool operandAsvSame (AstNode* nodep) {
|
||||||
|
// BIASV(SAMEa, BIASV(SAMEb,...)) -> BIASV( BIASV(SAMEa,SAMEb), ...)
|
||||||
|
AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv();
|
||||||
|
if (!bnodep) return false;
|
||||||
|
AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv();
|
||||||
|
if (!rnodep) return false;
|
||||||
|
if (rnodep->type() != bnodep->type()) return false;
|
||||||
|
if (rnodep->width() != bnodep->width()) return false;
|
||||||
|
return operandsSame(bnodep->lhsp(), rnodep->lhsp());
|
||||||
|
}
|
||||||
bool operandHugeShiftL(AstNodeBiop* nodep) {
|
bool operandHugeShiftL(AstNodeBiop* nodep) {
|
||||||
return (nodep->rhsp()->castConst()
|
return (nodep->rhsp()->castConst()
|
||||||
&& nodep->rhsp()->castConst()->asInt() >= (uint32_t)(nodep->width()));
|
&& nodep->rhsp()->castConst()->asInt() >= (uint32_t)(nodep->width()));
|
||||||
@@ -170,15 +181,10 @@ private:
|
|||||||
static bool operandsSame(AstNode* node1p, AstNode* node2p) {
|
static bool operandsSame(AstNode* node1p, AstNode* node2p) {
|
||||||
// For now we just detect constants & simple vars, though it could be more generic
|
// For now we just detect constants & simple vars, though it could be more generic
|
||||||
if (node1p->castConst() && node2p->castConst()) {
|
if (node1p->castConst() && node2p->castConst()) {
|
||||||
// Match ignoring any X values
|
return node1p->sameTree(node2p);
|
||||||
V3Number num (node1p->fileline(), 1);
|
|
||||||
num.opCaseEq(node1p->castConst()->num(), node2p->castConst()->num());
|
|
||||||
return num.isNeqZero();
|
|
||||||
}
|
}
|
||||||
else if (node1p->castVarRef() && node2p->castVarRef()
|
else if (node1p->castVarRef() && node2p->castVarRef()) {
|
||||||
&& node1p->sameTree(node2p)) {
|
return node1p->sameTree(node2p);
|
||||||
// Same variable
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -239,6 +245,11 @@ private:
|
|||||||
void replaceZero(AstNode* nodep) {
|
void replaceZero(AstNode* nodep) {
|
||||||
replaceNum(nodep, 0); nodep=NULL;
|
replaceNum(nodep, 0); nodep=NULL;
|
||||||
}
|
}
|
||||||
|
void replaceAllOnes (AstNode* nodep) {
|
||||||
|
V3Number ones (nodep->fileline(), nodep->width(), 0);
|
||||||
|
ones.setMask(nodep->width());
|
||||||
|
replaceNum(nodep, ones); nodep=NULL;
|
||||||
|
}
|
||||||
void replaceConst(AstNodeUniop* nodep) {
|
void replaceConst(AstNodeUniop* nodep) {
|
||||||
V3Number num (nodep->fileline(), nodep->width());
|
V3Number num (nodep->fileline(), nodep->width());
|
||||||
nodep->numberOperate(num, nodep->lhsp()->castConst()->num());
|
nodep->numberOperate(num, nodep->lhsp()->castConst()->num());
|
||||||
@@ -283,8 +294,9 @@ private:
|
|||||||
// Keep RHS, remove LHS
|
// Keep RHS, remove LHS
|
||||||
replaceWChild(nodep, nodep->rhsp());
|
replaceWChild(nodep, nodep->rhsp());
|
||||||
}
|
}
|
||||||
void replaceAsvConst (AstNodeBiop* nodep) {
|
void replaceAsv (AstNodeBiop* nodep) {
|
||||||
// BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
|
// BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
|
||||||
|
// BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c)
|
||||||
//nodep->dumpTree(cout, " repAsvConst_old: ");
|
//nodep->dumpTree(cout, " repAsvConst_old: ");
|
||||||
AstNode* ap = nodep->lhsp();
|
AstNode* ap = nodep->lhsp();
|
||||||
AstNodeBiop* rp = nodep->rhsp()->castNodeBiop();
|
AstNodeBiop* rp = nodep->rhsp()->castNodeBiop();
|
||||||
@@ -298,7 +310,7 @@ private:
|
|||||||
nodep->rhsp(cp);
|
nodep->rhsp(cp);
|
||||||
rp->lhsp(ap);
|
rp->lhsp(ap);
|
||||||
rp->rhsp(bp);
|
rp->rhsp(bp);
|
||||||
replaceConst(rp);
|
if (rp->lhsp()->castConst() && rp->rhsp()->castConst()) replaceConst(rp);
|
||||||
//nodep->dumpTree(cout, " repAsvConst_new: ");
|
//nodep->dumpTree(cout, " repAsvConst_new: ");
|
||||||
}
|
}
|
||||||
void replaceExtend (AstNode* nodep, AstNode* arg0p) {
|
void replaceExtend (AstNode* nodep, AstNode* arg0p) {
|
||||||
@@ -375,7 +387,7 @@ private:
|
|||||||
AstNode* newp;
|
AstNode* newp;
|
||||||
V3Number mask1 (nodep->fileline(), nodep->width());
|
V3Number mask1 (nodep->fileline(), nodep->width());
|
||||||
V3Number ones (nodep->fileline(), nodep->width());
|
V3Number ones (nodep->fileline(), nodep->width());
|
||||||
ones.opNot(mask1);
|
ones.setMask(nodep->width());
|
||||||
if (shift1<0) {
|
if (shift1<0) {
|
||||||
mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1));
|
mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1));
|
||||||
} else {
|
} else {
|
||||||
@@ -744,7 +756,8 @@ private:
|
|||||||
nodep->varp()->initp()->iterateAndNext(*this);
|
nodep->varp()->initp()->iterateAndNext(*this);
|
||||||
if (operandConst(nodep->varp()->initp())
|
if (operandConst(nodep->varp()->initp())
|
||||||
&& !nodep->lvalue()
|
&& !nodep->lvalue()
|
||||||
&& ((v3Global.opt.oConst() && !m_params) // Can reduce constant wires into equations
|
&& ((v3Global.opt.oConst() && !m_params // Can reduce constant wires into equations
|
||||||
|
&& !nodep->varp()->isSigPublic())
|
||||||
|| nodep->varp()->isParam())) {
|
|| nodep->varp()->isParam())) {
|
||||||
AstConst* constp = nodep->varp()->initp()->castConst();
|
AstConst* constp = nodep->varp()->initp()->castConst();
|
||||||
const V3Number& num = constp->num();
|
const V3Number& num = constp->num();
|
||||||
@@ -803,7 +816,7 @@ private:
|
|||||||
}
|
}
|
||||||
UINFO(8,"senItem(NOT...) "<<nodep<<" "<<invert<<endl);
|
UINFO(8,"senItem(NOT...) "<<nodep<<" "<<invert<<endl);
|
||||||
if (invert) nodep->edgeType( nodep->edgeType().invert() );
|
if (invert) nodep->edgeType( nodep->edgeType().invert() );
|
||||||
AstVarRef* senvarp = lastSensp->unlinkFrBack()->castVarRef();
|
AstNodeVarRef* senvarp = lastSensp->unlinkFrBack()->castNodeVarRef();
|
||||||
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
|
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
|
||||||
sensp->replaceWith(senvarp);
|
sensp->replaceWith(senvarp);
|
||||||
sensp->deleteTree(); sensp=NULL;
|
sensp->deleteTree(); sensp=NULL;
|
||||||
@@ -945,6 +958,7 @@ private:
|
|||||||
// }" # bracket not paren
|
// }" # bracket not paren
|
||||||
// ,"function to call"
|
// ,"function to call"
|
||||||
// or ,"AstREPLACEMENT_TYPE{ $accessor }"
|
// or ,"AstREPLACEMENT_TYPE{ $accessor }"
|
||||||
|
// or ,"! # Print line number when matches, so can see operations
|
||||||
|
|
||||||
// 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
|
||||||
@@ -969,6 +983,7 @@ private:
|
|||||||
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("AstSub {$lhsp.isZero, $rhsp}", "AstUnaryMin{$rhsp}");
|
TREEOP("AstSub {$lhsp.isZero, $rhsp}", "AstUnaryMin{$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)");
|
||||||
@@ -982,6 +997,7 @@ private:
|
|||||||
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}");
|
||||||
// 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)");
|
||||||
@@ -992,6 +1008,7 @@ private:
|
|||||||
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("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)");
|
||||||
@@ -1012,8 +1029,9 @@ private:
|
|||||||
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.isZero, $expr2p}", "AstAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&b
|
||||||
TREEOP("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
|
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, $rhsp.castConst}", "swapSides(nodep)");
|
TREEOP("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
|
||||||
TREEOP("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsvConst(nodep)");
|
TREEOP("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
|
||||||
|
TREEOP("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(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)");
|
||||||
@@ -1058,6 +1076,31 @@ 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)");
|
||||||
|
// Identical operands on both sides
|
||||||
|
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
|
||||||
|
// AstAdd->ShiftL(#,1) but uncommon
|
||||||
|
TREEOP("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
|
||||||
|
TREEOP("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
|
||||||
|
TREEOP("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(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("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
|
||||||
|
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
|
||||||
|
TREEOP("AstNeqCase{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
|
||||||
@@ -1075,7 +1118,6 @@ private:
|
|||||||
TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)");
|
TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)");
|
||||||
// Simplify reduction operators
|
// Simplify reduction operators
|
||||||
// This also gets &{...,0,....} => const 0 (Common for unused_ok signals)
|
// This also gets &{...,0,....} => const 0 (Common for unused_ok signals)
|
||||||
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
|
|
||||||
TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
|
TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
|
||||||
TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
|
TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
|
||||||
TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
|
TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
|
||||||
@@ -1108,6 +1150,7 @@ private:
|
|||||||
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)");
|
||||||
// Conversions
|
// Conversions
|
||||||
|
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}}");
|
||||||
|
|
||||||
@@ -1171,12 +1214,14 @@ void V3Const::constifyAll(AstNetlist* nodep) {
|
|||||||
visitor.main(nodep);
|
visitor.main(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3Const::constifyAllLint(AstNode* nodep) {
|
void V3Const::constifyAllLint(AstNetlist* nodep) {
|
||||||
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
ConstVisitor visitor (false,false,true,false);
|
ConstVisitor visitor (false,false,true,false);
|
||||||
visitor.main(nodep);
|
visitor.main(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3Const::constifyCpp(AstNode* nodep) {
|
void V3Const::constifyCpp(AstNetlist* nodep) {
|
||||||
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
ConstVisitor visitor (false,false,false,true);
|
ConstVisitor visitor (false,false,false,true);
|
||||||
visitor.main(nodep);
|
visitor.main(nodep);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3CONST_H_
|
#ifndef _V3CONST_H_
|
||||||
#define _V3CONST_H_ 1
|
#define _V3CONST_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
@@ -34,9 +35,9 @@ public:
|
|||||||
// Everything that's possible
|
// Everything that's possible
|
||||||
static void constifyAll(AstNetlist* nodep);
|
static void constifyAll(AstNetlist* nodep);
|
||||||
// Also, warn
|
// Also, warn
|
||||||
static void constifyAllLint(AstNode* nodep);
|
static void constifyAllLint(AstNetlist* nodep);
|
||||||
// C++ datatypes
|
// C++ datatypes
|
||||||
static void constifyCpp(AstNode* nodep);
|
static void constifyCpp(AstNetlist* nodep);
|
||||||
// Only the current node and lower
|
// Only the current node and lower
|
||||||
static void constifyTree(AstNode* nodep);
|
static void constifyTree(AstNode* nodep);
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -29,7 +29,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3COVERAGE_H_
|
#ifndef _V3COVERAGE_H_
|
||||||
#define _V3COVERAGE_H_ 1
|
#define _V3COVERAGE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+40
-5
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -24,11 +24,13 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
#include "V3Dead.h"
|
#include "V3Dead.h"
|
||||||
@@ -70,10 +72,15 @@ private:
|
|||||||
// AstVar::user() -> int. Count of number of references
|
// AstVar::user() -> int. Count of number of references
|
||||||
// AstVarScope::user() -> int. Count of number of references
|
// AstVarScope::user() -> int. Count of number of references
|
||||||
|
|
||||||
|
// TYPES
|
||||||
|
typedef multimap<AstVarScope*,AstNodeAssign*> AssignMap;
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
vector<AstVar*> m_varsp; // List of all encountered to avoid another loop through tree
|
vector<AstVar*> m_varsp; // List of all encountered to avoid another loop through tree
|
||||||
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through tree
|
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through tree
|
||||||
|
AssignMap m_assignMap; // List of all simple assignments for each variable
|
||||||
bool m_elimUserVars; // Allow removal of user's vars
|
bool m_elimUserVars; // Allow removal of user's vars
|
||||||
|
bool m_sideEffect; // Side effects discovered in assign RHS
|
||||||
//int debug() { return 9; }
|
//int debug() { return 9; }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
@@ -102,6 +109,25 @@ private:
|
|||||||
m_varsp.push_back(nodep);
|
m_varsp.push_back(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||||
|
// See if simple assignments to variables may be eliminated because that variable is never used.
|
||||||
|
// Similar code in V3Life
|
||||||
|
m_sideEffect = false;
|
||||||
|
nodep->rhsp()->iterateAndNext(*this);
|
||||||
|
// Has to be direct assignment without any EXTRACTing.
|
||||||
|
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
|
||||||
|
if (varrefp && !m_sideEffect
|
||||||
|
&& varrefp->varScopep()) { // For simplicity, we only remove post-scoping
|
||||||
|
m_assignMap.insert(make_pair(varrefp->varScopep(), nodep));
|
||||||
|
} else { // Track like any other statement
|
||||||
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstUCFunc* nodep, AstNUser*) {
|
||||||
|
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
//-----
|
//-----
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
@@ -131,14 +157,22 @@ private:
|
|||||||
}
|
}
|
||||||
bool canElim(AstVar* nodep) {
|
bool canElim(AstVar* nodep) {
|
||||||
return (!nodep->isSigPublic() // Can't elim publics!
|
return (!nodep->isSigPublic() // Can't elim publics!
|
||||||
|
&& !nodep->isIO()
|
||||||
&& (nodep->isTemp() || nodep->isParam() || m_elimUserVars));
|
&& (nodep->isTemp() || nodep->isParam() || m_elimUserVars));
|
||||||
}
|
}
|
||||||
void deadCheckVar() {
|
void deadCheckVar() {
|
||||||
// Delete any unused varscopes
|
// Delete any unused varscopes
|
||||||
for (vector<AstVarScope*>::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) {
|
for (vector<AstVarScope*>::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) {
|
||||||
if ((*it)->user() == 0 && canElim((*it)->varp())) {
|
AstVarScope* vscp = *it;
|
||||||
UINFO(4," Dead "<<(*it)<<endl);
|
if (vscp->user() == 0 && canElim(vscp->varp())) {
|
||||||
(*it)->unlinkFrBack()->deleteTree(); (*it)=NULL;
|
UINFO(4," Dead "<<vscp<<endl);
|
||||||
|
pair <AssignMap::iterator,AssignMap::iterator> eqrange = m_assignMap.equal_range(vscp);
|
||||||
|
for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) {
|
||||||
|
AstNodeAssign* assp = it->second;
|
||||||
|
UINFO(4," Dead assign "<<assp<<endl);
|
||||||
|
assp->unlinkFrBack()->deleteTree(); assp=NULL;
|
||||||
|
}
|
||||||
|
vscp->unlinkFrBack()->deleteTree(); vscp=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (vector<AstVar*>::iterator it = m_varsp.begin(); it!=m_varsp.end(); ++it) {
|
for (vector<AstVar*>::iterator it = m_varsp.begin(); it!=m_varsp.end(); ++it) {
|
||||||
@@ -153,6 +187,7 @@ public:
|
|||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
DeadVisitor(AstNetlist* nodep, bool elimUserVars) {
|
DeadVisitor(AstNetlist* nodep, bool elimUserVars) {
|
||||||
m_elimUserVars = elimUserVars;
|
m_elimUserVars = elimUserVars;
|
||||||
|
m_sideEffect = false;
|
||||||
// Operate on whole netlist
|
// Operate on whole netlist
|
||||||
AstNode::userClearTree(); // userp() used on entire tree
|
AstNode::userClearTree(); // userp() used on entire tree
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3DEAD_H_
|
#ifndef _V3DEAD_H_
|
||||||
#define _V3DEAD_H_ 1
|
#define _V3DEAD_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -52,7 +52,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3DELAYED_H_
|
#ifndef _V3DELAYED_H_
|
||||||
#define _V3DELAYED_H_ 1
|
#define _V3DELAYED_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -28,7 +28,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3DEPTH_H_
|
#ifndef _V3DEPTH_H_
|
||||||
#define _V3DEPTH_H_ 1
|
#define _V3DEPTH_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+12
-10
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -27,7 +27,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -159,8 +160,8 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Not really any way the user could do this, and we'd need to come up with some return value
|
// Not really any way the user could do this, and we'd need to come up with some return value
|
||||||
//newfuncp->addStmtsp(new AstDisplay (newfuncp->fileline(),
|
//newfuncp->addStmtsp(new AstDisplay (newfuncp->fileline(), AstDisplayType::DISPLAY,
|
||||||
// '\n', string("%%Error: ")+name+"() called with bad scope", NULL));
|
// string("%%Error: ")+name+"() called with bad scope", NULL));
|
||||||
//newfuncp->addStmtsp(new AstStop (newfuncp->fileline()));
|
//newfuncp->addStmtsp(new AstStop (newfuncp->fileline()));
|
||||||
if (debug()>=9) newfuncp->dumpTree(cout," newfunc: ");
|
if (debug()>=9) newfuncp->dumpTree(cout," newfunc: ");
|
||||||
} else {
|
} else {
|
||||||
@@ -224,12 +225,13 @@ private:
|
|||||||
if (m_scopep) {
|
if (m_scopep) {
|
||||||
nodep->unlinkFrBack();
|
nodep->unlinkFrBack();
|
||||||
m_modp->addStmtp(nodep);
|
m_modp->addStmtp(nodep);
|
||||||
}
|
|
||||||
if (nodep->funcPublic()) {
|
if (nodep->funcPublic()) {
|
||||||
// There may be multiple public functions by the same name;
|
// There may be multiple public functions by the same name;
|
||||||
// record for later correction or making of shells
|
// record for later correction or making of shells
|
||||||
m_modFuncs.insert(make_pair(nodep->name(), nodep));
|
m_modFuncs.insert(make_pair(nodep->name(), nodep));
|
||||||
nodep->name(m_scopep->nameDotless() +"__" + nodep->name());
|
nodep->name(m_scopep->nameDotless() +"__" + nodep->name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3DESCOPE_H_
|
#ifndef _V3DESCOPE_H_
|
||||||
#define _V3DESCOPE_H_ 1
|
#define _V3DESCOPE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+80
-24
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -96,12 +97,17 @@ public:
|
|||||||
string cFuncArgs(AstCFunc* nodep) {
|
string cFuncArgs(AstCFunc* nodep) {
|
||||||
// Return argument list for given C function
|
// Return argument list for given C function
|
||||||
string args = nodep->argTypes();
|
string args = nodep->argTypes();
|
||||||
if (args=="") {
|
// Might be a user function with argument list.
|
||||||
// Might be a user function with argument list.
|
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||||
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
if (AstVar* portp = stmtp->castVar()) {
|
||||||
if (AstVar* portp = stmtp->castVar()) {
|
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
if (args != "") args+= ", ";
|
||||||
if (args != "") args+= ", ";
|
if (portp->isWide()) {
|
||||||
|
if (portp->isInOnly()) args += "const ";
|
||||||
|
args += portp->cType();
|
||||||
|
args += " (& "+portp->name();
|
||||||
|
args += ")["+cvtToStr(portp->widthWords())+"]";
|
||||||
|
} else {
|
||||||
args += portp->cType();
|
args += portp->cType();
|
||||||
if (portp->isOutput()) args += "&";
|
if (portp->isOutput()) args += "&";
|
||||||
args += " "+portp->name();
|
args += " "+portp->name();
|
||||||
@@ -217,8 +223,7 @@ public:
|
|||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstCoverInc* nodep, AstNUser*) {
|
virtual void visit(AstCoverInc* nodep, AstNUser*) {
|
||||||
puts("if (VL_LIKELY(vlSymsp->__Vm_coverageRequest))");
|
puts("++this->__Vcoverage[");
|
||||||
puts(" ++this->__Vcoverage[");
|
|
||||||
puts(cvtToStr(m_coverIds.remap(nodep->declp()))); puts("];\n");
|
puts(cvtToStr(m_coverIds.remap(nodep->declp()))); puts("];\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstCReturn* nodep, AstNUser*) {
|
virtual void visit(AstCReturn* nodep, AstNUser*) {
|
||||||
@@ -234,14 +239,49 @@ public:
|
|||||||
emitIQW(nodep->modep());
|
emitIQW(nodep->modep());
|
||||||
if (nodep->modep()->width()>4*8) nodep->modep()->v3error("$fopen mode should be <= 4 characters");
|
if (nodep->modep()->width()>4*8) nodep->modep()->v3error("$fopen mode should be <= 4 characters");
|
||||||
puts("(");
|
puts("(");
|
||||||
if (nodep->filenamep()->isWide()) puts(cvtToStr(nodep->filenamep()->widthWords()));
|
if (nodep->filenamep()->isWide()) {
|
||||||
|
puts(cvtToStr(nodep->filenamep()->widthWords()));
|
||||||
|
putbs(", ");
|
||||||
|
}
|
||||||
|
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
||||||
|
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
||||||
|
}
|
||||||
|
nodep->filenamep()->iterateAndNext(*this);
|
||||||
|
putbs(", ");
|
||||||
|
nodep->modep()->iterateAndNext(*this);
|
||||||
|
puts(");\n");
|
||||||
|
}
|
||||||
|
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||||
|
puts("VL_READMEM_");
|
||||||
|
emitIQW(nodep->filenamep());
|
||||||
|
puts(" ("); // We take a void* rather then emitIQW(nodep->memp());
|
||||||
|
puts(nodep->isHex()?"true":"false");
|
||||||
|
putbs(",");
|
||||||
|
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
||||||
|
putbs(",");
|
||||||
|
uint32_t array_lsb = 0;
|
||||||
|
{
|
||||||
|
AstVarRef* varrefp = nodep->memp()->castVarRef();
|
||||||
|
if (!varrefp || !varrefp->varp()->arrayp(0)) { nodep->v3error("Readmem loading non-arrayed variable"); }
|
||||||
|
else {
|
||||||
|
puts(cvtToStr(varrefp->varp()->arrayElements()));
|
||||||
|
array_lsb = varrefp->varp()->arrayp(0)->lsbConst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putbs(", ");
|
||||||
|
puts(cvtToStr(array_lsb));
|
||||||
|
putbs(",");
|
||||||
|
puts(cvtToStr(nodep->filenamep()->widthWords()));
|
||||||
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
||||||
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
||||||
}
|
}
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
nodep->filenamep()->iterateAndNext(*this);
|
nodep->filenamep()->iterateAndNext(*this);
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
nodep->modep()->iterateAndNext(*this);
|
nodep->memp()->iterateAndNext(*this);
|
||||||
|
putbs(","); if (nodep->lsbp()) { nodep->lsbp()->iterateAndNext(*this); }
|
||||||
|
else puts(cvtToStr(array_lsb));
|
||||||
|
putbs(","); if (nodep->msbp()) { nodep->msbp()->iterateAndNext(*this); } else puts("~0");
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstFClose* nodep, AstNUser*) {
|
virtual void visit(AstFClose* nodep, AstNUser*) {
|
||||||
@@ -647,6 +687,21 @@ class EmitCImp : EmitCStmts {
|
|||||||
if (gotOne) {
|
if (gotOne) {
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
//puts("VL_DEBUG_IF( if (__req) cout<<\"\tCLOCKREQ );");
|
//puts("VL_DEBUG_IF( if (__req) cout<<\"\tCLOCKREQ );");
|
||||||
|
for (vector<AstChangeDet*>::iterator it = m_blkChangeDetVec.begin();
|
||||||
|
it != m_blkChangeDetVec.end(); ++it) {
|
||||||
|
AstChangeDet* nodep = *it;
|
||||||
|
if (nodep->lhsp()) {
|
||||||
|
puts("VL_DEBUG_IF( if(__req && (");
|
||||||
|
bool gotOneIgnore = false;
|
||||||
|
doubleOrDetect(nodep, gotOneIgnore);
|
||||||
|
string varname;
|
||||||
|
if (nodep->lhsp()->castVarRef()) {
|
||||||
|
varname = ": "+nodep->lhsp()->castVarRef()->varp()->prettyName();
|
||||||
|
}
|
||||||
|
puts(")) cout<<\"\tCHANGE: "+nodep->fileline()->ascii()
|
||||||
|
+varname+"\"<<endl; );");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,19 +758,19 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
|||||||
if (nodep->attrScClocked() && nodep->isInput()) {
|
if (nodep->attrScClocked() && nodep->isInput()) {
|
||||||
puts("sc_in_clk\t");
|
puts("sc_in_clk\t");
|
||||||
} else {
|
} else {
|
||||||
if (nodep->isTristate()) puts("sc_inout<");
|
if (nodep->isInout()) puts("sc_inout<");
|
||||||
else if (nodep->isInput()) puts("sc_in<");
|
else if (nodep->isInput()) puts("sc_in<");
|
||||||
else if (nodep->isOutput()) puts("sc_out<");
|
else if (nodep->isOutput()) puts("sc_out<");
|
||||||
else nodep->v3fatalSrc("Unknown type");
|
else nodep->v3fatalSrc("Unknown type");
|
||||||
|
|
||||||
puts(nodep->cType());
|
puts(nodep->scType());
|
||||||
puts(">\t");
|
puts(">\t");
|
||||||
}
|
}
|
||||||
puts(nodep->name());
|
puts(nodep->name());
|
||||||
puts(";\n");
|
puts(";\n");
|
||||||
} else { // C++ signals
|
} else { // C++ signals
|
||||||
ofp()->putAlign(nodep->isStatic(), nodep->widthAlignBytes());
|
ofp()->putAlign(nodep->isStatic(), nodep->widthAlignBytes());
|
||||||
if (nodep->isTristate()) puts("VL_INOUT");
|
if (nodep->isInout()) puts("VL_INOUT");
|
||||||
else if (nodep->isInput()) puts("VL_IN");
|
else if (nodep->isInput()) puts("VL_IN");
|
||||||
else if (nodep->isOutput()) puts("VL_OUT");
|
else if (nodep->isOutput()) puts("VL_OUT");
|
||||||
else nodep->v3fatalSrc("Unknown type");
|
else nodep->v3fatalSrc("Unknown type");
|
||||||
@@ -910,7 +965,6 @@ string EmitCStmts::displayFormat(AstNode* widthNodep, string in,
|
|||||||
} else {
|
} else {
|
||||||
fmt=in;
|
fmt=in;
|
||||||
}
|
}
|
||||||
if (widthNodep->isQuad() && fmtLetter!='c' && fmtLetter!='s' && !reallyString) fmt+="ll";
|
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,10 +995,17 @@ void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, cha
|
|||||||
emitDispState.pushFormat(pfmt);
|
emitDispState.pushFormat(pfmt);
|
||||||
emitDispState.pushArg(*elistp,func);
|
emitDispState.pushArg(*elistp,func);
|
||||||
} else {
|
} else {
|
||||||
|
string func;
|
||||||
string nfmt = displayFormat(*elistp, fmt, fmtLetter, true, false);
|
string nfmt = displayFormat(*elistp, fmt, fmtLetter, true, false);
|
||||||
|
// We don't need to check for fmtLetter=='d', as it is above.
|
||||||
|
if ((*elistp)->isQuad() && (fmtLetter=='u'||fmtLetter=='o'||fmtLetter=='x')) {
|
||||||
|
nfmt+="ll";
|
||||||
|
func="(unsigned long long)("; // Must match %ull to avoid warnings
|
||||||
|
}
|
||||||
string pfmt = "%"+nfmt+fmtLetter;
|
string pfmt = "%"+nfmt+fmtLetter;
|
||||||
|
|
||||||
emitDispState.pushFormat(pfmt);
|
emitDispState.pushFormat(pfmt);
|
||||||
emitDispState.pushArg(*elistp,"");
|
emitDispState.pushArg(*elistp,func);
|
||||||
}
|
}
|
||||||
// Next parameter
|
// Next parameter
|
||||||
*elistp = (*elistp)->nextp();
|
*elistp = (*elistp)->nextp();
|
||||||
@@ -952,7 +1013,6 @@ void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, cha
|
|||||||
|
|
||||||
void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
||||||
string vformat = nodep->text();
|
string vformat = nodep->text();
|
||||||
bool addNewline = (nodep->newline() == '\n');
|
|
||||||
AstNode* elistp = nodep->exprsp();
|
AstNode* elistp = nodep->exprsp();
|
||||||
|
|
||||||
// Convert Verilog display to C printf formats
|
// Convert Verilog display to C printf formats
|
||||||
@@ -1015,7 +1075,7 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
|||||||
if (elistp != NULL) {
|
if (elistp != NULL) {
|
||||||
nodep->v3error("Extra arguments for $display format\n");
|
nodep->v3error("Extra arguments for $display format\n");
|
||||||
}
|
}
|
||||||
if (addNewline) emitDispState.pushFormat("\\n");
|
if (nodep->addNewline()) emitDispState.pushFormat("\\n");
|
||||||
displayEmit(nodep);
|
displayEmit(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1246,12 +1306,8 @@ void EmitCImp::emitWrapEval(AstModule* modp) {
|
|||||||
puts("while (VL_LIKELY(__Vchange)) {\n");
|
puts("while (VL_LIKELY(__Vchange)) {\n");
|
||||||
puts( "VL_DEBUG_IF(cout<<\" Clock loop\"<<endl;);\n");
|
puts( "VL_DEBUG_IF(cout<<\" Clock loop\"<<endl;);\n");
|
||||||
#endif
|
#endif
|
||||||
// Not exactly correct for coverage. w/combo logic interspersed, this is complicated. Punt.
|
|
||||||
// Perhaps have temp & each _combo_ turn it on or off
|
|
||||||
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = true;\n");
|
|
||||||
puts( "vlSymsp->__Vm_activity = true;\n");
|
puts( "vlSymsp->__Vm_activity = true;\n");
|
||||||
puts( "_eval(vlSymsp);\n");
|
puts( "_eval(vlSymsp);\n");
|
||||||
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = false;\n");
|
|
||||||
#ifndef NEW_ORDERING
|
#ifndef NEW_ORDERING
|
||||||
puts( "__Vchange = _change_request(vlSymsp);\n");
|
puts( "__Vchange = _change_request(vlSymsp);\n");
|
||||||
puts( "if (++__VclockLoop > 100) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
|
puts( "if (++__VclockLoop > 100) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
|
||||||
@@ -1284,7 +1340,7 @@ void EmitCImp::emitWrapEval(AstModule* modp) {
|
|||||||
|
|
||||||
void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp) {
|
void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp) {
|
||||||
// Put out a list of signal declarations
|
// Put out a list of signal declarations
|
||||||
// in order of 0:clocks, 1:uint8, 2:uint16, 4:uint32, 5:uint64, 6:wide, 7:arrays
|
// in order of 0:clocks, 1:vluint8, 2:vluint16, 4:vluint32, 5:vluint64, 6:wide, 7:arrays
|
||||||
// This aids cache packing and locality
|
// This aids cache packing and locality
|
||||||
// Largest->smallest reduces the number of pad variables.
|
// Largest->smallest reduces the number of pad variables.
|
||||||
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
|
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3EMITC_H_
|
#ifndef _V3EMITC_H_
|
||||||
#define _V3EMITC_H_ 1
|
#define _V3EMITC_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -22,7 +22,8 @@
|
|||||||
#ifndef _V3EMITCBASE_H_
|
#ifndef _V3EMITCBASE_H_
|
||||||
#define _V3EMITCBASE_H_ 1
|
#define _V3EMITCBASE_H_ 1
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -109,7 +110,7 @@ public:
|
|||||||
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
|
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
|
||||||
static string symClassName() { return v3Global.opt.prefix()+"__Syms"; }
|
static string symClassName() { return v3Global.opt.prefix()+"__Syms"; }
|
||||||
static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; }
|
static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; }
|
||||||
static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp = vlSymsp->TOPp;"; }
|
static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; }
|
||||||
static string modClassName(AstModule* modp) { // Return name of current module being processed
|
static string modClassName(AstModule* modp) { // Return name of current module being processed
|
||||||
if (modp->isTop()) {
|
if (modp->isTop()) {
|
||||||
return v3Global.opt.prefix();
|
return v3Global.opt.prefix();
|
||||||
|
|||||||
+5
-9
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -124,18 +125,14 @@ void EmitCSyms::emitInt() {
|
|||||||
//puts("\n// STATIC STATE\n");
|
//puts("\n// STATIC STATE\n");
|
||||||
|
|
||||||
puts("\n// LOCAL STATE\n");
|
puts("\n// LOCAL STATE\n");
|
||||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
|
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
|
||||||
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
|
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
|
||||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||||
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
|
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
|
||||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||||
puts("bool\t__Vm_didInit;\n");
|
puts("bool\t__Vm_didInit;\n");
|
||||||
if (v3Global.opt.coverage()) {
|
|
||||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
|
||||||
puts("bool __Vm_coverageRequest;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
|
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
|
||||||
puts("\n// SUBCELL STATE\n");
|
puts("\n// SUBCELL STATE\n");
|
||||||
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
||||||
AstScope* scopep = it->first; AstModule* modp = it->second;
|
AstScope* scopep = it->first; AstModule* modp = it->second;
|
||||||
@@ -184,7 +181,6 @@ void EmitCSyms::emitImp() {
|
|||||||
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
|
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
|
||||||
puts("\t, __Vm_activity(false)\n");
|
puts("\t, __Vm_activity(false)\n");
|
||||||
puts("\t, __Vm_didInit(false)\n");
|
puts("\t, __Vm_didInit(false)\n");
|
||||||
if (v3Global.opt.coverage()) puts("\t, __Vm_coverageRequest(false)\n");
|
|
||||||
puts("\t// Setup submodule names\n");
|
puts("\t// Setup submodule names\n");
|
||||||
char comma=',';
|
char comma=',';
|
||||||
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
||||||
|
|||||||
+6
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -96,6 +97,9 @@ public:
|
|||||||
// Imply generating verilated.o
|
// Imply generating verilated.o
|
||||||
if (v3Global.opt.exe()) {
|
if (v3Global.opt.exe()) {
|
||||||
v3Global.opt.addCppFile("verilated.cpp");
|
v3Global.opt.addCppFile("verilated.cpp");
|
||||||
|
if (v3Global.opt.trace()) {
|
||||||
|
v3Global.opt.addCppFile("SpTraceVcdC.cpp");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V3StringSet dirs;
|
V3StringSet dirs;
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3EMITMK_H_
|
#ifndef _V3EMITMK_H_
|
||||||
#define _V3EMITMK_H_ 1
|
#define _V3EMITMK_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+13
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -192,6 +193,16 @@ public:
|
|||||||
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
|
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||||
|
putbs(nodep->verilogKwd());
|
||||||
|
putbs(" (");
|
||||||
|
if (nodep->filenamep()) nodep->filenamep()->iterateChildren(*this);
|
||||||
|
putbs(",");
|
||||||
|
if (nodep->memp()) nodep->memp()->iterateChildren(*this);
|
||||||
|
if (nodep->lsbp()) { putbs(","); nodep->lsbp()->iterateChildren(*this); }
|
||||||
|
if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateChildren(*this); }
|
||||||
|
puts(");\n");
|
||||||
|
}
|
||||||
virtual void visit(AstNodeFor* nodep, AstNUser*) {
|
virtual void visit(AstNodeFor* nodep, AstNUser*) {
|
||||||
puts("for (");
|
puts("for (");
|
||||||
m_suppressSemi = true;
|
m_suppressSemi = true;
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3EMITV_H_
|
#ifndef _V3EMITV_H_
|
||||||
#define _V3EMITV_H_ 1
|
#define _V3EMITV_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+16
-8
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -92,7 +92,7 @@ void FileLine::lineDirective(const char* textp) {
|
|||||||
|
|
||||||
bool FileLine::warnOff(const string& msg, bool flag) {
|
bool FileLine::warnOff(const string& msg, bool flag) {
|
||||||
V3ErrorCode code (msg.c_str());
|
V3ErrorCode code (msg.c_str());
|
||||||
if (code == V3ErrorCode::ERROR) {
|
if (code < V3ErrorCode::FIRST_WARN) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
warnOff(code, flag);
|
warnOff(code, flag);
|
||||||
@@ -168,9 +168,8 @@ void FileLine::v3errorEnd(ostringstream& str) {
|
|||||||
void V3Error::init() {
|
void V3Error::init() {
|
||||||
for (int i=0; i<V3ErrorCode::MAX; i++) {
|
for (int i=0; i<V3ErrorCode::MAX; i++) {
|
||||||
s_describedEachWarn[i] = false;
|
s_describedEachWarn[i] = false;
|
||||||
s_pretendError[i] = false;
|
s_pretendError[i] = V3ErrorCode(i).pretendError();
|
||||||
}
|
}
|
||||||
pretendError(V3ErrorCode::BLKANDNBLK, true);
|
|
||||||
|
|
||||||
if (string(V3ErrorCode(V3ErrorCode::MAX).ascii()) != " MAX") {
|
if (string(V3ErrorCode(V3ErrorCode::MAX).ascii()) != " MAX") {
|
||||||
v3fatalSrc("Enum table in V3ErrorCode::ascii() is munged");
|
v3fatalSrc("Enum table in V3ErrorCode::ascii() is munged");
|
||||||
@@ -204,8 +203,9 @@ void V3Error::abortIfErrors() {
|
|||||||
string V3Error::msgPrefix(V3ErrorCode code) {
|
string V3Error::msgPrefix(V3ErrorCode code) {
|
||||||
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
|
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
|
||||||
else if (code==V3ErrorCode::FATAL) return "%Error: ";
|
else if (code==V3ErrorCode::FATAL) return "%Error: ";
|
||||||
else if (code==V3ErrorCode::ERROR
|
else if (code==V3ErrorCode::ERROR) return "%Error: ";
|
||||||
|| s_pretendError[code]) return "%Error: ";
|
else if (code<V3ErrorCode::FIRST_WARN
|
||||||
|
|| s_pretendError[code]) return "%Error-"+(string)code.ascii()+": ";
|
||||||
else return "%Warning-"+(string)code.ascii()+": ";
|
else return "%Warning-"+(string)code.ascii()+": ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +236,9 @@ void V3Error::v3abort () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void V3Error::v3errorEnd (ostringstream& sstr) {
|
void V3Error::v3errorEnd (ostringstream& sstr) {
|
||||||
|
#ifdef __COVERITY__
|
||||||
|
if (s_errorCode==V3ErrorCode::FATAL) __coverity_panic__(x);
|
||||||
|
#endif
|
||||||
if (s_errorCode!=V3ErrorCode::SUPPRESS || debug()) {
|
if (s_errorCode!=V3ErrorCode::SUPPRESS || debug()) {
|
||||||
cerr<<msgPrefix()<<sstr.str();
|
cerr<<msgPrefix()<<sstr.str();
|
||||||
if (sstr.str()[sstr.str().length()-1] != '\n') {
|
if (sstr.str()[sstr.str().length()-1] != '\n') {
|
||||||
@@ -268,8 +271,13 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
abort();
|
|
||||||
// exit(10);
|
if (V3Error::debugDefault()) {
|
||||||
|
cerr<<msgPrefix()<<"Aborting since under --debug"<<endl;
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-4
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3ERROR_H_
|
#ifndef _V3ERROR_H_
|
||||||
#define _V3ERROR_H_ 1
|
#define _V3ERROR_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -34,9 +35,13 @@ public:
|
|||||||
enum en {
|
enum en {
|
||||||
SUPPRESS, // Warning suppressed by user
|
SUPPRESS, // Warning suppressed by user
|
||||||
FATAL, // Kill the program
|
FATAL, // Kill the program
|
||||||
ERROR, // Error out, can't suppress
|
ERROR, // General error out, can't suppress
|
||||||
|
// Error codes:
|
||||||
|
MULTITOP, // Error: Multiple top level modules
|
||||||
|
TASKNSVAR, // Error: Task I/O not simple
|
||||||
// Warning codes:
|
// Warning codes:
|
||||||
FIRST_WARN, // Just a code so the program knows where to start warnings
|
FIRST_WARN, // Just a code so the program knows where to start warnings
|
||||||
|
//
|
||||||
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
|
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
|
||||||
CASEINCOMPLETE, // Case statement has missing values
|
CASEINCOMPLETE, // Case statement has missing values
|
||||||
CASEOVERLAP, // Case statements overlap
|
CASEOVERLAP, // Case statements overlap
|
||||||
@@ -45,6 +50,7 @@ public:
|
|||||||
COMBDLY, // Combinatorial delayed assignment
|
COMBDLY, // Combinatorial delayed assignment
|
||||||
GENCLK, // Generated Clock
|
GENCLK, // Generated Clock
|
||||||
IMPLICIT, // Implicit wire
|
IMPLICIT, // Implicit wire
|
||||||
|
IMPURE, // Impure function not being inlined
|
||||||
MULTIDRIVEN, // Driven from multiple blocks
|
MULTIDRIVEN, // Driven from multiple blocks
|
||||||
UNDRIVEN, // No drivers
|
UNDRIVEN, // No drivers
|
||||||
UNOPT, // Unoptimizable block
|
UNOPT, // Unoptimizable block
|
||||||
@@ -66,10 +72,11 @@ public:
|
|||||||
const char* names[] = {
|
const char* names[] = {
|
||||||
// Leading spaces indicate it can't be disabled.
|
// Leading spaces indicate it can't be disabled.
|
||||||
" SUPPRESS", " FATAL", " ERROR",
|
" SUPPRESS", " FATAL", " ERROR",
|
||||||
|
"MULTITOP", "TASKNSVAR",
|
||||||
" FIRST_WARN",
|
" FIRST_WARN",
|
||||||
"BLKANDNBLK",
|
"BLKANDNBLK",
|
||||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
|
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
|
||||||
"COMBDLY", "GENCLK", "IMPLICIT",
|
"COMBDLY", "GENCLK", "IMPLICIT", "IMPURE",
|
||||||
"MULTIDRIVEN",
|
"MULTIDRIVEN",
|
||||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||||
"VARHIDDEN", "WIDTH",
|
"VARHIDDEN", "WIDTH",
|
||||||
@@ -79,6 +86,9 @@ public:
|
|||||||
};
|
};
|
||||||
// Warnings that warn about nasty side effects
|
// Warnings that warn about nasty side effects
|
||||||
bool dangerous() const { return ( m_e==COMBDLY );};
|
bool dangerous() const { return ( m_e==COMBDLY );};
|
||||||
|
// Warnings we'll present to the user as errors
|
||||||
|
// Later -Werror- options may make more of these.
|
||||||
|
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE); };
|
||||||
};
|
};
|
||||||
inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
|||||||
+7
-6
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2004-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -30,7 +30,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -64,11 +65,8 @@ private:
|
|||||||
if (nodep->isWide()) {
|
if (nodep->isWide()) {
|
||||||
return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin()));
|
return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin()));
|
||||||
} else {
|
} else {
|
||||||
V3Number zero (nodep->fileline(), nodep->widthMin(),0);
|
|
||||||
V3Number masksmall (nodep->fileline(), nodep->widthMin());
|
|
||||||
masksmall.opNot(zero);
|
|
||||||
V3Number mask (nodep->fileline(), longOrQuadWidth(nodep));
|
V3Number mask (nodep->fileline(), longOrQuadWidth(nodep));
|
||||||
mask.opAssign(masksmall);
|
mask.setMask(nodep->widthMin());
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,6 +658,9 @@ private:
|
|||||||
// Lhs or Rhs may be word, long, or quad.
|
// Lhs or Rhs may be word, long, or quad.
|
||||||
// newAstWordSelClone nicely abstracts the difference.
|
// newAstWordSelClone nicely abstracts the difference.
|
||||||
int rhsshift = rhsp->rhsp()->widthMin();
|
int rhsshift = rhsp->rhsp()->widthMin();
|
||||||
|
// Sometimes doing the words backwards is preferrable.
|
||||||
|
// When we have x={x,foo} backwards is better, when x={foo,x} forward is better
|
||||||
|
// However V3Subst tends to rip this up, so not worth optimizing now.
|
||||||
for (int w=0; w<rhsp->widthWords(); w++) {
|
for (int w=0; w<rhsp->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w,
|
addWordAssign(nodep, w,
|
||||||
new AstOr (rhsp->fileline(),
|
new AstOr (rhsp->fileline(),
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3EXPAND_H_
|
#ifndef _V3EXPAND_H_
|
||||||
#define _V3EXPAND_H_ 1
|
#define _V3EXPAND_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+6
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3FILE_H_
|
#ifndef _V3FILE_H_
|
||||||
#define _V3FILE_H_ 1
|
#define _V3FILE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
@@ -42,6 +43,9 @@ public:
|
|||||||
}
|
}
|
||||||
static ofstream* new_ofstream(const string& filename, bool append=false) {
|
static ofstream* new_ofstream(const string& filename, bool append=false) {
|
||||||
addTgtDepend(filename);
|
addTgtDepend(filename);
|
||||||
|
return new_ofstream_nodepend (filename, append);
|
||||||
|
}
|
||||||
|
static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
|
||||||
if (append) {
|
if (append) {
|
||||||
return new ofstream(filename.c_str(), ios::app);
|
return new ofstream(filename.c_str(), ios::app);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+13
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -197,10 +198,18 @@ public:
|
|||||||
m_substTreep = NULL;
|
m_substTreep = NULL;
|
||||||
m_buffersOnly = buffersOnly;
|
m_buffersOnly = buffersOnly;
|
||||||
m_lhsVarRef = NULL;
|
m_lhsVarRef = NULL;
|
||||||
|
// Iterate
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
|
// Check results
|
||||||
if (!m_substTreep) {
|
if (!m_substTreep) {
|
||||||
clearSimple("No assignment found\n");
|
clearSimple("No assignment found\n");
|
||||||
}
|
}
|
||||||
|
for (GateVarRefList::const_iterator it = rhsVarRefs().begin();
|
||||||
|
it != rhsVarRefs().end(); ++it) {
|
||||||
|
if (m_lhsVarRef && m_lhsVarRef->varScopep() == (*it)->varScopep()) {
|
||||||
|
clearSimple("Circular logic\n"); // Oh my, we'll get a UNOPTFLAT much later.
|
||||||
|
}
|
||||||
|
}
|
||||||
if (debug()>=9 && !m_isSimple) {
|
if (debug()>=9 && !m_isSimple) {
|
||||||
nodep->dumpTree(cout,"\tgate!Ok: ");
|
nodep->dumpTree(cout,"\tgate!Ok: ");
|
||||||
}
|
}
|
||||||
@@ -223,6 +232,7 @@ private:
|
|||||||
//Entire netlist:
|
//Entire netlist:
|
||||||
// AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet
|
// AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet
|
||||||
// {statement}Node::userp -> GateLogicVertex* for this statement
|
// {statement}Node::userp -> GateLogicVertex* for this statement
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
||||||
GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored
|
GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored
|
||||||
@@ -457,6 +467,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Process it
|
||||||
if (!doit) {
|
if (!doit) {
|
||||||
if (allowMultiIn && (debug()>=9)) {
|
if (allowMultiIn && (debug()>=9)) {
|
||||||
UINFO(9, "Not ok simp"<<okVisitor.isSimple()<<" mi"<<multiInputs
|
UINFO(9, "Not ok simp"<<okVisitor.isSimple()<<" mi"<<multiInputs
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3GATE_H_
|
#ifndef _V3GATE_H_
|
||||||
#define _V3GATE_H_ 1
|
#define _V3GATE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -24,7 +24,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3GENCLK_H_
|
#ifndef _V3GENCLK_H_
|
||||||
#define _V3GENCLK_H_ 1
|
#define _V3GENCLK_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -22,7 +22,8 @@
|
|||||||
#ifndef _V3GLOBAL_H_
|
#ifndef _V3GLOBAL_H_
|
||||||
#define _V3GLOBAL_H_ 1
|
#define _V3GLOBAL_H_ 1
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
|
|||||||
+8
-3
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -179,6 +180,7 @@ void V3Graph::userClearVertices() {
|
|||||||
// the extra code on each read of user() would probably slow things down more then help.
|
// the extra code on each read of user() would probably slow things down more then help.
|
||||||
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||||
vertexp->user(0);
|
vertexp->user(0);
|
||||||
|
vertexp->userp(NULL); // Its a union, but might be different size then user()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +188,8 @@ void V3Graph::userClearEdges() {
|
|||||||
// Clear user() in all of tree
|
// Clear user() in all of tree
|
||||||
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||||
edgep->userp(NULL);
|
edgep->user(0);
|
||||||
|
edgep->userp(NULL); // Its a union, but might be different size then user()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,6 +255,8 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) {
|
|||||||
*logp<<"digraph v3graph {\n";
|
*logp<<"digraph v3graph {\n";
|
||||||
*logp<<"\trankdir="<<dotRankDir()<<"\n";
|
*logp<<"\trankdir="<<dotRankDir()<<"\n";
|
||||||
*logp<<"\tsize="<<"\"7.5,10\""<<"\n";
|
*logp<<"\tsize="<<"\"7.5,10\""<<"\n";
|
||||||
|
*logp<<"\tnTITLE\t[fontsize=20 label=\""<<filename<<"\", shape=box, style=bold, color=black];\n";
|
||||||
|
*logp<<"\n";
|
||||||
|
|
||||||
// List of all possible subgraphs
|
// List of all possible subgraphs
|
||||||
typedef multimap<string,V3GraphVertex*> SubgraphMmap;
|
typedef multimap<string,V3GraphVertex*> SubgraphMmap;
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3GRAPH_H_
|
#ifndef _V3GRAPH_H_
|
||||||
#define _V3GRAPH_H_ 1
|
#define _V3GRAPH_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3List.h"
|
#include "V3List.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
+11
-6
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
// Break the minimal number of backward edges to make the graph acyclic
|
// Break the minimal number of backward edges to make the graph acyclic
|
||||||
|
|
||||||
class GraphAcycVertex : public V3GraphVertex {
|
class GraphAcycVertex : public V3GraphVertex {
|
||||||
|
// user() is used for various sub-algorithm pieces
|
||||||
V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents
|
V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents
|
||||||
protected:
|
protected:
|
||||||
friend class GraphAcyc;
|
friend class GraphAcyc;
|
||||||
@@ -307,6 +309,9 @@ void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) {
|
|||||||
avertexp->setDelete(); // Mark so we won't delete it twice
|
avertexp->setDelete(); // Mark so we won't delete it twice
|
||||||
// Make a new edge connecting the two vertices directly
|
// Make a new edge connecting the two vertices directly
|
||||||
// If both are breakable, we pick the one with less weight, else it's arbitrary
|
// If both are breakable, we pick the one with less weight, else it's arbitrary
|
||||||
|
// We can forget about the origEdge list for the "non-selected" set of edges,
|
||||||
|
// as we need to break only one set or the other set of edges, not both.
|
||||||
|
// (This is why we must give preference to the cutable set.)
|
||||||
V3GraphEdge* templateEdgep = ( (inEdgep->cutable()
|
V3GraphEdge* templateEdgep = ( (inEdgep->cutable()
|
||||||
&& (!outEdgep->cutable()
|
&& (!outEdgep->cutable()
|
||||||
|| inEdgep->weight()<outEdgep->weight() ))
|
|| inEdgep->weight()<outEdgep->weight() ))
|
||||||
@@ -352,7 +357,7 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
|
|||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
// Clear marks
|
// Clear marks
|
||||||
for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||||
edgep->top()->user(false);
|
edgep->top()->userp(NULL);
|
||||||
}
|
}
|
||||||
// Mark edges and detect duplications
|
// Mark edges and detect duplications
|
||||||
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
|
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
|
||||||
@@ -363,16 +368,16 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
|
|||||||
if (!prevEdgep->cutable()) {
|
if (!prevEdgep->cutable()) {
|
||||||
// !cutable duplicates prev !cutable: we can ignore it, redundant
|
// !cutable duplicates prev !cutable: we can ignore it, redundant
|
||||||
// cutable duplicates prev !cutable: know it's not a relevant loop, ignore it
|
// cutable duplicates prev !cutable: know it's not a relevant loop, ignore it
|
||||||
UINFO(8," DelDupEdge "<<avertexp<<endl);
|
UINFO(8," DelDupEdge "<<avertexp<<" -> "<<edgep->top()<<endl);
|
||||||
edgep->unlinkDelete(); edgep = NULL;
|
edgep->unlinkDelete(); edgep = NULL;
|
||||||
} else if (!edgep->cutable()) {
|
} else if (!edgep->cutable()) {
|
||||||
// !cutable duplicates prev cutable: delete the earlier cutable
|
// !cutable duplicates prev cutable: delete the earlier cutable
|
||||||
UINFO(8," DelDupPrev "<<avertexp<<endl);
|
UINFO(8," DelDupPrev "<<avertexp<<" -> "<<prevEdgep->top()<<endl);
|
||||||
prevEdgep->unlinkDelete(); prevEdgep = NULL;
|
prevEdgep->unlinkDelete(); prevEdgep = NULL;
|
||||||
outVertexp->userp(edgep);
|
outVertexp->userp(edgep);
|
||||||
} else {
|
} else {
|
||||||
// cutable duplicates prev cutable: combine weights
|
// cutable duplicates prev cutable: combine weights
|
||||||
UINFO(8," DelDupComb "<<avertexp<<endl);
|
UINFO(8," DelDupComb "<<avertexp<<" -> "<<edgep->top()<<endl);
|
||||||
prevEdgep->weight (prevEdgep->weight() + edgep->weight());
|
prevEdgep->weight (prevEdgep->weight() + edgep->weight());
|
||||||
addOrigEdgep (prevEdgep, edgep);
|
addOrigEdgep (prevEdgep, edgep);
|
||||||
edgep->unlinkDelete(); edgep = NULL;
|
edgep->unlinkDelete(); edgep = NULL;
|
||||||
|
|||||||
+4
-3
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -85,7 +86,7 @@ private:
|
|||||||
void vertexIterate(V3GraphVertex* vertexp) {
|
void vertexIterate(V3GraphVertex* vertexp) {
|
||||||
// Clear marks
|
// Clear marks
|
||||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||||
edgep->top()->user(false);
|
edgep->top()->userp(NULL);
|
||||||
}
|
}
|
||||||
// Mark edges and detect duplications
|
// Mark edges and detect duplications
|
||||||
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
|
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3GRAPHALG_H_
|
#ifndef _V3GRAPHALG_H_
|
||||||
#define _V3GRAPHALG_H_ 1
|
#define _V3GRAPHALG_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
#include "V3Graph.h"
|
#include "V3Graph.h"
|
||||||
|
|||||||
+4
-3
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -64,7 +65,7 @@ class GraphNfaToDfa : GraphAlg {
|
|||||||
private:
|
private:
|
||||||
// TYPES
|
// TYPES
|
||||||
typedef deque<DfaVertex*> DfaStates;
|
typedef deque<DfaVertex*> DfaStates;
|
||||||
typedef multimap<uint64_t,DfaVertex*> HashMap;
|
typedef multimap<vluint64_t,DfaVertex*> HashMap;
|
||||||
|
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
uint32_t m_step; // Processing step, so we can avoid clearUser all the time
|
uint32_t m_step; // Processing step, so we can avoid clearUser all the time
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3GRAPHDFA_H_
|
#ifndef _V3GRAPHDFA_H_
|
||||||
#define _V3GRAPHDFA_H_ 1
|
#define _V3GRAPHDFA_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
|
|||||||
+32
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -310,6 +311,34 @@ public:
|
|||||||
gp->dfaReduce();
|
gp->dfaReduce();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
class V3GraphTestImport : public V3GraphTest {
|
||||||
|
|
||||||
|
void dotImport();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual string name() { return "import"; }
|
||||||
|
virtual void runTest() {
|
||||||
|
DfaGraph* gp = &m_graph;
|
||||||
|
if (V3GraphTest::debug()) gp->debug(9);
|
||||||
|
dotImport();
|
||||||
|
dump();
|
||||||
|
gp->acyclic(&V3GraphEdge::followAlwaysTrue);
|
||||||
|
dump();
|
||||||
|
gp->rank(&V3GraphEdge::followAlwaysTrue);
|
||||||
|
dump();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
# include "graph_export.cpp"
|
||||||
|
#else
|
||||||
|
void V3GraphTestImport::dotImport() {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
void V3Graph::test() {
|
void V3Graph::test() {
|
||||||
@@ -319,5 +348,6 @@ void V3Graph::test() {
|
|||||||
{ V3GraphTestAcyc test; test.run(); }
|
{ V3GraphTestAcyc test; test.run(); }
|
||||||
{ V3GraphTestVars test; test.run(); }
|
{ V3GraphTestVars test; test.run(); }
|
||||||
{ V3GraphTestDfa test; test.run(); }
|
{ V3GraphTestDfa test; test.run(); }
|
||||||
|
{ V3GraphTestImport test; test.run(); }
|
||||||
if (V3GraphTest::debug()) v3fatalSrc("Exiting due to graph testing enabled");
|
if (V3GraphTest::debug()) v3fatalSrc("Exiting due to graph testing enabled");
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3HASHED_H_
|
#ifndef _V3HASHED_H_
|
||||||
#define _V3HASHED_H_ 1
|
#define _V3HASHED_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+6
-7
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -29,7 +29,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -111,7 +112,6 @@ private:
|
|||||||
nodep->name(), nodep->modp()->origName());
|
nodep->name(), nodep->modp()->origName());
|
||||||
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
||||||
// Create assignments to the pins
|
// Create assignments to the pins
|
||||||
AstNode* assignlistsp = NULL;
|
|
||||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||||
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
|
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
|
||||||
// First, simplify it
|
// First, simplify it
|
||||||
@@ -142,13 +142,11 @@ private:
|
|||||||
// Cleanup var names, etc, to not conflict
|
// Cleanup var names, etc, to not conflict
|
||||||
m_cellp = nodep;
|
m_cellp = nodep;
|
||||||
newmodp->iterateAndNext(*this);
|
newmodp->iterateAndNext(*this);
|
||||||
if (assignlistsp) assignlistsp->iterateAndNext(*this); // And cleanup any varrefs under assigns we created...
|
|
||||||
m_cellp = NULL;
|
m_cellp = NULL;
|
||||||
// Move statements to top module
|
// Move statements to top module
|
||||||
if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); }
|
if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); }
|
||||||
AstNode* stmtsp = newmodp->stmtsp();
|
AstNode* stmtsp = newmodp->stmtsp();
|
||||||
if (stmtsp) stmtsp->unlinkFrBackWithNext();
|
if (stmtsp) stmtsp->unlinkFrBackWithNext();
|
||||||
if (assignlistsp) m_modp->addStmtp(assignlistsp);
|
|
||||||
if (stmtsp) m_modp->addStmtp(stmtsp);
|
if (stmtsp) m_modp->addStmtp(stmtsp);
|
||||||
// Remove the cell
|
// Remove the cell
|
||||||
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
|
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
|
||||||
@@ -237,8 +235,8 @@ private:
|
|||||||
}
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||||
if (m_cellp
|
// Similar code in V3Begin
|
||||||
&& nodep->name().find("%m") != string::npos) {
|
if (m_cellp && nodep->needScopeTracking()) {
|
||||||
// To keep correct visual order, must add before other Text's
|
// To keep correct visual order, must add before other Text's
|
||||||
AstNode* afterp = nodep->scopeAttrp();
|
AstNode* afterp = nodep->scopeAttrp();
|
||||||
if (afterp) afterp->unlinkFrBackWithNext();
|
if (afterp) afterp->unlinkFrBackWithNext();
|
||||||
@@ -353,6 +351,7 @@ private:
|
|||||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||||
// Cleanup link until V3LinkDot can correct it
|
// Cleanup link until V3LinkDot can correct it
|
||||||
nodep->taskp(NULL);
|
nodep->taskp(NULL);
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
// Nop's to speed up the loop
|
// Nop's to speed up the loop
|
||||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3INLINE_H_
|
#ifndef _V3INLINE_H_
|
||||||
#define _V3INLINE_H_ 1
|
#define _V3INLINE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+15
-10
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -79,7 +80,7 @@ private:
|
|||||||
// or ASSIGNW(expr,VARXREF(p)) (if sub's output)
|
// or ASSIGNW(expr,VARXREF(p)) (if sub's output)
|
||||||
UINFO(4," PIN "<<nodep<<endl);
|
UINFO(4," PIN "<<nodep<<endl);
|
||||||
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
|
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
|
||||||
if (nodep->modVarp()->isOutput() && nodep->exprp()->castConst())
|
if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst())
|
||||||
nodep->v3error("Output pin is assigned to a constant, electrical short");
|
nodep->v3error("Output pin is assigned to a constant, electrical short");
|
||||||
// Use userp on the PIN to indicate we created an assign for this pin
|
// Use userp on the PIN to indicate we created an assign for this pin
|
||||||
if (!nodep->user()) {
|
if (!nodep->user()) {
|
||||||
@@ -90,7 +91,9 @@ private:
|
|||||||
AstNode* exprp = nodep->exprp()->cloneTree(false);
|
AstNode* exprp = nodep->exprp()->cloneTree(false);
|
||||||
if (nodep->width() != nodep->modVarp()->width())
|
if (nodep->width() != nodep->modVarp()->width())
|
||||||
nodep->v3fatalSrc("Width mismatch, should have been handled in pinReconnectSimple\n");
|
nodep->v3fatalSrc("Width mismatch, should have been handled in pinReconnectSimple\n");
|
||||||
if (nodep->modVarp()->isOutput()) {
|
if (nodep->modVarp()->isInout()) {
|
||||||
|
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
|
||||||
|
} else if (nodep->modVarp()->isOutput()) {
|
||||||
AstNode* rhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
AstNode* rhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
||||||
rhsp->widthSignedFrom(nodep);
|
rhsp->widthSignedFrom(nodep);
|
||||||
AstAssignW* assp = new AstAssignW (exprp->fileline(), exprp, rhsp);
|
AstAssignW* assp = new AstAssignW (exprp->fileline(), exprp, rhsp);
|
||||||
@@ -160,8 +163,8 @@ private:
|
|||||||
// Somewhat illogically, we need to rename the orignal name of the cell too.
|
// Somewhat illogically, we need to rename the orignal name of the cell too.
|
||||||
// as that is the name users expect for dotting
|
// as that is the name users expect for dotting
|
||||||
// The spec says we add [x], but that won't work in C...
|
// The spec says we add [x], but that won't work in C...
|
||||||
newp->name(newp->name()+"__"+cvtToStr(m_instNum));
|
newp->name(newp->name()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
|
||||||
newp->origName(newp->origName()+"__"+cvtToStr(m_instNum));
|
newp->origName(newp->origName()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
|
||||||
// Fixup pins
|
// Fixup pins
|
||||||
newp->pinsp()->iterateAndNext(*this);
|
newp->pinsp()->iterateAndNext(*this);
|
||||||
if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<<endl; }
|
if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<<endl; }
|
||||||
@@ -198,7 +201,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save some time
|
// Save some time
|
||||||
virtual void visit(AstNodeStmt*, AstNUser*) {}
|
virtual void visit(AstNodeMath*, AstNUser*) {}
|
||||||
//--------------------
|
//--------------------
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
@@ -236,12 +239,14 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstModule* modp) {
|
|||||||
} else {
|
} else {
|
||||||
// Make a new temp wire
|
// Make a new temp wire
|
||||||
//if (1||debug()>=9) { pinp->dumpTree(cout,"in_pin:"); }
|
//if (1||debug()>=9) { pinp->dumpTree(cout,"in_pin:"); }
|
||||||
AstAssignW* assignp;
|
AstAssignW* assignp = NULL;
|
||||||
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
|
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
|
||||||
string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name();
|
string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name();
|
||||||
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
||||||
modp->addStmtp(newvarp);
|
modp->addStmtp(newvarp);
|
||||||
if (pinVarp->isOutput()) {
|
if (pinVarp->isInout()) {
|
||||||
|
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
|
||||||
|
} else if (pinVarp->isOutput()) {
|
||||||
// See also V3Inst
|
// See also V3Inst
|
||||||
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
|
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
|
||||||
if (pinp->width() > rhsp->width()) {
|
if (pinp->width() > rhsp->width()) {
|
||||||
@@ -265,7 +270,7 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstModule* modp) {
|
|||||||
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
|
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
|
||||||
}
|
}
|
||||||
pinp->widthSignedFrom(pinp->exprp());
|
pinp->widthSignedFrom(pinp->exprp());
|
||||||
modp->addStmtp(assignp);
|
if (assignp) modp->addStmtp(assignp);
|
||||||
//if (1||debug()) { pinp->dumpTree(cout," out:"); }
|
//if (1||debug()) { pinp->dumpTree(cout," out:"); }
|
||||||
//if (1||debug()) { assignp->dumpTree(cout," aout:"); }
|
//if (1||debug()) { assignp->dumpTree(cout," aout:"); }
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3INST_H_
|
#ifndef _V3INST_H_
|
||||||
#define _V3INST_H_ 1
|
#define _V3INST_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2005-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3LANGUAGEWORDS_H_
|
#ifndef _V3LANGUAGEWORDS_H_
|
||||||
#define _V3LANGUAGEWORDS_H_ 1
|
#define _V3LANGUAGEWORDS_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|||||||
+300
-138
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -28,7 +28,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -38,152 +39,243 @@
|
|||||||
#include "V3Life.h"
|
#include "V3Life.h"
|
||||||
#include "V3Stats.h"
|
#include "V3Stats.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
#include "V3Const.h"
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Life state, as a visitor of each AstNode
|
// Structure for global state
|
||||||
|
|
||||||
class LifeVarEntry {
|
class LifeState {
|
||||||
AstNode* m_assignp; // Last assignment to this varscope
|
// STATE
|
||||||
bool m_firstSet; // True if creation was a set (and thus block above may have a set that can be deleted
|
|
||||||
public:
|
public:
|
||||||
LifeVarEntry() { // Construction for when a var is used
|
V3Double0 m_statAssnDel; // Statistic tracking
|
||||||
clearAssign();
|
V3Double0 m_statAssnCon; // Statistic tracking
|
||||||
m_firstSet = false;
|
|
||||||
|
public:
|
||||||
|
LifeState() {}
|
||||||
|
~LifeState() {
|
||||||
|
V3Stats::addStat("Optimizations, Lifetime assign deletions", m_statAssnDel);
|
||||||
|
V3Stats::addStat("Optimizations, Lifetime constant prop", m_statAssnCon);
|
||||||
}
|
}
|
||||||
LifeVarEntry(AstNode* assp) { // Construction for when a var is set
|
|
||||||
m_assignp = assp;
|
|
||||||
m_firstSet = true;
|
|
||||||
}
|
|
||||||
LifeVarEntry(bool) { // Construction for when a var is set, but ass isn't
|
|
||||||
m_assignp = NULL;
|
|
||||||
m_firstSet = true;
|
|
||||||
}
|
|
||||||
AstNode* assignp() const { return m_assignp; }
|
|
||||||
bool firstSet() const { return m_firstSet; }
|
|
||||||
void clearAssign() { m_assignp = NULL; }
|
|
||||||
void newerAssign(AstNode* assp) { m_assignp = assp; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LifeVisitor : public AstNVisitor {
|
//######################################################################
|
||||||
private:
|
// Structure for each variable encountered
|
||||||
// NODE STATE
|
|
||||||
// AstVarScope::user() -> int. Used in combining to detect duplicates
|
|
||||||
|
|
||||||
// STATE
|
class LifeVarEntry {
|
||||||
//static int debug() { return 9; }
|
AstNodeAssign* m_assignp; // Last assignment to this varscope, NULL if no longer relevant
|
||||||
int m_ifCount; // If counter
|
AstConst* m_constp; // Known constant value
|
||||||
V3Double0 m_statAssnDel; // Statistic tracking
|
bool m_setBeforeUse; // First access was a set (and thus block above may have a set that can be deleted
|
||||||
|
bool m_everSet; // Was ever assigned (and thus above block may not preserve constant propagation)
|
||||||
|
|
||||||
|
inline void init (bool setBeforeUse) {
|
||||||
|
m_assignp = NULL;
|
||||||
|
m_constp = NULL;
|
||||||
|
m_setBeforeUse = setBeforeUse;
|
||||||
|
m_everSet = false;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
class SIMPLEASSIGN {};
|
||||||
|
class COMPLEXASSIGN {};
|
||||||
|
class CONSUMED {};
|
||||||
|
|
||||||
|
LifeVarEntry(SIMPLEASSIGN, AstNodeAssign* assp) {
|
||||||
|
init(true); simpleAssign(assp);
|
||||||
|
}
|
||||||
|
LifeVarEntry(COMPLEXASSIGN) {
|
||||||
|
init(false); complexAssign();
|
||||||
|
}
|
||||||
|
LifeVarEntry(CONSUMED) {
|
||||||
|
init(false); consumed();
|
||||||
|
}
|
||||||
|
~LifeVarEntry() {}
|
||||||
|
inline void simpleAssign(AstNodeAssign* assp) { // New simple A=.... assignment
|
||||||
|
m_assignp = assp;
|
||||||
|
m_constp = NULL;
|
||||||
|
m_everSet = true;
|
||||||
|
if (assp->rhsp()->castConst()) m_constp = assp->rhsp()->castConst();
|
||||||
|
}
|
||||||
|
inline void complexAssign() { // A[x]=... or some complicated assignment
|
||||||
|
m_assignp = NULL;
|
||||||
|
m_constp = NULL;
|
||||||
|
m_everSet = true;
|
||||||
|
}
|
||||||
|
inline void consumed() { // Rvalue read of A
|
||||||
|
m_assignp = NULL;
|
||||||
|
}
|
||||||
|
AstNodeAssign* assignp() const { return m_assignp; }
|
||||||
|
AstConst* constNodep() const { return m_constp; }
|
||||||
|
bool setBeforeUse() const { return m_setBeforeUse; }
|
||||||
|
bool everSet() const { return m_everSet; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
// Structure for all variables under a given meta-basic block
|
||||||
|
|
||||||
|
class LifeBlock {
|
||||||
|
// NODE STATE
|
||||||
|
// Cleared each AstIf:
|
||||||
|
// AstVarScope::user() -> int. Used in combining to detect duplicates
|
||||||
|
|
||||||
// LIFE MAP
|
// LIFE MAP
|
||||||
// For each basic block, we'll make a new map of what variables that if/else is changing
|
// For each basic block, we'll make a new map of what variables that if/else is changing
|
||||||
typedef std::map<AstVarScope*, LifeVarEntry> LifeMap;
|
typedef std::map<AstVarScope*, LifeVarEntry> LifeMap;
|
||||||
LifeMap *m_lifep; // Current active lifetime map for current scope
|
LifeMap m_map; // Current active lifetime map for current scope
|
||||||
|
LifeBlock* m_aboveLifep; // Upper life, or NULL
|
||||||
|
LifeState* m_statep; // Current global state
|
||||||
|
|
||||||
|
public:
|
||||||
|
LifeBlock(LifeBlock* aboveLifep, LifeState* statep) {
|
||||||
|
m_aboveLifep = aboveLifep; // Null if top
|
||||||
|
m_statep = statep;
|
||||||
|
}
|
||||||
|
~LifeBlock() {}
|
||||||
// METHODS
|
// METHODS
|
||||||
void checkRemoveAssign(LifeVarEntry* entp) {
|
void checkRemoveAssign(const LifeMap::iterator& it) {
|
||||||
// Check the var entry, and remove if appropriate
|
AstVar* varp = it->first->varp();
|
||||||
if (AstNode* oldassp = entp->assignp()) {
|
LifeVarEntry* entp = &(it->second);
|
||||||
UINFO(7," PREV: "<<oldassp<<endl);
|
if (!varp->isSigPublic()) {
|
||||||
// Redundant assignment, in same level block
|
// Rather then track what sigs AstUCFunc/AstUCStmt may change,
|
||||||
if (debug()>4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK ");
|
// we just don't optimize any public sigs
|
||||||
entp->clearAssign();
|
// Check the var entry, and remove if appropriate
|
||||||
oldassp->unlinkFrBack();
|
if (AstNode* oldassp = entp->assignp()) {
|
||||||
pushDeletep(oldassp);
|
UINFO(7," PREV: "<<oldassp<<endl);
|
||||||
m_statAssnDel++;
|
// Redundant assignment, in same level block
|
||||||
|
if (debug()>4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK ");
|
||||||
|
entp->complexAssign();
|
||||||
|
oldassp->unlinkFrBack()->deleteTree(); oldassp=NULL;
|
||||||
|
m_statep->m_statAssnDel++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void setLast(AstVarScope* nodep, AstNode* assp) {
|
void simpleAssign(AstVarScope* nodep, AstNodeAssign* assp) {
|
||||||
// Do we have a old assignment we can nuke?
|
// Do we have a old assignment we can nuke?
|
||||||
UINFO(4," ASSIGNof: "<<nodep<<endl);
|
UINFO(4," ASSIGNof: "<<nodep<<endl);
|
||||||
UINFO(7," new: "<<assp<<endl);
|
UINFO(7," new: "<<assp<<endl);
|
||||||
LifeMap::iterator iter = m_lifep->find(nodep);
|
LifeMap::iterator it = m_map.find(nodep);
|
||||||
if (iter != m_lifep->end()) {
|
if (it != m_map.end()) {
|
||||||
checkRemoveAssign(&(iter->second));
|
checkRemoveAssign(it);
|
||||||
iter->second.newerAssign(assp);
|
it->second.simpleAssign(assp);
|
||||||
} else {
|
} else {
|
||||||
m_lifep->insert(make_pair(nodep,LifeVarEntry(assp)));
|
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::SIMPLEASSIGN(), assp)));
|
||||||
}
|
}
|
||||||
//lifeDump();
|
//lifeDump();
|
||||||
}
|
}
|
||||||
void clearLastAssign(AstVarScope* nodep) {
|
void complexAssign(AstVarScope* nodep) {
|
||||||
UINFO(4," clearof: "<<nodep<<endl);
|
UINFO(4," clearof: "<<nodep<<endl);
|
||||||
LifeMap::iterator iter = m_lifep->find(nodep);
|
LifeMap::iterator it = m_map.find(nodep);
|
||||||
if (iter != m_lifep->end()) {
|
if (it != m_map.end()) {
|
||||||
iter->second.clearAssign();
|
it->second.complexAssign();
|
||||||
} else {
|
} else {
|
||||||
m_lifep->insert(make_pair(nodep,LifeVarEntry()));
|
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void lifeDump(LifeMap* lifep) {
|
void varUsageReplace (AstVarScope* nodep, AstVarRef* varrefp) {
|
||||||
|
// Variable rvalue. If it references a constant, we can simply replace it
|
||||||
|
LifeMap::iterator it = m_map.find(nodep);
|
||||||
|
if (it != m_map.end()) {
|
||||||
|
if (AstConst* constp = it->second.constNodep()) {
|
||||||
|
if (!varrefp->varp()->isSigPublic()) {
|
||||||
|
// Aha, variable is constant; substitute in.
|
||||||
|
// We'll later constant propagate
|
||||||
|
UINFO(4," replaceconst: "<<varrefp<<endl);
|
||||||
|
varrefp->replaceWith(constp->cloneTree(false));
|
||||||
|
varrefp->deleteTree(); varrefp=NULL;
|
||||||
|
m_statep->m_statAssnCon++;
|
||||||
|
return; // **DONE, no longer a var reference**
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UINFO(4," usage: "<<nodep<<endl);
|
||||||
|
it->second.consumed();
|
||||||
|
} else {
|
||||||
|
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::CONSUMED())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void complexAssignFind(AstVarScope* nodep) {
|
||||||
|
LifeMap::iterator it = m_map.find(nodep);
|
||||||
|
if (it != m_map.end()) {
|
||||||
|
UINFO(4," casfind: "<<it->first<<endl);
|
||||||
|
it->second.complexAssign();
|
||||||
|
} else {
|
||||||
|
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void consumedFind(AstVarScope* nodep) {
|
||||||
|
LifeMap::iterator it = m_map.find(nodep);
|
||||||
|
if (it != m_map.end()) {
|
||||||
|
it->second.consumed();
|
||||||
|
} else {
|
||||||
|
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::CONSUMED())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void lifeToAbove() {
|
||||||
|
// Any varrefs under a if/else branch affect statements outside and after the if/else
|
||||||
|
if (!m_aboveLifep) v3fatalSrc("Pushing life when already at the top level");
|
||||||
|
for (LifeMap::iterator it = m_map.begin(); it!=m_map.end(); ++it) {
|
||||||
|
AstVarScope* nodep = it->first;
|
||||||
|
m_aboveLifep->complexAssignFind(nodep);
|
||||||
|
if (it->second.everSet()) {
|
||||||
|
// Record there may be an assignment, so we don't constant propagate across the if.
|
||||||
|
complexAssignFind(nodep);
|
||||||
|
} else {
|
||||||
|
// Record consumption, so we don't eliminate earlier assignments
|
||||||
|
consumedFind(nodep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void dualBranch (LifeBlock* life1p, LifeBlock* life2p) {
|
||||||
|
// Find any common sets on both branches of IF and propagate upwards
|
||||||
|
//life1p->lifeDump();
|
||||||
|
//life2p->lifeDump();
|
||||||
|
AstNode::userClearTree(); // userp() used on entire tree
|
||||||
|
for (LifeMap::iterator it = life1p->m_map.begin(); it!=life1p->m_map.end(); ++it) {
|
||||||
|
// When the if branch sets a var before it's used, mark that variable
|
||||||
|
if (it->second.setBeforeUse()) it->first->user(1);
|
||||||
|
}
|
||||||
|
for (LifeMap::iterator it = life2p->m_map.begin(); it!=life2p->m_map.end(); ++it) {
|
||||||
|
// When the else branch sets a var before it's used
|
||||||
|
AstVarScope* nodep = it->first;
|
||||||
|
if (it->second.setBeforeUse() && nodep->user()) {
|
||||||
|
// Both branches set the var, we can remove the assignment before the IF.
|
||||||
|
UINFO(4,"DUALBRANCH "<<nodep<<endl);
|
||||||
|
LifeMap::iterator itab = m_map.find(nodep);
|
||||||
|
if (itab != m_map.end()) {
|
||||||
|
checkRemoveAssign(itab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//this->lifeDump();
|
||||||
|
}
|
||||||
|
// DEBUG
|
||||||
|
void lifeDump() {
|
||||||
UINFO(5, " LifeMap:"<<endl);
|
UINFO(5, " LifeMap:"<<endl);
|
||||||
for (LifeMap::iterator it = lifep->begin(); it!=lifep->end(); ++it) {
|
for (LifeMap::iterator it = m_map.begin(); it!=m_map.end(); ++it) {
|
||||||
UINFO(5, " Ent: "
|
UINFO(5, " Ent: "
|
||||||
<<(it->second.firstSet()?"[F] ":" ")
|
<<(it->second.setBeforeUse()?"[F] ":" ")
|
||||||
<<it->first<<endl);
|
<<it->first<<endl);
|
||||||
if (it->second.assignp()) {
|
if (it->second.assignp()) {
|
||||||
UINFO(5, " Ass: "<<it->second.assignp()<<endl);
|
UINFO(5, " Ass: "<<it->second.assignp()<<endl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void clearLifeFromSublife (LifeMap* sublifep) {
|
};
|
||||||
// Any varrefs under a if/else branch affect statements outside and after the if/else
|
|
||||||
for (LifeMap::iterator it = sublifep->begin(); it!=sublifep->end(); ++it) {
|
|
||||||
clearLastAssign(it->first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void dualBranch (LifeMap* life1p, LifeMap* life2p) {
|
|
||||||
// Find any common sets on both branches of IF and propagate upwards
|
|
||||||
//lifeDump(life1p);
|
|
||||||
//lifeDump(life2p);
|
|
||||||
m_ifCount++;
|
|
||||||
for (LifeMap::iterator it = life1p->begin(); it!=life1p->end(); ++it) {
|
|
||||||
// When the if branch sets a var before it's used, mark that variable
|
|
||||||
if (it->second.firstSet()) it->first->user(m_ifCount);
|
|
||||||
}
|
|
||||||
for (LifeMap::iterator it = life2p->begin(); it!=life2p->end(); ++it) {
|
|
||||||
// When the else branch sets a var before it's used
|
|
||||||
AstVarScope* nodep = it->first;
|
|
||||||
if (it->second.firstSet()
|
|
||||||
&& nodep->user()==m_ifCount) { // And the if hit the same var
|
|
||||||
UINFO(4,"DUALBRANCH "<<nodep<<endl);
|
|
||||||
LifeMap::iterator iter = m_lifep->find(nodep);
|
|
||||||
if (iter != m_lifep->end()) {
|
|
||||||
checkRemoveAssign(&(iter->second));
|
|
||||||
iter->second.clearAssign();
|
|
||||||
} else {
|
|
||||||
m_lifep->insert(make_pair(nodep,LifeVarEntry(true)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//lifeDump(m_lifep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
// Life state, as a visitor of each AstNode
|
||||||
|
|
||||||
|
class LifeVisitor : public AstNVisitor {
|
||||||
|
private:
|
||||||
|
// STATE
|
||||||
|
LifeState* m_statep; // Current state
|
||||||
|
bool m_sideEffect; // Side effects discovered in assign RHS
|
||||||
|
//static int debug() { return 9; }
|
||||||
|
|
||||||
|
// LIFE MAP
|
||||||
|
// For each basic block, we'll make a new map of what variables that if/else is changing
|
||||||
|
typedef std::map<AstVarScope*, LifeVarEntry> LifeMap;
|
||||||
|
LifeBlock* m_lifep; // Current active lifetime map for current scope
|
||||||
|
|
||||||
|
// METHODS
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
|
||||||
// Only track the top scopes, not lower level functions
|
|
||||||
if (nodep->isTop()) nodep->iterateChildren(*this);
|
|
||||||
}
|
|
||||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
|
||||||
AstNode::userClearTree(); // userp() used on entire tree
|
|
||||||
AstNode::user2ClearTree(); // userp() used on entire tree
|
|
||||||
AstNode::user3ClearTree(); // userp() used on entire tree
|
|
||||||
AstNode::user4ClearTree(); // userp() used on entire tree
|
|
||||||
|
|
||||||
AstScope* scopep = nodep->scopep();
|
|
||||||
if (!scopep) nodep->v3fatalSrc("TopScope has no scope\n");
|
|
||||||
AstCFunc* evalp = NULL;
|
|
||||||
for (AstNode* searchp = scopep->blocksp(); searchp; searchp=searchp->nextp()) {
|
|
||||||
if (AstCFunc* funcp = searchp->castCFunc()) {
|
|
||||||
if (funcp->name() == "_eval") {
|
|
||||||
evalp = funcp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!evalp) nodep->v3fatalSrc("Top _eval entry function not found\n");
|
|
||||||
evalp->iterateChildren(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
// Consumption/generation of a variable,
|
// Consumption/generation of a variable,
|
||||||
// it's used so can't elim assignment before this use.
|
// it's used so can't elim assignment before this use.
|
||||||
@@ -191,44 +283,61 @@ private:
|
|||||||
//
|
//
|
||||||
AstVarScope* vscp = nodep->varScopep();
|
AstVarScope* vscp = nodep->varScopep();
|
||||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||||
clearLastAssign(vscp);
|
if (nodep->lvalue()) {
|
||||||
|
m_lifep->complexAssign(vscp);
|
||||||
|
} else {
|
||||||
|
m_lifep->varUsageReplace(vscp, nodep); nodep=NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||||
// Collect any used variables first, as lhs may also be on rhs
|
// Collect any used variables first, as lhs may also be on rhs
|
||||||
|
// Similar code in V3Dead
|
||||||
|
vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited
|
||||||
|
m_sideEffect = false;
|
||||||
nodep->rhsp()->iterateAndNext(*this);
|
nodep->rhsp()->iterateAndNext(*this);
|
||||||
|
if (lastEdit != AstNode::editCountGbl()) {
|
||||||
|
// We changed something, try to constant propagate, but don't delete the
|
||||||
|
// assignment as we still need nodep to remain.
|
||||||
|
V3Const::constifyTree(nodep->rhsp());
|
||||||
|
}
|
||||||
// Has to be direct assignment without any EXTRACTing.
|
// Has to be direct assignment without any EXTRACTing.
|
||||||
if (nodep->lhsp()->castVarRef()) {
|
if (nodep->lhsp()->castVarRef() && !m_sideEffect) {
|
||||||
AstVarScope* vscp = nodep->lhsp()->castVarRef()->varScopep();
|
AstVarScope* vscp = nodep->lhsp()->castVarRef()->varScopep();
|
||||||
if (!vscp) vscp->v3fatalSrc("Scope lost on variable");
|
if (!vscp) vscp->v3fatalSrc("Scope lost on variable");
|
||||||
setLast(vscp, nodep);
|
m_lifep->simpleAssign(vscp, nodep);
|
||||||
} else {
|
} else {
|
||||||
nodep->lhsp()->iterateAndNext(*this);
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||||
|
// Don't treat as normal assign; V3Life doesn't understand time sense
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
//---- Track control flow changes
|
//---- Track control flow changes
|
||||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||||
UINFO(4," IF "<<nodep<<endl);
|
UINFO(4," IF "<<nodep<<endl);
|
||||||
// Condition is part of PREVIOUS block
|
// Condition is part of PREVIOUS block
|
||||||
nodep->condp()->iterateAndNext(*this);
|
nodep->condp()->iterateAndNext(*this);
|
||||||
LifeMap* prevLifeMapp = m_lifep;
|
LifeBlock* prevLifep = m_lifep;
|
||||||
LifeMap* ifLifep = new LifeMap;
|
LifeBlock* ifLifep = new LifeBlock (prevLifep, m_statep);
|
||||||
LifeMap* elseLifep = new LifeMap;
|
LifeBlock* elseLifep = new LifeBlock (prevLifep, m_statep);
|
||||||
{
|
{
|
||||||
m_lifep = ifLifep;
|
m_lifep = ifLifep;
|
||||||
nodep->ifsp()->iterateAndNext(*this);
|
nodep->ifsp()->iterateAndNext(*this);
|
||||||
|
m_lifep = prevLifep;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
m_lifep = elseLifep;
|
m_lifep = elseLifep;
|
||||||
nodep->elsesp()->iterateAndNext(*this);
|
nodep->elsesp()->iterateAndNext(*this);
|
||||||
|
m_lifep = prevLifep;
|
||||||
}
|
}
|
||||||
UINFO(4," join "<<endl);
|
UINFO(4," join "<<endl);
|
||||||
m_lifep = prevLifeMapp;
|
|
||||||
// Find sets on both flows
|
// Find sets on both flows
|
||||||
dualBranch (ifLifep, elseLifep);
|
m_lifep->dualBranch (ifLifep, elseLifep);
|
||||||
// For the next assignments, clear any variables that were read or written in the block
|
// For the next assignments, clear any variables that were read or written in the block
|
||||||
clearLifeFromSublife(ifLifep);
|
ifLifep->lifeToAbove();
|
||||||
clearLifeFromSublife(elseLifep);
|
elseLifep->lifeToAbove();
|
||||||
delete ifLifep;
|
delete ifLifep;
|
||||||
delete elseLifep;
|
delete elseLifep;
|
||||||
}
|
}
|
||||||
@@ -240,24 +349,25 @@ private:
|
|||||||
// assignment in the body that's used in the cond. (And otherwise
|
// assignment in the body that's used in the cond. (And otherwise
|
||||||
// would because it only appears used after-the-fact. So, we model
|
// would because it only appears used after-the-fact. So, we model
|
||||||
// it as a IF statement, and just don't allow elimination of
|
// it as a IF statement, and just don't allow elimination of
|
||||||
// variables in the body.
|
// variables across the body.
|
||||||
LifeMap* prevLifeMapp = m_lifep;
|
LifeBlock* prevLifep = m_lifep;
|
||||||
LifeMap* condLifep = new LifeMap;
|
LifeBlock* condLifep = new LifeBlock (prevLifep, m_statep);
|
||||||
LifeMap* bodyLifep = new LifeMap;
|
LifeBlock* bodyLifep = new LifeBlock (prevLifep, m_statep);
|
||||||
{
|
{
|
||||||
m_lifep = condLifep;
|
m_lifep = condLifep;
|
||||||
nodep->precondsp()->iterateAndNext(*this);
|
nodep->precondsp()->iterateAndNext(*this);
|
||||||
nodep->condp()->iterateAndNext(*this);
|
nodep->condp()->iterateAndNext(*this);
|
||||||
|
m_lifep = prevLifep;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
m_lifep = bodyLifep;
|
m_lifep = bodyLifep;
|
||||||
nodep->bodysp()->iterateAndNext(*this);
|
nodep->bodysp()->iterateAndNext(*this);
|
||||||
|
m_lifep = prevLifep;
|
||||||
}
|
}
|
||||||
UINFO(4," joinfor"<<endl);
|
UINFO(4," joinfor"<<endl);
|
||||||
m_lifep = prevLifeMapp;
|
|
||||||
// For the next assignments, clear any variables that were read or written in the block
|
// For the next assignments, clear any variables that were read or written in the block
|
||||||
clearLifeFromSublife(condLifep);
|
condLifep->lifeToAbove();
|
||||||
clearLifeFromSublife(bodyLifep);
|
bodyLifep->lifeToAbove();
|
||||||
delete condLifep;
|
delete condLifep;
|
||||||
delete bodyLifep;
|
delete bodyLifep;
|
||||||
}
|
}
|
||||||
@@ -265,8 +375,15 @@ private:
|
|||||||
//UINFO(4," CCALL "<<nodep<<endl);
|
//UINFO(4," CCALL "<<nodep<<endl);
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
// Enter the function and trace it
|
// Enter the function and trace it
|
||||||
nodep->funcp()->accept(*this);
|
if (!nodep->funcp()->entryPoint()) { // else is non-inline or public function we optimize separately
|
||||||
|
nodep->funcp()->accept(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstUCFunc* nodep, AstNUser*) {
|
||||||
|
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it
|
virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
@@ -274,15 +391,60 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
LifeVisitor(AstNetlist* nodep) {
|
LifeVisitor(AstNode* nodep, LifeState* statep) {
|
||||||
m_ifCount = 1;
|
UINFO(4," LifeVisitor on "<<nodep<<endl);
|
||||||
m_lifep = new LifeMap;
|
m_statep = statep;
|
||||||
|
m_sideEffect = false;
|
||||||
|
{
|
||||||
|
m_lifep = new LifeBlock (NULL, m_statep);
|
||||||
|
nodep->accept(*this);
|
||||||
|
delete m_lifep; m_lifep=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual ~LifeVisitor() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
|
class LifeTopVisitor : public AstNVisitor {
|
||||||
|
// Visit all top nodes searching for functions that are entry points we want to start
|
||||||
|
// finding code within.
|
||||||
|
private:
|
||||||
|
// STATE
|
||||||
|
LifeState* m_statep; // Current state
|
||||||
|
|
||||||
|
// VISITORS
|
||||||
|
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||||
|
if (nodep->entryPoint()) {
|
||||||
|
// Usage model 1: Simulate all C code, doing lifetime analysis
|
||||||
|
LifeVisitor visitor (nodep, m_statep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||||
|
// Usage model 2: Cleanup basic blocks
|
||||||
|
LifeVisitor visitor (nodep, m_statep);
|
||||||
|
}
|
||||||
|
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||||
|
// Usage model 2: Cleanup basic blocks
|
||||||
|
LifeVisitor visitor (nodep, m_statep);
|
||||||
|
}
|
||||||
|
virtual void visit(AstFinal* nodep, AstNUser*) {
|
||||||
|
// Usage model 2: Cleanup basic blocks
|
||||||
|
LifeVisitor visitor (nodep, m_statep);
|
||||||
|
}
|
||||||
|
virtual void visit(AstVar*, AstNUser*) {} // Accelerate
|
||||||
|
virtual void visit(AstNodeStmt*, AstNUser*) {} // Accelerate
|
||||||
|
virtual void visit(AstNodeMath*, AstNUser*) {} // Accelerate
|
||||||
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
// CONSTRUCTORS
|
||||||
|
LifeTopVisitor(AstNetlist* nodep, LifeState* statep) {
|
||||||
|
m_statep = statep;
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
delete m_lifep;
|
|
||||||
}
|
|
||||||
virtual ~LifeVisitor() {
|
|
||||||
V3Stats::addStat("Optimizations, Lifetime assign deletions", m_statAssnDel);
|
|
||||||
}
|
}
|
||||||
|
virtual ~LifeTopVisitor() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
@@ -290,6 +452,6 @@ public:
|
|||||||
|
|
||||||
void V3Life::lifeAll(AstNetlist* nodep) {
|
void V3Life::lifeAll(AstNetlist* nodep) {
|
||||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
// Delete lifelicate assignments
|
LifeState state;
|
||||||
LifeVisitor visitor (nodep);
|
LifeTopVisitor visitor (nodep, &state);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3LIFE_H_
|
#ifndef _V3LIFE_H_
|
||||||
#define _V3LIFE_H_ 1
|
#define _V3LIFE_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -29,7 +29,8 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 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
|
||||||
// General Public License or the Perl Artistic License.
|
// General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#ifndef _V3LIFEPOST_H_
|
#ifndef _V3LIFEPOST_H_
|
||||||
#define _V3LIFEPOST_H_ 1
|
#define _V3LIFEPOST_H_ 1
|
||||||
#include "config.h"
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
#include "V3Error.h"
|
#include "V3Error.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user