mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
749ff021b6 | ||
|
|
85c5765c00 | ||
|
|
9e76078939 | ||
|
|
334e0e1ca6 | ||
|
|
dce4519995 | ||
|
|
45bbae80e7 | ||
|
|
d37709a922 | ||
|
|
2560ae9bc1 | ||
|
|
2bdd3ca353 | ||
|
|
8a8aab1aae | ||
|
|
85d790ff79 | ||
|
|
68afc96a9f | ||
|
|
94efaa7675 | ||
|
|
180af74a50 | ||
|
|
88af0d3509 | ||
|
|
97633f7bed | ||
|
|
053e016388 | ||
|
|
2d61e0270e | ||
|
|
3a23afb0bc | ||
|
|
470f12ff46 | ||
|
|
4422de0c6c | ||
|
|
8a708f52f7 | ||
|
|
bcefc17631 | ||
|
|
daf19e241e | ||
|
|
b5f5b1fdf9 | ||
|
|
801b718953 | ||
|
|
f571658aa4 | ||
|
|
5d233b8c09 | ||
|
|
00724597f4 | ||
|
|
c659940ea8 | ||
|
|
23539eb55c | ||
|
|
e69bf418de | ||
|
|
0e1fcd38bb | ||
|
|
e74186565d | ||
|
|
7e54281e26 | ||
|
|
15f512bdee | ||
|
|
ecfe0283e2 | ||
|
|
3b874f759c | ||
|
|
9c9b4ed4e0 | ||
|
|
4f6d80c602 | ||
|
|
b50542531d | ||
|
|
8ab28d1d12 | ||
|
|
9567da22f8 | ||
|
|
36814b7681 | ||
|
|
82235e6c6f | ||
|
|
a8310f35f2 | ||
|
|
85989af031 | ||
|
|
cf9ffd16dd | ||
|
|
0602537cce | ||
|
|
24e32420b7 | ||
|
|
39c494260b | ||
|
|
761b9c9290 | ||
|
|
27686d8c2f | ||
|
|
d2b007005d | ||
|
|
f1ef30a5bb | ||
|
|
f1d9437c55 | ||
|
|
bcba5075e8 | ||
|
|
d6e8b0263c | ||
|
|
9aba617bad | ||
|
|
c24f7b1391 | ||
|
|
d4e27b635f | ||
|
|
c996d2870c | ||
|
|
bbd59f8a22 | ||
|
|
d3d359e757 | ||
|
|
ae763ea93d | ||
|
|
236b9e9761 | ||
|
|
e42c9dfd84 | ||
|
|
bebf5b291b | ||
|
|
1e3dcd203d | ||
|
|
cc7da63dec | ||
|
|
1baa2a2558 | ||
|
|
e63ff77b15 | ||
|
|
6cf9468477 | ||
|
|
b277bc8750 | ||
|
|
ba9da64207 | ||
|
|
9cb9f9c80b | ||
|
|
7a65df7636 | ||
|
|
eab46d547d | ||
|
|
3dd552c4a2 | ||
|
|
23bb045a72 | ||
|
|
7c834ad118 | ||
|
|
8e2617ab8d | ||
|
|
24fcae4f49 | ||
|
|
ce18674d88 | ||
|
|
6b8d9b5c36 | ||
|
|
81bf95763c | ||
|
|
2d64077fd0 | ||
|
|
38faebcf20 | ||
|
|
48d177a9d0 | ||
|
|
3b3a7f7354 | ||
|
|
99cd2818a1 | ||
|
|
5765e099a6 | ||
|
|
175d59ecba | ||
|
|
3bd3d01968 | ||
|
|
85e2a6bb45 | ||
|
|
84efd239a5 | ||
|
|
6a69813326 | ||
|
|
2c9dcc3913 | ||
|
|
20ea1ca018 | ||
|
|
0abde90933 | ||
|
|
e01b69198a | ||
|
|
53cd9d2403 | ||
|
|
3d0f5fc078 | ||
|
|
54eedcc739 | ||
|
|
ae6f5844da | ||
|
|
1bea845ceb | ||
|
|
d581582339 | ||
|
|
4eabc1992e | ||
|
|
316eb24bbb | ||
|
|
f0a8824efc | ||
|
|
345a5d5646 | ||
|
|
464679c78b | ||
|
|
28eeec1cf4 | ||
|
|
7d0dce3267 | ||
|
|
9e29625207 | ||
|
|
a767da4f3f | ||
|
|
7bd96c2876 | ||
|
|
70fd64dcd6 | ||
|
|
bb2822f4b5 | ||
|
|
ad21108b63 | ||
|
|
e6808a787c | ||
|
|
1fb2762725 | ||
|
|
cce55941d3 | ||
|
|
6c8d95e0e2 | ||
|
|
216a178b28 | ||
|
|
6594a54a95 | ||
|
|
a9a4cf061a | ||
|
|
b7f0e204cb | ||
|
|
e6a15f233b | ||
|
|
e0edb596ea | ||
|
|
f2fb77c15a | ||
|
|
772a3a97eb | ||
|
|
6c310836a1 | ||
|
|
75416a3016 | ||
|
|
ebef78a13e | ||
|
|
e71baca39b | ||
|
|
18eb210313 | ||
|
|
7d38a5e1f9 | ||
|
|
4386077e2d | ||
|
|
49dbfd2131 | ||
|
|
a80fce5ac1 | ||
|
|
891b981cab | ||
|
|
2dd87b8384 | ||
|
|
062eb85075 | ||
|
|
e1f6802f5f | ||
|
|
6cfcd50f12 | ||
|
|
bcadb0b3b3 | ||
|
|
0df561f873 | ||
|
|
238fc24684 | ||
|
|
936855c81c | ||
|
|
61ad9d4651 | ||
|
|
f07f6a26a8 | ||
|
|
4a5a56f8ef | ||
|
|
7d44bba95c | ||
|
|
6e6f1045b8 | ||
|
|
5dd3221759 | ||
|
|
09edb467f6 | ||
|
|
ffb187ae15 | ||
|
|
b4a8be07f3 | ||
|
|
4968a2abc5 | ||
|
|
91159da30d | ||
|
|
c9ad61b4fb | ||
|
|
3f0dcd8c0e | ||
|
|
e1eb41fe77 | ||
|
|
498ab23355 | ||
|
|
5d6a053f98 | ||
|
|
929aeebf12 | ||
|
|
00bd947385 | ||
|
|
d4ef86afc0 | ||
|
|
1856cad816 | ||
|
|
91e2d1d2a0 | ||
|
|
f29f30dce0 | ||
|
|
e7ba6ef492 | ||
|
|
de4016dcff | ||
|
|
bbeb382cbb | ||
|
|
385c166830 | ||
|
|
410e6ff203 | ||
|
|
8b47c4e307 | ||
|
|
6d1b42bedb | ||
|
|
f0a4bd28b6 | ||
|
|
2879684f21 | ||
|
|
0437d0abea | ||
|
|
0286f588bf | ||
|
|
042fb76837 | ||
|
|
795e66eac9 | ||
|
|
aae0615ffd | ||
|
|
8127a79cb1 | ||
|
|
057ca497dd | ||
|
|
66b1611649 | ||
|
|
7f5220a6ca | ||
|
|
e41e26717b | ||
|
|
7a8184d206 | ||
|
|
13bf2f19ac | ||
|
|
1d5ebfd0b1 | ||
|
|
dfc11da2ce | ||
|
|
191af2e87b | ||
|
|
0985b82760 | ||
|
|
26f4b5a69a | ||
|
|
5c7a6e278f | ||
|
|
ae1ab8aaaa | ||
|
|
18c25d1b6f | ||
|
|
5888a2c399 | ||
|
|
c00603704e | ||
|
|
786bc4b04f | ||
|
|
5eca20f849 | ||
|
|
0a3a582949 | ||
|
|
08fec0534d | ||
|
|
5bf92c9d3a | ||
|
|
a8bbf7231b | ||
|
|
83c171012d | ||
|
|
229d854607 | ||
|
|
562460606f | ||
|
|
46f70b1cbb | ||
|
|
a547133efe | ||
|
|
cf445898ce | ||
|
|
98f68e46d6 | ||
|
|
27660b271d | ||
|
|
895e374860 | ||
|
|
4c7f051247 | ||
|
|
e68afa53a8 | ||
|
|
cc47ba2404 | ||
|
|
2238fa46ed | ||
|
|
de8b040e31 | ||
|
|
4ffc48d194 | ||
|
|
2433848408 | ||
|
|
e602f7febc | ||
|
|
f607b32938 | ||
|
|
c7a088faa5 | ||
|
|
30f6c0e105 | ||
|
|
38b9fa7b93 | ||
|
|
39a31fc17f | ||
|
|
899a7df14a | ||
|
|
7a8c425103 | ||
|
|
0e8ce59022 | ||
|
|
77ac76a158 | ||
|
|
8108b97050 | ||
|
|
a1c3491dea | ||
|
|
8bba96a84e | ||
|
|
6cd9b25a53 | ||
|
|
0431b1909c | ||
|
|
907665e2e8 | ||
|
|
61e8836fbd | ||
|
|
0e921b5dff | ||
|
|
7ef37d6e17 | ||
|
|
dce227684a | ||
|
|
158e112752 | ||
|
|
ec992c7f5e | ||
|
|
e7d63c7644 | ||
|
|
6464e8fee6 | ||
|
|
047d66a657 | ||
|
|
55c23360d9 | ||
|
|
c378d32c85 | ||
|
|
3d9540c58c | ||
|
|
39724eb916 | ||
|
|
48dddd4ae7 | ||
|
|
9c00fd10de | ||
|
|
9309d0b00f | ||
|
|
038b5d32a3 | ||
|
|
706920ba19 | ||
|
|
39492a0726 | ||
|
|
df1170fea9 | ||
|
|
f0e1d204fa | ||
|
|
8ece0a8a5f | ||
|
|
1373b81e7c | ||
|
|
d3601dd561 | ||
|
|
f685cf1d0c | ||
|
|
d5fcf0c153 | ||
|
|
5f9810070d | ||
|
|
923efa004b | ||
|
|
869e8eab3c | ||
|
|
b51d197117 | ||
|
|
e4f0a8952c | ||
|
|
072ee425f4 | ||
|
|
a4c2819be2 | ||
|
|
2a274f9c19 |
@@ -12,6 +12,7 @@
|
||||
*.pdf
|
||||
/Makefile
|
||||
README
|
||||
TAGS
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.status
|
||||
|
||||
@@ -3,6 +3,266 @@ Revision history for Verilator
|
||||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.856 2014-03-11
|
||||
|
||||
*** Support case inside, bug708. [Jan Egil Ruud]
|
||||
|
||||
*** Add parameters into trace files, bug706. [Alex Solomatnikov]
|
||||
|
||||
**** Fix parsing "#0 'b0", bug256.
|
||||
|
||||
**** Fix array bound checks on real variables.
|
||||
|
||||
**** Fix --skip-identical mis-detecting on OS-X, bug707.
|
||||
|
||||
**** Fix missing VL_SHIFTRS_IQI with WIDTH warning, bug714. [Fabrizio Ferrandi]
|
||||
|
||||
**** Fix signed shift right optimization, bug715. [Fabrizio Ferrandi]
|
||||
|
||||
**** Fix internal error on "input x =" syntax error, bug716. [Lane Brooks]
|
||||
|
||||
**** Fix slice extraction from packed array, bug717. [Jan Egil Ruud]
|
||||
|
||||
**** Fix inside statement EQWILD error, bug718. [Jan Egil Ruud]
|
||||
|
||||
|
||||
* Verilator 3.855 2014-01-18
|
||||
|
||||
*** Support modport import, bug696. [Jeremy Bennett]
|
||||
|
||||
*** Add --trace-structs to show struct names, bug673. [Chris Randall]
|
||||
|
||||
**** Fix tracing of packed structs, bug705. [Jie Xu]
|
||||
|
||||
**** Fix --lint-only with MinGW, msg1283. [HyungKi Jeong]
|
||||
|
||||
**** Fix some delayed assignments of typedefed unpacked arrays.
|
||||
|
||||
**** Fix wire declarations with size and not range, bug466. [Alex Solomatnikov]
|
||||
|
||||
**** Fix parameter pin vs. normal pin error, bug704. [Alex Solomatnikov]
|
||||
|
||||
|
||||
* Verilator 3.854 2013-11-26
|
||||
|
||||
*** Add UNPACKED warning to convert unpacked structs. [Jeremy Bennett]
|
||||
|
||||
*** Add --compiler clang to work around compiler bug, bug694. [Stefan Ludwig]
|
||||
|
||||
**** Support vpi_get of vpiSuppressVal, bug687. [Varun Koyyalagunta]
|
||||
|
||||
**** Support vpi_get_time, bug688. [Varun Koyyalagunta]
|
||||
|
||||
**** Fix evaluation of chained parameter functions, bug684. [Ted Campbell]
|
||||
|
||||
**** Fix enum value extension of '1.
|
||||
|
||||
**** Fix multiple VPI variable callbacks, bug679. [Rich Porter]
|
||||
|
||||
**** Fix vpi_get of vpiSize, bug680. [Rich Porter]
|
||||
|
||||
**** Fix vpi_remove_cb inside callback, bug689. [Varun Koyyalagunta]
|
||||
|
||||
**** Fix crash with coverage of structures, bug691. [Eivind Liland]
|
||||
|
||||
**** Fix array assignment from const var, bug693. [Jie Xu]
|
||||
|
||||
|
||||
* Verilator 3.853 2013-09-30
|
||||
|
||||
**** Add --no-order-clock-delay to work around bug613. [Charlie Brej]
|
||||
|
||||
|
||||
* Verilator 3.852 2013-09-29
|
||||
|
||||
*** Support named function and task arguments. [Chris Randall]
|
||||
|
||||
*** Report SELRANGE warning for non-generate if, bug675. [Roland Kruse]
|
||||
|
||||
**** Fix ordering of $fgetc, msg1229. [Frederic Requin]
|
||||
|
||||
**** Fix --output-split-cfunc to count internal functions. [Chris Randall]
|
||||
|
||||
**** Fix crash on 32-bit Ubuntu, bug670. [Mark Jackson Pulver]
|
||||
|
||||
|
||||
* Verilator 3.851 2013-08-15
|
||||
|
||||
*** Fix ordering of clock enables with delayed assigns, bug613. [Jeremy Bennett]
|
||||
|
||||
*** Fix vpi_iterate on memory words, bug655. [Rich Porter]
|
||||
|
||||
**** Fix final duplicate declarations when non-inlined, bug661. [Charlie Brej]
|
||||
|
||||
**** Fix interface ports with comma lists, msg1058. [Ed Lander]
|
||||
|
||||
**** Fix parameter real conversion from integer.
|
||||
|
||||
**** Fix clang warnings, bug668. [Yutetsu Takatsukasa]
|
||||
|
||||
|
||||
* Verilator 3.850 2013-06-02
|
||||
|
||||
** Support interfaces and modports, bug102. [Byron Bradley, Jeremy Bennett]
|
||||
|
||||
*** Duplicate clock gate optimization on by default, bug621.
|
||||
|
||||
**** Fix arrayed input compile error, bug645. [Krzysztof Jankowski]
|
||||
|
||||
**** Fix GCC version runtime changes, bug651. [Jeremy Bennett]
|
||||
|
||||
**** Fix packed array select internal error, bug652. [Krzysztof Jankowski]
|
||||
|
||||
|
||||
* Verilator 3.847 2013-05-11
|
||||
|
||||
*** Add ALWCOMBORDER warning. [KC Buckenmaier]
|
||||
|
||||
*** Add --pins-sc-uint and --pins-sc-biguint, bug638. [Alex Hornung]
|
||||
|
||||
**** Support "signal[vec]++".
|
||||
|
||||
**** Fix simulation error when inputs and MULTIDRIVEN, bug634. [Ted Campbell]
|
||||
|
||||
**** Fix module resolution with __, bug631. [Jason McMullan]
|
||||
|
||||
**** Fix packed array non-zero right index select crash, bug642. [Krzysztof Jankowski]
|
||||
|
||||
**** Fix nested union crash, bug643. [Krzysztof Jankowski]
|
||||
|
||||
|
||||
* Verilator 3.846 2013-03-09
|
||||
|
||||
** IEEE 1800-2012 is now the default language. This adds 4 new keywords
|
||||
and updates the svdpi.h and vpi_user.h header files.
|
||||
|
||||
*** Add --report-unoptflat, bug611. [Jeremy Bennett]
|
||||
|
||||
*** Add duplicate clock gate optimization, msg980. [Varun Koyyalagunta]
|
||||
Disabled unless -OD or -O3 used, please try it as may get some
|
||||
significant speedups.
|
||||
|
||||
*** Fix wrong dot resolution under inlining. [Art Stamness]
|
||||
|
||||
**** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander]
|
||||
|
||||
**** Support bind in $unit, bug602. [Ed Lander]
|
||||
|
||||
**** Support <number>'() sized casts, bug628. [Ed Lander]
|
||||
|
||||
**** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett]
|
||||
|
||||
**** Fix LITENDIAN on unpacked structures, bug614. [Wai Sum Mong]
|
||||
|
||||
**** Fix 32-bit OS VPI scan issue, bug615. [Jeremy Bennett, Rich Porter]
|
||||
|
||||
**** Fix opening a VerilatedVcdC file multiple times, msg1021. [Frederic Requin]
|
||||
|
||||
**** Fix UNOPTFLAT circular array bounds crossing, bug630. [Jie Xu]
|
||||
|
||||
|
||||
* Verilator 3.845 2013/02/04
|
||||
|
||||
*** Fix nested packed arrays and struct, bug600. [Jeremy Bennett]
|
||||
Packed arrays are now represented as a single linear vector in
|
||||
Verilated models. This may affect packed arrays that are public or
|
||||
accessed via the VPI.
|
||||
|
||||
*** Support wires with data types, bug608. [Ed Lander]
|
||||
|
||||
*** Support bind, to module names only, bug602. [Ed Lander]
|
||||
|
||||
*** Support VPI product info, warning calls, etc, bug588. [Rick Porter]
|
||||
|
||||
*** Support $left, $right and related functions, bug448. [Iztok Jeras]
|
||||
|
||||
*** Support inside expressions.
|
||||
|
||||
*** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines.
|
||||
|
||||
**** Fix pin width mismatch error, bug595. [Alex Solomatnikov]
|
||||
|
||||
**** Fix implicit one bit parameter selection, bug603. [Jeremy Bennett]
|
||||
|
||||
**** Fix signed/unsigned parameter misconversion, bug606. [Jeremy Bennett]
|
||||
|
||||
**** Fix segfault on multidimensional dotted arrays, bug607. [Jie Xu]
|
||||
|
||||
**** Fix per-bit array output connection error, bug414. [Jan Egil Ruud]
|
||||
|
||||
**** Fix package logic var compile error.
|
||||
|
||||
**** Fix enums with X values.
|
||||
|
||||
|
||||
* Verilator 3.844 2013/01/09
|
||||
|
||||
*** Support "unsigned int" DPI import functions, msg966. [Alex Lee]
|
||||
|
||||
*** Fix package resolution of parameters, bug586. [Jeremy Bennett]
|
||||
|
||||
**** Fix non-integer vpi_get_value, bug587. [Rich Porter]
|
||||
|
||||
**** Fix task inlining under $display and case, bug589, bug598. [Holger Waechtler]
|
||||
|
||||
**** Fix package import of non-localparam parameter, bug474, bug591. [Jeremy Bennett]
|
||||
|
||||
**** Fix package import of package imports, partial bug592. [Jeremy Bennett]
|
||||
|
||||
**** Fix package import preventing local var, bug599. [Jeremy Bennett]
|
||||
|
||||
**** Fix array extraction of implicit vars, bug601. [Joe Eiler]
|
||||
|
||||
|
||||
* Verilator 3.843 2012/12/01
|
||||
|
||||
*** Add +1364-1995ext and similar language options, bug532. [Jeremy Bennett]
|
||||
|
||||
**** Fix mis-optimized identical submodule subtract, bug581. [Charlie Brej]
|
||||
|
||||
**** Fix crash on dotted references into dead modules, bug583. [Jeremy Bennett]
|
||||
|
||||
**** Fix compile issues on MSVCC, bug571, bug577. [Amir Gonnen]
|
||||
|
||||
**** Fix --debug overriding preceding --dump-treei, bug580. [Jeremy Bennett]
|
||||
|
||||
|
||||
* Verilator 3.842 2012/11/03
|
||||
|
||||
**** Add -x-initial-edge, bug570. [Jeremy Bennett]
|
||||
|
||||
**** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman]
|
||||
|
||||
**** Fix large shift error on large shift constants. [David Welch]
|
||||
|
||||
**** Fix $display mangling on GCC 4.7 and speed up, msg927, bug373, bug574. [R Diez]
|
||||
|
||||
**** Fix array of struct references giving false error, bug566. [Julius Baxter]
|
||||
|
||||
**** Fix missing var access functions when no DPI, bug572. [Amir Gonnen]
|
||||
|
||||
**** Fix name collision on unnamed blocks, bug567. [Chandan Egbert]
|
||||
|
||||
**** Fix name collision on task inputs, bug569. [Chandan Egbert]
|
||||
|
||||
|
||||
* Verilator 3.841 2012/09/03
|
||||
|
||||
*** Add --savable to support model save/restore. [Jeremy Bennett]
|
||||
|
||||
*** Support '{} assignment pattern on structures, part of bug355.
|
||||
|
||||
**** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda]
|
||||
|
||||
**** Fix imports under multiple instantiated cells, bug542. [Alex Solomatnikov]
|
||||
|
||||
**** Fix defparam in generate broke in 3.840, bug543. [Alex Solomatnikov]
|
||||
|
||||
**** Fix duplicate begin error broke in 3.840, bug548. [Alex Solomatnikov]
|
||||
|
||||
**** Fix triangle symbol resolution error broke in 3.840, bug550. [Ted Campbell]
|
||||
|
||||
|
||||
* Verilator 3.840 2012/07/31 Beta
|
||||
|
||||
** Rewrote tristate handling; supports tri0, tri1, tristate bit selects,
|
||||
@@ -2083,7 +2343,7 @@ of input ports exists for tracing.
|
||||
|
||||
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
||||
|
||||
Copyright 2001-2012 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2001-2014 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+3
-1
@@ -1,6 +1,5 @@
|
||||
^CVS/
|
||||
/CVS/
|
||||
\.gdbinit$
|
||||
\.git/
|
||||
\.svn/
|
||||
\.(bak|old)/
|
||||
@@ -23,6 +22,7 @@
|
||||
src/Makefile$
|
||||
src/Makefile_obj$
|
||||
include/verilated.mk$
|
||||
test_regress/.gdbinit$
|
||||
config.cache$
|
||||
config.status$
|
||||
verilator.log
|
||||
@@ -36,3 +36,5 @@ nodist/
|
||||
/vc_hdrs.h$
|
||||
/csrc/
|
||||
doxygen-doc/.*
|
||||
TAGS
|
||||
.*~
|
||||
|
||||
+8
-4
@@ -9,7 +9,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -121,6 +121,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
include/vltstd/*.[chv]* \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
|
||||
src/.gdbinit \
|
||||
src/*.pl src/*.pod \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||
@@ -398,14 +399,17 @@ endif
|
||||
# VERILATOR_AUTHOR_SITE
|
||||
endif
|
||||
|
||||
# Use --xml flag to see the cppcheck code to use for suppression
|
||||
CPPCHECK = cppcheck
|
||||
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject
|
||||
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject --suppress=cstyleCast
|
||||
CPPCHECK_FLAGS += --xml
|
||||
CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp)
|
||||
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
|
||||
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||
|
||||
cppcheck: $(CPPCHECK_DEP)
|
||||
%.cppcheck: %.cpp
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -I$(srcdir)/include -I$(srcdir)/src $<
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 $(CPPCHECK_INC) $<
|
||||
|
||||
ftp: info
|
||||
|
||||
@@ -455,7 +459,7 @@ clean mostlyclean distclean maintainer-clean::
|
||||
|
||||
distclean maintainer-clean::
|
||||
rm -f Makefile config.status config.cache config.log verilator_bin* TAGS
|
||||
rm -f include/verilated.mk
|
||||
rm -f include/verilated.mk include/verilated_config.h
|
||||
|
||||
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
|
||||
${srcdir}/*.in ${srcdir}/*.pod
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// DESCRIPTION: Verilator: List of To Do issues.
|
||||
//
|
||||
// Copyright 2004-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -62,7 +62,7 @@ Usability:
|
||||
* Print version/etc message at runtime. (4.000?)
|
||||
Include number of lines of code, percent comments, code complexity measurement
|
||||
<-80chars------------------------------------------------------------------->
|
||||
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2012.
|
||||
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2013.
|
||||
Verilated #### modules, #### instances, ##### sigs,
|
||||
#### non-comment lines, ##### ops, ### KB model size
|
||||
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
|
||||
|
||||
+341
-59
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2014 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -202,9 +202,8 @@ Verilator - Convert Verilog code to C++/SystemC
|
||||
|
||||
verilator --help
|
||||
verilator --version
|
||||
verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --cc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --sc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --lint-only [top_level.v]...
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -241,6 +240,12 @@ descriptions in the next sections for more information.
|
||||
{file.c/cc/cpp} Optional C++ files to compile in
|
||||
{file.a/o/so} Optional C++ files to link in
|
||||
|
||||
+1364-1995ext+<ext> Use Verilog 1995 with file extension <ext>
|
||||
+1364-2001ext+<ext> Use Verilog 2001 with file extension <ext>
|
||||
+1364-2005ext+<ext> Use Verilog 2005 with file extension <ext>
|
||||
+1800-2005ext+<ext> Use SystemVerilog 2005 with file extension <ext>
|
||||
+1800-2009ext+<ext> Use SystemVerilog 2009 with file extension <ext>
|
||||
+1800-2012ext+<ext> Use SystemVerilog 2012 with file extension <ext>
|
||||
--assert Enable all assertions
|
||||
--autoflush Flush streams after all $displays
|
||||
--bbox-sys Blackbox unknown $system calls
|
||||
@@ -261,6 +266,7 @@ descriptions in the next sections for more information.
|
||||
--debug-check Enable debugging assertions
|
||||
--debugi <level> Enable debugging at a specified level
|
||||
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
||||
--default-language <lang> Default language to parse
|
||||
+define+<var>+<value> Set preprocessor define
|
||||
--dump-tree Enable dumping .tree files
|
||||
--dump-treei <level> Enable dumping .tree files at a level
|
||||
@@ -279,7 +285,7 @@ descriptions in the next sections for more information.
|
||||
--inline-mult <value> Tune module inlining
|
||||
-LDFLAGS <flags> Linker pre-object flags for makefile
|
||||
-LDLIBS <flags> Linker library flags for makefile
|
||||
--language <lang> Language standard to parse
|
||||
--language <lang> Default language standard to parse
|
||||
+libext+<ext>+[ext]... Extensions for finding modules
|
||||
--lint-only Lint, but do not make output
|
||||
--MMD Create .d dependency files
|
||||
@@ -293,9 +299,13 @@ descriptions in the next sections for more information.
|
||||
-O3 High performance optimizations
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
-o <executable> Name of final executable
|
||||
--no-order-clock-delay Disable ordering clock enable assignments
|
||||
--output-split <bytes> Split .cpp files into pieces
|
||||
--output-split-cfuncs <statements> Split .ccp functions
|
||||
--output-split-cfuncs <statements> Split .cpp functions
|
||||
--output-split-ctrace <statements> Split tracing functions
|
||||
--pins-bv <bits> Specify types for top level ports
|
||||
--pins-sc-uint Specify types for top level ports
|
||||
--pins-sc-biguint Specify types for top level ports
|
||||
--pins-uint8 Specify types for top level ports
|
||||
--pipe-filter <command> Filter all input through a script
|
||||
--prefix <topname> Name of top level class
|
||||
@@ -303,15 +313,19 @@ descriptions in the next sections for more information.
|
||||
--private Debugging; see docs
|
||||
--psl Enable PSL parsing
|
||||
--public Debugging; see docs
|
||||
--report-unoptflat Extra diagnostics for UNOPTFLAT
|
||||
--savable Enable model save-restore
|
||||
--sc Create SystemC output
|
||||
--sp Create SystemPerl output
|
||||
--stats Create statistics file
|
||||
-sv Enable SystemVerilog parsing
|
||||
+systemverilogext+<ext> Synonym for +1800-2012ext+<ext>
|
||||
--top-module <topname> Name of top level input module
|
||||
--trace Enable waveform creation
|
||||
--trace-depth <levels> Depth of tracing
|
||||
--trace-max-array <depth> Maximum bit width for tracing
|
||||
--trace-max-width <width> Maximum array depth for tracing
|
||||
--trace-structs Enable tracing structure names
|
||||
--trace-underscore Enable tracing of _signals
|
||||
-U<var> Undefine preprocessor define
|
||||
--unroll-count <loops> Tune maximum loop iterations
|
||||
@@ -319,13 +333,16 @@ descriptions in the next sections for more information.
|
||||
--unused-regexp <regexp> Tune UNUSED lint signals
|
||||
-V Verbose version and config
|
||||
-v <filename> Verilog library
|
||||
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
|
||||
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
|
||||
-Werror-<message> Convert warning to error
|
||||
-Wfuture-<message> Disable unknown message warnings
|
||||
-Wno-<message> Disable warning
|
||||
-Wno-lint Disable all lint warnings
|
||||
-Wno-style Disable all style warnings
|
||||
-Wno-fatal Disable fatal exit on warnings
|
||||
-x-assign <mode> Initially assign Xs to this value
|
||||
--x-assign <mode> Initially assign Xs to this value
|
||||
--x-initial-edge Enable initial X->0 and X->1 edge triggers
|
||||
-y <dir> Directory to search for modules
|
||||
|
||||
|
||||
@@ -353,18 +370,58 @@ this way, Verilator will include a make rule that uses these files when
|
||||
linking the I<module> executable. This generally is only useful when used
|
||||
with the --exe option.
|
||||
|
||||
=item +1364-1995ext+I<ext>
|
||||
|
||||
=item +1364-2001ext+I<ext>
|
||||
|
||||
=item +1364-2005ext+I<ext>
|
||||
|
||||
=item +1800-2005ext+I<ext>
|
||||
|
||||
=item +1800-2009ext+I<ext>
|
||||
|
||||
=item +1800-2012ext+I<ext>
|
||||
|
||||
Specifies the language standard to be used with a specific filename
|
||||
extension, I<ext>.
|
||||
|
||||
For compatibility with other simulators, see also the synonyms
|
||||
C<+verilog1995ext+>I<ext>, C<+verilog2001ext+>I<ext>, and
|
||||
C<+systemverilogext+>I<ext>.
|
||||
|
||||
For any source file, the language specified by these options takes
|
||||
precedence over any language specified by the C<--default-language> or
|
||||
C<--language> options.
|
||||
|
||||
These options take effect in the order they are encountered. Thus the
|
||||
following would use Verilog 1995 for C<a.v> and Verilog 2001 for C<b.v>.
|
||||
|
||||
verilator ... +1364-1995ext+v a.v +1364-2001ext+v b.v
|
||||
|
||||
These flags are only recommended for legacy mixed language designs, as the
|
||||
preferable option is to edit the code to repair new keywords, or add
|
||||
appropriate C<`begin_keywords>.
|
||||
|
||||
B<Note> C<`begin_keywords> is a SystemVerilog construct, which specifies
|
||||
I<only> which the set of keywords is to be recognized. Whatever set is
|
||||
chosen, the semantics will be those of SystemVerilog. By contrast
|
||||
C<+1364-1995ext+> etc. specify both the syntax I<and> semantics to be used.
|
||||
|
||||
=item --assert
|
||||
|
||||
Enable all assertions, includes enabling the --psl flag. (If psl is not
|
||||
desired, but other assertions are, use --assert --nopsl.)
|
||||
|
||||
See also --x-assign; setting "--x-assign unique" may be desirable.
|
||||
See also --x-assign and --x-initial-edge; setting "--x-assign unique"
|
||||
and/or "--x-initial-edge" may be desirable.
|
||||
|
||||
=item --autoflush
|
||||
|
||||
After every $display or $fdisplay, flush the output stream. This insures
|
||||
that messages will appear immediately but may reduce performance. Defaults
|
||||
off, which will buffer output as provided by the normal C stdio calls.
|
||||
that messages will appear immediately but may reduce performance; for best
|
||||
performance call "fflush(stdout)" occasionally in the main C loop.
|
||||
Defaults off, which will buffer output as provided by the normal C stdio
|
||||
calls.
|
||||
|
||||
=item --bbox-sys
|
||||
|
||||
@@ -413,6 +470,12 @@ Enables tunings and work-arounds for the specified C++ compiler.
|
||||
|
||||
=over 4
|
||||
|
||||
=item clang
|
||||
|
||||
Tune for clang. This may reduce execution speed as it enables several
|
||||
workarounds to avoid silly hardcoded limits in clang. This includes
|
||||
breaking deep structures as for msvc as described below.
|
||||
|
||||
=item gcc
|
||||
|
||||
Tune for Gnu C++, although generated code should work on almost any
|
||||
@@ -524,6 +587,7 @@ Rarely needed. Enable internal debugging assertion checks, without
|
||||
changing debug verbosity. Enabled automatically when --debug specified.
|
||||
|
||||
=item --debugi <level>
|
||||
|
||||
=item --debugi-<srcfile> <level>
|
||||
|
||||
Rarely needed - for developer use. Set internal debugging level globally
|
||||
@@ -531,6 +595,25 @@ to the specified debug level (1-10) or set the specified source file to the
|
||||
specified level. Higher levels produce more detailed messages (plain
|
||||
C<--debug> is equivalent to C<--debugi 4>).
|
||||
|
||||
=item --default-language I<value>
|
||||
|
||||
Select the language to be used by default when first processing each
|
||||
Verilog file. The language value must be "1364-1995", "1364-2001",
|
||||
"1364-2005", "1800-2005", "1800-2009" or "1800-2012".
|
||||
|
||||
Any language associated with a particular file extension (see the various
|
||||
+I<lang>ext+ options) will be used in preference to the language specified
|
||||
by --default-language.
|
||||
|
||||
The --default-language flag is only recommended for legacy code using the
|
||||
same language in all source files, as the preferable option is to edit the
|
||||
code to repair new keywords, or add appropriate C<`begin_keywords>. For
|
||||
legacy mixed language designs, the various +I<lang>ext+ options should be
|
||||
used.
|
||||
|
||||
If no language is specified, either by this flag or +I<lang>ext+ options,
|
||||
then the latest SystemVerilog language (IEEE 1800-2012) is used.
|
||||
|
||||
=item +define+I<var>+I<value>
|
||||
|
||||
Defines the given preprocessor symbol. Same as -D; +define is fairly
|
||||
@@ -544,7 +627,7 @@ the Verilator Internals manual. --dump-tree is enabled automatically with
|
||||
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
|
||||
large and not desired.
|
||||
|
||||
=item --dump-treei
|
||||
=item --dump-treei <level>
|
||||
|
||||
Rarely needed. Enable writing .tree debug files with a specific dumping
|
||||
level, 0 disbles dumps and is equivelent to "--no-dump-tree". Level 9
|
||||
@@ -640,15 +723,8 @@ in the Make variable LDLIBS, not LDFLAGS.)
|
||||
|
||||
=item --language I<value>
|
||||
|
||||
Select the language to be used when first processing each Verilog file.
|
||||
The language value must be "1364-1995", "1364-2001", "1364-2001",
|
||||
"1364-2005", "1800-2005", "VAMS-2.3". Verilator also allows the
|
||||
non-standard "1800+VAMS" to allow both the full SystemVerilog and
|
||||
Verilog-AMS keywords.
|
||||
|
||||
The --language flag is only recommended for legacy code, as the preferable
|
||||
option is to edit the code to repair new keywords, or add appropriate
|
||||
`begin_keywords.
|
||||
A synonym for C<--default-langauge>, for compatibility with other tools and
|
||||
earlier versions of Verilator.
|
||||
|
||||
=item +libext+I<ext>+I<ext>...
|
||||
|
||||
@@ -679,7 +755,9 @@ to gcc -MP option.
|
||||
=item --Mdir I<directory>
|
||||
|
||||
Specifies the name of the Make object directory. All generated files will
|
||||
be placed in this directory. If not specified, "obj_dir" is used.
|
||||
be placed in this directory. If not specified, "obj_dir" is used. The
|
||||
directory is created if it does not exist and the parent directories exist;
|
||||
otherwise manually create the Mdir before calling Verilator.
|
||||
|
||||
=item --mod-prefix I<topname>
|
||||
|
||||
@@ -721,6 +799,12 @@ mappings of optimizations to -O letters.
|
||||
Specify the name for the final executable built if using --exe. Defaults
|
||||
to the --prefix if not specified.
|
||||
|
||||
=item --no-order-clock-delay
|
||||
|
||||
Rarely needed. Disables a bug fix for ordering of clock enables with
|
||||
delayed assignments. This flag should only be used when suggested by the
|
||||
developers.
|
||||
|
||||
=item --output-split I<bytes>
|
||||
|
||||
Enables splitting the output .cpp/.sp files into multiple outputs. When a
|
||||
@@ -743,6 +827,11 @@ worse with decreasing split values. Note that this option is stronger than
|
||||
--output-split in the sense that --output-split will not split inside a
|
||||
function.
|
||||
|
||||
=item --output-split-ctrace I<statements>
|
||||
|
||||
Enables splitting trace functions in the output .cpp/.sp files into
|
||||
multiple functions. Defaults to same setting as --output-split-cfuncs.
|
||||
|
||||
=item --pins64
|
||||
|
||||
Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.
|
||||
@@ -755,6 +844,20 @@ wide should use sc_bv's instead of uint32/vluint64_t's. The default is
|
||||
33". The more sc_bv is used, the worse for performance. Use the
|
||||
"/*verilator sc_bv*/" attribute to select specific ports to be sc_bv.
|
||||
|
||||
=item --pins-sc-uint
|
||||
|
||||
Specifies SystemC inputs/outputs of greater than 2 bits wide should use
|
||||
sc_uint between 2 and 64. When combined with the "--pins-sc-biguint"
|
||||
combination, it results in sc_uint being used between 2 and 64 and
|
||||
sc_biguint being used between 65 and 512.
|
||||
|
||||
=item --pins-sc-biguint
|
||||
|
||||
Specifies SystemC inputs/outputs of greater than 65 bits wide should use
|
||||
sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined
|
||||
with the "--pins-sc-uint" combination, it results in sc_uint being used
|
||||
between 2 and 64 and sc_biguint being used between 65 and 512.
|
||||
|
||||
=item --pins-uint8
|
||||
|
||||
Specifies SystemC inputs/outputs that are smaller than the --pins-bv
|
||||
@@ -816,6 +919,48 @@ inlining. This will also turn off inlining as if all modules had a
|
||||
/*verilator public_module*/, unless the module specifically enabled it with
|
||||
/*verilator inline_module*/.
|
||||
|
||||
=item --report-unoptflat
|
||||
|
||||
Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the
|
||||
10 widest variables in the loop, and the 10 most fanned out variables in
|
||||
the loop. These are candidates for splitting into multiple variables to
|
||||
break the loop.
|
||||
|
||||
In addition produces a GraphViz DOT file of the entire strongly connected
|
||||
components within the source associated with each loop. This is produced
|
||||
irrespective of whether --dump-tree is set. Such graphs may help in
|
||||
analysing the problem, but can be very large indeed.
|
||||
|
||||
Various commands exist for viewing and manipulating DOT files. For example
|
||||
the I<dot> command can be used to convert a DOT file to a PDF for
|
||||
printing. For example:
|
||||
|
||||
dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot
|
||||
|
||||
will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT
|
||||
file.
|
||||
|
||||
=item --savable
|
||||
|
||||
Enable including save and restore functions in the generated model.
|
||||
|
||||
The user code must create a VerilatedSerialize or VerilatedDeserialze
|
||||
object then calling the << or >> operators on the generated model and any
|
||||
other data the process needs saved/restored. For example:
|
||||
|
||||
void save_model(const char* filenamep) {
|
||||
VerilatedSave os;
|
||||
os.open(filenamep);
|
||||
os << main_time; // user code must save the timestamp, etc
|
||||
os << *topp;
|
||||
}
|
||||
void restore_model(const char* filenamep) {
|
||||
VerilatedRestore os;
|
||||
os.open(filenamep);
|
||||
os >> main_time;
|
||||
os >> *topp;
|
||||
}
|
||||
|
||||
=item --sc
|
||||
|
||||
Specifies SystemC output mode; see also --cc and -sp.
|
||||
@@ -834,6 +979,10 @@ Specifies SystemVerilog language features should be enabled; equivalent to
|
||||
"--language 1800-2005". This option is selected by default, it exists for
|
||||
compatibility with other simulators.
|
||||
|
||||
=item +systemverilogext+I<ext>
|
||||
|
||||
A synonym for C<+1800-2012ext+>I<ext>.
|
||||
|
||||
=item --top-module I<topname>
|
||||
|
||||
When the input Verilog contains more than one top level module, specifies
|
||||
@@ -873,6 +1022,13 @@ Rarely needed. Specify the maximum bit width of a signal that may be
|
||||
traced. Defaults to 256, as tracing large vectors may greatly slow traced
|
||||
simulations.
|
||||
|
||||
=item --trace-structs
|
||||
|
||||
Enable tracing to show the name of packed structure, union, and packed
|
||||
array fields, rather than a simgle combined packed bus. Due to VCD file
|
||||
format constraints this may result in significantly slower trace times and
|
||||
larger trace files.
|
||||
|
||||
=item --trace-underscore
|
||||
|
||||
Enable tracing of signals that start with an underscore. Normally, these
|
||||
@@ -909,6 +1065,12 @@ Read the filename as a Verilog library. Any modules in the file may be
|
||||
used to resolve cell instantiations in the top level module, else ignored.
|
||||
Note -v is fairly standard across Verilog tools.
|
||||
|
||||
=item +verilog1995ext+I<ext>
|
||||
|
||||
=item +verilog2001ext+I<ext>
|
||||
|
||||
Synonyms for C<+1364-1995ext+>I<ext> and C<+1364-2001ext+>I<ext> respectively
|
||||
|
||||
=item -Wall
|
||||
|
||||
Enable all warnings, including code style warnings that are normally
|
||||
@@ -935,10 +1097,10 @@ Disable the specified warning message.
|
||||
=item -Wno-lint
|
||||
|
||||
Disable all lint related warning messages, and all style warnings. This is
|
||||
equivalent to "-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX
|
||||
-Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN
|
||||
-Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED
|
||||
-Wno-WIDTH" plus the list shown for Wno-style.
|
||||
equivalent to "-Wno-ALWCOMBORDER -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP
|
||||
-Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT
|
||||
-Wno-LITENDIAN -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN
|
||||
-Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style.
|
||||
|
||||
It is strongly recommended you cleanup your code rather than using this
|
||||
option, it is only intended to be use when running test-cases of code
|
||||
@@ -967,9 +1129,10 @@ Enables the specified warning message.
|
||||
|
||||
Enable all lint related warning messages (note by default they are already
|
||||
enabled), but do not affect style messages. This is equivalent to
|
||||
"-Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX
|
||||
-Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN
|
||||
-Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH".
|
||||
"-Wwarn-ALWCOMBORDER -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX
|
||||
-Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT
|
||||
-Wwarn-LITENDIAN -Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED
|
||||
-Wwarn-WIDTH".
|
||||
|
||||
=item -Wwarn-style
|
||||
|
||||
@@ -978,29 +1141,63 @@ Enable all code style related warning messages. This is equivalent to
|
||||
-Wwarn-PINNOCONNECT -Wwarn-SYNCASYNCNET -Wwarn-UNDRIVEN -Wwarn-UNUSED
|
||||
-Wwarn-VARHIDDEN".
|
||||
|
||||
=item -x-assign 0
|
||||
=item --x-assign 0
|
||||
|
||||
=item -x-assign 1
|
||||
=item --x-assign 1
|
||||
|
||||
=item -x-assign fast (default)
|
||||
=item --x-assign fast (default)
|
||||
|
||||
=item -x-assign unique
|
||||
=item --x-assign unique
|
||||
|
||||
Controls the two-state value that is replaced when an assignment to X is
|
||||
encountered. -x-assign=fast, the default, converts all Xs to whatever is
|
||||
best for performance. -x-assign=0 converts all Xs to 0s, and is also fast.
|
||||
-x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
|
||||
likely to find reset bugs as active high logic will fire. -x-assign=unique
|
||||
encountered. --x-assign=fast, the default, converts all Xs to whatever is
|
||||
best for performance. --x-assign=0 converts all Xs to 0s, and is also fast.
|
||||
--x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
|
||||
likely to find reset bugs as active high logic will fire. --x-assign=unique
|
||||
will call a function to determine the value, this allows randomization of
|
||||
all Xs to find reset bugs and is the slowest, but safest for finding reset
|
||||
bugs in code.
|
||||
|
||||
If using -x-assign unique, you may want to seed your random number
|
||||
If using --x-assign unique, you may want to seed your random number
|
||||
generator such that each regression run gets a different randomization
|
||||
sequence. Use the system's srand48() or for Windows srand() function to do
|
||||
this. You'll probably also want to print any seeds selected, and code to
|
||||
enable rerunning with that same seed so you can reproduce bugs.
|
||||
|
||||
B<Note.> This option applies only to variables which are explicitly assigned
|
||||
to X in the Verilog source code. Initial values of clocks are set to 0 unless
|
||||
--x-initial-edge is specified. Initial values of all other state holding
|
||||
variables are set as though --x-assign unique had been specified.
|
||||
|
||||
=item --x-initial-edge
|
||||
|
||||
Enables emulation of event driven simulators which generally trigger an
|
||||
edge on a transition from X to 1 (C<posedge>) or X to 0 (C<negedge>). Thus
|
||||
the following code, where C<rst_n> is uninitialized would set C<res_n> to
|
||||
C<1'b1> when C<rst_n> is first set to zero:
|
||||
|
||||
reg res_n = 1'b0;
|
||||
|
||||
always @(negedge rst_n) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
res_n <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
In Verilator, by default, uninitialized clocks are given a value of zero,
|
||||
so the above C<always> block would not trigger.
|
||||
|
||||
While it is not good practice, there are some designs that rely on X
|
||||
E<rarr> 0 triggering a C<negedge>, particularly in reset sequences. Using
|
||||
--x-initial-edge with Verilator will replicate this behaviour. It will also
|
||||
ensure that X E<rarr> 1 triggers a C<posedge>.
|
||||
|
||||
B<Note.> Some users have reported that using this option can affect
|
||||
convergence, and that it may be necessary to use --converge-limit to
|
||||
increase the number of convergence iterations. This may be another
|
||||
indication of problems with the modelled design that should be addressed.
|
||||
|
||||
=item -y I<dir>
|
||||
|
||||
Add the directory to the list of directories that should be searched for
|
||||
@@ -1036,6 +1233,7 @@ We'll compile this example into C++.
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Vour* top = new Vour;
|
||||
while (!Verilated::gotFinish()) { top->eval(); }
|
||||
delete top;
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
@@ -1103,6 +1301,7 @@ This is an example similar to the above, but using SystemPerl.
|
||||
top = new Vour("top"); // SP_CELL (top, Vour);
|
||||
top->clk(clk); // SP_PIN (top, clk, clk);
|
||||
while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
|
||||
delete top;
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
@@ -1159,9 +1358,9 @@ the test_sp directory in the distribution for an example.
|
||||
|
||||
=head1 BENCHMARKING & OPTIMIZATION
|
||||
|
||||
For best performance, run Verilator with the "-O3 -x-assign=fast
|
||||
For best performance, run Verilator with the "-O3 --x-assign=fast
|
||||
--noassert" flags. The -O3 flag will require longer compile times, and
|
||||
-x-assign=fast may increase the risk of reset bugs in trade for
|
||||
--x-assign=fast may increase the risk of reset bugs in trade for
|
||||
performance; see the above documentation for these flags.
|
||||
|
||||
Minor Verilog code changes can also give big wins. You should not have any
|
||||
@@ -1176,8 +1375,10 @@ C++ compiler and size of your CPU's caches.
|
||||
By default, the lib/verilated.mk file has optimization turned off. This is
|
||||
for the benefit of new users, as it improves compile times at the cost of
|
||||
runtimes. To add optimization as the default, set one of three variables,
|
||||
OPT, OPT_FAST, or OPT_SLOW in lib/verilated.mk. Or, just for one run, pass
|
||||
them on the command line to make:
|
||||
OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or
|
||||
-LDFLAGS option on the verilator command line to pass the flags directly to
|
||||
the compiler or linker. Or, just for one run, pass them on the command
|
||||
line to make:
|
||||
|
||||
make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a
|
||||
|
||||
@@ -1188,7 +1389,10 @@ rarely, yet take a long time to compile with optimization on. OPT
|
||||
specifies overall optimization and affects all compiles, including those
|
||||
OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link
|
||||
with "-static". Nearly the same results can be had with much better
|
||||
compile times with OPT_FAST="-O1 -fstrict-aliasing".
|
||||
compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization
|
||||
such as "-O3" may help, but gcc compile times may be excessive under O3 on
|
||||
even medium sized designs. Alternatively, some larger designs report
|
||||
better performance using "-Os".
|
||||
|
||||
Unfortunately, using the optimizer with SystemC files can result in
|
||||
compiles taking several minutes. (The SystemC libraries have many little
|
||||
@@ -1202,6 +1406,11 @@ If you will be running many simulations on a single compile, investigate
|
||||
feedback driven compilation. With GCC, using -fprofile-arcs, then
|
||||
-fbranch-probabilities will yield another 15% or so.
|
||||
|
||||
Modern compilers also support link-time optimization (LTO), which can help
|
||||
especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in
|
||||
both compilation and link. Note LTO may cause excessive compile times on
|
||||
large designs.
|
||||
|
||||
You may uncover further tuning possibilities by profiling the Verilog code.
|
||||
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
|
||||
either oprofile or gprof to see where in the C++ code the time is spent.
|
||||
@@ -1401,6 +1610,7 @@ example:
|
||||
|
||||
top->final(); // Done simulating
|
||||
// // (Though this example doesn't get here)
|
||||
delete top;
|
||||
}
|
||||
|
||||
Note signals are read and written as member variables of the lower module.
|
||||
@@ -1739,29 +1949,25 @@ uwire keyword.
|
||||
|
||||
=head2 SystemVerilog 2005 (IEEE 1800-2005) Support
|
||||
|
||||
Verilator currently has some support for SystemVerilog synthesis
|
||||
constructs. As SystemVerilog features enter common usage they are added;
|
||||
please file a bug if a feature you need is missing.
|
||||
|
||||
Verilator supports ==? and !=? operators, ++ and -- in some contexts,
|
||||
$bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0,
|
||||
$unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle,
|
||||
const, do-while, enum, export, final, import, int, logic, longint, package,
|
||||
program, shortint, struct, time, typedef, union, var, void, priority
|
||||
case/if, and unique case/if.
|
||||
const, do-while, enum, export, final, import, int, interface, logic,
|
||||
longint, modport, package, program, shortint, struct, time, typedef, union,
|
||||
var, void, priority case/if, and unique case/if.
|
||||
|
||||
It also supports .name and .* interconnection.
|
||||
|
||||
Verilator partially supports concurrent assert and cover statements; see
|
||||
the enclosed coverage tests for the syntax which is allowed.
|
||||
|
||||
=head2 SystemVerilog 2009 (IEEE 1800-2009) Support
|
||||
=head2 SystemVerilog 2012 (IEEE 1800-2012) Support
|
||||
|
||||
Verilator implements a full SystemVerilog 2009 preprocessor, including
|
||||
Verilator implements a full SystemVerilog 2012 preprocessor, including
|
||||
function call-like preprocessor defines, default define arguments,
|
||||
`__FILE__, `__LINE__ and `undefineall.
|
||||
|
||||
Verilator currently has some support for SystemVerilog 2009 synthesis
|
||||
Verilator currently has some support for SystemVerilog synthesis
|
||||
constructs. As SystemVerilog features enter common usage they are added;
|
||||
please file a bug if a feature you need is missing.
|
||||
|
||||
@@ -1931,6 +2137,11 @@ functions, the Verilog signals must be declared with /*verilator public*/.
|
||||
See also the public task feature; writing an accessor may result in cleaner
|
||||
code.
|
||||
|
||||
=item `SYSTEMVERILOG
|
||||
|
||||
The SYSTEMVERILOG, SV_COV_START and related standard defines are set by
|
||||
default when --language is 1800-*.
|
||||
|
||||
=item `VERILATOR
|
||||
|
||||
=item `verilator
|
||||
@@ -2188,6 +2399,11 @@ always @* to reduce missing activity items. Avoid putting $displays in
|
||||
combo blocks, as they may print multiple times when not desired, even on
|
||||
compliant simulators as event ordering is not specified.
|
||||
|
||||
=head2 Bind
|
||||
|
||||
Verilator only supports "bind" to a target module name, not an instance
|
||||
path.
|
||||
|
||||
=head2 Dotted cross-hierarchy references
|
||||
|
||||
Verilator supports dotted references to variables, functions and tasks in
|
||||
@@ -2242,7 +2458,7 @@ from a four state simulator. An === comparison to X will always be false,
|
||||
so that Verilog code which checks for uninitialized logic will not fire.
|
||||
|
||||
Assigning a variable to a X will actually assign the variable to a random
|
||||
value (see the -x-assign switch.) Thus if the value is actually used, the
|
||||
value (see the --x-assign switch.) Thus if the value is actually used, the
|
||||
random value should cause downstream errors. Integers also randomize, even
|
||||
though the Verilog 2001 specification says they initialize to zero.
|
||||
|
||||
@@ -2254,6 +2470,18 @@ following runs have it initialize them randomly. If the results match,
|
||||
reset works. (Note this is what the hardware will really do.) In
|
||||
practice, just setting all variables to one at startup finds most problems.
|
||||
|
||||
B<Note.> --x-assign applies to variables explicitly initialized or assigned to
|
||||
X. Unititialized clocks are initialized to zero, while all other state holding
|
||||
variables are initialized to a random value.
|
||||
|
||||
Event driven simulators will generally trigger an edge on a transition from X
|
||||
to 1 (C<posedge>) or X to 0 (C<negedge>). However, by default, since clocks
|
||||
are initialized to zero, Verilator will not trigger an initial negedge. Some
|
||||
code (particulary for reset) may rely on X->0 triggering an edge. Verilator
|
||||
provides a switch (see --x-initial-edge) to enable this behavior. Comparing
|
||||
runs with and without this switch will find such problems.
|
||||
|
||||
|
||||
=head2 Tri/Inout
|
||||
|
||||
Verilator converts some simple tristate structures into two state. Pullup,
|
||||
@@ -2374,6 +2602,12 @@ Increment/decrement can only be used as standalone statements or in for
|
||||
loops. They cannot be used as side effect operators inside more complicate
|
||||
expressions ("a = b++;").
|
||||
|
||||
=item '{} operator
|
||||
|
||||
Assignment patterns with order based, default, constant integer (array) or
|
||||
member identifier (struct/union) keys are supported. Data type keys and
|
||||
keys which are computed from a constant expression are not supported.
|
||||
|
||||
=item cast operator
|
||||
|
||||
Casting is supported only between simple scalar types, signed and unsigned,
|
||||
@@ -2391,6 +2625,17 @@ the disable statement itself is inside. This was commonly used to provide
|
||||
loop break and continue functionality before SystemVerilog added the break
|
||||
and continue keywords.
|
||||
|
||||
=item inside
|
||||
|
||||
Inside expressions may not include unpacked array traversal or $ as an
|
||||
upper bound. Case inside and case matches are also unsupported.
|
||||
|
||||
=item interface
|
||||
|
||||
Interfaces and modports, including with generated data types are supported.
|
||||
Generate blocks around modports are not supported, nor are virtual
|
||||
interfaces nor unnamed interfaces.
|
||||
|
||||
=item priority if, unique if
|
||||
|
||||
Priority and unique if's are treated as normal ifs and not asserted to be
|
||||
@@ -2501,6 +2746,20 @@ List of all warnings:
|
||||
|
||||
=over 4
|
||||
|
||||
=item ALWCOMBORDER
|
||||
|
||||
Warns that an always_comb block has a variable which is set after it is
|
||||
used. This may cause simulation-synthesis mismatches, as not all
|
||||
commercial simulators allow this ordering.
|
||||
|
||||
always_comb begin
|
||||
a = b;
|
||||
b = 1;
|
||||
end
|
||||
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
|
||||
=item ASSIGNIN
|
||||
|
||||
Error that an assignment is being made to an input signal. This is almost
|
||||
@@ -2665,6 +2924,15 @@ designs should now be using the #(...) format to specify parameters.
|
||||
Disabled by default as this is a code style warning; it will simulate
|
||||
correctly.
|
||||
|
||||
=item DETECTARRAY
|
||||
|
||||
Error when Verilator tries to deal with a combinatorial loop that could not be
|
||||
flattened, and which involves a datatype which Verilator cannot handle, such
|
||||
as an unpacked struct or a large unpacked array. This typically ocurrs when
|
||||
-Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below).
|
||||
|
||||
The solution is to break the loop, as described for UNOPTFLAT.
|
||||
|
||||
=item ENDLABEL
|
||||
|
||||
Warns that a label attached to a "end"-something statement does not match
|
||||
@@ -2746,7 +3014,7 @@ simulators.
|
||||
|
||||
=item LITENDIAN
|
||||
|
||||
Warns that a vector is declared with little endian bit numbering
|
||||
Warns that a packed vector is declared with little endian bit numbering
|
||||
(i.e. [0:7]). Big endian bit numbering is now the overwhelming standard,
|
||||
and little numbering is now thus often due to simple oversight instead of
|
||||
intent.
|
||||
@@ -2965,9 +3233,21 @@ 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.
|
||||
|
||||
To assist in resolving UNOPTFLAT, the option C<--report-unoptflat> can be
|
||||
used, which will provide suggestions for variables that can be split up,
|
||||
and a graph of all the nodes connected in the loop. See the L<Arguments>
|
||||
section for more details.
|
||||
|
||||
Ignoring this warning will only slow simulations, it will simulate
|
||||
correctly.
|
||||
|
||||
=item UNPACKED
|
||||
|
||||
Warns that unpacked structs and unions are not supported.
|
||||
|
||||
Ignoring this warning will make Verilator treat the structure as packed,
|
||||
which may make Verilator simulations differ from other simulators.
|
||||
|
||||
=item UNSIGNED
|
||||
|
||||
Warns that you are comparing a unsigned value in a way that implies it is
|
||||
@@ -3263,8 +3543,8 @@ coverage. Both require the SystemPerl package to be installed but do not
|
||||
require use of the SystemPerl output mode.
|
||||
|
||||
First, run verilator with the --coverage option. If you're using your own
|
||||
makefile, compile the model with the GCC flag -DSP_COVERAGE_ENABLE (if
|
||||
using Verilator's, it will do this for you.)
|
||||
makefile, compile the model with the GCC flag -DSP_COVERAGE (if using
|
||||
Verilator's, it will do this for you.)
|
||||
|
||||
Run your tests in different directories. Each test will create a
|
||||
logs/coverage.pl file.
|
||||
@@ -3551,7 +3831,7 @@ Thanks to them, and all those we've missed including above.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2003-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify the Verilator internals under the terms of
|
||||
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
||||
License Version 2.0.
|
||||
@@ -3566,9 +3846,11 @@ Major concepts by Paul Wasson and Duane Galbi.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>
|
||||
L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>,
|
||||
|
||||
And internals.txt in the distribution.
|
||||
L<verilator --help> which is the source for this document,
|
||||
|
||||
and internals.txt in the distribution.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ Do not show differences in line numbering.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/verilator>.
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. This package is free software; you can
|
||||
Copyright 2005-2014 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 Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# DESCRIPTION: Print include statements for each ARGV
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. This package is free software; you can
|
||||
# Copyright 2003-2014 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 Version 3 or the Perl Artistic License Version 2.0.
|
||||
######################################################################
|
||||
|
||||
@@ -208,7 +208,7 @@ Displays this message and program version and exits.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2007-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2007-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+5
-3
@@ -1,12 +1,14 @@
|
||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
# Copyright 2003-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
AC_INIT([Verilator],[3.840 2012-07-31])
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.856 2014-03-11])
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
|
||||
|
||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
verilated.mk
|
||||
verilated_config.h
|
||||
|
||||
+58
-24
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -33,17 +33,14 @@
|
||||
// Global variables
|
||||
|
||||
// Slow path variables
|
||||
int Verilated::s_randReset = 0;
|
||||
VerilatedVoidCb Verilated::s_flushCb = NULL;
|
||||
|
||||
// Keep below together in one cache line
|
||||
int Verilated::s_debug = 0;
|
||||
bool Verilated::s_calcUnusedSigs = false;
|
||||
bool Verilated::s_gotFinish = false;
|
||||
bool Verilated::s_assertOn = true;
|
||||
Verilated::Serialized Verilated::s_s;
|
||||
VL_THREAD const VerilatedScope* Verilated::t_dpiScopep = NULL;
|
||||
VL_THREAD const char* Verilated::t_dpiFilename = "";
|
||||
VL_THREAD int Verilated::t_dpiLineno = 0;
|
||||
struct Verilated::CommandArgValues Verilated::s_args = {0, NULL};
|
||||
|
||||
VerilatedImp VerilatedImp::s_s;
|
||||
|
||||
@@ -81,6 +78,18 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
// Overall class init
|
||||
|
||||
Verilated::Serialized::Serialized() {
|
||||
s_randReset = 0;
|
||||
s_debug = 0;
|
||||
s_calcUnusedSigs = false;
|
||||
s_gotFinish = false;
|
||||
s_assertOn = true;
|
||||
s_fatalOnVpiError = true; // retains old default behaviour
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Random reset -- Only called at init time, so don't inline.
|
||||
|
||||
@@ -301,7 +310,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
const char *ep = pos;
|
||||
while (ep[0] && ep[0]!='%') ep++;
|
||||
if (ep != pos) {
|
||||
output += string(pos, ep-pos);
|
||||
output.append(pos, ep-pos);
|
||||
pos += ep-pos-1;
|
||||
}
|
||||
} else { // Format character
|
||||
@@ -346,9 +355,9 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
// Deal with all read-and-print somethings
|
||||
const int lbits = va_arg(ap, int);
|
||||
QData ld = 0;
|
||||
WData qlwp[2];
|
||||
WDataInP lwp;
|
||||
if (lbits <= VL_QUADSIZE) {
|
||||
WData qlwp[2];
|
||||
ld = _VL_VA_ARG_Q(ap, lbits);
|
||||
VL_SET_WQ(qlwp,ld);
|
||||
lwp = qlwp;
|
||||
@@ -594,7 +603,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
vlsint64_t ld;
|
||||
sscanf(tmp,"%" VL_PRI64 "d",&ld);
|
||||
sscanf(tmp,"%30" VL_PRI64 "d",&ld);
|
||||
VL_SET_WQ(owp,ld);
|
||||
break;
|
||||
}
|
||||
@@ -615,7 +624,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
QData ld;
|
||||
sscanf(tmp,"%" VL_PRI64 "u",&ld);
|
||||
sscanf(tmp,"%30" VL_PRI64 "u",&ld);
|
||||
VL_SET_WQ(owp,ld);
|
||||
break;
|
||||
}
|
||||
@@ -750,19 +759,30 @@ void VL_FCLOSE_I(IData fdi) {
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
|
||||
VL_STATIC_OR_THREAD string output; // static only for speed
|
||||
output = "";
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
string output;
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
|
||||
_VL_STRING_TO_VINT(obits, destp, (int)output.length(), output.c_str());
|
||||
}
|
||||
|
||||
string VL_SFORMATF_NX(const char* formatp, ...) {
|
||||
void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
|
||||
if (obits_ignored) {}
|
||||
output = "";
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
string VL_SFORMATF_NX(const char* formatp, ...) {
|
||||
VL_STATIC_OR_THREAD string output; // static only for speed
|
||||
output = "";
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
string output;
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
|
||||
@@ -770,9 +790,10 @@ string VL_SFORMATF_NX(const char* formatp, ...) {
|
||||
}
|
||||
|
||||
void VL_WRITEF(const char* formatp, ...) {
|
||||
VL_STATIC_OR_THREAD string output; // static only for speed
|
||||
output = "";
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
string output;
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
|
||||
@@ -781,12 +802,13 @@ void VL_WRITEF(const char* formatp, ...) {
|
||||
}
|
||||
|
||||
void VL_FWRITEF(IData fpi, const char* formatp, ...) {
|
||||
VL_STATIC_OR_THREAD string output; // static only for speed
|
||||
output = "";
|
||||
FILE* fp = VL_CVT_I_FP(fpi);
|
||||
if (VL_UNLIKELY(!fp)) return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
string output;
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
|
||||
@@ -949,13 +971,13 @@ IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
|
||||
}
|
||||
|
||||
IData VL_TESTPLUSARGS_I(const char* formatp) {
|
||||
string match = VerilatedImp::argPlusMatch(formatp);
|
||||
const string& match = VerilatedImp::argPlusMatch(formatp);
|
||||
if (match == "") return 0;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp) {
|
||||
string match = VerilatedImp::argPlusMatch(prefixp);
|
||||
const string& match = VerilatedImp::argPlusMatch(prefixp);
|
||||
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
|
||||
if (match == "") return 0;
|
||||
VL_ZERO_RESET_W(rbits, rwp);
|
||||
@@ -964,7 +986,7 @@ IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rw
|
||||
break;
|
||||
case 'd':
|
||||
vlsint64_t ld;
|
||||
sscanf(dp,"%" VL_PRI64 "d",&ld);
|
||||
sscanf(dp,"%30" VL_PRI64 "d",&ld);
|
||||
VL_SET_WQ(rwp,ld);
|
||||
break;
|
||||
case 'b':
|
||||
@@ -991,7 +1013,7 @@ IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rw
|
||||
}
|
||||
|
||||
const char* vl_mc_scan_plusargs(const char* prefixp) {
|
||||
string match = VerilatedImp::argPlusMatch(prefixp);
|
||||
const string& match = VerilatedImp::argPlusMatch(prefixp);
|
||||
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
|
||||
if (match == "") return NULL;
|
||||
strncpy(outstr, match.c_str()+strlen(prefixp)+1, // +1 to skip the "+"
|
||||
@@ -1053,9 +1075,19 @@ void Verilated::flushCb(VerilatedVoidCb cb) {
|
||||
}
|
||||
|
||||
void Verilated::commandArgs(int argc, const char** argv) {
|
||||
s_args.argc = argc;
|
||||
s_args.argv = argv;
|
||||
VerilatedImp::commandArgs(argc,argv);
|
||||
}
|
||||
|
||||
const char* Verilated::commandArgsPlusMatch(const char* prefixp) {
|
||||
return VerilatedImp::argPlusMatch(prefixp).c_str();
|
||||
}
|
||||
|
||||
void Verilated::internalsDump() {
|
||||
VerilatedImp::internalsDump();
|
||||
}
|
||||
|
||||
void Verilated::scopesDump() {
|
||||
VerilatedImp::scopesDump();
|
||||
}
|
||||
@@ -1082,6 +1114,7 @@ VerilatedModule::~VerilatedModule() {
|
||||
//======================================================================
|
||||
// VerilatedVar:: Methods
|
||||
|
||||
// cppcheck-suppress unusedFunction // Used by applications
|
||||
vluint32_t VerilatedVar::entSize() const {
|
||||
vluint32_t size = 1;
|
||||
switch (vltype()) {
|
||||
@@ -1090,7 +1123,7 @@ vluint32_t VerilatedVar::entSize() const {
|
||||
case VLVT_UINT16: size=sizeof(SData); break;
|
||||
case VLVT_UINT32: size=sizeof(IData); break;
|
||||
case VLVT_UINT64: size=sizeof(QData); break;
|
||||
case VLVT_WDATA: size=VL_WORDS_I(range().bits())*sizeof(IData); break;
|
||||
case VLVT_WDATA: size=VL_WORDS_I(range().elements())*sizeof(IData); break;
|
||||
default: size=0; break;
|
||||
}
|
||||
return size;
|
||||
@@ -1162,11 +1195,11 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
|
||||
int msb = va_arg(ap,int);
|
||||
int lsb = va_arg(ap,int);
|
||||
if (i==0) {
|
||||
var.m_range.m_lhs = msb;
|
||||
var.m_range.m_rhs = lsb;
|
||||
var.m_range.m_left = msb;
|
||||
var.m_range.m_right = lsb;
|
||||
} else if (i==1) {
|
||||
var.m_array.m_lhs = msb;
|
||||
var.m_array.m_rhs = lsb;
|
||||
var.m_array.m_left = msb;
|
||||
var.m_array.m_right = lsb;
|
||||
} else {
|
||||
// We could have a linked list of ranges, but really this whole thing needs
|
||||
// to be generalized to support structs and unions, etc.
|
||||
@@ -1178,6 +1211,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
|
||||
m_varsp->insert(make_pair(namep,var));
|
||||
}
|
||||
|
||||
// cppcheck-suppress unusedFunction // Used by applications
|
||||
VerilatedVar* VerilatedScope::varFind(const char* namep) const {
|
||||
if (VL_LIKELY(m_varsp)) {
|
||||
VerilatedVarNameMap::iterator it = m_varsp->find(namep);
|
||||
|
||||
+96
-30
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -28,6 +28,7 @@
|
||||
#ifndef _VERILATED_H_
|
||||
#define _VERILATED_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilated_config.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <cassert>
|
||||
@@ -144,7 +145,7 @@ public:
|
||||
# define VL_CELL(instname,type) ///< Declare a cell, ala SP_CELL
|
||||
|
||||
/// Declare a module, ala SC_MODULE
|
||||
# define VL_MODULE(modname) struct modname : public VerilatedModule
|
||||
# define VL_MODULE(modname) class modname : public VerilatedModule
|
||||
|
||||
/// Constructor, ala SC_CTOR
|
||||
# define VL_CTOR(modname) modname(const char* __VCname="")
|
||||
@@ -215,23 +216,34 @@ public: // But internals only - called from VerilatedModule's
|
||||
//===========================================================================
|
||||
/// Verilator global static information class
|
||||
|
||||
struct Verilated {
|
||||
class Verilated {
|
||||
// MEMBERS
|
||||
private:
|
||||
// Slow path variables
|
||||
static int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
|
||||
static VerilatedVoidCb s_flushCb; ///< Flush callback function
|
||||
|
||||
// Fast path
|
||||
static int s_debug; ///< See accessors... only when VL_DEBUG set
|
||||
static bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
|
||||
static bool s_gotFinish; ///< A $finish statement executed
|
||||
static bool s_assertOn; ///< Assertions are enabled
|
||||
static struct Serialized { // All these members serialized/deserialized
|
||||
// Slow path
|
||||
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
|
||||
// Fast path
|
||||
int s_debug; ///< See accessors... only when VL_DEBUG set
|
||||
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
|
||||
bool s_gotFinish; ///< A $finish statement executed
|
||||
bool s_assertOn; ///< Assertions are enabled
|
||||
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
|
||||
Serialized();
|
||||
} s_s;
|
||||
|
||||
static VL_THREAD const VerilatedScope* t_dpiScopep; ///< DPI context scope
|
||||
static VL_THREAD const char* t_dpiFilename; ///< DPI context filename
|
||||
static VL_THREAD int t_dpiLineno; ///< DPI context line number
|
||||
|
||||
// no need to be save-restored (serialized) the
|
||||
// assumption is that the restore is allowed to pass different arguments
|
||||
static struct CommandArgValues {
|
||||
int argc;
|
||||
const char** argv;
|
||||
} s_args;
|
||||
|
||||
public:
|
||||
|
||||
// METHODS - User called
|
||||
@@ -241,29 +253,32 @@ public:
|
||||
/// 0 = Set to zeros
|
||||
/// 1 = Set all bits to one
|
||||
/// 2 = Randomize all bits
|
||||
static void randReset(int val) { s_randReset=val; }
|
||||
static int randReset() { return s_randReset; } ///< Return randReset value
|
||||
static void randReset(int val) { s_s.s_randReset=val; }
|
||||
static int randReset() { return s_s.s_randReset; } ///< Return randReset value
|
||||
|
||||
/// Enable debug of internal verilated code
|
||||
static inline void debug(int level) { s_debug = level; }
|
||||
static inline void debug(int level) { s_s.s_debug = level; }
|
||||
#ifdef VL_DEBUG
|
||||
static inline int debug() { return s_debug; } ///< Return debug value
|
||||
static inline int debug() { return s_s.s_debug; } ///< Return debug value
|
||||
#else
|
||||
static inline int debug() { return 0; } ///< Constant 0 debug, so C++'s optimizer rips up
|
||||
#endif
|
||||
/// Enable calculation of unused signals
|
||||
static void calcUnusedSigs(bool flag) { s_calcUnusedSigs=flag; }
|
||||
static bool calcUnusedSigs() { return s_calcUnusedSigs; } ///< Return calcUnusedSigs value
|
||||
static void calcUnusedSigs(bool flag) { s_s.s_calcUnusedSigs=flag; }
|
||||
static bool calcUnusedSigs() { return s_s.s_calcUnusedSigs; } ///< Return calcUnusedSigs value
|
||||
/// Did the simulation $finish?
|
||||
static void gotFinish(bool flag) { s_gotFinish=flag; }
|
||||
static bool gotFinish() { return s_gotFinish; } ///< Return if got a $finish
|
||||
static void gotFinish(bool flag) { s_s.s_gotFinish=flag; }
|
||||
static bool gotFinish() { return s_s.s_gotFinish; } ///< Return if got a $finish
|
||||
/// Allow traces to at some point be enabled (disables some optimizations)
|
||||
static void traceEverOn(bool flag) {
|
||||
if (flag) { calcUnusedSigs(flag); }
|
||||
}
|
||||
/// Enable/disable assertions
|
||||
static void assertOn(bool flag) { s_assertOn=flag; }
|
||||
static bool assertOn() { return s_assertOn; }
|
||||
static void assertOn(bool flag) { s_s.s_assertOn=flag; }
|
||||
static bool assertOn() { return s_s.s_assertOn; }
|
||||
/// Enable/disable vpi fatal
|
||||
static void fatalOnVpiError(bool flag) { s_s.s_fatalOnVpiError=flag; }
|
||||
static bool fatalOnVpiError() { return s_s.s_fatalOnVpiError; }
|
||||
/// Flush callback for VCD waves
|
||||
static void flushCb(VerilatedVoidCb cb);
|
||||
static void flushCall() { if (s_flushCb) (*s_flushCb)(); }
|
||||
@@ -271,6 +286,17 @@ public:
|
||||
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
|
||||
static void commandArgs(int argc, const char** argv);
|
||||
static void commandArgs(int argc, char** argv) { commandArgs(argc,(const char**)argv); }
|
||||
static CommandArgValues* getCommandArgs() {return &s_args;}
|
||||
static const char* commandArgsPlusMatch(const char* prefixp);
|
||||
|
||||
/// Produce name & version for (at least) VPI
|
||||
static const char* productName() { return VERILATOR_PRODUCT; }
|
||||
static const char* productVersion() { return VERILATOR_VERSION; }
|
||||
|
||||
/// For debugging, print much of the Verilator internal state.
|
||||
/// The output of this function may change in future
|
||||
/// releases - contact the authors before production use.
|
||||
static void internalsDump();
|
||||
|
||||
/// For debugging, print text list of all scope names with
|
||||
/// dpiImport/Export context. This function may change in future
|
||||
@@ -292,6 +318,8 @@ public:
|
||||
static const char* dpiFilenamep() { return t_dpiFilename; }
|
||||
static int dpiLineno() { return t_dpiLineno; }
|
||||
static int exportFuncNum(const char* namep);
|
||||
static size_t serializedSize() { return sizeof(s_s); }
|
||||
static void* serializedPtr() { return &s_s; }
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
@@ -523,6 +551,7 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
//===================================================================
|
||||
// SYSTEMC OPERATORS
|
||||
// Copying verilog format to systemc integers and bit vectors.
|
||||
// Get a SystemC variable
|
||||
|
||||
#define VL_ASSIGN_ISI(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
|
||||
#define VL_ASSIGN_QSQ(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read()); }
|
||||
@@ -540,7 +569,21 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
owp[words-1] &= VL_MASK_I(obits); \
|
||||
}
|
||||
|
||||
#define VL_ASSIGN_ISU(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read().to_uint()); }
|
||||
#define VL_ASSIGN_QSU(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read().to_uint64()); }
|
||||
#define VL_ASSIGN_WSB(obits,owp,svar) { \
|
||||
int words = VL_WORDS_I(obits); \
|
||||
sc_biguint<obits> _butemp = (svar).read(); \
|
||||
for (int i=0; i < words; i++) { \
|
||||
int msb = ((i+1)*VL_WORDSIZE) - 1; \
|
||||
msb = (msb >= obits) ? (obits-1) : msb; \
|
||||
owp[i] = _butemp.range(msb,i*VL_WORDSIZE).to_uint(); \
|
||||
} \
|
||||
owp[words-1] &= VL_MASK_I(obits); \
|
||||
}
|
||||
|
||||
// Copying verilog format from systemc integers and bit vectors.
|
||||
// Set a SystemC variable
|
||||
|
||||
#define VL_ASSIGN_SII(obits,svar,vvar) { (svar).write(vvar); }
|
||||
#define VL_ASSIGN_SQQ(obits,svar,vvar) { (svar).write(vvar); }
|
||||
@@ -562,6 +605,20 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
|
||||
#define VL_ASSIGN_SUI(obits,svar,rd) { (svar).write(rd); }
|
||||
#define VL_ASSIGN_SUQ(obits,svar,rd) { (svar).write(rd); }
|
||||
#define VL_ASSIGN_SBI(obits,svar,rd) { (svar).write(rd); }
|
||||
#define VL_ASSIGN_SBQ(obits,svar,rd) { (svar).write(rd); }
|
||||
#define VL_ASSIGN_SBW(obits,svar,rwp) { \
|
||||
sc_biguint<obits> _butemp; \
|
||||
for (int i=0; i < VL_WORDS_I(obits); i++) { \
|
||||
int msb = ((i+1)*VL_WORDSIZE) - 1; \
|
||||
msb = (msb >= obits) ? (obits-1) : msb; \
|
||||
_butemp.range(msb,i*VL_WORDSIZE) = rwp[i]; \
|
||||
} \
|
||||
svar.write(_butemp); \
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// Extending sizes
|
||||
|
||||
@@ -813,7 +870,7 @@ static inline WDataOutP VL_OR_W(int words, WDataOutP owp,WDataInP lwp,WDataInP r
|
||||
}
|
||||
// EMIT_RULE: VL_CHANGEXOR: oclean=1; obits=32; lbits==rbits;
|
||||
static inline IData VL_CHANGEXOR_W(int words, WDataInP lwp,WDataInP rwp){
|
||||
IData od;
|
||||
IData od = 0;
|
||||
for (int i=0; (i < words); i++) od |= (lwp[i] ^ rwp[i]);
|
||||
return(od);
|
||||
}
|
||||
@@ -1398,29 +1455,37 @@ static inline WDataOutP VL_SHIFTR_WWI(int obits,int,int,WDataOutP owp,WDataInP l
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean;
|
||||
static inline IData VL_SHIFTRS_III(int obits, int, int, IData lhs, IData rhs) {
|
||||
static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData rhs) {
|
||||
// Note the C standard does not specify the >> operator as a arithmetic shift!
|
||||
IData sign = -(lhs >> (obits-1)); // ffff_ffff if negative
|
||||
IData signext = ~(VL_MASK_I(obits) >> rhs); // One with bits where we've shifted "past"
|
||||
// IEEE says signed if output signed, but bit position from lbits;
|
||||
// must use lbits for sign; lbits might != obits,
|
||||
// an EXTEND(SHIFTRS(...)) can became a SHIFTRS(...) within same 32/64 bit word length
|
||||
IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
|
||||
IData signext = ~(VL_MASK_I(lbits) >> rhs); // One with bits where we've shifted "past"
|
||||
return (lhs >> rhs) | (sign & VL_CLEAN_II(obits,obits,signext));
|
||||
}
|
||||
static inline QData VL_SHIFTRS_QQI(int obits, int, int, QData lhs, IData rhs) {
|
||||
QData sign = -(lhs >> (obits-1));
|
||||
QData signext = ~(VL_MASK_Q(obits) >> rhs);
|
||||
static inline QData VL_SHIFTRS_QQI(int obits, int lbits, int, QData lhs, IData rhs) {
|
||||
QData sign = -(lhs >> (lbits-1));
|
||||
QData signext = ~(VL_MASK_Q(lbits) >> rhs);
|
||||
return (lhs >> rhs) | (sign & VL_CLEAN_QQ(obits,obits,signext));
|
||||
}
|
||||
static inline WDataOutP VL_SHIFTRS_WWI(int obits,int,int,WDataOutP owp,WDataInP lwp, IData rd) {
|
||||
static inline IData VL_SHIFTRS_IQI(int obits, int lbits, int rbits, QData lhs, IData rhs) {
|
||||
return (IData)(VL_SHIFTRS_QQI(obits, lbits, rbits, lhs, rhs));
|
||||
}
|
||||
static inline WDataOutP VL_SHIFTRS_WWI(int obits,int lbits,int,WDataOutP owp,WDataInP lwp, IData rd) {
|
||||
int word_shift = VL_BITWORD_I(rd);
|
||||
int bit_shift = VL_BITBIT_I(rd);
|
||||
int lmsw = VL_WORDS_I(obits)-1;
|
||||
IData sign = VL_SIGNONES_I(obits,lwp[lmsw]);
|
||||
if ((int)rd >= obits) {
|
||||
IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]);
|
||||
if ((int)rd >= obits) { // Shifting past end, sign in all of lbits
|
||||
for (int i=0; i <= lmsw; i++) owp[i] = sign;
|
||||
owp[lmsw] &= VL_MASK_I(lbits);
|
||||
} else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc)
|
||||
int copy_words = (VL_WORDS_I(obits)-word_shift);
|
||||
for (int i=0; i < copy_words; i++) owp[i] = lwp[i+word_shift];
|
||||
if (copy_words>=0) owp[copy_words-1] |= ~VL_MASK_I(obits) & sign;
|
||||
for (int i=copy_words; i < VL_WORDS_I(obits); i++) owp[i] = sign;
|
||||
owp[lmsw] &= VL_MASK_I(lbits);
|
||||
} else {
|
||||
int loffset = rd & VL_SIZEBITS_I;
|
||||
int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0)
|
||||
@@ -1435,6 +1500,7 @@ static inline WDataOutP VL_SHIFTRS_WWI(int obits,int,int,WDataOutP owp,WDataInP
|
||||
}
|
||||
if (words) owp[words-1] |= sign & ~VL_MASK_I(obits-loffset);
|
||||
for (int i=words; i<VL_WORDS_I(obits); i++) owp[i] = sign;
|
||||
owp[lmsw] &= VL_MASK_I(lbits);
|
||||
}
|
||||
return(owp);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
# Copyright 2003-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
######################################################################
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -22,7 +22,7 @@
|
||||
`define _VERILATED_V_ 1
|
||||
|
||||
// Hide verilator pragmas from other tools
|
||||
`ifdef verilator `else
|
||||
`ifdef VERILATOR `else
|
||||
`define coverage_block_off
|
||||
`endif
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Auto version information include for all Verilated C files
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
///**** Product and Version name
|
||||
|
||||
// Autoconf substitutes this with the strings from AC_INIT.
|
||||
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
|
||||
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -104,9 +104,6 @@ int svHigh(const svOpenArrayHandle h, int d) {
|
||||
int svIncrement(const svOpenArrayHandle h, int d) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
}
|
||||
int svLength(const svOpenArrayHandle h, int d) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
}
|
||||
int svDimensions(const svOpenArrayHandle h) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -41,11 +41,15 @@ inline string VL_CVT_PACK_STR_NQ(QData lhs) {
|
||||
IData lw[2]; VL_SET_WQ(lw, lhs);
|
||||
return VL_CVT_PACK_STR_NW(2, lw);
|
||||
}
|
||||
inline string VL_CVT_PACK_STR_NQ(string lhs) {
|
||||
return lhs;
|
||||
}
|
||||
inline string VL_CVT_PACK_STR_NI(IData lhs) {
|
||||
IData lw[1]; lw[0] = lhs;
|
||||
return VL_CVT_PACK_STR_NW(1, lw);
|
||||
}
|
||||
|
||||
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
|
||||
extern string VL_SFORMATF_NX(const char* formatp, ...);
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+32
-4
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -55,7 +55,9 @@ class VerilatedImp {
|
||||
// MEMBERS
|
||||
static VerilatedImp s_s; ///< Static Singleton; One and only static this
|
||||
|
||||
ArgVec m_argVec; ///< Argument list
|
||||
// Nothing here is save-restored; users expected to re-register appropriately
|
||||
|
||||
ArgVec m_argVec; ///< Argument list (NOT save-restored, may want different results)
|
||||
bool m_argVecLoaded; ///< Ever loaded argument list
|
||||
UserMap m_userMap; ///< Map of <(scope,userkey), userData>
|
||||
ScopeNameMap m_nameMap; ///< Map of <scope_name, scope pointer>
|
||||
@@ -76,6 +78,18 @@ public: // But only for verilated*.cpp
|
||||
m_fdps[2] = stderr;
|
||||
}
|
||||
~VerilatedImp() {}
|
||||
static void internalsDump() {
|
||||
VL_PRINTF("internalsDump:\n");
|
||||
VL_PRINTF(" Argv:");
|
||||
for (ArgVec::iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
|
||||
VL_PRINTF(" %s",it->c_str());
|
||||
}
|
||||
VL_PRINTF("\n");
|
||||
VL_PRINTF(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
|
||||
scopesDump();
|
||||
exportsDump();
|
||||
userDump();
|
||||
}
|
||||
|
||||
// METHODS - arguments
|
||||
static void commandArgs(int argc, const char** argv) {
|
||||
@@ -127,6 +141,14 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
static void userDump() {
|
||||
bool first = true;
|
||||
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
|
||||
if (first) { VL_PRINTF(" userDump:\n"); first=false; }
|
||||
VL_PRINTF(" DPI_USER_DATA scope %p key %p: %p\n",
|
||||
it->first.first, it->first.second, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - scope name
|
||||
@@ -148,9 +170,8 @@ public: // But only for verilated*.cpp
|
||||
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
||||
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
|
||||
}
|
||||
|
||||
static void scopesDump() {
|
||||
VL_PRINTF("scopesDump:\n");
|
||||
VL_PRINTF(" scopesDump:\n");
|
||||
for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
|
||||
const VerilatedScope* scopep = it->second;
|
||||
scopep->scopeDump();
|
||||
@@ -192,6 +213,13 @@ public: // But only for verilated*.cpp
|
||||
}
|
||||
return "*UNKNOWN*";
|
||||
}
|
||||
static void exportsDump() {
|
||||
bool first = true;
|
||||
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
|
||||
if (first) { VL_PRINTF(" exportDump:\n"); first=false; }
|
||||
VL_PRINTF(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
|
||||
}
|
||||
}
|
||||
// We don't free up m_exportMap until the end, because we can't be sure
|
||||
// what other models are using the assigned funcnum's.
|
||||
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in VCD Format
|
||||
///
|
||||
/// AUTHOR: Wilson Snyder
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_save.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <cerrno>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_LARGEFILE // For example on WIN32
|
||||
# define O_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
# define O_NONBLOCK 0
|
||||
#endif
|
||||
|
||||
// CONSTANTS
|
||||
static const char* VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file
|
||||
static const char* VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Searalization
|
||||
|
||||
bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) {
|
||||
bufferCheck();
|
||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
||||
vluint8_t miss = 0;
|
||||
while (size--) {
|
||||
miss |= (*dp++ ^ *m_cp++);
|
||||
}
|
||||
return (miss!=0);
|
||||
}
|
||||
|
||||
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) {
|
||||
if (VL_UNLIKELY(readDiffers(datap,size))) {
|
||||
string msg = (string)"Can't deserialize save-restore file as was made from different model";
|
||||
vl_fatal(filename().c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
|
||||
void VerilatedSerialize::header() {
|
||||
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
|
||||
assert((strlen(VLTSAVE_HEADER_STR) & 7) == 0); // Keep aligned
|
||||
os.write(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR));
|
||||
|
||||
// Verilated doesn't do it itself, as if we're not using save/restore
|
||||
// it doesn't need to compile this stuff in
|
||||
os.write(Verilated::serializedPtr(), Verilated::serializedSize());
|
||||
}
|
||||
|
||||
void VerilatedDeserialize::header() {
|
||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
|
||||
string msg = (string)"Can't deserialize; file has wrong header signature";
|
||||
vl_fatal(filename().c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
|
||||
}
|
||||
|
||||
void VerilatedSerialize::trailer() {
|
||||
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
|
||||
assert((strlen(VLTSAVE_TRAILER_STR) & 7) == 0); // Keep aligned
|
||||
os.write(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR));
|
||||
}
|
||||
|
||||
void VerilatedDeserialize::trailer() {
|
||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
|
||||
string msg = (string)"Can't deserialize; file has wrong end-of-file signature";
|
||||
vl_fatal(filename().c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Opening/Closing
|
||||
|
||||
void VerilatedSave::open (const char* filenamep) {
|
||||
if (isOpen()) return;
|
||||
VL_DEBUG_IF(VL_PRINTF("-vltSave: opening save file %s\n",filenamep););
|
||||
|
||||
if (filenamep[0]=='|') {
|
||||
assert(0); // Not supported yet.
|
||||
} else {
|
||||
// cppcheck-suppress duplicateExpression
|
||||
m_fd = ::open (filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
|
||||
, 0666);
|
||||
if (m_fd<0) {
|
||||
// User code can check isOpen()
|
||||
m_isOpen = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_isOpen = true;
|
||||
m_filename = filenamep;
|
||||
m_cp = m_bufp;
|
||||
header();
|
||||
}
|
||||
|
||||
void VerilatedRestore::open (const char* filenamep) {
|
||||
if (isOpen()) return;
|
||||
VL_DEBUG_IF(VL_PRINTF("-vltRestore: opening restore file %s\n",filenamep););
|
||||
|
||||
if (filenamep[0]=='|') {
|
||||
assert(0); // Not supported yet.
|
||||
} else {
|
||||
// cppcheck-suppress duplicateExpression
|
||||
m_fd = ::open (filenamep, O_CREAT|O_RDONLY|O_LARGEFILE
|
||||
, 0666);
|
||||
if (m_fd<0) {
|
||||
// User code can check isOpen()
|
||||
m_isOpen = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_isOpen = true;
|
||||
m_filename = filenamep;
|
||||
m_cp = m_bufp;
|
||||
m_endp = m_bufp;
|
||||
header();
|
||||
}
|
||||
|
||||
void VerilatedSave::close () {
|
||||
if (!isOpen()) return;
|
||||
trailer();
|
||||
flush();
|
||||
m_isOpen = false;
|
||||
::close(m_fd); // May get error, just ignore it
|
||||
}
|
||||
|
||||
void VerilatedRestore::close () {
|
||||
if (!isOpen()) return;
|
||||
trailer();
|
||||
flush();
|
||||
m_isOpen = false;
|
||||
::close(m_fd); // May get error, just ignore it
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Buffer management
|
||||
|
||||
void VerilatedSave::flush() {
|
||||
if (VL_UNLIKELY(!isOpen())) return;
|
||||
vluint8_t* wp = m_bufp;
|
||||
while (1) {
|
||||
ssize_t remaining = (m_cp - wp);
|
||||
if (remaining==0) break;
|
||||
errno = 0;
|
||||
ssize_t got = ::write (m_fd, wp, remaining);
|
||||
if (got>0) {
|
||||
wp += got;
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
string msg = string(__FUNCTION__)+": "+strerror(errno);
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_cp = m_bufp; // Reset buffer
|
||||
}
|
||||
|
||||
void VerilatedRestore::fill() {
|
||||
if (VL_UNLIKELY(!isOpen())) return;
|
||||
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
|
||||
vluint8_t* rp = m_bufp;
|
||||
for (vluint8_t* sp=m_cp; rp < m_endp;) *rp++ = *sp++; // Overlaps
|
||||
m_endp = m_bufp + (m_endp - m_cp);
|
||||
m_cp = m_bufp; // Reset buffer
|
||||
// Read into buffer starting at m_endp
|
||||
while (1) {
|
||||
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
||||
if (remaining==0) break;
|
||||
errno = 0;
|
||||
ssize_t got = ::read (m_fd, m_endp, remaining);
|
||||
if (got>0) {
|
||||
m_endp += got;
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
string msg = string(__FUNCTION__)+": "+strerror(errno);
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
close();
|
||||
break;
|
||||
}
|
||||
} else { // got==0, EOF
|
||||
// Fill buffer from here to end with NULLs so reader's don't need to check eof each character.
|
||||
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Serialization of types
|
||||
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2012-2014 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Save-restore serialization of verilated modules
|
||||
///
|
||||
/// AUTHOR: Wilson Snyder
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _VERILATED_SAVE_C_H_
|
||||
#define _VERILATED_SAVE_C_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSerialBase - internal base class for common code between VerilatedSerialize and VerilatedDeserialize
|
||||
|
||||
class VerilatedSerialBase {
|
||||
protected:
|
||||
// MEMBERS
|
||||
// For speed, keep m_cp as the first member of this structure
|
||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||
vluint8_t* m_bufp; ///< Output buffer
|
||||
bool m_isOpen; ///< True indicates open file/stream
|
||||
string m_filename;
|
||||
|
||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||
|
||||
// CREATORS
|
||||
VerilatedSerialBase() {
|
||||
m_isOpen = false;
|
||||
m_bufp = new vluint8_t [bufferSize()];
|
||||
m_cp = m_bufp;
|
||||
}
|
||||
public:
|
||||
// CREATORS
|
||||
virtual ~VerilatedSerialBase() {
|
||||
close();
|
||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
string filename() const { return m_filename; }
|
||||
virtual void close() { flush(); }
|
||||
virtual void flush() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSerialize - convert structures to a stream representation
|
||||
|
||||
class VerilatedSerialize : public VerilatedSerialBase {
|
||||
protected:
|
||||
virtual void close() { flush(); }
|
||||
virtual void flush() {}
|
||||
void header();
|
||||
void trailer();
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedSerialize() {}
|
||||
virtual ~VerilatedSerialize() { close(); }
|
||||
// METHODS
|
||||
VerilatedSerialize& bufferCheck() {
|
||||
// Flush the write buffer if there's not enough space left for new information
|
||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
|
||||
flush();
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
inline VerilatedSerialize& write (const void* __restrict datap, size_t size) {
|
||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
||||
while (size) {
|
||||
bufferCheck();
|
||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||
const vluint8_t* __restrict maxp = dp + blk;
|
||||
while (dp < maxp) *m_cp++ = *dp++;
|
||||
size -= blk;
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedDeserial - load structures from a stream representation
|
||||
|
||||
class VerilatedDeserialize : public VerilatedSerialBase {
|
||||
protected:
|
||||
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
||||
virtual void fill() = 0;
|
||||
void header();
|
||||
void trailer();
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedDeserialize() { m_endp = NULL; }
|
||||
virtual ~VerilatedDeserialize() { close(); }
|
||||
// METHODS
|
||||
inline VerilatedDeserialize& read (void* __restrict datap, size_t size) {
|
||||
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
||||
while (size) {
|
||||
bufferCheck();
|
||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||
const vluint8_t* __restrict maxp = dp + blk;
|
||||
while (dp < maxp) *dp++ = *m_cp++;
|
||||
size -= blk;
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
// Read a datum and compare with expected value
|
||||
bool readDiffers (const void* __restrict datap, size_t size);
|
||||
VerilatedDeserialize& readAssert (const void* __restrict datap, size_t size);
|
||||
VerilatedDeserialize& readAssert (vluint64_t data) { return readAssert(&data, sizeof(data)); }
|
||||
VerilatedDeserialize& bufferCheck() {
|
||||
// Flush the write buffer if there's not enough space left for new information
|
||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||
if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) {
|
||||
fill();
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSave - serialize to a file
|
||||
|
||||
class VerilatedSave : public VerilatedSerialize {
|
||||
private:
|
||||
int m_fd; ///< File descriptor we're writing to
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedSave() { m_fd=-1; }
|
||||
virtual ~VerilatedSave() { close(); }
|
||||
// METHODS
|
||||
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
|
||||
void open(const string& filename) { open(filename.c_str()); }
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedRestore - deserialize from a file
|
||||
|
||||
class VerilatedRestore : public VerilatedDeserialize {
|
||||
private:
|
||||
int m_fd; ///< File descriptor we're writing to
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedRestore() { m_fd=-1; }
|
||||
virtual ~VerilatedRestore() { close(); }
|
||||
|
||||
// METHODS
|
||||
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
|
||||
void open(const string& filename) { open(filename.c_str()); }
|
||||
virtual void close();
|
||||
virtual void flush() {}
|
||||
virtual void fill();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint64_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint64_t& rhs){
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint32_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint32_t& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint16_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint16_t& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint8_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint8_t& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, bool& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, bool& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, double& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, double& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) {
|
||||
vluint32_t len=rhs.length();
|
||||
os<<len;
|
||||
return os.write(rhs.data(), len);
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, string& rhs) {
|
||||
vluint32_t len;
|
||||
os>>len;
|
||||
rhs.resize(len);
|
||||
return os.read((void*)rhs.data(), len);
|
||||
}
|
||||
|
||||
#endif // guard
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -45,19 +45,20 @@ struct VerilatedCStrCmp {
|
||||
//===========================================================================
|
||||
/// Verilator range
|
||||
|
||||
// See also V3Ast::VNumRange
|
||||
class VerilatedRange {
|
||||
int m_lhs;
|
||||
int m_rhs;
|
||||
int m_left;
|
||||
int m_right;
|
||||
protected:
|
||||
friend class VerilatedVar;
|
||||
friend class VerilatedScope;
|
||||
VerilatedRange() : m_lhs(0), m_rhs(0) {}
|
||||
void sets(int lhs, int rhs) { m_lhs=lhs; m_rhs=rhs; }
|
||||
VerilatedRange() : m_left(0), m_right(0) {}
|
||||
void sets(int left, int right) { m_left=left; m_right=right; }
|
||||
public:
|
||||
~VerilatedRange() {}
|
||||
int lhs() const { return m_lhs; }
|
||||
int rhs() const { return m_rhs; }
|
||||
int bits() const { return (VL_LIKELY(m_lhs>=m_rhs)?(m_lhs-m_rhs+1):(m_rhs-m_lhs+1)); }
|
||||
int left() const { return m_left; }
|
||||
int right() const { return m_right; }
|
||||
int elements() const { return (VL_LIKELY(m_left>=m_right)?(m_left-m_right+1):(m_right-m_left+1)); }
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
@@ -92,7 +93,8 @@ public:
|
||||
//======================================================================
|
||||
/// Types
|
||||
|
||||
struct VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
|
||||
class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
|
||||
public:
|
||||
VerilatedVarNameMap() {}
|
||||
~VerilatedVarNameMap() {}
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2012 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
@@ -141,6 +141,7 @@ void VerilatedVcd::openNext (bool incFilename) {
|
||||
if (m_filename[0]=='|') {
|
||||
assert(0); // Not supported yet.
|
||||
} else {
|
||||
// cppcheck-suppress duplicateExpression
|
||||
m_fd = ::open (m_filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
|
||||
, 0666);
|
||||
if (m_fd<0) {
|
||||
@@ -156,6 +157,8 @@ void VerilatedVcd::openNext (bool incFilename) {
|
||||
|
||||
void VerilatedVcd::makeNameMap() {
|
||||
// Take signal information from each module and build m_namemapp
|
||||
deleteNameMap();
|
||||
m_nextCode = 1;
|
||||
m_namemapp = new NameMap;
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
|
||||
VerilatedVcdCallInfo *cip = m_callbacks[ent];
|
||||
@@ -182,15 +185,20 @@ void VerilatedVcd::makeNameMap() {
|
||||
newname += hiername;
|
||||
newmapp->insert(make_pair(newname,decl));
|
||||
}
|
||||
delete m_namemapp; m_namemapp=NULL;
|
||||
deleteNameMap();
|
||||
m_namemapp = newmapp;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::deleteNameMap() {
|
||||
if (m_namemapp) { delete m_namemapp; m_namemapp=NULL; }
|
||||
}
|
||||
|
||||
VerilatedVcd::~VerilatedVcd() {
|
||||
close();
|
||||
if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; }
|
||||
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
|
||||
deleteNameMap();
|
||||
// Remove from list of traces
|
||||
vector<VerilatedVcd*>::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this);
|
||||
if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); }
|
||||
@@ -413,7 +421,7 @@ void VerilatedVcd::dumpHeader () {
|
||||
assert (m_modDepth==0);
|
||||
|
||||
// Reclaim storage
|
||||
delete m_namemapp;
|
||||
deleteNameMap();
|
||||
}
|
||||
|
||||
void VerilatedVcd::module (string name) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2012 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
@@ -57,7 +57,8 @@ typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluin
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcd
|
||||
/// Create a SystemPerl VCD dump
|
||||
/// Base class to create a Verilator VCD dump
|
||||
/// This is an internally used class - see VerilatedVcdC for what to call from applications
|
||||
|
||||
class VerilatedVcd {
|
||||
private:
|
||||
@@ -100,6 +101,7 @@ private:
|
||||
void closeErr();
|
||||
void openNext();
|
||||
void makeNameMap();
|
||||
void deleteNameMap();
|
||||
void printIndent (int levelchange);
|
||||
void printStr (const char* str);
|
||||
void printQuad (vluint64_t n);
|
||||
@@ -400,8 +402,12 @@ public:
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new VCD file
|
||||
/// This includes a complete header dump each time it is called,
|
||||
/// just as if this object was deleted and reconstructed.
|
||||
void open (const char* filename) { m_sptrace.open(filename); }
|
||||
/// Continue a VCD dump by rotating to a new file name
|
||||
/// The header is only in the first file created, this allows
|
||||
/// "cat" to be used to combine the header plus any number of data files.
|
||||
void openNext (bool incFilename=true) { m_sptrace.openNext(incFilename); }
|
||||
/// Set size in megabytes after which new file should be created
|
||||
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); };
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2012 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2012 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
+332
-1
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -31,3 +31,334 @@ VerilatedVpi VerilatedVpi::s_s; // Singleton
|
||||
vluint8_t* VerilatedVpio::s_freeHead = NULL;
|
||||
|
||||
//======================================================================
|
||||
|
||||
const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) {
|
||||
static const char *names[] = {
|
||||
"*undefined*",
|
||||
"vpiBinStrVal",
|
||||
"vpiOctStrVal",
|
||||
"vpiDecStrVal",
|
||||
"vpiHexStrVal",
|
||||
"vpiScalarVal",
|
||||
"vpiIntVal",
|
||||
"vpiRealVal",
|
||||
"vpiStringVal",
|
||||
"vpiVectorVal",
|
||||
"vpiStrengthVal",
|
||||
"vpiTimeVal",
|
||||
"vpiObjTypeVal",
|
||||
"vpiSuppressVal",
|
||||
"vpiShortIntVal",
|
||||
"vpiLongIntVal",
|
||||
"vpiShortRealVal",
|
||||
"vpiRawTwoStateVal",
|
||||
"vpiRawFourStateVal",
|
||||
};
|
||||
if (vpiVal < 0) return names[0];
|
||||
return names[(vpiVal<=vpiRawFourStateVal)?vpiVal:0];
|
||||
}
|
||||
const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) {
|
||||
static const char *names[] = {
|
||||
"*undefined*",
|
||||
"vpiAlways",
|
||||
"vpiAssignStmt",
|
||||
"vpiAssignment",
|
||||
"vpiBegin",
|
||||
"vpiCase",
|
||||
"vpiCaseItem",
|
||||
"vpiConstant",
|
||||
"vpiContAssign",
|
||||
"vpiDeassign",
|
||||
"vpiDefParam",
|
||||
"vpiDelayControl",
|
||||
"vpiDisable",
|
||||
"vpiEventControl",
|
||||
"vpiEventStmt",
|
||||
"vpiFor",
|
||||
"vpiForce",
|
||||
"vpiForever",
|
||||
"vpiFork",
|
||||
"vpiFuncCall",
|
||||
"vpiFunction",
|
||||
"vpiGate",
|
||||
"vpiIf",
|
||||
"vpiIfElse",
|
||||
"vpiInitial",
|
||||
"vpiIntegerVar",
|
||||
"vpiInterModPath",
|
||||
"vpiIterator",
|
||||
"vpiIODecl",
|
||||
"vpiMemory",
|
||||
"vpiMemoryWord",
|
||||
"vpiModPath",
|
||||
"vpiModule",
|
||||
"vpiNamedBegin",
|
||||
"vpiNamedEvent",
|
||||
"vpiNamedFork",
|
||||
"vpiNet",
|
||||
"vpiNetBit",
|
||||
"vpiNullStmt",
|
||||
"vpiOperation",
|
||||
"vpiParamAssign",
|
||||
"vpiParameter",
|
||||
"vpiPartSelect",
|
||||
"vpiPathTerm",
|
||||
"vpiPort",
|
||||
"vpiPortBit",
|
||||
"vpiPrimTerm",
|
||||
"vpiRealVar",
|
||||
"vpiReg",
|
||||
"vpiRegBit",
|
||||
"vpiRelease",
|
||||
"vpiRepeat",
|
||||
"vpiRepeatControl",
|
||||
"vpiSchedEvent",
|
||||
"vpiSpecParam",
|
||||
"vpiSwitch",
|
||||
"vpiSysFuncCall",
|
||||
"vpiSysTaskCall",
|
||||
"vpiTableEntry",
|
||||
"vpiTask",
|
||||
"vpiTaskCall",
|
||||
"vpiTchk",
|
||||
"vpiTchkTerm",
|
||||
"vpiTimeVar",
|
||||
"vpiTimeQueue",
|
||||
"vpiUdp",
|
||||
"vpiUdpDefn",
|
||||
"vpiUserSystf",
|
||||
"vpiVarSelect",
|
||||
"vpiWait",
|
||||
"vpiWhile",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"vpiAttribute",
|
||||
"vpiBitSelect",
|
||||
"vpiCallback",
|
||||
"vpiDelayTerm",
|
||||
"vpiDelayDevice",
|
||||
"vpiFrame",
|
||||
"vpiGateArray",
|
||||
"vpiModuleArray",
|
||||
"vpiPrimitiveArray",
|
||||
"vpiNetArray",
|
||||
"vpiRange",
|
||||
"vpiRegArray",
|
||||
"vpiSwitchArray",
|
||||
"vpiUdpArray",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"vpiContAssignBit",
|
||||
"vpiNamedEventArray",
|
||||
"vpiIndexedPartSelect",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"vpiGenScopeArray",
|
||||
"vpiGenScope",
|
||||
"vpiGenVar"
|
||||
};
|
||||
if (vpiVal < 0) return names[0];
|
||||
return names[(vpiVal<=vpiGenVar)?vpiVal:0];
|
||||
}
|
||||
const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) {
|
||||
static const char *names[] = {
|
||||
"vpiCondition",
|
||||
"vpiDelay",
|
||||
"vpiElseStmt",
|
||||
"vpiForIncStmt",
|
||||
"vpiForInitStmt",
|
||||
"vpiHighConn",
|
||||
"vpiLhs",
|
||||
"vpiIndex",
|
||||
"vpiLeftRange",
|
||||
"vpiLowConn",
|
||||
"vpiParent",
|
||||
"vpiRhs",
|
||||
"vpiRightRange",
|
||||
"vpiScope",
|
||||
"vpiSysTfCall",
|
||||
"vpiTchkDataTerm",
|
||||
"vpiTchkNotifier",
|
||||
"vpiTchkRefTerm",
|
||||
"vpiArgument",
|
||||
"vpiBit",
|
||||
"vpiDriver",
|
||||
"vpiInternalScope",
|
||||
"vpiLoad",
|
||||
"vpiModDataPathIn",
|
||||
"vpiModPathIn",
|
||||
"vpiModPathOut",
|
||||
"vpiOperand",
|
||||
"vpiPortInst",
|
||||
"vpiProcess",
|
||||
"vpiVariables",
|
||||
"vpiUse",
|
||||
"vpiExpr",
|
||||
"vpiPrimitive",
|
||||
"vpiStmt"
|
||||
};
|
||||
if (vpiVal>vpiStmt || vpiVal<vpiCondition) {
|
||||
return "*undefined*";
|
||||
}
|
||||
return names[vpiVal-vpiCondition];
|
||||
}
|
||||
const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) {
|
||||
static const char *names[] = {
|
||||
"*undefined*",
|
||||
"cbValueChange",
|
||||
"cbStmt",
|
||||
"cbForce",
|
||||
"cbRelease",
|
||||
"cbAtStartOfSimTime",
|
||||
"cbReadWriteSynch",
|
||||
"cbReadOnlySynch",
|
||||
"cbNextSimTime",
|
||||
"cbAfterDelay",
|
||||
"cbEndOfCompile",
|
||||
"cbStartOfSimulation",
|
||||
"cbEndOfSimulation",
|
||||
"cbError",
|
||||
"cbTchkViolation",
|
||||
"cbStartOfSave",
|
||||
"cbEndOfSave",
|
||||
"cbStartOfRestart",
|
||||
"cbEndOfRestart",
|
||||
"cbStartOfReset",
|
||||
"cbEndOfReset",
|
||||
"cbEnterInteractive",
|
||||
"cbExitInteractive",
|
||||
"cbInteractiveScopeChange",
|
||||
"cbUnresolvedSystf",
|
||||
"cbAssign",
|
||||
"cbDeassign",
|
||||
"cbDisable",
|
||||
"cbPLIError",
|
||||
"cbSignal",
|
||||
"cbNBASynch",
|
||||
"cbAtEndOfSimTime"
|
||||
};
|
||||
if (vpiVal < 0) return names[0];
|
||||
return names[(vpiVal<=cbAtEndOfSimTime)?vpiVal:0];
|
||||
}
|
||||
const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) {
|
||||
static const char *names[] = {
|
||||
"*undefined or other*",
|
||||
"vpiType",
|
||||
"vpiName",
|
||||
"vpiFullName",
|
||||
"vpiSize",
|
||||
"vpiFile",
|
||||
"vpiLineNo",
|
||||
"vpiTopModule",
|
||||
"vpiCellInstance",
|
||||
"vpiDefName",
|
||||
"vpiProtected",
|
||||
"vpiTimeUnit",
|
||||
"vpiTimePrecision",
|
||||
"vpiDefNetType",
|
||||
"vpiUnconnDrive",
|
||||
"vpiDefFile",
|
||||
"vpiDefLineNo",
|
||||
"vpiScalar",
|
||||
"vpiVector",
|
||||
"vpiExplicitName",
|
||||
"vpiDirection",
|
||||
"vpiConnByName",
|
||||
"vpiNetType",
|
||||
"vpiExplicitScalared",
|
||||
"vpiExplicitVectored",
|
||||
"vpiExpanded",
|
||||
"vpiImplicitDecl",
|
||||
"vpiChargeStrength",
|
||||
"vpiArray",
|
||||
"vpiPortIndex",
|
||||
"vpiTermIndex",
|
||||
"vpiStrength0",
|
||||
"vpiStrength1",
|
||||
"vpiPrimType",
|
||||
"vpiPolarity",
|
||||
"vpiDataPolarity",
|
||||
"vpiEdge",
|
||||
"vpiPathType",
|
||||
"vpiTchkType",
|
||||
"vpiOpType",
|
||||
"vpiConstType",
|
||||
"vpiBlocking",
|
||||
"vpiCaseType",
|
||||
"vpiFuncType",
|
||||
"vpiNetDeclAssign",
|
||||
"vpiUserDefn",
|
||||
"vpiScheduled",
|
||||
"*undefined*",
|
||||
"*undefined*",
|
||||
"vpiActive",
|
||||
"vpiAutomatic",
|
||||
"vpiCell",
|
||||
"vpiConfig",
|
||||
"vpiConstantSelect",
|
||||
"vpiDecompile",
|
||||
"vpiDefAttribute",
|
||||
"vpiDelayType",
|
||||
"vpiIteratorType",
|
||||
"vpiLibrary",
|
||||
"*undefined*",
|
||||
"vpiOffset",
|
||||
"vpiResolvedNetType",
|
||||
"vpiSaveRestartID",
|
||||
"vpiSaveRestartLocation",
|
||||
"vpiValid",
|
||||
"vpiSigned",
|
||||
"vpiStop",
|
||||
"vpiFinish",
|
||||
"vpiReset",
|
||||
"vpiSetInteractiveScope",
|
||||
"vpiLocalParam",
|
||||
"vpiModPathHasIfNone",
|
||||
"vpiIndexedPartSelectType",
|
||||
"vpiIsMemory",
|
||||
"vpiIsProtected"
|
||||
};
|
||||
if (vpiVal == vpiUndefined) {
|
||||
return "vpiUndefined";
|
||||
}
|
||||
return names[(vpiVal<=vpiIsProtected)?vpiVal:0];
|
||||
}
|
||||
|
||||
+776
-155
File diff suppressed because it is too large
Load Diff
+14
-1
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -78,8 +78,12 @@
|
||||
# else
|
||||
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
|
||||
# endif
|
||||
# define VL_STATIC_OR_THREAD ///< Static if unthreaded, as some strings can be faster
|
||||
// ///< if non-dynamic and can't do "static VL_THREAD string"
|
||||
#else
|
||||
# define VL_THREAD ///< Storage class for thread-local storage
|
||||
# define VL_STATIC_OR_THREAD static ///< Static if unthreaded, as some strings can be faster
|
||||
// ///< if non-dynamic and can't do "static VL_THREAD string"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -185,6 +189,15 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// File system functions
|
||||
|
||||
#ifdef _WIN32
|
||||
# define VL_DEV_NULL "nul"
|
||||
#else // Linux or compliant Unix flavors
|
||||
# define VL_DEV_NULL "/dev/null"
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Integer size macros
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* This file contains the constant definitions, structure definitions,
|
||||
* and routine declarations used by SystemVerilog DPI.
|
||||
*
|
||||
* This file is from the SystemVerilog IEEE 1800-2009 Annex I.
|
||||
* This file is from the SystemVerilog IEEE 1800-2012 Annex I.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SVDPI
|
||||
@@ -35,19 +35,23 @@ typedef signed __int8 int8_t;
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* Use to export a symbol from application */
|
||||
#if defined (_MSC_VER)
|
||||
/* Use to import a symbol into dll */
|
||||
#ifndef DPI_DLLISPEC
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#define DPI_DLLISPEC __declspec(dllimport)
|
||||
#else
|
||||
#define DPI_DLLISPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to import a symbol into application */
|
||||
#if defined (_MSC_VER)
|
||||
/* Use to export a symbol from dll */
|
||||
#ifndef DPI_DLLESPEC
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#define DPI_DLLESPEC __declspec(dllexport)
|
||||
#else
|
||||
#define DPI_DLLESPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to mark a function as external */
|
||||
#ifndef DPI_EXTERN
|
||||
|
||||
+21
-21
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* vpi_user.h
|
||||
*
|
||||
* IEEE Std 1800 Programming Language Interface (PLI)
|
||||
* IEEE Std 1800-2012 Programming Language Interface (PLI)
|
||||
*
|
||||
* This file contains the constant definitions, structure definitions, and
|
||||
* routine declarations used by the SystemVerilog Verification Procedural
|
||||
@@ -61,9 +61,9 @@ typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
/* Use to export a symbol */
|
||||
/* Use to import a symbol */
|
||||
|
||||
#if WIN32
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#ifndef PLI_DLLISPEC
|
||||
#define PLI_DLLISPEC __declspec(dllimport)
|
||||
#define VPI_USER_DEFINED_DLLISPEC 1
|
||||
@@ -74,9 +74,9 @@ typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to import a symbol */
|
||||
/* Use to export a symbol */
|
||||
|
||||
#if WIN32
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#ifndef PLI_DLLESPEC
|
||||
#define PLI_DLLESPEC __declspec(dllexport)
|
||||
#define VPI_USER_DEFINED_DLLESPEC 1
|
||||
@@ -438,12 +438,12 @@ typedef PLI_UINT32 *vpiHandle;
|
||||
#define vpiPlusOp 2 /* unary plus */
|
||||
#define vpiNotOp 3 /* unary not */
|
||||
#define vpiBitNegOp 4 /* bitwise negation */
|
||||
#define vpiUnaryAndOp 5 /* bitwise reduction and */
|
||||
#define vpiUnaryNandOp 6 /* bitwise reduction nand */
|
||||
#define vpiUnaryOrOp 7 /* bitwise reduction or */
|
||||
#define vpiUnaryNorOp 8 /* bitwise reduction nor */
|
||||
#define vpiUnaryXorOp 9 /* bitwise reduction xor */
|
||||
#define vpiUnaryXNorOp 10 /* bitwise reduction xnor */
|
||||
#define vpiUnaryAndOp 5 /* bitwise reduction AND */
|
||||
#define vpiUnaryNandOp 6 /* bitwise reduction NAND */
|
||||
#define vpiUnaryOrOp 7 /* bitwise reduction OR */
|
||||
#define vpiUnaryNorOp 8 /* bitwise reduction NOR */
|
||||
#define vpiUnaryXorOp 9 /* bitwise reduction XOR */
|
||||
#define vpiUnaryXNorOp 10 /* bitwise reduction XNOR */
|
||||
#define vpiSubOp 11 /* binary subtraction */
|
||||
#define vpiDivOp 12 /* binary division */
|
||||
#define vpiModOp 13 /* binary modulus */
|
||||
@@ -459,17 +459,17 @@ typedef PLI_UINT32 *vpiHandle;
|
||||
#define vpiRShiftOp 23 /* binary right shift */
|
||||
#define vpiAddOp 24 /* binary addition */
|
||||
#define vpiMultOp 25 /* binary multiplication */
|
||||
#define vpiLogAndOp 26 /* binary logical and */
|
||||
#define vpiLogOrOp 27 /* binary logical or */
|
||||
#define vpiBitAndOp 28 /* binary bitwise and */
|
||||
#define vpiBitOrOp 29 /* binary bitwise or */
|
||||
#define vpiBitXorOp 30 /* binary bitwise xor */
|
||||
#define vpiBitXNorOp 31 /* binary bitwise xnor */
|
||||
#define vpiLogAndOp 26 /* binary logical AND */
|
||||
#define vpiLogOrOp 27 /* binary logical OR */
|
||||
#define vpiBitAndOp 28 /* binary bitwise AND */
|
||||
#define vpiBitOrOp 29 /* binary bitwise OR */
|
||||
#define vpiBitXorOp 30 /* binary bitwise XOR */
|
||||
#define vpiBitXNorOp 31 /* binary bitwise XNOR */
|
||||
#define vpiBitXnorOp vpiBitXNorOp /* added with 1364-2001 */
|
||||
#define vpiConditionOp 32 /* ternary conditional */
|
||||
#define vpiConcatOp 33 /* n-ary concatenation */
|
||||
#define vpiMultiConcatOp 34 /* repeated concatenation */
|
||||
#define vpiEventOrOp 35 /* event or */
|
||||
#define vpiEventOrOp 35 /* event OR */
|
||||
#define vpiNullOp 36 /* null operation */
|
||||
#define vpiListOp 37 /* list of expressions */
|
||||
#define vpiMinTypMaxOp 38 /* min:typ:max: delay expression */
|
||||
@@ -536,7 +536,7 @@ typedef PLI_UINT32 *vpiHandle;
|
||||
same subtypes as vpiNetType */
|
||||
#define vpiSaveRestartID 62 /* unique ID for save/restart data */
|
||||
#define vpiSaveRestartLocation 63 /* name of save/restart data file */
|
||||
/* vpiValid,vpiValidTrue,vpiValidFalse are deprecated in 1800-2009 */
|
||||
/* vpiValid,vpiValidTrue,vpiValidFalse were deprecated in 1800-2009 */
|
||||
#define vpiValid 64 /* reentrant task/func frame or automatic
|
||||
variable is valid */
|
||||
#define vpiValidFalse 0
|
||||
@@ -661,7 +661,7 @@ typedef struct t_vpi_arrayvalue
|
||||
{
|
||||
PLI_INT32 *integers; /* integer values */
|
||||
PLI_INT16 *shortints; /* short integer values */
|
||||
PLI_INT16 *longints; /* long integer values */
|
||||
PLI_INT64 *longints; /* long integer values */
|
||||
PLI_BYTE8 *rawvals; /* 2/4-state vector elements */
|
||||
struct t_vpi_vecval *vectors; /* 4-state vector elements */
|
||||
struct t_vpi_time *times; /* time values */
|
||||
@@ -944,7 +944,7 @@ XXTERN PLI_INT32 vpi_compare_objects PROTO_PARAMS((vpiHandle object1,
|
||||
vpiHandle object2));
|
||||
XXTERN PLI_INT32 vpi_chk_error PROTO_PARAMS((p_vpi_error_info
|
||||
error_info_p));
|
||||
/* vpi_free_object() is deprecated in 1800-2009 */
|
||||
/* vpi_free_object() was deprecated in 1800-2009 */
|
||||
XXTERN PLI_INT32 vpi_free_object PROTO_PARAMS((vpiHandle object));
|
||||
XXTERN PLI_INT32 vpi_release_handle PROTO_PARAMS((vpiHandle object));
|
||||
XXTERN PLI_INT32 vpi_get_vlog_info PROTO_PARAMS((p_vpi_vlog_info
|
||||
|
||||
+234
-38
@@ -14,32 +14,6 @@ the first for reference for developers and debugging problems.
|
||||
|
||||
See also the Verilator internals presentation at http://www.veripool.org.
|
||||
|
||||
=head1 ADDING A NEW FEATURE
|
||||
|
||||
Generally what would you do to add a new feature?
|
||||
|
||||
=over 4
|
||||
|
||||
File a bug (if there isn't already) so others know what you're working on.
|
||||
|
||||
Make a testcase in the test_regress/t/t_EXAMPLE format, see TESTING Below.
|
||||
|
||||
If grammar changes are needed, look at the git version of VerilogPerl's
|
||||
src/VParseGrammar.y, as this grammar supports the full SystemVerilog
|
||||
language and has a lot of back-and-forth with Verilator's grammar. Copy
|
||||
the appropriate rules to src/verilog.y and modify the productions.
|
||||
|
||||
If a new Ast type is needed, add it to V3AstNodes.h.
|
||||
|
||||
Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll
|
||||
probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree
|
||||
file which you can examine to see if the parsing worked. See also the
|
||||
sections below on debugging.
|
||||
|
||||
Modify the later visitor functions to process the new feature as needed.
|
||||
|
||||
=back
|
||||
|
||||
=head1 CODE FLOWS
|
||||
|
||||
=head2 Verilator Flow
|
||||
@@ -93,6 +67,10 @@ Verilator finally writes the C++ modules.
|
||||
|
||||
=head2 Key Classes Used in the Verilator Flow
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<AstNode>
|
||||
|
||||
The AST is represented at the top level by the class C<AstNode>. This abstract
|
||||
class has derived classes for the individual components (e.g. C<AstGenerate>
|
||||
for a generate block) or groups of components (e.g. C<AstNodeFTask> for
|
||||
@@ -119,11 +97,64 @@ are at the top of the tree.
|
||||
By convention, each function/method uses the variable C<nodep> as a pointer
|
||||
to the C<AstNode> currently being processed.
|
||||
|
||||
=item C<AstNVistor>
|
||||
|
||||
The passes are implemented by AST visitor classes (see L</Visitor
|
||||
Functions>). These are implemented by subclasses of the abstract class,
|
||||
C<AstNVisitor>. Each pass creates an instance of the visitor class, which
|
||||
in turn implements a method to perform the pass.
|
||||
|
||||
=item C<V3Graph>
|
||||
|
||||
A number of passes use graph algorithms, and the class C<V3Graph> is provided
|
||||
to represent those graphs. Graphs are directed, and algorithms are provided to
|
||||
manipulate the graphs and to output them in I<GraphViz> dot format (see
|
||||
L<http://www.graphviz.org/>). C<V3Graph.h> provides documentation of this
|
||||
class.
|
||||
|
||||
=item C<V3GraphVertex>
|
||||
|
||||
This is the base class for vertices in a graph. Vertices have an associated
|
||||
C<fanout>, C<color> and C<rank>, which may be used in algorithms for ordering
|
||||
the graph. A generic C<user>/C<userp> member variable is also provided.
|
||||
|
||||
Virtual methods are provided to specify the name, color, shape and style to be
|
||||
used in dot output. Typically users provided derived classes from
|
||||
C<V3GraphVertex> which will reimplement these methods.
|
||||
|
||||
Iterators are provided to access in and out edges. Typically these are used in
|
||||
the form:
|
||||
|
||||
for (V3GraphEdge *edgep = vertexp->inBeginp();
|
||||
edgep;
|
||||
edgep = edgep->inNextp()) {
|
||||
|
||||
=item C<V3GraphEdge>
|
||||
|
||||
This is the base class for directed edges between pairs of vertices. Edges
|
||||
have an associated C<weight> and may also be made C<cutable>. A generic
|
||||
C<user>/C<userp> member variable is also provided.
|
||||
|
||||
Accessors, C<fromp> and C<top> return the "from" and "to" vertices
|
||||
respectively.
|
||||
|
||||
Virtual methods are provided to specify the label, color and style to be
|
||||
used in dot output. Typically users provided derived classes from
|
||||
C<V3GraphEdge> which will reimplement these methods.
|
||||
|
||||
=item C<V3GraphAlg>
|
||||
|
||||
This is the base class for graph algorithms. It implements a C<bool> method,
|
||||
C<followEdge> which algorithms can use to decide whether an edge is
|
||||
followed. This method returns true if the graph edge has weight greater than
|
||||
one and a user function, C<edgeFuncp> (supplied in the constructor) returns
|
||||
C<true>.
|
||||
|
||||
A number of predefined derived algorithm classes and access methods are
|
||||
provided and documented in C<V3GraphAlg.cpp>.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Verilated Flow
|
||||
|
||||
The evaluation loop outputted by Verilator is designed to allow a single
|
||||
@@ -178,16 +209,15 @@ TREEOP macro.
|
||||
|
||||
The original C++ source code is transformed into C++ code in the C<obj_opt>
|
||||
and C<obj_dbg> sub-directories (the former for the optimized version of
|
||||
verilator, the latter for the debug version). So for example C<V3Const.cpp>
|
||||
Verilator, the latter for the debug version). So for example C<V3Const.cpp>
|
||||
into C<V3Const__gen.cpp>.
|
||||
|
||||
=head2 Visitor Functions
|
||||
|
||||
The verilator uses the I<Visitor> design pattern to implement its
|
||||
refinement and optimization passes. This allows separation of the pass
|
||||
algorithm from the AST on which it operates. Wikipedia provides an
|
||||
introduction to the concept at
|
||||
L<http://en.wikipedia.org/wiki/Visitor_pattern>.
|
||||
Verilator uses the I<Visitor> design pattern to implement its refinement
|
||||
and optimization passes. This allows separation of the pass algorithm from
|
||||
the AST on which it operates. Wikipedia provides an introduction to the
|
||||
concept at L<http://en.wikipedia.org/wiki/Visitor_pattern>.
|
||||
|
||||
As noted above, all visitors are derived classes of C<AstNvisitor>. All
|
||||
derived classes of C<AstNode> implement the C<accept> method, which takes
|
||||
@@ -336,10 +366,129 @@ AST.
|
||||
|
||||
=head1 TESTING
|
||||
|
||||
To write a test see the BUGS section of the Verilator primary manual, and
|
||||
the documentation in:
|
||||
For an overview of how to write a test see the BUGS section of the
|
||||
Verilator primary manual.
|
||||
|
||||
test_regress/t/driver.pl --help
|
||||
It is important to add tests for failures as well as success (for example to
|
||||
check that an error message is correctly triggered).
|
||||
|
||||
Tests that fail should by convenition have the suffix C<_bad> in their name,
|
||||
and include C<fails =E<gt> 1> in either their C<compile> or C<execute> step as
|
||||
appropriate.
|
||||
|
||||
=head2 Controlling the Test Driver
|
||||
|
||||
Test drivers are written in PERL. All invoke the main test driver script,
|
||||
which can provide detailed help on all the features available when writing
|
||||
a test driver.
|
||||
|
||||
test_regress/t/driver.pl --help
|
||||
|
||||
For convenience, a summary of the most commonly used features is provided
|
||||
here. All drivers require a call to C<compile> subroutine to compile the
|
||||
test. For run-time tests, this is followed by a call to the C<execute>
|
||||
subroutine. Both of these functions can optionally be provided with a hash
|
||||
table as argument specifying additonal options.
|
||||
|
||||
The test driver assumes by default that the source Verilog file name
|
||||
matches the PERL driver name. So a test whose driver is C<t/t_mytest.pl>
|
||||
will expect a Verilog source file C<t/t_mytest.v>. This can be changed
|
||||
using the C<top_filename> subroutine, for example
|
||||
|
||||
top_filename("t/t_myothertest.v");
|
||||
|
||||
By default all tests will run with major simulators (Icarus Verilog, NC,
|
||||
VCS, ModelSim) as well as Verilator, to allow results to be
|
||||
compared. However if you wish a test only to be used with Verilator, you
|
||||
can use the following:
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
Of the many options that can be set through arguments to C<compiler> and
|
||||
C<execute>, the following are particularly useful:
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<verilator_flags2>
|
||||
|
||||
A list of flags to be passed to verilator when compiling.
|
||||
|
||||
=item C<fails>
|
||||
|
||||
Set to 1 to indicate that the compilation or execution is intended to fail.
|
||||
|
||||
=back
|
||||
|
||||
For example the following would specify that compilation requires two
|
||||
defines and is expected to fail.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"],
|
||||
fails => 1,
|
||||
);
|
||||
|
||||
=head2 Regression Testing for Developers
|
||||
|
||||
Developers will also want to call ./configure with two extra flags:
|
||||
|
||||
=over 4
|
||||
|
||||
=item --enable-ccwarn
|
||||
|
||||
Causes the build to stop on warnings as well as errors. A good way to
|
||||
ensure no sloppy code gets added, however it can be painful when it comes
|
||||
to testing, since third party code used in the tests (e.g. SystemC) may not
|
||||
be warning free.
|
||||
|
||||
=item --enable-longtests
|
||||
|
||||
In addition to the standard C, SystemC and SystemPerl tests also run the
|
||||
tests in the C<test_vcs>, C<test_verilated> and C<test_regress> directories
|
||||
when using I<make test>. This is disabled by default as SystemC/SystemPerl
|
||||
installation problems would otherwise falsely indicate a Verilator problem.
|
||||
|
||||
=back
|
||||
|
||||
When enabling the long tests, some additional PERL modules are needed, which
|
||||
you can install using cpan.
|
||||
|
||||
cpan install Unix::Processors
|
||||
|
||||
There are some traps to avoid when running regression tests
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The regression tests will assume that you have a version of SystemPerl to
|
||||
match. Typically if working on Verilator from git, also use SystemPerl from
|
||||
git.
|
||||
|
||||
=item *
|
||||
|
||||
When checking the MANIFEST, the test will barf on unexpected code in the
|
||||
Verilator tree. So make sure to keep any such code outside the tree.
|
||||
|
||||
=item *
|
||||
|
||||
Not all Linux systems install Perldoc by default. This is needed for the
|
||||
I<--help> option to Verilator, and also for regression testing. This can be
|
||||
installed using cpan:
|
||||
|
||||
cpan install Pod::Perldoc
|
||||
|
||||
Many Linux systems also offer a standard package for this. Red
|
||||
Hat/Fedora/Centos offer I<perl-Pod-Perldoc>, while Debian/Ubuntu/Linux Mint
|
||||
offer I<perl-doc>.
|
||||
|
||||
=item *
|
||||
|
||||
Running regression may exhaust resources on some Linux systems, particularly
|
||||
file handles and user processes. Increase these to respectively 16,384 and
|
||||
4,096. The method of doing this is system dependent, but on Fedora Linux it
|
||||
would require editing the C</etc/security/limits.conf> file as root.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DEBUGGING
|
||||
|
||||
@@ -376,6 +525,9 @@ algorithmic stage. An example:
|
||||
|
||||
=over 4
|
||||
|
||||
The following summarizes the above example dump, with more detail on each
|
||||
field in the section below.
|
||||
|
||||
"1:2:" indicates the hierarchy of the C<VAR> is the C<op2p> pointer under
|
||||
the C<MODULE>, which in turn is the C<op1p> pointer under the C<NETLIST>
|
||||
|
||||
@@ -439,7 +591,7 @@ Of the form C<< <ennnn> >> or C<< <ennnn#> >> , where C<nnnn> is the number
|
||||
of the last edit to modify this node. The trailing C<#> indicates the node
|
||||
has been edited since the last tree dump (which typically means in the last
|
||||
refinement or optimization pass). GDB can watch for this, see L</Debugging
|
||||
with GDB> below.
|
||||
with GDB>.
|
||||
|
||||
=item Source file and line
|
||||
|
||||
@@ -498,7 +650,7 @@ under gdb and break when an error is hit or the program is about to exit.
|
||||
You can also use --debug --gdbbt to just backtrace and then exit gdb. To
|
||||
debug the Verilated executable, use --gdbsim.
|
||||
|
||||
If you wish to start verilator under GDB (or another debugger), then you
|
||||
If you wish to start Verilator under GDB (or another debugger), then you
|
||||
can use --debug and look at the underlying invocation of verilator_dgb. For
|
||||
example
|
||||
|
||||
@@ -548,11 +700,55 @@ backtrace. You will typically see a frame sequence something like
|
||||
visit()
|
||||
...
|
||||
|
||||
=head1 ADDING A NEW FEATURE
|
||||
|
||||
Generally what would you do to add a new feature?
|
||||
|
||||
=over 4
|
||||
|
||||
=item 1.
|
||||
|
||||
File a bug (if there isn't already) so others know what you're working on.
|
||||
|
||||
=item 2.
|
||||
|
||||
Make a testcase in the test_regress/t/t_EXAMPLE format, see L<TESTING>.
|
||||
|
||||
=item 3.
|
||||
|
||||
If grammar changes are needed, look at the git version of VerilogPerl's
|
||||
src/VParseGrammar.y, as this grammar supports the full SystemVerilog
|
||||
language and has a lot of back-and-forth with Verilator's grammar. Copy
|
||||
the appropriate rules to src/verilog.y and modify the productions.
|
||||
|
||||
=item 4.
|
||||
|
||||
If a new Ast type is needed, add it to V3AstNodes.h.
|
||||
|
||||
=back
|
||||
|
||||
Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll
|
||||
probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree
|
||||
file which you can examine to see if the parsing worked. See also the
|
||||
sections above on debugging.
|
||||
|
||||
Modify the later visitor functions to process the new feature as needed.
|
||||
|
||||
=head2 Adding a new pass
|
||||
|
||||
For more substantial changes you may need to add a new pass. The simplest way
|
||||
to do this is to copy the C<.cpp> and C<.h> files from an existing
|
||||
pass. You'll need to add a call into your pass from the C<process()> function
|
||||
in C<src/verilator.cpp>.
|
||||
|
||||
To get your pass to build you'll need to add its binary filename to the list
|
||||
in C<src/Makefile_obj.in> and reconfigure.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2008-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2008-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2012 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2014 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 Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2012 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2014 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 Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2012 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2014 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 Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ Runs a specific test stage (see the script).
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2009-2012 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2009-2014 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 Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ invoke_atsim - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2014 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 Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ invoke_iccr - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2007-2012 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2007-2014 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 Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
@@ -28,7 +28,7 @@ invoke_ncverilog - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2014 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 Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2014 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 Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2010-2012 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2010-2014 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 Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
@@ -331,7 +331,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2012 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2014 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+20
-24
@@ -9,7 +9,7 @@ This is the Verilator Package README file.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
This package is Copyright 2003-2012 by Wilson Snyder. (Report bugs to
|
||||
This package is Copyright 2003-2014 by Wilson Snyder. (Report bugs to
|
||||
L<http://www.veripool.org/>.)
|
||||
|
||||
Verilator is free software; you can redistribute it and/or modify it under
|
||||
@@ -24,14 +24,14 @@ more details.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Verilator converts synthesizable (not behavioral) Verilog code into C++ or
|
||||
SystemC code. It is not a complete simulator, just a translator.
|
||||
Verilator converts synthesizable (generally not behavioral) Verilog code
|
||||
into C++ or SystemC code. It is not a complete simulator, just a
|
||||
translator.
|
||||
|
||||
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
|
||||
reads the specified Verilog code, lints it, and optionally adds coverage
|
||||
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
|
||||
it outputs .sp files for the SystemPerl preprocessor available at
|
||||
http://www.veripool.org.
|
||||
it outputs .cpp and .h files using the standard SystemC headers.
|
||||
|
||||
The resulting files are then compiled with C++. The user writes a little
|
||||
C++ wrapper file, which instantiates the top level module. This is
|
||||
@@ -41,14 +41,11 @@ The resulting executable will perform the actual simulation.
|
||||
|
||||
=head1 SUPPORTED SYSTEMS
|
||||
|
||||
Verilator is developed and has primary testing on:
|
||||
|
||||
SuSE 11.1 AMD64 i686-linux-2.6.27, GCC 4.3.2
|
||||
|
||||
Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It
|
||||
should run with minor porting on any Linix-ish platform. Verilator also
|
||||
works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin).
|
||||
Verilated output (not Verilator itself) compiles under MSVC++ 2008.
|
||||
Verilator is developed and has primary testing on Ubuntu. Versions have
|
||||
also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run
|
||||
with minor porting on any Linix-ish platform. Verilator also works on
|
||||
Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated
|
||||
output (not Verilator itself) compiles under MSVC++ 2008 and newer.
|
||||
|
||||
=head1 INSTALLATION
|
||||
|
||||
@@ -71,11 +68,11 @@ Download the latest package from that site, and decompress.
|
||||
=item
|
||||
|
||||
If you will be using SystemC (vs straight C++ output), download SystemC
|
||||
2.0.1 from L<http://www.systemc.org>. Follow their installation
|
||||
instructions. You will need to set SYSTEMC_INCLUDE to point to the
|
||||
include directory with systemc.h in it, and SYSTEMC_LIBDIR to points
|
||||
to the directory with libsystemc.a in it. (Older installations may
|
||||
set SYSTEMC and SYSTEMC_ARCH instead.)
|
||||
from L<http://www.systemc.org>. Follow their installation instructions.
|
||||
You will need to set SYSTEMC_INCLUDE to point to the include directory with
|
||||
systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with
|
||||
libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH
|
||||
instead.)
|
||||
|
||||
=item
|
||||
|
||||
@@ -107,7 +104,7 @@ executable, so try to have them correct before configuring.
|
||||
|
||||
Our personal favorite is to always run Verilator from the kit directory.
|
||||
This allows the easiest experimentation and upgrading. It's also how most
|
||||
EDA tools operate; to run any of them you point to the tarball.
|
||||
EDA tools operate; to run you point to the tarball, no install is needed.
|
||||
|
||||
export VERILATOR_ROOT=`pwd` # if your shell is bash
|
||||
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
||||
@@ -156,11 +153,10 @@ PATH.
|
||||
|
||||
Type C<make> to compile Verilator.
|
||||
|
||||
Type C<make test_c> to check the compilation.
|
||||
Type C<make test> to check the compilation.
|
||||
|
||||
Type C<make test> for a more complete test. You may get a error about the
|
||||
Bit::Vector Perl package. You will need to install it and SystemPerl if
|
||||
you want all tests to pass.
|
||||
Configure with C<--enable-longtests> for more complete developer tests.
|
||||
Additional packages may be required for these tests.
|
||||
|
||||
You may get a error about a typedef conflict for uint32_t. Edit
|
||||
verilated.h to change the typedef to work, probably to @samp{typedef
|
||||
@@ -195,7 +191,7 @@ The directories in the kit after de-taring are as follows:
|
||||
bin/verilator => Compiler Wrapper invoked to Verilate code
|
||||
include/ => Files that should be in your -I compiler path
|
||||
include/verilated*.cpp => Global routines to link into your simulator
|
||||
include/verilated.h => Global headers
|
||||
include/verilated*.h => Global headers
|
||||
include/verilated.v => Stub defines for linting
|
||||
include/verilated.mk => Common makefile
|
||||
src/ => Translator source code
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# DESCRIPTION: Verilator: GDB startup file with useful defines
|
||||
#
|
||||
# Copyright 2012-2012 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2012-2014 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+2
-1
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -219,6 +219,7 @@ RAW_OBJS = \
|
||||
V3SplitAs.o \
|
||||
V3Stats.o \
|
||||
V3StatsReport.o \
|
||||
V3String.o \
|
||||
V3Subst.o \
|
||||
V3Table.o \
|
||||
V3Task.o \
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -291,7 +291,7 @@ private:
|
||||
}
|
||||
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
|
||||
if (!m_scopeFinalp) {
|
||||
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
|
||||
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final_"+m_namer.scopep()->nameDotless(), m_namer.scopep());
|
||||
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
|
||||
m_scopeFinalp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign()+"\n"));
|
||||
m_scopeFinalp->dontCombine(true);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+3
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -62,6 +62,7 @@ private:
|
||||
nodep->displayType(AstDisplayType::DT_WRITE);
|
||||
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
|
||||
AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
|
||||
// cppcheck-suppress nullPointer
|
||||
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
||||
nodep->fmtp()->exprsp(timesp);
|
||||
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
|
||||
@@ -136,6 +137,7 @@ private:
|
||||
if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
//
|
||||
AstNode* newp = new AstAlways (nodep->fileline(),
|
||||
VAlwaysKwd::ALWAYS,
|
||||
sentreep,
|
||||
bodysp);
|
||||
// Install it
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+18
-6
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -764,6 +764,7 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
while (nodep) {
|
||||
AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited
|
||||
ASTNODE_PREFETCH(nodep->m_nextp);
|
||||
// cppcheck-suppress nullPointer
|
||||
niterp->m_iterpp = &niterp;
|
||||
niterp->accept(v, vup);
|
||||
// accept may do a replaceNode and change niterp on us...
|
||||
@@ -964,6 +965,14 @@ void AstNode::dumpTreeFileGdb(const char* filenamep) { // For GDB only
|
||||
v3Global.rootp()->dumpTreeFile(filename);
|
||||
}
|
||||
|
||||
void AstNode::checkIter() const {
|
||||
if (m_iterpp) {
|
||||
dumpPtrs(cout);
|
||||
// Perhaps something forgot to clear m_iterpp?
|
||||
this->v3fatalSrc("Iteration link should be NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void AstNode::dumpPtrs(ostream& os) const {
|
||||
os<<"This="<<typeName()<<" "<<(void*)this;
|
||||
os<<" back="<<(void*)backp();
|
||||
@@ -1007,8 +1016,8 @@ void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) {
|
||||
}
|
||||
}
|
||||
|
||||
void AstNode::dumpTreeFile(const string& filename, bool append) {
|
||||
if (v3Global.opt.dumpTree()) {
|
||||
void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
|
||||
if (v3Global.opt.dumpTree() && doDump) {
|
||||
{ // Write log & close
|
||||
UINFO(2,"Dumping "<<filename<<endl);
|
||||
const auto_ptr<ofstream> logsp (V3File::new_ofstream(filename, append));
|
||||
@@ -1041,7 +1050,7 @@ void AstNode::v3errorEnd(ostringstream& str) const {
|
||||
nsstr<<str.str();
|
||||
if (debug()) {
|
||||
nsstr<<endl;
|
||||
nsstr<<"-node: "<<this<<endl;
|
||||
nsstr<<"-node: "; ((AstNode*)this)->dump(nsstr); nsstr<<endl;
|
||||
}
|
||||
m_fileline->v3errorEnd(nsstr);
|
||||
} else {
|
||||
@@ -1067,8 +1076,7 @@ void AstNode::dtypeChgWidth(int width, int widthMin) {
|
||||
dtypeChgWidthSigned(width, widthMin, dtypep()->numeric());
|
||||
}
|
||||
|
||||
void AstNode::dtypeChgWidthSigned(int width, int widthMin, bool issigned) {
|
||||
AstNumeric numeric = issigned ? AstNumeric::SIGNED : AstNumeric::UNSIGNED;
|
||||
void AstNode::dtypeChgWidthSigned(int width, int widthMin, AstNumeric numeric) {
|
||||
if (!dtypep()) {
|
||||
// We allow dtypep() to be null, as before/during widthing dtypes are not resolved
|
||||
dtypeSetLogicSized(width, widthMin, numeric);
|
||||
@@ -1099,6 +1107,10 @@ AstNodeDType* AstNode::findLogicDType(int width, int widthMin, AstNumeric numeri
|
||||
return v3Global.rootp()->typeTablep()
|
||||
->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, width, widthMin, numeric);
|
||||
}
|
||||
AstNodeDType* AstNode::findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const {
|
||||
return v3Global.rootp()->typeTablep()
|
||||
->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, range, widthMin, numeric);
|
||||
}
|
||||
AstBasicDType* AstNode::findInsertSameDType(AstBasicDType* nodep) {
|
||||
return v3Global.rootp()->typeTablep()
|
||||
->findInsertSameDType(nodep);
|
||||
|
||||
+164
-46
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -38,6 +38,9 @@ class VFlagLogicPacked {};
|
||||
class VFlagBitPacked {};
|
||||
class VFlagChildDType {}; // Used by parser.y to select constructor that sets childDType
|
||||
|
||||
// For broken() function, return error string if have a match
|
||||
#define BROKEN_RTN(test) do { if (VL_UNLIKELY(test)) return # test; } while(0)
|
||||
|
||||
//######################################################################
|
||||
|
||||
class AstType {
|
||||
@@ -47,6 +50,7 @@ public:
|
||||
// enum en {...};
|
||||
// const char* ascii() const {...};
|
||||
enum en m_e;
|
||||
// cppcheck-suppress uninitVar // responsiblity of each subclass
|
||||
inline AstType () {}
|
||||
inline AstType (en _e) : m_e(_e) {}
|
||||
explicit inline AstType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
@@ -219,7 +223,16 @@ class AstAttrType {
|
||||
public:
|
||||
enum en {
|
||||
ILLEGAL,
|
||||
EXPR_BITS, // V3Const converts to constant
|
||||
//
|
||||
DIM_BITS, // V3Const converts to constant
|
||||
DIM_DIMENSIONS, // V3Width converts to constant
|
||||
DIM_HIGH, // V3Width processes
|
||||
DIM_INCREMENT, // V3Width processes
|
||||
DIM_LEFT, // V3Width processes
|
||||
DIM_LOW, // V3Width processes
|
||||
DIM_RIGHT, // V3Width processes
|
||||
DIM_SIZE, // V3Width processes
|
||||
DIM_UNPK_DIMENSIONS, // V3Width converts to constant
|
||||
//
|
||||
MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
||||
//
|
||||
@@ -237,7 +250,10 @@ public:
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
"%E-AT", "EXPR_BITS", "MEMBER_BASE",
|
||||
"%E-AT",
|
||||
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
|
||||
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
|
||||
"MEMBER_BASE",
|
||||
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
||||
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
||||
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT"
|
||||
@@ -356,6 +372,9 @@ public:
|
||||
bool isDpiUnsupported() const {
|
||||
return (m_e==LOGIC || m_e==TIME);
|
||||
}
|
||||
bool isDpiUnsignable() const { // Can add "unsigned" to DPI
|
||||
return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER);
|
||||
}
|
||||
bool isOpaque() const { // IE not a simple number we can bit optimize
|
||||
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==DOUBLE || m_e==FLOAT);
|
||||
}
|
||||
@@ -391,7 +410,8 @@ public:
|
||||
BLOCKTEMP,
|
||||
MODULETEMP,
|
||||
STMTTEMP,
|
||||
XTEMP
|
||||
XTEMP,
|
||||
IFACEREF // Used to link Interfaces between modules
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstVarType () : m_e(UNKNOWN) {}
|
||||
@@ -405,7 +425,8 @@ public:
|
||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE",
|
||||
"TRIWIRE","TRI0","TRI1",
|
||||
"PORT",
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP",
|
||||
"IFACEREF"};
|
||||
return names[m_e]; }
|
||||
bool isSignal() const { return (m_e==WIRE || m_e==IMPLICITWIRE
|
||||
|| m_e==TRIWIRE
|
||||
@@ -451,22 +472,47 @@ public:
|
||||
|
||||
//######################################################################
|
||||
|
||||
class AstCaseType {
|
||||
class VAlwaysKwd {
|
||||
public:
|
||||
enum en {
|
||||
ALWAYS,
|
||||
ALWAYS_FF,
|
||||
ALWAYS_LATCH,
|
||||
ALWAYS_COMB
|
||||
};
|
||||
enum en m_e;
|
||||
inline VAlwaysKwd () : m_e(ALWAYS) {}
|
||||
inline VAlwaysKwd (en _e) : m_e(_e) {}
|
||||
explicit inline VAlwaysKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
"always","always_ff","always_latch","always_comb"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
inline bool operator== (VAlwaysKwd lhs, VAlwaysKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (VAlwaysKwd lhs, VAlwaysKwd::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (VAlwaysKwd::en lhs, VAlwaysKwd rhs) { return (lhs == rhs.m_e); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
class VCaseType {
|
||||
public:
|
||||
enum en {
|
||||
CT_CASE,
|
||||
CT_CASEX,
|
||||
CT_CASEZ
|
||||
CT_CASEZ,
|
||||
CT_CASEINSIDE
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstCaseType () : m_e(CT_CASE) {}
|
||||
inline AstCaseType (en _e) : m_e(_e) {}
|
||||
explicit inline AstCaseType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
inline VCaseType () : m_e(CT_CASE) {}
|
||||
inline VCaseType (en _e) : m_e(_e) {}
|
||||
explicit inline VCaseType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
};
|
||||
inline bool operator== (AstCaseType lhs, AstCaseType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstCaseType lhs, AstCaseType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstCaseType::en lhs, AstCaseType rhs) { return (lhs == rhs.m_e); }
|
||||
inline bool operator== (VCaseType lhs, VCaseType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (VCaseType lhs, VCaseType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (VCaseType::en lhs, VCaseType rhs) { return (lhs == rhs.m_e); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -502,11 +548,7 @@ class AstParseRefExp {
|
||||
public:
|
||||
enum en {
|
||||
PX_NONE, // Used in V3LinkParse only
|
||||
PX_TEXT, // Unknown ID component
|
||||
PX_PREDOT, // Module name or misc component above var/task/func/member
|
||||
PX_VAR_MEM, // Variable that must be a memory
|
||||
PX_VAR_ANY, // Variable/structure member
|
||||
PX_FTASK // Task/Function (AstParse::ftaskrefp() will be set)
|
||||
PX_TEXT // Unknown ID component
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstParseRefExp() : m_e(PX_NONE) {}
|
||||
@@ -515,7 +557,7 @@ public:
|
||||
operator en () const { return m_e; }
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
"","TEXT","PREDOT","VAR_MEM","VAR_ANY","FTASK"};
|
||||
"","TEXT","PREDOT"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
@@ -528,8 +570,8 @@ public:
|
||||
// See also AstRange, which is a symbolic version of this
|
||||
|
||||
struct VNumRange {
|
||||
int m_msb; // MSB, MSB always >= LSB
|
||||
int m_lsb; // LSB
|
||||
int m_hi; // HI part, HI always >= LO
|
||||
int m_lo; // LO
|
||||
union {
|
||||
int mu_flags;
|
||||
struct {
|
||||
@@ -538,33 +580,38 @@ struct VNumRange {
|
||||
};
|
||||
};
|
||||
inline bool operator== (const VNumRange& rhs) const {
|
||||
return m_msb == rhs.m_msb
|
||||
&& m_lsb == rhs.m_lsb
|
||||
return m_hi == rhs.m_hi
|
||||
&& m_lo == rhs.m_lo
|
||||
&& mu_flags == rhs.mu_flags; }
|
||||
inline bool operator< (const VNumRange& rhs) const {
|
||||
if ( (m_msb < rhs.m_msb)) return true;
|
||||
if (!(m_msb == rhs.m_msb)) return false; // lhs > rhs
|
||||
if ( (m_lsb < rhs.m_lsb)) return true;
|
||||
if (!(m_lsb == rhs.m_lsb)) return false; // lhs > rhs
|
||||
if ( (m_hi < rhs.m_hi)) return true;
|
||||
if (!(m_hi == rhs.m_hi)) return false; // lhs > rhs
|
||||
if ( (m_lo < rhs.m_lo)) return true;
|
||||
if (!(m_lo == rhs.m_lo)) return false; // lhs > rhs
|
||||
if ( (mu_flags < rhs.mu_flags)) return true;
|
||||
if (!(mu_flags == rhs.mu_flags)) return false; // lhs > rhs
|
||||
return false;
|
||||
}
|
||||
//
|
||||
VNumRange() : m_msb(0), m_lsb(0), mu_flags(0) {}
|
||||
VNumRange() : m_hi(0), m_lo(0), mu_flags(0) {}
|
||||
VNumRange(int hi, int lo, bool littleEndian)
|
||||
: m_hi(0), m_lo(0), mu_flags(0)
|
||||
{ init(hi,lo,littleEndian); }
|
||||
~VNumRange() {}
|
||||
// MEMBERS
|
||||
void init(int msb, int lsb, bool littleEndian) {
|
||||
m_msb=msb; m_lsb=lsb; mu_flags=0; m_ranged=true; m_littleEndian=littleEndian;
|
||||
void init(int hi, int lo, bool littleEndian) {
|
||||
m_hi=hi; m_lo=lo; mu_flags=0; m_ranged=true; m_littleEndian=littleEndian;
|
||||
}
|
||||
int msb() const { return m_msb; }
|
||||
int lsb() const { return m_lsb; }
|
||||
int left() const { return littleEndian()?lsb():msb(); } // How to show a declaration
|
||||
int right() const { return littleEndian()?msb():lsb(); }
|
||||
int hi() const { return m_hi; }
|
||||
int lo() const { return m_lo; }
|
||||
int left() const { return littleEndian()?lo():hi(); } // How to show a declaration
|
||||
int right() const { return littleEndian()?hi():lo(); }
|
||||
int elements() const { return hi()-lo()+1; }
|
||||
bool ranged() const { return m_ranged; }
|
||||
bool littleEndian() const { return m_littleEndian; }
|
||||
int hiMaxSelect() const { return (lo()<0 ? hi()-lo() : hi()); } // Maximum value a [] select may index
|
||||
bool representableByWidth() const // Could be represented by just width=1, or [width-1:0]
|
||||
{ return (!m_ranged || (m_lsb==0 && m_msb>=1 && !m_littleEndian)); }
|
||||
{ return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -766,7 +813,7 @@ protected:
|
||||
RelinkWhatEn m_chg;
|
||||
AstNode** m_iterpp;
|
||||
public:
|
||||
AstNRelinker() { m_backp=NULL; m_chg=RELINK_BAD; m_iterpp=NULL;}
|
||||
AstNRelinker() { m_oldp=NULL; m_backp=NULL; m_chg=RELINK_BAD; m_iterpp=NULL;}
|
||||
void relink(AstNode* newp);
|
||||
AstNode* oldp() const { return m_oldp; }
|
||||
void dump(ostream& str=cout) const;
|
||||
@@ -1058,7 +1105,7 @@ public:
|
||||
void dtypeFrom(AstNode* fromp) { if (fromp) { dtypep(fromp->dtypep()); }}
|
||||
void dtypeChgSigned(bool flag=true);
|
||||
void dtypeChgWidth(int width, int widthMin);
|
||||
void dtypeChgWidthSigned(int width, int widthMin, bool issigned);
|
||||
void dtypeChgWidthSigned(int width, int widthMin, AstNumeric numeric);
|
||||
void dtypeSetBitSized(int width, int widthMin, AstNumeric numeric) { dtypep(findBitDType(width,widthMin,numeric)); }
|
||||
void dtypeSetLogicSized(int width, int widthMin, AstNumeric numeric) { dtypep(findLogicDType(width,widthMin,numeric)); }
|
||||
void dtypeSetLogicBool() { dtypep(findLogicBoolDType()); }
|
||||
@@ -1075,6 +1122,7 @@ public:
|
||||
AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); } // Twostate
|
||||
AstNodeDType* findBitDType(int width, int widthMin, AstNumeric numeric) const;
|
||||
AstNodeDType* findLogicDType(int width, int widthMin, AstNumeric numeric) const;
|
||||
AstNodeDType* findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const;
|
||||
AstNodeDType* findBasicDType(AstBasicDTypeKwd kwd) const;
|
||||
AstBasicDType* findInsertSameDType(AstBasicDType* nodep);
|
||||
|
||||
@@ -1106,18 +1154,21 @@ public:
|
||||
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
|
||||
void deleteTree(); // Always deletes the next link
|
||||
void checkTree(); // User Interface version
|
||||
void checkIter() const;
|
||||
void clearIter() { m_iterpp=NULL; }
|
||||
void dumpPtrs(ostream& str=cout) const;
|
||||
void dumpTree(ostream& str=cout, const string& indent=" ", int maxDepth=0);
|
||||
void dumpTree(const string& indent, int maxDepth=0) { dumpTree(cout,indent,maxDepth); }
|
||||
void dumpTreeGdb(); // For GDB only
|
||||
void dumpTreeAndNext(ostream& str=cout, const string& indent=" ", int maxDepth=0);
|
||||
void dumpTreeFile(const string& filename, bool append=false);
|
||||
void dumpTreeFile(const string& filename, bool append=false, bool doDump=true);
|
||||
static void dumpTreeFileGdb(const char* filenamep=NULL);
|
||||
|
||||
// METHODS - queries
|
||||
virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays
|
||||
virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations
|
||||
virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out
|
||||
virtual bool isGateDedupable() const { return isGateOptimizable(); } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
|
||||
virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out
|
||||
virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input
|
||||
virtual bool isOutputter() const { return false; } // Else creates output or exits, etc, not unconsumed
|
||||
@@ -1128,7 +1179,7 @@ public:
|
||||
virtual bool hasDType() const { return false; } // Iff has a data type; dtype() must be non null
|
||||
virtual AstNodeDType* getChildDTypep() const { return NULL; } // Iff has a non-null childDTypep(), as generic node function
|
||||
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 const char* broken() const { return NULL; }
|
||||
|
||||
// INVOKERS
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0;
|
||||
@@ -1371,6 +1422,7 @@ public:
|
||||
void addIfsp(AstNode* newp) { addOp2p(newp); }
|
||||
void addElsesp(AstNode* newp) { addOp3p(newp); }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isGateDedupable() const { return true; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
@@ -1428,7 +1480,7 @@ public:
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeVarRef)
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool broken() const;
|
||||
virtual const char* broken() const;
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
virtual void cloneRelink();
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
@@ -1491,6 +1543,7 @@ public:
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs to next non-typeref type
|
||||
virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const type
|
||||
virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
@@ -1499,7 +1552,7 @@ public:
|
||||
//
|
||||
// Changing the width may confuse the data type resolution, so must clear TypeTable cache after use.
|
||||
void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; }
|
||||
// For backward compatibility AstArrayDType and others inherit width and signing from the subDType/base type
|
||||
// For backward compatibility inherit width and signing from the subDType/base type
|
||||
void widthFromSub(AstNodeDType* nodep) { m_width=nodep->m_width; m_widthMin=nodep->m_widthMin; m_numeric=nodep->m_numeric; }
|
||||
//
|
||||
int width() const { return m_width; }
|
||||
@@ -1515,8 +1568,8 @@ public:
|
||||
bool generic() const { return m_generic; }
|
||||
void generic(bool flag) { m_generic = flag; }
|
||||
AstNodeDType* dtypeDimensionp(int depth);
|
||||
pair<uint32_t,uint32_t> dimensions();
|
||||
uint32_t arrayElements(); // 1, or total multiplication of all dimensions
|
||||
pair<uint32_t,uint32_t> dimensions(bool includeBasic);
|
||||
uint32_t arrayUnpackedElements(); // 1, or total multiplication of all dimensions
|
||||
static int uniqueNumInc() { return ++s_uniqueNum; }
|
||||
};
|
||||
|
||||
@@ -1535,23 +1588,74 @@ public:
|
||||
numeric(numericUnpack.isSigned() ? AstNumeric::SIGNED : AstNumeric::UNSIGNED);
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeClassDType)
|
||||
virtual bool broken() const;
|
||||
virtual const char* broken() const;
|
||||
virtual void dump(ostream& str);
|
||||
// For basicp() we reuse the size to indicate a "fake" basic type of same size
|
||||
virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); }
|
||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
// op1 = members
|
||||
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
|
||||
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool packed() const { return m_packed; }
|
||||
bool packedUnsup() const { return true; } // packed() but as don't support unpacked, presently all structs
|
||||
void clearCache() { m_members.clear(); }
|
||||
void repairMemberCache();
|
||||
AstMemberDType* findMember(const string& name) const {
|
||||
MemberNameMap::const_iterator it = m_members.find(name);
|
||||
return (it==m_members.end()) ? NULL : it->second;
|
||||
}
|
||||
int lsb() const { return 0; }
|
||||
int msb() const { return dtypep()->width()-1; } // Packed classes look like arrays
|
||||
VNumRange declRange() const { return VNumRange(msb(), lsb(), false); }
|
||||
};
|
||||
|
||||
struct AstNodeArrayDType : public AstNodeDType {
|
||||
// Array data type, ie "some_dtype var_name [2:0]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: RANGE (array bounds)
|
||||
private:
|
||||
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
||||
AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable
|
||||
public:
|
||||
AstNodeArrayDType(FileLine* fl) : AstNodeDType(fl) {
|
||||
m_refDTypep = NULL;
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeArrayDType)
|
||||
virtual void dump(ostream& str);
|
||||
virtual void dumpSmall(ostream& str);
|
||||
virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
||||
|| (!m_refDTypep && childDTypep()))); return NULL; }
|
||||
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
|
||||
m_refDTypep = m_refDTypep->clonep()->castNodeDType();
|
||||
}}
|
||||
virtual bool same(AstNode* samep) const {
|
||||
AstNodeArrayDType* sp = samep->castNodeArrayDType();
|
||||
return (msb()==sp->msb()
|
||||
&& subDTypep()==sp->subDTypep()
|
||||
&& rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children
|
||||
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
|
||||
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
|
||||
AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
||||
void rangep(AstRange* nodep);
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
|
||||
virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); }
|
||||
int msb() const;
|
||||
int lsb() const;
|
||||
int elementsConst() const;
|
||||
VNumRange declRange() const;
|
||||
};
|
||||
|
||||
struct AstNodeSel : public AstNodeBiop {
|
||||
@@ -1648,7 +1752,7 @@ public:
|
||||
addNOp2p(pinsp);
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeFTaskRef)
|
||||
virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); }
|
||||
virtual const char* broken() const { BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); return NULL; }
|
||||
virtual void cloneRelink() { if (m_taskp && m_taskp->clonep()) {
|
||||
m_taskp = m_taskp->clonep()->castNodeFTask();
|
||||
}}
|
||||
@@ -1685,13 +1789,14 @@ private:
|
||||
bool m_modTrace:1; // Tracing this module
|
||||
bool m_inLibrary:1; // From a library, no error if not used, never top level
|
||||
bool m_dead:1; // LinkDot believes is dead; will remove in Dead visitors
|
||||
bool m_internal:1; // Internally created
|
||||
int m_level; // 1=top module, 2=cell off top module, ...
|
||||
int m_varNum; // Incrementing variable number
|
||||
public:
|
||||
AstNodeModule(FileLine* fl, const string& name)
|
||||
: AstNode (fl)
|
||||
,m_name(name), m_origName(name)
|
||||
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false)
|
||||
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false), m_internal(false)
|
||||
,m_level(0), m_varNum(0) { }
|
||||
ASTNODE_BASE_FUNCS(NodeModule)
|
||||
virtual void dump(ostream& str);
|
||||
@@ -1718,6 +1823,8 @@ public:
|
||||
bool modTrace() const { return m_modTrace; }
|
||||
void dead(bool flag) { m_dead = flag; }
|
||||
bool dead() const { return m_dead; }
|
||||
void internal(bool flag) { m_internal = flag; }
|
||||
bool internal() const { return m_internal; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -1746,4 +1853,15 @@ inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst
|
||||
|
||||
inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); }
|
||||
|
||||
inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
|
||||
inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); }
|
||||
inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); }
|
||||
inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); }
|
||||
inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange(msb(), lsb(), rangep()->littleEndian()); }
|
||||
|
||||
inline void AstIfaceRefDType::cloneRelink() {
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep()->castCell();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep()->castIface();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep()->castModport(); }
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+155
-49
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -35,8 +35,22 @@
|
||||
// Special methods
|
||||
|
||||
// We need these here, because the classes they point to aren't defined when we declare the class
|
||||
bool AstNodeVarRef::broken() const { return ((m_varScopep && !m_varScopep->brokeExists())
|
||||
|| (m_varp && !m_varp->brokeExists())); }
|
||||
const char* AstIfaceRefDType::broken() const {
|
||||
BROKEN_RTN(m_ifacep && !m_ifacep->brokeExists());
|
||||
BROKEN_RTN(m_cellp && !m_cellp->brokeExists());
|
||||
BROKEN_RTN(m_modportp && !m_modportp->brokeExists());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AstIface* AstIfaceRefDType::ifaceViaCellp() const {
|
||||
return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep);
|
||||
}
|
||||
|
||||
const char* AstNodeVarRef::broken() const {
|
||||
BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists());
|
||||
BROKEN_RTN(m_varp && !m_varp->brokeExists());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AstNodeVarRef::cloneRelink() {
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); }
|
||||
@@ -54,18 +68,18 @@ void AstNodeClassDType::repairMemberCache() {
|
||||
}
|
||||
}
|
||||
|
||||
bool AstNodeClassDType::broken() const {
|
||||
const char* AstNodeClassDType::broken() const {
|
||||
set<AstMemberDType*> exists;
|
||||
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
exists.insert(itemp);
|
||||
}
|
||||
for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) {
|
||||
if (exists.find(it->second) == exists.end()) {
|
||||
if (VL_UNLIKELY(exists.find(it->second) == exists.end())) {
|
||||
this->v3error("Internal: Structure member broken: "<<it->first);
|
||||
return true;
|
||||
return "member broken";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int AstBasicDType::widthAlignBytes() const {
|
||||
@@ -98,18 +112,55 @@ int AstNodeClassDType::widthAlignBytes() const {
|
||||
else return 8;
|
||||
}
|
||||
|
||||
AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
if (lhsp->isDouble() && rhsp->isDouble()) {
|
||||
return new AstEqD(fl, lhsp, rhsp);
|
||||
} else {
|
||||
return new AstEq(fl, lhsp, rhsp);
|
||||
}
|
||||
}
|
||||
|
||||
AstNodeBiop* AstGte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
if (lhsp->isDouble() && rhsp->isDouble()) {
|
||||
return new AstGteD(fl, lhsp, rhsp);
|
||||
} else if (lhsp->isSigned() && rhsp->isSigned()) {
|
||||
return new AstGteS(fl, lhsp, rhsp);
|
||||
} else {
|
||||
return new AstGte(fl, lhsp, rhsp);
|
||||
}
|
||||
}
|
||||
|
||||
AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
if (lhsp->isDouble() && rhsp->isDouble()) {
|
||||
return new AstLteD(fl, lhsp, rhsp);
|
||||
} else if (lhsp->isSigned() && rhsp->isSigned()) {
|
||||
return new AstLteS(fl, lhsp, rhsp);
|
||||
} else {
|
||||
return new AstLte(fl, lhsp, rhsp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AstVar::isSigPublic() const {
|
||||
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
|
||||
}
|
||||
|
||||
bool AstVar::isScQuad() const {
|
||||
return (isSc() && isQuad() && !isScBv());
|
||||
return (isSc() && isQuad() && !isScBv() && !isScBigUint());
|
||||
}
|
||||
|
||||
bool AstVar::isScBv() const {
|
||||
return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
|
||||
}
|
||||
|
||||
bool AstVar::isScUint() const {
|
||||
return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv());
|
||||
}
|
||||
|
||||
bool AstVar::isScBigUint() const {
|
||||
return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512) && !isScBv());
|
||||
}
|
||||
|
||||
void AstVar::combineType(AstVarType type) {
|
||||
// These flags get combined with the existing settings of the flags.
|
||||
// We don't test varType for certain types, instead set flags since
|
||||
@@ -268,6 +319,9 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
|
||||
}
|
||||
} else {
|
||||
arg = basicp()->keyword().dpiType();
|
||||
if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) {
|
||||
arg = "unsigned "+arg;
|
||||
}
|
||||
if (!forReturn && isOutput()) arg += "*";
|
||||
}
|
||||
if (named) arg += " "+name();
|
||||
@@ -275,7 +329,11 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
|
||||
}
|
||||
|
||||
string AstVar::scType() const {
|
||||
if (isScBv()) {
|
||||
if (isScBigUint()) {
|
||||
return (string("sc_biguint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else if (isScUint()) {
|
||||
return (string("sc_uint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else if (isScBv()) {
|
||||
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else if (widthMin() == 1) {
|
||||
return "bool";
|
||||
@@ -304,10 +362,12 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
||||
// DECL: VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (DT RANGE3))))
|
||||
// *or* VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (ARRAYSEL3 (DT))))
|
||||
// SEL1 needs to select from entire variable which is a pointer to ARRAYSEL0
|
||||
// TODO this function should be removed in favor of recursing the dtype(),
|
||||
// as that allows for more complicated data types.
|
||||
int dim = 0;
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if ((dim++)==dimension) {
|
||||
return dtypep;
|
||||
}
|
||||
@@ -337,11 +397,11 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t AstNodeDType::arrayElements() {
|
||||
uint32_t AstNodeDType::arrayUnpackedElements() {
|
||||
uint32_t entries=1;
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
|
||||
if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
|
||||
entries *= adtypep->elementsConst();
|
||||
dtypep = adtypep->subDTypep();
|
||||
}
|
||||
@@ -353,21 +413,22 @@ uint32_t AstNodeDType::arrayElements() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
pair<uint32_t,uint32_t> AstNodeDType::dimensions() {
|
||||
pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
|
||||
// How many array dimensions (packed,unpacked) does this Var have?
|
||||
uint32_t packed = 0;
|
||||
uint32_t unpacked = 0;
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
|
||||
if (adtypep->isPacked()) packed += 1;
|
||||
else unpacked += 1;
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (adtypep->castPackArrayDType()) packed++;
|
||||
else unpacked++;
|
||||
dtypep = adtypep->subDTypep();
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// AstBasicDType - nothing below, 1
|
||||
break;
|
||||
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||
if (includeBasic && adtypep->isRanged()) packed++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return make_pair(packed, unpacked);
|
||||
}
|
||||
@@ -381,26 +442,12 @@ int AstNodeDType::widthPow2() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Special operators
|
||||
int AstArraySel::dimension(AstNode* nodep) {
|
||||
// How many dimensions is this reference from the base variable?
|
||||
// nodep is typically the fromp() of a select; thus the first select
|
||||
// is selecting from the entire variable type - effectively dimension 0.
|
||||
// Dimension passed to AstVar::dtypeDimensionp; see comments there
|
||||
int dim = 0;
|
||||
while (nodep) {
|
||||
if (nodep->castNodeSel()) { dim++; nodep=nodep->castNodeSel()->fromp(); continue; }
|
||||
if (nodep->castNodePreSel()) { dim++; nodep=nodep->castNodePreSel()->fromp(); continue; }
|
||||
break;
|
||||
}
|
||||
return dim;
|
||||
}
|
||||
AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
|
||||
// Else AstArraySel etc; search for the base
|
||||
while (nodep) {
|
||||
if (nodep->castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; }
|
||||
else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; }
|
||||
// AstNodeSelPre stashes the associated variable under a ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
|
||||
// AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
|
||||
else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; }
|
||||
else if (nodep->castNodePreSel()) {
|
||||
if (nodep->castNodePreSel()->attrp()) {
|
||||
@@ -415,10 +462,12 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable
|
||||
return nodep;
|
||||
}
|
||||
|
||||
bool AstScope::broken() const {
|
||||
return ((m_aboveScopep && !m_aboveScopep->brokeExists())
|
||||
|| (m_aboveCellp && !m_aboveCellp->brokeExists())
|
||||
|| !m_modp || !m_modp->brokeExists());
|
||||
const char* AstScope::broken() const {
|
||||
BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists());
|
||||
BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists());
|
||||
BROKEN_RTN(!m_modp);
|
||||
BROKEN_RTN(m_modp && !m_modp->brokeExists());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AstScope::cloneRelink() {
|
||||
@@ -552,7 +601,7 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw
|
||||
LogicMap::const_iterator it = mapr.find(widths);
|
||||
if (it != mapr.end()) return it->second;
|
||||
//
|
||||
AstBasicDType* new1p = new AstBasicDType(fl, AstBasicDTypeKwd::BIT, numeric, width, widthMin);
|
||||
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin);
|
||||
// Because the detailed map doesn't update this map,
|
||||
// check the detailed map for this same node, and if found update this map
|
||||
// Also adds this new node to the detailed map
|
||||
@@ -564,6 +613,15 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw
|
||||
return newp;
|
||||
}
|
||||
|
||||
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
|
||||
VNumRange range, int widthMin, AstNumeric numeric) {
|
||||
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin);
|
||||
AstBasicDType* newp = findInsertSameDType(new1p);
|
||||
if (newp != new1p) new1p->deleteTree();
|
||||
else addTypesp(newp);
|
||||
return newp;
|
||||
}
|
||||
|
||||
AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
|
||||
VBasicTypeKey key (nodep->width(), nodep->widthMin(), nodep->numeric(),
|
||||
nodep->keyword(), nodep->nrange());
|
||||
@@ -664,10 +722,11 @@ void AstNode::dump(ostream& str) {
|
||||
if (name()!="") str<<" "<<AstNode::quoteName(name());
|
||||
}
|
||||
|
||||
void AstArrayDType::dump(ostream& str) {
|
||||
this->AstNodeDType::dump(str);
|
||||
if (isPacked()) str<<" [PACKED]";
|
||||
void AstAlways::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
|
||||
}
|
||||
|
||||
void AstArraySel::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" [start:"<<start()<<"] [length:"<<length()<<"]";
|
||||
@@ -698,17 +757,43 @@ void AstDisplay::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
//str<<" "<<displayType().ascii();
|
||||
}
|
||||
void AstEnumItemRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> ";
|
||||
if (itemp()) { itemp()->dump(str); }
|
||||
else { str<<"UNLINKED"; }
|
||||
}
|
||||
void AstIfaceRefDType::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (cellName()!="") { str<<" cell="<<cellName(); }
|
||||
if (ifaceName()!="") { str<<" if="<<ifaceName(); }
|
||||
if (modportName()!="") { str<<" mp="<<modportName(); }
|
||||
if (cellp()) { str<<" -> "; cellp()->dump(str); }
|
||||
else if (ifacep()) { str<<" -> "; ifacep()->dump(str); }
|
||||
else { str<<" -> UNLINKED"; }
|
||||
}
|
||||
void AstIfaceRefDType::dumpSmall(ostream& str) {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
str<<"iface";
|
||||
}
|
||||
void AstJumpGo::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> ";
|
||||
if (labelp()) { labelp()->dump(str); }
|
||||
else { str<<"%Error:UNLINKED"; }
|
||||
}
|
||||
void AstEnumItemRef::dump(ostream& str) {
|
||||
void AstModportFTaskRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> ";
|
||||
if (itemp()) { itemp()->dump(str); }
|
||||
else { str<<"UNLINKED"; }
|
||||
if (isExport()) str<<" EXPORT";
|
||||
if (isImport()) str<<" IMPORT";
|
||||
if (ftaskp()) { str<<" -> "; ftaskp()->dump(str); }
|
||||
else { str<<" -> UNLINKED"; }
|
||||
}
|
||||
void AstModportVarRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" "<<varType();
|
||||
if (varp()) { str<<" -> "; varp()->dump(str); }
|
||||
else { str<<" -> UNLINKED"; }
|
||||
}
|
||||
void AstPin::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
@@ -747,6 +832,15 @@ void AstNodeDType::dumpSmall(ostream& str) {
|
||||
if (!widthSized()) str<<"/"<<widthMin();
|
||||
str<<")";
|
||||
}
|
||||
void AstNodeArrayDType::dumpSmall(ostream& str) {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
if (castPackArrayDType()) str<<"p"; else str<<"u";
|
||||
str<<"["<<declRange().left()<<":"<<declRange().right()<<"]";
|
||||
}
|
||||
void AstNodeArrayDType::dump(ostream& str) {
|
||||
this->AstNodeDType::dump(str);
|
||||
str<<" ["<<declRange().left()<<":"<<declRange().right()<<"]";
|
||||
}
|
||||
void AstNodeModule::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" L"<<level();
|
||||
@@ -758,6 +852,13 @@ void AstPackageImport::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<packagep();
|
||||
}
|
||||
void AstSel::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (declRange().ranged()) {
|
||||
str<<" decl["<<declRange().left()<<":"<<declRange().right()<<"]";
|
||||
if (declElWidth()!=1) str<<"/"<<declElWidth();
|
||||
}
|
||||
}
|
||||
void AstTypeTable::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
|
||||
@@ -809,7 +910,7 @@ void AstVarXRef::dump(ostream& str) {
|
||||
if (lvalue()) str<<" [LV] => ";
|
||||
else str<<" [RV] <- ";
|
||||
str<<dotted()<<". - ";
|
||||
if (inlinedDots()!="") str<<" flat.="<<inlinedDots()<<" - ";
|
||||
if (inlinedDots()!="") str<<" inline.="<<inlinedDots()<<" - ";
|
||||
if (varScopep()) { varScopep()->dump(str); }
|
||||
else if (varp()) { varp()->dump(str); }
|
||||
else { str<<"UNLINKED"; }
|
||||
@@ -856,11 +957,16 @@ void AstSenItem::dump(ostream& str) {
|
||||
void AstParseRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" ["<<expect().ascii()<<"]";
|
||||
if (start()) str<<" [START]";
|
||||
}
|
||||
void AstPackageRef::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
|
||||
str<<" -> ";
|
||||
if (packagep()) { packagep()->dump(str); }
|
||||
else { str<<"UNLINKED"; }
|
||||
}
|
||||
void AstDot::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (start()) str<<" [START]";
|
||||
}
|
||||
void AstActive::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
|
||||
+469
-143
File diff suppressed because it is too large
Load Diff
+8
-5
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -134,9 +134,11 @@ private:
|
||||
if (m_unnamedScope=="") m_unnamedScope = ident;
|
||||
else m_unnamedScope = m_unnamedScope + "__DOT__"+ident;
|
||||
// Create CellInline for dotted var resolution
|
||||
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
|
||||
m_unnamedScope, "__BEGIN__");
|
||||
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
||||
if (!m_ftaskp) {
|
||||
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
|
||||
m_unnamedScope, "__BEGIN__");
|
||||
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +153,7 @@ private:
|
||||
AstNode* addsp = NULL;
|
||||
if (AstNode* stmtsp = nodep->stmtsp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
addsp = addsp->addNextNull(stmtsp);
|
||||
if (addsp) { addsp = addsp->addNextNull(stmtsp); } else { addsp = stmtsp; }
|
||||
}
|
||||
if (addsp) {
|
||||
nodep->replaceWith(addsp);
|
||||
@@ -184,6 +186,7 @@ private:
|
||||
virtual void visit(AstScopeName* 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 (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
if (m_namedScope != "") {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -202,8 +202,8 @@ class BrokenCheckVisitor : public AstNVisitor {
|
||||
private:
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
BrokenTable::setUnder(nodep,true);
|
||||
if (nodep->broken()) {
|
||||
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo)");
|
||||
if (const char* whyp=nodep->broken()) {
|
||||
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
|
||||
}
|
||||
if (nodep->dtypep()) {
|
||||
if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+25
-18
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -97,7 +97,8 @@ private:
|
||||
nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')");
|
||||
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) {
|
||||
// Don't sweat it, we already complained about casex in general
|
||||
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casez()) {
|
||||
} else if (m_caseExprp->castCase() && (m_caseExprp->castCase()->casez()
|
||||
|| m_caseExprp->castCase()->caseInside())) {
|
||||
if (nodep->num().isUnknown()) {
|
||||
nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)");
|
||||
}
|
||||
@@ -322,36 +323,42 @@ private:
|
||||
icondNextp = icondp->nextp();
|
||||
icondp->unlinkFrBack();
|
||||
|
||||
AstNode* and1p;
|
||||
AstNode* and2p;
|
||||
AstNode* condp = NULL; // Default is to use and1p/and2p
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
if (iconstp && neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
// For simplicity, make expression that is not equal, and let later
|
||||
// optimizations remove it
|
||||
and1p = new AstConst(itemp->fileline(), AstConst::LogicFalse());
|
||||
and2p = new AstConst(itemp->fileline(), AstConst::LogicTrue());
|
||||
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
|
||||
} else if (AstInsideRange* irangep = icondp->castInsideRange()) {
|
||||
// Similar logic in V3Width::visit(AstInside)
|
||||
AstNode* ap = AstGte::newTyped(itemp->fileline(),
|
||||
cexprp->cloneTree(false),
|
||||
irangep->lhsp()->unlinkFrBack());
|
||||
AstNode* bp = AstLte::newTyped(itemp->fileline(),
|
||||
cexprp->cloneTree(false),
|
||||
irangep->rhsp()->unlinkFrBack());
|
||||
condp = new AstAnd(itemp->fileline(), ap, bp);
|
||||
} else if (iconstp && iconstp->num().isFourState()
|
||||
&& (nodep->casex() || nodep->casez())) {
|
||||
&& (nodep->casex() || nodep->casez() || nodep->caseInside())) {
|
||||
V3Number nummask (itemp->fileline(), iconstp->width());
|
||||
nummask.opBitsNonX(iconstp->num());
|
||||
V3Number numval (itemp->fileline(), iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
and2p = new AstAnd(itemp->fileline(),
|
||||
new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
AstNode* and2p = new AstAnd(itemp->fileline(),
|
||||
new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
|
||||
} else {
|
||||
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
|
||||
and1p = cexprp->cloneTree(false);
|
||||
and2p = icondp;
|
||||
AstNode* and1p = cexprp->cloneTree(false);
|
||||
AstNode* and2p = icondp;
|
||||
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
|
||||
}
|
||||
AstNodeBiop* condp = (and1p->isDouble()
|
||||
? (new AstEqD(itemp->fileline(), and1p, and2p))->castNodeBiop()
|
||||
: (new AstEq(itemp->fileline(), and1p, and2p))->castNodeBiop());
|
||||
if (!ifexprp) {
|
||||
ifexprp = condp;
|
||||
} else {
|
||||
@@ -435,7 +442,7 @@ private:
|
||||
bool neverItem(AstCase* casep, AstConst* itemp) {
|
||||
// Xs in case or casez are impossible due to two state simulations
|
||||
if (casep->casex()) {
|
||||
} else if (casep->casez()) {
|
||||
} else if (casep->casez() || casep->caseInside()) {
|
||||
if (itemp->num().isUnknown()) return true;
|
||||
} else {
|
||||
if (itemp->num().isFourState()) return true;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -526,7 +526,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
sort(report.begin(), report.end());
|
||||
stable_sort(report.begin(), report.end());
|
||||
for (deque<string>::iterator it = report.begin(); it!=report.end(); ++it) {
|
||||
*ofp << *it;
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+9
-8
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -86,16 +86,17 @@ private:
|
||||
#endif
|
||||
AstVar* varp = vscp->varp();
|
||||
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
|
||||
AstArrayDType* arrayp = varp->dtypeSkipRefp()->castArrayDType();
|
||||
AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType();
|
||||
AstStructDType *structp = varp->dtypeSkipRefp()->castStructDType();
|
||||
bool isArray = arrayp;
|
||||
int msb = isArray ? arrayp->msb() : 0;
|
||||
int lsb = isArray ? arrayp->lsb() : 0;
|
||||
if (isArray && ((msb - lsb + 1) > DETECTARRAY_MAX_INDEXES)) {
|
||||
bool isStruct = structp && structp->packedUnsup();
|
||||
int elements = isArray ? arrayp->elementsConst() : 1;
|
||||
if (isArray && (elements > DETECTARRAY_MAX_INDEXES)) {
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<<cvtToStr(DETECTARRAY_MAX_INDEXES)
|
||||
<<" array indexes (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName()<<endl
|
||||
<<vscp->warnMore()
|
||||
<<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(msb-lsb+1));
|
||||
} else if (!isArray
|
||||
<<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(elements));
|
||||
} else if (!isArray && !isStruct
|
||||
&& !varp->dtypeSkipRefp()->castBasicDType()) {
|
||||
if (debug()) varp->dumpTree(cout,"-DETECTARRAY-");
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
|
||||
@@ -109,7 +110,7 @@ private:
|
||||
m_topModp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
m_scopetopp->addVarp(newvscp);
|
||||
for (int index=lsb; index<=msb; ++index) {
|
||||
for (int index=0; index<elements; ++index) {
|
||||
AstChangeDet* changep
|
||||
= new AstChangeDet (vscp->fileline(),
|
||||
aselIfNeeded(isArray, index,
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+2
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2008-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2008-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -684,6 +684,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
AstNode* bodyp = nodep->bodysp()->cloneTree(true);
|
||||
|
||||
AstAlways* alwp = new AstAlways(nodep->fileline(),
|
||||
nodep->keyword(),
|
||||
sensesp,
|
||||
bodyp);
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+6
-10
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
if (vscp->user1p()) return ((AstVarScope*)vscp->user1p());
|
||||
AstVar* varp = vscp->varp();
|
||||
if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
|
||||
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
|
||||
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name());
|
||||
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
|
||||
m_modp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||
@@ -346,14 +346,10 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
// Link to global function
|
||||
if (nodep->formCallTree()) {
|
||||
if (nodep->name() == "_final") {
|
||||
UINFO(4, " formCallTree "<<nodep<<endl);
|
||||
AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
|
||||
callp->argTypes("vlSymsp");
|
||||
m_finalFuncp->addStmtsp(callp);
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unknown CFunc name. Make code more generic, with a map of func names");
|
||||
}
|
||||
UINFO(4, " formCallTree "<<nodep<<endl);
|
||||
AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
|
||||
callp->argTypes("vlSymsp");
|
||||
m_finalFuncp->addStmtsp(callp);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+3
-2
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3String.h"
|
||||
#include "V3Config.h"
|
||||
|
||||
//######################################################################
|
||||
@@ -89,7 +90,7 @@ class V3ConfigIgnores {
|
||||
it = m_ignFiles.find(filename);
|
||||
// Make new list for this file of all matches
|
||||
for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) {
|
||||
if (V3Options::wildmatch(filename.c_str(), fnit->first.c_str())) {
|
||||
if (VString::wildmatch(filename.c_str(), fnit->first.c_str())) {
|
||||
for (IgnLines::iterator lit = fnit->second.begin(); lit != fnit->second.end(); ++lit) {
|
||||
it->second.insert(*lit);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+74
-48
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -327,27 +327,27 @@ private:
|
||||
}
|
||||
|
||||
bool operandBiExtendConst(AstNodeBiop* nodep) {
|
||||
// Loop unrolling likes standalone compares
|
||||
// EQ(EXTEND(xx{width3}), const{width32}) -> EQ(xx{3},const{3})
|
||||
// Loop unrolling favors standalone compares
|
||||
// EQ(const{width32}, EXTEND(xx{width3})) -> EQ(const{3}, xx{3})
|
||||
// Beware that the constant must have zero bits (+ 1 if signed) or compare
|
||||
// would be incorrect
|
||||
AstExtend* extendp = nodep->lhsp()->castExtend();
|
||||
AstExtend* extendp = nodep->rhsp()->castExtend();
|
||||
if (!extendp) return false;
|
||||
AstNode* smallerp = extendp->lhsp();
|
||||
int subsize = smallerp->width();
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
AstConst* constp = nodep->lhsp()->castConst();
|
||||
if (!constp) return false;
|
||||
if (!constp->num().isBitsZero(constp->width()-1, subsize)) return false;
|
||||
//
|
||||
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-in:");
|
||||
smallerp->unlinkFrBack();
|
||||
extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp.
|
||||
nodep->lhsp(smallerp);
|
||||
nodep->rhsp(smallerp);
|
||||
|
||||
constp->unlinkFrBack();
|
||||
V3Number num (constp->fileline(), subsize);
|
||||
num.opAssign(constp->num());
|
||||
nodep->rhsp(new AstConst(constp->fileline(), num));
|
||||
nodep->lhsp(new AstConst(constp->fileline(), num));
|
||||
constp->deleteTree(); constp=NULL;
|
||||
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:");
|
||||
return true;
|
||||
@@ -370,37 +370,40 @@ private:
|
||||
|
||||
// Extraction checks
|
||||
bool warnSelect(AstSel* nodep) {
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep);
|
||||
if (m_doGenerate) {
|
||||
// Never checked yet
|
||||
V3Width::widthParamsEdit(nodep);
|
||||
nodep->iterateChildren(*this); // May need "constifying"
|
||||
}
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||
AstVar* varp = varrefp->varp();
|
||||
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
|
||||
AstBasicDType* bdtypep = varp->basicp(); if (!bdtypep) varp->v3fatalSrc("Select of non-selectable type");
|
||||
if (m_warn
|
||||
&& nodep->lsbp()->castConst()
|
||||
&& nodep->widthp()->castConst()
|
||||
&& (!bdtypep->isRanged() || bdtypep->msb())) { // else it's non-resolvable parameterized
|
||||
if (nodep->lsbp()->castConst()->num().isFourState()
|
||||
|| nodep->widthp()->castConst()->num().isFourState()) {
|
||||
nodep->v3error("Selection index is constantly unknown or tristated: "
|
||||
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
|
||||
// Replacing nodep will make a mess above, so we replace the offender
|
||||
replaceZero(nodep->lsbp());
|
||||
}
|
||||
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|
||||
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
|
||||
// See also warning in V3Width
|
||||
nodep->v3warn(SELRANGE, "Selection index out of range: "
|
||||
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
||||
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
|
||||
<<(bdtypep->lsb()>=0 ? ""
|
||||
:" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)"));
|
||||
// Don't replace with zero, we'll do it later
|
||||
}
|
||||
// Find range of dtype we are selecting from
|
||||
// Similar code in V3Unknown::AstSel
|
||||
bool doit = true;
|
||||
if (m_warn
|
||||
&& nodep->lsbp()->castConst()
|
||||
&& nodep->widthp()->castConst()
|
||||
&& doit) {
|
||||
int maxDeclBit = nodep->declRange().hiMaxSelect()*nodep->declElWidth() + (nodep->declElWidth()-1);
|
||||
if (nodep->lsbp()->castConst()->num().isFourState()
|
||||
|| nodep->widthp()->castConst()->num().isFourState()) {
|
||||
nodep->v3error("Selection index is constantly unknown or tristated: "
|
||||
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
|
||||
// Replacing nodep will make a mess above, so we replace the offender
|
||||
replaceZero(nodep->lsbp());
|
||||
}
|
||||
else if (nodep->declRange().ranged()
|
||||
&& (nodep->msbConst() > maxDeclBit
|
||||
|| nodep->lsbConst() > maxDeclBit)) {
|
||||
// See also warning in V3Width
|
||||
// Must adjust by element width as declRange() is in number of elements
|
||||
nodep->v3warn(SELRANGE, "Selection index out of range: "
|
||||
<<(nodep->msbConst()/nodep->declElWidth())
|
||||
<<":"<<(nodep->lsbConst()/nodep->declElWidth())
|
||||
<<" outside "<<nodep->declRange().hiMaxSelect()<<":0"
|
||||
<<(nodep->declRange().lo()>=0 ? ""
|
||||
:(" (adjusted +"+cvtToStr(-nodep->declRange().lo())
|
||||
+" to account for negative lsb)")));
|
||||
UINFO(1," Related Raw index is "<<nodep->msbConst()<<":"<<nodep->lsbConst()<<endl);
|
||||
// Don't replace with zero, we'll do it later
|
||||
}
|
||||
}
|
||||
return false; // Not a transform, so NOP
|
||||
@@ -415,8 +418,7 @@ private:
|
||||
// Avoid comparing widthMin's, which results in lost optimization attempts
|
||||
// If cleanup sameTree to be smarter, this can be restored.
|
||||
//return node1p->sameTree(node2p);
|
||||
return node1p->castVarRef()->varp() == node2p->castVarRef()->varp()
|
||||
&& node1p->castVarRef()->lvalue() == node2p->castVarRef()->lvalue();
|
||||
return node1p->same(node2p);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -431,7 +433,7 @@ private:
|
||||
AstVarRef* elsevarp = elsep->lhsp()->castVarRef();
|
||||
if (!ifvarp || !elsevarp) return false;
|
||||
if (ifvarp->isWide()) return false; // Would need temporaries, so not worth it
|
||||
if (ifvarp->varp() != elsevarp->varp()) return false;
|
||||
if (!ifvarp->sameTree(elsevarp)) return false;
|
||||
return true;
|
||||
}
|
||||
bool operandIfIf(AstNodeIf* nodep) {
|
||||
@@ -536,6 +538,8 @@ private:
|
||||
void replaceWChild(AstNode* nodep, AstNode* childp) {
|
||||
// NODE(..., CHILD(...)) -> CHILD(...)
|
||||
childp->unlinkFrBackWithNext();
|
||||
// If replacing a SEL for example, the data type comes from the parent (is less wide).
|
||||
// This may adversly affect the operation of the node being replaced.
|
||||
childp->dtypeFrom(nodep);
|
||||
nodep->replaceWith(childp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
@@ -776,7 +780,7 @@ private:
|
||||
AstSel* sel2p = nextp->lhsp()->castSel(); if (!sel2p) return false;
|
||||
AstVarRef* varref1p = sel1p->fromp()->castVarRef(); if (!varref1p) return false;
|
||||
AstVarRef* varref2p = sel2p->fromp()->castVarRef(); if (!varref2p) return false;
|
||||
if (varref1p->varp() != varref2p->varp()) return false;
|
||||
if (!varref1p->sameTree(varref2p)) return false;
|
||||
AstConst* con1p = sel1p->lsbp()->castConst(); if (!con1p) return false;
|
||||
AstConst* con2p = sel2p->lsbp()->castConst(); if (!con2p) return false;
|
||||
// We need to make sure there's no self-references involved in either
|
||||
@@ -813,9 +817,10 @@ private:
|
||||
|
||||
bool varNotReferenced(AstNode* nodep, AstVar* varp, int level=0) {
|
||||
// Return true if varp never referenced under node.
|
||||
// Return false if referenced, or tree too deep to be worth it
|
||||
// Return false if referenced, or tree too deep to be worth it, or side effects
|
||||
if (!nodep) return true;
|
||||
if (level>2) return false;
|
||||
if (nodep->isPure()) return false; // For example a $fgetc can't be reordered
|
||||
if (nodep->castNodeVarRef() && nodep->castNodeVarRef()->varp()==varp) return false;
|
||||
return (varNotReferenced (nodep->nextp(),varp,level+1)
|
||||
&& varNotReferenced(nodep->op1p(),varp,level+1)
|
||||
@@ -827,7 +832,7 @@ private:
|
||||
bool replaceNodeAssign(AstNodeAssign* nodep) {
|
||||
if (nodep->lhsp()->castVarRef()
|
||||
&& nodep->rhsp()->castVarRef()
|
||||
&& nodep->lhsp()->sameTree(nodep->rhsp())
|
||||
&& nodep->lhsp()->castVarRef()->sameNoLvalue(nodep->rhsp()->castVarRef())
|
||||
&& !nodep->castAssignDly()) {
|
||||
// X = X. Quite pointless, though X <= X may override another earlier assignment
|
||||
if (nodep->castAssignW()) {
|
||||
@@ -1228,6 +1233,8 @@ private:
|
||||
&& ((!m_params // Can reduce constant wires into equations
|
||||
&& m_doNConst
|
||||
&& v3Global.opt.oConst()
|
||||
&& !(nodep->varp()->isFuncLocal() // Default value, not a "known" constant for this usage
|
||||
&& nodep->varp()->isInput())
|
||||
&& !nodep->varp()->isSigPublic())
|
||||
|| nodep->varp()->isParam())) {
|
||||
AstConst* constp = nodep->varp()->valuep()->castConst();
|
||||
@@ -1271,6 +1278,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst
|
||||
&& (nodep->sensp()->castConst()
|
||||
|| nodep->sensp()->castEnumItemRef()
|
||||
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam()))) {
|
||||
// Constants in sensitivity lists may be removed (we'll simplify later)
|
||||
if (nodep->isClocked()) { // A constant can never get a pos/negexge
|
||||
@@ -1299,6 +1307,9 @@ private:
|
||||
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
|
||||
sensp->replaceWith(senvarp);
|
||||
sensp->deleteTree(); sensp=NULL;
|
||||
} else if (!m_doNConst // Deal with later when doNConst missing
|
||||
&& (nodep->sensp()->castEnumItemRef()
|
||||
|| nodep->sensp()->castConst())) {
|
||||
} else {
|
||||
if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable");
|
||||
}
|
||||
@@ -1398,6 +1409,7 @@ private:
|
||||
for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem();
|
||||
senp; senp=nextp) {
|
||||
nextp=senp->nextp()->castNodeSenItem();
|
||||
// cppcheck-suppress unassignedVariable // cppcheck bug
|
||||
SenItemCmp cmp;
|
||||
if (nextp && !cmp(senp, nextp)) {
|
||||
// Something's out of order, sort it
|
||||
@@ -1406,7 +1418,7 @@ private:
|
||||
for (AstNodeSenItem* senp = nodep->sensesp()->castNodeSenItem(); senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
vec.push_back(senp);
|
||||
}
|
||||
sort(vec.begin(), vec.end(), SenItemCmp());
|
||||
stable_sort(vec.begin(), vec.end(), SenItemCmp());
|
||||
for (vector<AstNodeSenItem*>::iterator it=vec.begin(); it!=vec.end(); ++it) {
|
||||
(*it)->unlinkFrBack();
|
||||
}
|
||||
@@ -1459,6 +1471,9 @@ private:
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
// Don't perform any optimizations, keep the alias around
|
||||
}
|
||||
virtual void visit(AstAssignVarScope* nodep, AstNUser*) {
|
||||
// Don't perform any optimizations, the node won't be linked yet
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||
@@ -1633,7 +1648,10 @@ private:
|
||||
replaceWithSimulation(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstArg* nodep, AstNUser*) {
|
||||
// replaceWithSimulation on the Arg's parent FuncRef replaces these
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst) {
|
||||
@@ -1796,6 +1814,14 @@ private:
|
||||
TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
|
||||
TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
|
||||
TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
|
||||
TREEOP ("AstLt {!$lhsp.castConst,$rhsp.castConst}", "AstGt {$rhsp,$lhsp}");
|
||||
TREEOP ("AstLtS {!$lhsp.castConst,$rhsp.castConst}", "AstGtS {$rhsp,$lhsp}");
|
||||
TREEOP ("AstLte {!$lhsp.castConst,$rhsp.castConst}", "AstGte {$rhsp,$lhsp}");
|
||||
TREEOP ("AstLteS {!$lhsp.castConst,$rhsp.castConst}", "AstGteS{$rhsp,$lhsp}");
|
||||
TREEOP ("AstGt {!$lhsp.castConst,$rhsp.castConst}", "AstLt {$rhsp,$lhsp}");
|
||||
TREEOP ("AstGtS {!$lhsp.castConst,$rhsp.castConst}", "AstLtS {$rhsp,$lhsp}");
|
||||
TREEOP ("AstGte {!$lhsp.castConst,$rhsp.castConst}", "AstLte {$rhsp,$lhsp}");
|
||||
TREEOP ("AstGteS {!$lhsp.castConst,$rhsp.castConst}", "AstLteS{$rhsp,$lhsp}");
|
||||
// v--- *1* as These ops are always first, as we warn before replacing
|
||||
TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)");
|
||||
TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)");
|
||||
@@ -1807,7 +1833,7 @@ private:
|
||||
TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)");
|
||||
// Two level bubble pushing
|
||||
TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==$lhsp->castNot()->lhsp()->width()}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x
|
||||
TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x
|
||||
TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // LOGNOT(LOGNOT(x))->x
|
||||
TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
|
||||
TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
|
||||
TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
|
||||
@@ -1845,12 +1871,12 @@ private:
|
||||
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
|
||||
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
|
||||
// Compress out EXTENDs to appease loop unroller
|
||||
TREEOPV("AstEq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstNeq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstGt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstGte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstLt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstLte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
|
||||
// Identical operands on both sides
|
||||
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
|
||||
// AstAdd->ShiftL(#,1) but uncommon
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+56
-8
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
bool m_checkBlock; // Should this block get covered?
|
||||
AstNodeModule* m_modp; // Current module to add statement to
|
||||
bool m_inToggleOff; // In function/task etc
|
||||
bool m_inModOff; // In module with no coverage
|
||||
FileMap m_fileps; // Column counts for each fileline
|
||||
string m_beginHier; // AstBegin hier name for user coverage points
|
||||
|
||||
@@ -86,7 +87,7 @@ private:
|
||||
if (prettyName.find("._") != string::npos)
|
||||
return "Inlined leading underscore";
|
||||
}
|
||||
if ((nodep->width()*nodep->dtypep()->arrayElements()) > 256) return "Wide bus/array > 256 bits";
|
||||
if ((nodep->width()*nodep->dtypep()->arrayUnpackedElements()) > 256) return "Wide bus/array > 256 bits";
|
||||
// We allow this, though tracing doesn't
|
||||
// if (nodep->arrayp(1)) return "Unsupported: Multi-dimensional array";
|
||||
return NULL;
|
||||
@@ -124,9 +125,11 @@ private:
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
m_modp = nodep;
|
||||
m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created
|
||||
m_fileps.clear();
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
m_inModOff = true;
|
||||
}
|
||||
|
||||
// VISITORS - TOGGLE COVERAGE
|
||||
@@ -140,7 +143,7 @@ private:
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_modp && !m_inToggleOff
|
||||
if (m_modp && !m_inModOff && !m_inToggleOff
|
||||
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) {
|
||||
const char* disablep = varIgnoreToggle(nodep);
|
||||
if (disablep) {
|
||||
@@ -209,8 +212,8 @@ private:
|
||||
varp, chgVarp);
|
||||
}
|
||||
}
|
||||
else if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
|
||||
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb()+1; ++index_docs) {
|
||||
else if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
|
||||
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
|
||||
int index_code = index_docs - adtypep->lsb();
|
||||
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
|
||||
new AstArraySel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code),
|
||||
@@ -221,6 +224,50 @@ private:
|
||||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else if (AstPackArrayDType* adtypep = dtypep->castPackArrayDType()) {
|
||||
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
|
||||
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
|
||||
int index_code = index_docs - adtypep->lsb();
|
||||
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
|
||||
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
||||
index_code*subtypep->width(), subtypep->width()),
|
||||
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
|
||||
index_code*subtypep->width(), subtypep->width()));
|
||||
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1,
|
||||
newent,
|
||||
varp, chgVarp);
|
||||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else if (AstStructDType* adtypep = dtypep->castStructDType()) {
|
||||
// For now it's packed, so similar to array
|
||||
for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
int index_code = itemp->lsb();
|
||||
ToggleEnt newent (above.m_comment+string(".")+itemp->name(),
|
||||
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
||||
index_code, subtypep->width()),
|
||||
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
|
||||
index_code, subtypep->width()));
|
||||
toggleVarRecurse(subtypep, depth+1,
|
||||
newent,
|
||||
varp, chgVarp);
|
||||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else if (AstUnionDType* adtypep = dtypep->castUnionDType()) {
|
||||
// Arbitrarially handle only the first member of the union
|
||||
if (AstMemberDType* itemp = adtypep->membersp()) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
ToggleEnt newent (above.m_comment+string(".")+itemp->name(),
|
||||
above.m_varRefp->cloneTree(true),
|
||||
above.m_chgRefp->cloneTree(true));
|
||||
toggleVarRecurse(subtypep, depth+1,
|
||||
newent,
|
||||
varp, chgVarp);
|
||||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else {
|
||||
dtypep->v3fatalSrc("Unexpected node data type in toggle coverage generation: "<<dtypep->prettyTypeName());
|
||||
}
|
||||
@@ -231,7 +278,7 @@ private:
|
||||
UINFO(4," IF: "<<nodep<<endl);
|
||||
if (m_checkBlock) {
|
||||
nodep->ifsp()->iterateAndNext(*this);
|
||||
if (m_checkBlock
|
||||
if (m_checkBlock && !m_inModOff
|
||||
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it
|
||||
if (!nodep->backp()->castIf()
|
||||
|| nodep->backp()->castIf()->elsesp()!=nodep) { // Ignore if else; did earlier
|
||||
@@ -243,7 +290,7 @@ private:
|
||||
if (nodep->elsesp()) {
|
||||
m_checkBlock = true;
|
||||
nodep->elsesp()->iterateAndNext(*this);
|
||||
if (m_checkBlock
|
||||
if (m_checkBlock && !m_inModOff
|
||||
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it
|
||||
UINFO(4," COVER: "<<nodep<<endl);
|
||||
if (nodep->elsesp()->castIf()) {
|
||||
@@ -258,7 +305,7 @@ private:
|
||||
}
|
||||
virtual void visit(AstCaseItem* nodep, AstNUser*) {
|
||||
UINFO(4," CASEI: "<<nodep<<endl);
|
||||
if (m_checkBlock
|
||||
if (m_checkBlock && !m_inModOff
|
||||
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) {
|
||||
nodep->bodysp()->iterateAndNext(*this);
|
||||
if (m_checkBlock) { // if the case body didn't disable it
|
||||
@@ -327,6 +374,7 @@ public:
|
||||
m_checkBlock = true;
|
||||
m_beginHier = "";
|
||||
m_inToggleOff = false;
|
||||
m_inModOff = true;
|
||||
rootp->iterateChildren(*this);
|
||||
}
|
||||
virtual ~CoverageVisitor() {}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+8
-4
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -103,7 +103,9 @@ private:
|
||||
}
|
||||
void checkDType(AstNodeDType* nodep) {
|
||||
if (!nodep->generic() // Don't remove generic types
|
||||
&& m_elimDTypes) { // dtypes stick around until post-widthing
|
||||
&& m_elimDTypes // dtypes stick around until post-widthing
|
||||
&& !nodep->castMemberDType() // Keep member names iff upper type exists
|
||||
) {
|
||||
m_varEtcsp.push_back(nodep);
|
||||
}
|
||||
if (AstNode* subnodep = nodep->virtRefDTypep()) subnodep->user1Inc();
|
||||
@@ -206,7 +208,7 @@ private:
|
||||
AstNodeModule* nextmodp;
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
|
||||
nextmodp = modp->nextp()->castNodeModule();
|
||||
if (modp->level()>2 && modp->user1()==0) {
|
||||
if (modp->level()>2 && modp->user1()==0 && !modp->internal()) {
|
||||
// > 2 because L1 is the wrapper, L2 is the top user module
|
||||
UINFO(4," Dead module "<<modp<<endl);
|
||||
// And its children may now be killable too; correct counts
|
||||
@@ -221,7 +223,9 @@ private:
|
||||
bool mightElim(AstVar* nodep) {
|
||||
return (!nodep->isSigPublic() // Can't elim publics!
|
||||
&& !nodep->isIO()
|
||||
&& (nodep->isTemp() || nodep->isParam() || m_elimUserVars));
|
||||
&& (nodep->isTemp()
|
||||
|| (nodep->isParam() && !nodep->isTrace())
|
||||
|| m_elimUserVars)); // Post-Trace can kill most anything
|
||||
}
|
||||
void deadCheckVar() {
|
||||
// Delete any unused varscopes
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -124,10 +124,10 @@ private:
|
||||
AstVar* varp;
|
||||
AstNodeModule* addmodp = oldvarscp->scopep()->modp();
|
||||
// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
|
||||
VarMap::iterator iter = m_modVarMap.find(make_pair(addmodp,name));
|
||||
if (iter != m_modVarMap.end()) {
|
||||
VarMap::iterator it = m_modVarMap.find(make_pair(addmodp,name));
|
||||
if (it != m_modVarMap.end()) {
|
||||
// Created module's AstVar earlier under some other scope
|
||||
varp = iter->second;
|
||||
varp = it->second;
|
||||
} else {
|
||||
if (width==0) {
|
||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user