mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
132f61e900 | ||
|
|
0e9be8eea0 | ||
|
|
96f5f66c26 | ||
|
|
bbed4d50ab | ||
|
|
4b7ee8267b | ||
|
|
f6a745a4c2 | ||
|
|
a23a5505c4 | ||
|
|
21030f0a4f | ||
|
|
d21824cbae | ||
|
|
124786ad1b | ||
|
|
f81daac9c0 | ||
|
|
db8e8392fa | ||
|
|
5bc2f87d3e | ||
|
|
de35c90847 | ||
|
|
bc813fddcc | ||
|
|
13c91f5fce | ||
|
|
ac4690d74b | ||
|
|
a1a8f17617 | ||
|
|
12be852a43 | ||
|
|
440fbef79b | ||
|
|
e1c221a4d5 | ||
|
|
e1f1c82d4e | ||
|
|
3c1b82255e | ||
|
|
6bd47b54df | ||
|
|
3261a45ec1 | ||
|
|
0ac116bb4e | ||
|
|
221e4ff6fe | ||
|
|
fe80499f9c | ||
|
|
d3d1f3ab60 | ||
|
|
264b888ef2 | ||
|
|
ba270e09a4 | ||
|
|
8281ee1520 | ||
|
|
75aab4e9d2 | ||
|
|
b532a47e4a | ||
|
|
77a3d683e3 | ||
|
|
c132d0e1fe | ||
|
|
1a6348f113 | ||
|
|
89ac6ab594 | ||
|
|
3d1012b73b | ||
|
|
c98ad79e68 | ||
|
|
82460b0da3 | ||
|
|
0bdc57a14a | ||
|
|
33780a09df | ||
|
|
a9c9d5ca4b | ||
|
|
ab07dbdb9d | ||
|
|
6dd6750985 | ||
|
|
59aa0f43d5 | ||
|
|
04ca6a4307 | ||
|
|
c7cbe11ba4 | ||
|
|
4794093aba | ||
|
|
46e300b2c5 | ||
|
|
c693e52f6c | ||
|
|
4e2ec09f9a | ||
|
|
cdbae456d5 | ||
|
|
379177d2f4 | ||
|
|
fb193d6172 | ||
|
|
16234bb713 | ||
|
|
3f14e649b5 | ||
|
|
c2e8062f84 | ||
|
|
5d3fef21b0 | ||
|
|
b64e1b4a49 | ||
|
|
89f414b185 | ||
|
|
47e13cfdf4 | ||
|
|
48d3ce46d8 | ||
|
|
89c8449ec0 | ||
|
|
331fcb633e | ||
|
|
bffc2233a0 | ||
|
|
393b5d48b2 | ||
|
|
6006cdff2c | ||
|
|
d6b10465f3 | ||
|
|
b3cf5c4f5f | ||
|
|
3862f2f022 | ||
|
|
38ab22bf1d | ||
|
|
ce16f7689d | ||
|
|
b06a329466 | ||
|
|
c5b24f3850 | ||
|
|
103b956581 | ||
|
|
63361fc56e | ||
|
|
1e9e334929 | ||
|
|
f30d71b0c5 | ||
|
|
fee4aba9ec | ||
|
|
f1960273a0 | ||
|
|
778564e63b | ||
|
|
cf6a69da27 | ||
|
|
960b2ed023 | ||
|
|
74420550e6 | ||
|
|
cb5887b376 | ||
|
|
41b40157d8 | ||
|
|
b11b693c08 | ||
|
|
256eb4bba0 | ||
|
|
77804b4d38 | ||
|
|
8c9ca7a1b3 | ||
|
|
9d055f8c13 | ||
|
|
3dacd87dfb | ||
|
|
691fbb0c42 | ||
|
|
c28a6eef3b | ||
|
|
17fed3fedd | ||
|
|
1448cc56fc | ||
|
|
074689b5de | ||
|
|
8dd612a0a0 | ||
|
|
22fdbba0b5 | ||
|
|
39b787670b | ||
|
|
a221278c05 | ||
|
|
5f26b9ec66 | ||
|
|
48778d0a77 | ||
|
|
42d2cbad41 | ||
|
|
cb82c42e35 | ||
|
|
f13fb330ed | ||
|
|
d4bae48ca2 | ||
|
|
590ad964b1 | ||
|
|
d4595df8a4 | ||
|
|
7b642bcbb4 | ||
|
|
ca26596695 | ||
|
|
88cf5e5d98 | ||
|
|
13f790360d | ||
|
|
70daadf987 | ||
|
|
9d5004db1c | ||
|
|
ea82bfcced | ||
|
|
00a502942e | ||
|
|
2031bc7fc4 | ||
|
|
3adb22e971 | ||
|
|
331ea5116f | ||
|
|
1da5a33f88 | ||
|
|
6c87724af8 | ||
|
|
c7a5ff5e82 | ||
|
|
abf2fcf820 | ||
|
|
644c22b08f | ||
|
|
c54024a5e6 | ||
|
|
97093fdf81 | ||
|
|
50c4f60c68 | ||
|
|
f0fb3b78d1 | ||
|
|
9b06178f35 | ||
|
|
a01c96140b | ||
|
|
02530172e7 | ||
|
|
447d803800 | ||
|
|
6b04901c4d | ||
|
|
7fb29621c3 | ||
|
|
b032fce962 | ||
|
|
ce879122bb | ||
|
|
2fa16708b7 | ||
|
|
54bc8608e3 | ||
|
|
706a7802cc | ||
|
|
9dc01cf540 | ||
|
|
8943ad5966 | ||
|
|
deb7a1c9c0 | ||
|
|
96a5445d44 | ||
|
|
d693065afb | ||
|
|
bdeee35669 | ||
|
|
62b3deb90d | ||
|
|
9df9ff59e0 | ||
|
|
23a3271c06 | ||
|
|
f4a5aa2e94 | ||
|
|
bdd54eed1c | ||
|
|
c6a20a72f2 | ||
|
|
d7a54b3632 | ||
|
|
be6a3d0f10 | ||
|
|
e9125a3a22 | ||
|
|
c27a60658f | ||
|
|
8f2bc6e028 | ||
|
|
a6b78cbbee | ||
|
|
182a7076fd | ||
|
|
17a9b22dce | ||
|
|
f190d12802 | ||
|
|
b12dd526f9 | ||
|
|
473d555dc1 | ||
|
|
fa9208ccdd | ||
|
|
4aa088eb2f | ||
|
|
8f8147d646 | ||
|
|
e637dd2390 | ||
|
|
c90960fc88 | ||
|
|
da86a1c9f2 | ||
|
|
0adb789238 | ||
|
|
15082a178b | ||
|
|
4a0db26c36 | ||
|
|
ad3ea636d5 | ||
|
|
6a238b0514 | ||
|
|
e6d7e7e329 | ||
|
|
f942aba855 | ||
|
|
2f34132275 | ||
|
|
663b2be065 | ||
|
|
a1e4d676c3 | ||
|
|
6f28d21207 | ||
|
|
9f115e056e | ||
|
|
8352ba4af4 | ||
|
|
9b06310cbe | ||
|
|
77fe33e57f | ||
|
|
df58eb9bc7 | ||
|
|
2d0084308d | ||
|
|
7efa40966a | ||
|
|
6d644dc764 | ||
|
|
b0de0b1176 | ||
|
|
c72d473e96 | ||
|
|
c8a91bd46f | ||
|
|
498f19a6a1 | ||
|
|
c7a2138ece | ||
|
|
4078902543 | ||
|
|
9e38ed9a39 | ||
|
|
183cabc77d | ||
|
|
b582e481c6 | ||
|
|
ad39931e87 | ||
|
|
1ae22e1365 | ||
|
|
b748ddfe06 | ||
|
|
e52f5f1b63 | ||
|
|
bda4b326ab | ||
|
|
70ddf32719 | ||
|
|
3edba7b662 | ||
|
|
f74ef650ac | ||
|
|
f093c3d78b | ||
|
|
d933f33bdb | ||
|
|
813d62005d | ||
|
|
411de9bddf | ||
|
|
bd28945374 | ||
|
|
1e4c3751e1 | ||
|
|
5b6f47cd0f | ||
|
|
bec8c5bf4c | ||
|
|
15495bb200 | ||
|
|
999f278971 | ||
|
|
7ca1d35a4e | ||
|
|
2117fe414e | ||
|
|
7d8c51181d | ||
|
|
c30211cb27 | ||
|
|
901da118e5 | ||
|
|
f11757e43a | ||
|
|
3f143317a6 | ||
|
|
45d7312dfc | ||
|
|
26774eb045 | ||
|
|
6789d247e2 | ||
|
|
462bc3d707 | ||
|
|
e1755ea6a8 | ||
|
|
b4a7e4697e | ||
|
|
cd61b1d045 | ||
|
|
24dc36ba4c | ||
|
|
e8e4f1777d | ||
|
|
ae38a26af3 | ||
|
|
8ee94dd7aa | ||
|
|
e741a29d36 | ||
|
|
be1d275151 | ||
|
|
31c9e26e2e | ||
|
|
20ed1ada03 | ||
|
|
891214fa72 | ||
|
|
e819e285e2 | ||
|
|
171c175e54 | ||
|
|
675cbce8cb | ||
|
|
4f1398f773 | ||
|
|
ae89e399a3 | ||
|
|
2c9716c64c | ||
|
|
bc58245abf | ||
|
|
8c4aa8517e | ||
|
|
c0b7a54bb9 | ||
|
|
6b32bb635d | ||
|
|
691de22ae3 | ||
|
|
e64b2d3372 | ||
|
|
e190af9d87 | ||
|
|
8d14463b18 | ||
|
|
04977ef721 | ||
|
|
d84e6875c5 | ||
|
|
80678ae7bc | ||
|
|
482bdab0e0 | ||
|
|
b2623b9841 | ||
|
|
9ae40d64f0 | ||
|
|
cef097b7b7 | ||
|
|
b840334ad2 | ||
|
|
acff683e8e | ||
|
|
c5332de86d | ||
|
|
90ecf14a0a | ||
|
|
4945282369 | ||
|
|
ca532d23f0 | ||
|
|
a509b6a21c | ||
|
|
46229473cb | ||
|
|
65be2448dc | ||
|
|
be74806044 | ||
|
|
b488666c1e | ||
|
|
d1acaea611 | ||
|
|
db6e5ce7cf | ||
|
|
d56179df17 | ||
|
|
850100c9c2 | ||
|
|
0725999f0a | ||
|
|
cb2d8259f2 | ||
|
|
61a1f3d817 | ||
|
|
63f111b7f3 | ||
|
|
e061eb3003 | ||
|
|
29daa58222 | ||
|
|
340cc02171 | ||
|
|
b738d1960a | ||
|
|
38f5b780d7 | ||
|
|
fa9dac29e8 | ||
|
|
afc432042f | ||
|
|
21cb29baf0 | ||
|
|
e8b5001cfe | ||
|
|
849c1e46a2 | ||
|
|
ebad6cde36 | ||
|
|
f920b3945e | ||
|
|
178028a70a | ||
|
|
5e54d3e41a | ||
|
|
f0af8726e3 | ||
|
|
57f2fe77ea | ||
|
|
d56ca25089 | ||
|
|
d39ce17dea | ||
|
|
373a68ec8b | ||
|
|
5613758ee3 | ||
|
|
2102f86909 | ||
|
|
d5ea785de7 | ||
|
|
9edd28d2ed | ||
|
|
7698af5178 | ||
|
|
52ae451f5c | ||
|
|
9254443cd4 | ||
|
|
4e4bc7b90f | ||
|
|
c7e0f2e196 | ||
|
|
acabaab6ac | ||
|
|
b0a249f338 | ||
|
|
0cb5d5cc5a | ||
|
|
9208c87f91 | ||
|
|
0081ce4a75 | ||
|
|
7850f49963 | ||
|
|
c72ee41142 | ||
|
|
bf5dee955d | ||
|
|
3df23a148a | ||
|
|
0a1b55c296 | ||
|
|
14b8efe4bb | ||
|
|
64162efebd | ||
|
|
faf5e1de51 | ||
|
|
0d7b1a7dc7 | ||
|
|
fa63bc6b78 | ||
|
|
379bfd062f | ||
|
|
49108c23f0 | ||
|
|
4475060268 | ||
|
|
4f269e336d | ||
|
|
4464b13163 | ||
|
|
215d5f68b0 | ||
|
|
281f4e04ee | ||
|
|
17a3f9691d | ||
|
|
4fde6ee7af | ||
|
|
040b1b06d5 | ||
|
|
b16ea8b719 | ||
|
|
cc22847bc3 | ||
|
|
3702e17b2e | ||
|
|
7abc220fb3 | ||
|
|
4fc9a906f6 | ||
|
|
5de83c9805 | ||
|
|
f71d904a9b | ||
|
|
318ded4198 | ||
|
|
f1874b211f | ||
|
|
c60ffd7fd9 | ||
|
|
dc57282168 | ||
|
|
3c336e179f | ||
|
|
6bda57da5d | ||
|
|
9a16001e51 | ||
|
|
34870e899f | ||
|
|
d0653f72e2 | ||
|
|
64748b7b1d | ||
|
|
7163c8d048 | ||
|
|
d0ec991bb2 | ||
|
|
d458af4454 | ||
|
|
9e9e7c33ae | ||
|
|
ce7de5ed30 | ||
|
|
776d8edf52 | ||
|
|
5f21385e41 | ||
|
|
94fed93f54 | ||
|
|
a950e4816d | ||
|
|
c87c66efb1 | ||
|
|
5a5a0006fe | ||
|
|
60b48a6830 | ||
|
|
5e41350588 | ||
|
|
ff9f5b62ac | ||
|
|
882913f0ca | ||
|
|
2062f7e97b | ||
|
|
445c83a60d | ||
|
|
1891cfd79a | ||
|
|
06d5a7b2bf | ||
|
|
5af8a8aa4c | ||
|
|
dc6b085d8b | ||
|
|
00759f777e | ||
|
|
95ac0e61b2 | ||
|
|
6c5884853f | ||
|
|
7578ef889f | ||
|
|
da254af8d5 | ||
|
|
98123dc422 | ||
|
|
466909b3d9 | ||
|
|
0d4305192a | ||
|
|
9e61b9f696 | ||
|
|
491539ff32 | ||
|
|
4c29a13a6e | ||
|
|
b66e1bdb9e | ||
|
|
7312de6bc2 | ||
|
|
1d6bcda014 | ||
|
|
5a747bad7d | ||
|
|
9542783a7e | ||
|
|
a59639413d | ||
|
|
d5eb92a071 | ||
|
|
994cde57af | ||
|
|
238a5809bf | ||
|
|
49fa65c0dd | ||
|
|
49123f169c | ||
|
|
4dc64c387f | ||
|
|
98a63711dd | ||
|
|
cb95cf4745 | ||
|
|
acd48fa61d | ||
|
|
cb7abcbaea |
@@ -1,3 +1,5 @@
|
||||
\#*
|
||||
.#*
|
||||
*~
|
||||
*.old
|
||||
*.gz
|
||||
@@ -20,7 +22,10 @@ configure
|
||||
dddrun*
|
||||
doxygen-doc
|
||||
gdbrun*
|
||||
gmon.out
|
||||
internals.txt
|
||||
verilator.txt
|
||||
verilator_bin*
|
||||
verilator_coverage_bin*
|
||||
verilator.pc
|
||||
**/obj_dir/*
|
||||
|
||||
@@ -1,7 +1,409 @@
|
||||
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!
|
||||
The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
* Verilator 3.914 2017-10-14
|
||||
|
||||
** Added new examples/ directory with appropriate examples. This replaces the
|
||||
old test_c and test_sc directories.
|
||||
|
||||
*** Add --getenv option for simplifying Makefiles.
|
||||
|
||||
*** Add --x-initial option for specifying initial value assignment behavior.
|
||||
|
||||
*** Add --no-relative-cfuncs and related default optimization, bug1224. [John Coiner]
|
||||
|
||||
*** Add /*verilator tag*/ for XML extraction applications. [Chris Randall]
|
||||
|
||||
**** The internal test_verilated test directory is moved to be part of test_regress.
|
||||
|
||||
**** The experimental VL_THREADED setting (only, not normal mode) now requires C++11.
|
||||
|
||||
**** Fix over-aggressive inlining, bug1223. [John Coiner]
|
||||
|
||||
**** Fix Ubuntu 17.10 issues, bug1223 partial. [John Coiner]
|
||||
|
||||
**** Fix compiler warning when WIDTH warning ignored on large compare.
|
||||
|
||||
**** Fix memory leak in VerilatedVcd dumps, bug1222 partial. [Shareef Jalloq]
|
||||
|
||||
**** Fix unnecessary Vdly variables, bug1224 partial. [John Coiner]
|
||||
|
||||
**** Fix conditional slices and add related optimizations.
|
||||
|
||||
**** Fix `` expansion of `defines, bug1225, bug1227, bug1228. [Odd Magne Reitan]
|
||||
|
||||
**** Fix -E duplicating output, bug1226. [Odd Magne Reitan]
|
||||
|
||||
**** Fix float-conversion warning, bug1229. [Robert Henry]
|
||||
|
||||
**** Fix MacOS portability, bug1230, bug1231. [Jeff Bush]
|
||||
|
||||
|
||||
* Verilator 3.912 2017-09-23
|
||||
|
||||
** Verilated headers no longer "use namespace std;"
|
||||
User's code without "std::" prefixes may need "use namespace std;" to compile.
|
||||
|
||||
*** Support or/and/xor array intrinsic methods, bug1210. [Mike Popoloski]
|
||||
|
||||
*** Support package export, bug1217. [Usuario Eda]
|
||||
|
||||
*** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski]
|
||||
|
||||
**** Support module port parameters without defaults, bug 1213. [Mike Popoloski]
|
||||
|
||||
**** Add performance information to --stats file.
|
||||
|
||||
**** Simplify VL_CONST_W macro generation for faster compiles.
|
||||
|
||||
**** Fix LITENDIAN warning on arrayed cells, bug1202. [Mike Popoloski]
|
||||
|
||||
**** Fix enum ranges without colons, bug1204. [Mike Popoloski]
|
||||
|
||||
**** Fix GCC noreturn compile error, bug1209. [Mike Popoloski]
|
||||
|
||||
**** Fix constant function default parameters, bug1211. [Mike Popoloski]
|
||||
|
||||
**** Fix non-colon array of interface modports, bug1212. [Mike Popoloski]
|
||||
|
||||
**** Fix .name connections on interfaces, bug1214. [Mike Popoloski]
|
||||
|
||||
**** Fix wide array indices causing compile error.
|
||||
|
||||
**** Better optimize Shift-And, and replication constructs.
|
||||
|
||||
|
||||
* Verilator 3.910 2017-09-07
|
||||
|
||||
*** SystemPerl mode (-sp-deprecated) has been removed.
|
||||
|
||||
**** Update keyword warnings to include C++11 and others.
|
||||
|
||||
|
||||
* Verilator 3.908 2017-08-28
|
||||
|
||||
**** Support x in $readmem, bug1180. [Arthur Kahlich]
|
||||
|
||||
**** Support packed struct DPI imports, bug1190. [Rob Stoddard]
|
||||
|
||||
**** Fix GCC 6 warnings.
|
||||
|
||||
**** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson]
|
||||
|
||||
**** Fix undefined VL_POW_WWI. [Clifford Wolf]
|
||||
|
||||
**** Fix internal error on unconnected inouts, bug1187. [Rob Stoddard]
|
||||
|
||||
|
||||
* Verilator 3.906 2017-06-22
|
||||
|
||||
*** Support set_time_unit/set_time_precision in C traces, msg2261.
|
||||
|
||||
*** Fix extract of packed array with non-zero LSB, bug1172. [James Pallister]
|
||||
|
||||
*** Fix shifts by more than 32-bit numbers, bug1174. [Clifford Wolf]
|
||||
|
||||
*** Fix power operator on wide constants, bug761. [Clifford Wolf]
|
||||
|
||||
*** Fix .* on interface pins, bug1176. [Maciej Piechotka]
|
||||
|
||||
|
||||
* Verilator 3.904 2017-05-30
|
||||
|
||||
*** Fix non-cutable ordering loops on clock arrays, bug1009. [Todd Strader]
|
||||
|
||||
*** Support ports of array of reals, bug1154. [J Briquet]
|
||||
|
||||
*** Support arrayed parameter overrides, bug1153. [John Stevenson]
|
||||
|
||||
*** Support $value$plusargs with variables, bug1165. [Wesley Terpstra]
|
||||
|
||||
**** Support modport access to un-modport objects, bug1161. [Todd Strader]
|
||||
|
||||
**** Add stack trace when can't optimize function, bug1158. [Todd Strader]
|
||||
|
||||
**** Add warning on mis-sized literal, bug1156. [Todd Strader]
|
||||
|
||||
**** Fix interface functions returning wrong parameters, bug996. [Todd Strader]
|
||||
|
||||
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
|
||||
|
||||
**** Fix --assert with complex case statements, bug1164. [Enzo Chi]
|
||||
|
||||
|
||||
* Verilator 3.902 2017-04-02
|
||||
|
||||
** Add -FI option to force includes,msg2146. [Amir Gonnen]
|
||||
|
||||
** Add --relative-includes. [Rob Stoddard]
|
||||
|
||||
*** Add error on duplicate pattern assignments, bug1145. [Johan Bjork]
|
||||
|
||||
**** Fix error on improperly widthed default function, bug984. [Todd Strader]
|
||||
|
||||
**** Fix 2009 localparam syntax, msg2139. [Galen Seitz]
|
||||
|
||||
**** Fix ugly interface-to-non-interface errors, bug1112. [Johan Bjork]
|
||||
|
||||
**** Fix LDFLAGS and CFLAGS not preserving order, bug1130. [Olof Kindgren]
|
||||
|
||||
**** Fix internal error on initializing parameter array, bug1131. [Jie Xu]
|
||||
|
||||
**** Fix internal error on interface arrays, bug1135. [John Stevenson]
|
||||
|
||||
**** Fix calling sformatf to display, and elab $displays, bug1139. [Johan Bjork]
|
||||
|
||||
**** Fix realpath compile issue on MSVC++, bug1141. [Miodrag Milanovic]
|
||||
|
||||
**** Fix missing error on interface size mismatch, bug1143. [Johan Bjork]
|
||||
|
||||
**** Fix error on parameters with dotted references, bug1146. [Johan Bjork]
|
||||
|
||||
**** Fix wreal not handling continuous assign, bug1150. [J Briquet]
|
||||
|
||||
**** Fix nested structure parameter selects, bug1150. [J Briquet]
|
||||
|
||||
|
||||
* Verilator 3.900 2017-01-15
|
||||
|
||||
** Internal code changes for improved compatibility and performance.
|
||||
|
||||
*** Support old-style $display($time), bug467. [John Demme]
|
||||
|
||||
**** With --bbox-unsup, suppress desassign and mixed edges, bug1120. [Galen Seitz]
|
||||
|
||||
**** Fix parsing sensitivity with &&, bug934. [Luke Yang]
|
||||
|
||||
**** Fix internal error on double-for loop unrolling, bug1044. [Jan Egil Ruud]
|
||||
|
||||
**** Fix internal error on unique casez with --assert, bug1117. [Enzo Chi]
|
||||
|
||||
**** Fix bad code when tracing array of structs, bug1122. [Andrew Bardsley]
|
||||
|
||||
|
||||
* Verilator 3.890 2016-11-25
|
||||
|
||||
*** Honor --output-split on coverage constructors, bug1098. [Johan Bjork]
|
||||
|
||||
**** Fix various issues when making outside of the kit.
|
||||
|
||||
**** Fix flex 2.6.2 bug, bug1103. [Sergey Kvachonok]
|
||||
|
||||
**** Fix error on bad interface name, bug1097. [Todd Strader]
|
||||
|
||||
**** Fix error on referencing variable in parent, bug1099. [Ian Thompson]
|
||||
|
||||
**** Fix type parameters with low optimization, bug1101. [Stefan Wallentowitz]
|
||||
|
||||
|
||||
* Verilator 3.888 2016-10-14
|
||||
|
||||
** Support foreach, bug1078. [Xuan Guo]
|
||||
|
||||
*** Add --no-decoration to remove output comments, msg2015. [Frederic Requin]
|
||||
|
||||
*** If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin]
|
||||
Set VM_DEFAULT_RULES=0 for old behavior.
|
||||
|
||||
**** Add error on DPI functions > 32 bits, msg1995. [Elliot Mednick]
|
||||
|
||||
**** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich]
|
||||
|
||||
**** Fix error on wide numbers that represent shifts, msg1991, bug1088. [Mandy Xu]
|
||||
|
||||
**** Improve Verilation performance on internal strings, msg1975. [Johan Bjork]
|
||||
|
||||
**** Improve Verilation performance on trace duplicates, bug1090. [Johan Bjork]
|
||||
|
||||
|
||||
* Verilator 3.886 2016-07-30
|
||||
|
||||
**** Fix enum values of 11-16 bits wide using .next/.prev, bug1062. [Brian Flachs]
|
||||
|
||||
**** Fix false warnings on non-power-2 enums using .next/.prev.
|
||||
|
||||
**** Fix comparison of unpacked arrays, bug1071. [Andrew Bardsley]
|
||||
|
||||
**** Fix compiler warning in GCC 6. [David Horton]
|
||||
|
||||
|
||||
* Verilator 3.884 2016-05-18
|
||||
|
||||
** Support parameter type, bug376. [Alan Hunter, et al]
|
||||
|
||||
** Support command-line -G/+pvalue param overrides, bug1045. [Stefan Wallentowitz]
|
||||
|
||||
*** The default l2 scope name is now the same as the top-level module, bug1050.
|
||||
Use "--l2-name v" for the historical behavior.
|
||||
|
||||
*** Add --l2-name option for controlling "v" naming.
|
||||
|
||||
**** Fix --output-split of constructors, bug1035. [Johan Bjork]
|
||||
|
||||
**** Fix removal of empty packages, modules and cells, bug1034. [Johan Bjork]
|
||||
|
||||
**** Fix core dump on Arch Linux/GCC 6.1.1, bug1058. [Jannis Harder]
|
||||
|
||||
**** Fix $value$plusargs to string, msg1890. [Frederic Requin]
|
||||
|
||||
|
||||
* Verilator 3.882 2016-03-01
|
||||
|
||||
**** Internal Verilation-time performance enhancements, bug1021. [Johan Bjork]
|
||||
|
||||
**** Support inlining interfaces, bug1018. [Johan Bjork]
|
||||
|
||||
**** Support SV strings to readmemh, bug1040. [Stefan Wallentowitz]
|
||||
|
||||
**** Fix unrolling complicated for-loop bounds, bug677. [Johan Bjork]
|
||||
|
||||
**** Fix stats file containing multiple unroll entries, bug1020. [Johan Bjork]
|
||||
|
||||
**** Fix using short parameter names on negative params, bug1022. [Duraid Madina]
|
||||
|
||||
**** Fix read-after-free error, bug1031. [Johan Bjork]
|
||||
|
||||
**** Fix elaboration-time display warnings, bug1032. [Johan Bjork]
|
||||
|
||||
**** Fix crash on very deep function trees, bug1028. [Jonathan Kimmitt]
|
||||
|
||||
**** Fix slicing mix of big and little-endian, bug1033. [Geoff Barrett]
|
||||
|
||||
**** Fix pattern assignment width propagation, bug1037. [Johan Bjork]
|
||||
|
||||
|
||||
* Verilator 3.880 2015-12-19
|
||||
|
||||
*** Support display %u, %v, %p, %z, bug989. [Johan Bjork]
|
||||
|
||||
**** Fix real parameters causing bad module names, bug992. [Johan Bjork]
|
||||
|
||||
**** Fix size-changing cast on packed struct, bug993. [Johan Bjork]
|
||||
|
||||
**** Fix function calls on arrayed interface, bug994. [Johan Bjork]
|
||||
|
||||
**** Fix arrayed interfaces, bug879, bug1001. [Todd Strader]
|
||||
|
||||
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
|
||||
|
||||
**** Fix interface inside generate, bug998. [Johan Bjork]
|
||||
|
||||
**** Fix $signed casts under generates, bug999. [Clifford Wolf]
|
||||
|
||||
**** Fix genvar constant propagation, bug1003. [Johan Bjork]
|
||||
|
||||
**** Fix parameter constant propagation from package, bug1004. [Johan Bjork]
|
||||
|
||||
**** Fix array slicing of non-const indexes, bug1006. [Johan Bjork]
|
||||
|
||||
**** Fix dotted generated array error, bug1005. [Jeff Bush, Johan Bjork]
|
||||
|
||||
**** Fix error instead of warning on large concat, msg1768. [Paul Rolfe]
|
||||
|
||||
**** Fix $bitstoreal constant propagation, bug1012. [Jonathan Kimmitt]
|
||||
|
||||
**** Fix model restore crash, bug1013. [Jason McMullan]
|
||||
|
||||
**** Fix arrayed instances to unpacked of same size, bug1015. [Varun Koyyalagunta]
|
||||
|
||||
**** Fix slices of unpacked arrays with non-zero LSBs.
|
||||
|
||||
**** Fix ternary operation with unpacked array, bug1017. [Varun Koyyalagunta].
|
||||
|
||||
|
||||
* Verilator 3.878 2015-11-01
|
||||
|
||||
** Add --vpi flag, and fix VPI linkage, bug969. [Arthur Kahlich]
|
||||
|
||||
** Support genvar indexes into arrayed cells, bug517. [Todd Strader]
|
||||
|
||||
** Support $sformatf, bug977. [Johan Bjork]
|
||||
|
||||
*** Support elaboration assertions, bug973. [Johan Bjork]
|
||||
|
||||
*** Support $display with non-format arguments, bug467. [Jamey Hicks]
|
||||
|
||||
**** Add VerilatedScopeNameMap for introspection, bug966. [Todd Strader]
|
||||
|
||||
**** Ignore %l in $display, bug983. [Todd Strader]
|
||||
|
||||
**** Fix very long module names, bug937. [Todd Strader]
|
||||
|
||||
**** Fix internal error on dotted refs into generates, bug958. [Jie Xu]
|
||||
|
||||
**** Fix structure parameter constant propagation, bug968. [Todd Strader]
|
||||
|
||||
**** Fix enum constant propagation, bug970. [Todd Strader]
|
||||
|
||||
**** Fix mis-optimizing public DPI functions, bug963. [Wei Song]
|
||||
|
||||
**** Fix package:scope.scope variable references.
|
||||
|
||||
**** Fix $fwrite to constant stderr/stdout, bug961. [Wei Song]
|
||||
|
||||
**** Fix struct.enum.name method calls, bug855. [Jonathon Donaldson]
|
||||
|
||||
**** Fix dot indexing into arrayed inferfaces, bug978. [Johan Bjork]
|
||||
|
||||
**** Fix crash in commandArgsPlusMatch, bug987. [Jamie Iles]
|
||||
|
||||
**** Fix error message on missing interface, bug985. [Todd Strader]
|
||||
|
||||
|
||||
* Verilator 3.876 2015-08-12
|
||||
|
||||
*** Add tracing_on, etc to vlt files, bug932. [Frederic Requin]
|
||||
|
||||
**** Support extraction of enum bits, bug951. [Jonathon Donaldson]
|
||||
|
||||
**** Fix MinGW compiler error, bug927, bug929. [Hans Tichelaar]
|
||||
|
||||
**** Fix .c files to be treated as .cpp, bug930. [Jonathon Donaldson]
|
||||
|
||||
**** Fix string-to-int space conversion, bug931. [Fabrizio Ferrandi]
|
||||
|
||||
**** Fix dpi imports inside generates. [Michael Tresidder]
|
||||
|
||||
**** Fix rounding in trace $timescale, bug946. [Frederic Requin]
|
||||
|
||||
**** Fix $fopen with SV string, bug947. [Sven Stucki]
|
||||
|
||||
**** Fix hashed error with typedef inside block, bug948. [Sven Stucki]
|
||||
|
||||
**** Fix makefile with --coverage, bug953. [Eivind Liland]
|
||||
|
||||
**** Fix coverage documentation, bug954. [Thomas J Whatson]
|
||||
|
||||
**** Fix parameters with function parameter arguments, bug952. [Jie Xu]
|
||||
|
||||
**** Fix size casts as second argument of cast item, bug950. [Jonathon Donaldson]
|
||||
|
||||
|
||||
* Verilator 3.874 2015-06-06
|
||||
|
||||
*** Add pkg-config .pc file, bug919. [Stefan Wallentowitz]
|
||||
|
||||
**** Fix installing missing manpages, bug908. [Ahmed El-Mahmoudy]
|
||||
|
||||
**** Fix sign extension in large localparams, bug910. [Mike Thyer]
|
||||
|
||||
**** Fix core dump in sync-async warnings, bug911. [Sebastian Dressler]
|
||||
|
||||
**** Fix truncation warning with -pins-bv, bug912. [Alfonso Martinez]
|
||||
|
||||
**** Fix Cygwin uint32 compile, bug914. [Matthew Barr]
|
||||
|
||||
**** Fix preprocessing stringified newline escapes, bug915. [Anton Rapp]
|
||||
|
||||
**** Fix part-select in constant function, bug916. [Andrew Bardsley]
|
||||
|
||||
**** Fix width extension on mis-width ports, bug918. [Patrick Maupin]
|
||||
|
||||
**** Fix width propagation on sized casts, bug925. [Jonathon Donaldson]
|
||||
|
||||
**** Fix MSVC++ compiler error, bug927. [Hans Tichelaar]
|
||||
|
||||
|
||||
* Verilator 3.872 2015-04-05
|
||||
|
||||
@@ -2547,12 +2949,12 @@ of input ports exists for tracing.
|
||||
|
||||
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
||||
|
||||
Copyright 2001-2015 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2001-2017 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.
|
||||
|
||||
Local variables:
|
||||
mode: outline
|
||||
paragraph-separate: "[ \f\n]*$"
|
||||
paragraph-separate: "[ \f\n]*$"
|
||||
end:
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
.*\.tex
|
||||
.*\.key
|
||||
.*\.vcd
|
||||
.*\.1
|
||||
/obj_dir/
|
||||
/obj_dbg/
|
||||
/obj_opt/
|
||||
@@ -19,6 +20,8 @@
|
||||
/cov_work/
|
||||
/logs/
|
||||
^Makefile$
|
||||
bin/verilator_bin.*
|
||||
bin/verilator_coverage_bin.*
|
||||
src/Makefile$
|
||||
src/Makefile_obj$
|
||||
include/verilated.mk$
|
||||
@@ -27,6 +30,7 @@ config.cache$
|
||||
config.status$
|
||||
verilator.log
|
||||
verilator.tex
|
||||
verilator.pc$
|
||||
verilator_bin.*
|
||||
verilator_coverage_bin.*
|
||||
.vcsmx_rebuild$
|
||||
@@ -37,5 +41,6 @@ nodist/
|
||||
/vc_hdrs.h$
|
||||
/csrc/
|
||||
doxygen-doc/.*
|
||||
obj_dir/.*
|
||||
TAGS
|
||||
.*~
|
||||
|
||||
+77
-57
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2017 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.
|
||||
@@ -42,9 +42,6 @@
|
||||
# reconstructed with this Makefile. This typically includes
|
||||
# everything deleted by distclean, plus more: C source files
|
||||
# produced by Bison, tags tables, info files, and so on.
|
||||
#
|
||||
# make extraclean
|
||||
# Still more severe - delete backup and autosave files, too.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
@@ -71,7 +68,7 @@ exec_prefix = @exec_prefix@
|
||||
# Directory in which to install scripts.
|
||||
bindir = @bindir@
|
||||
|
||||
# Directory in which to install scripts.
|
||||
# Directory in which to install manpages.
|
||||
mandir = @mandir@
|
||||
|
||||
# Directory in which to install library files.
|
||||
@@ -84,6 +81,10 @@ infodir = @infodir@
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
# Directory in which to install pkgconfig file
|
||||
# Generall ${prefix}/share/pkgconfig
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
|
||||
# Directory in which to install data across multiple architectures
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
@@ -96,13 +97,17 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
#### End of system configuration section. ####
|
||||
######################################################################
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
SUBDIRS = src test_verilated test_c test_sc test_regress
|
||||
SUBDIRS = src test_regress \
|
||||
examples/hello_world_c examples/hello_world_sc \
|
||||
examples/tracing_c examples/tracing_sc \
|
||||
|
||||
INFOS = README README.html README.pdf internals.txt internals.html \
|
||||
internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf \
|
||||
verilator_coverage.1
|
||||
internals.pdf verilator.txt verilator.html verilator.pdf \
|
||||
$(VL_INST_MAN_FILES)
|
||||
|
||||
# Files that can be generated, but should be up to date for a distribution.
|
||||
DISTDEP = info Makefile
|
||||
@@ -111,7 +116,11 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
*.in *.ac \
|
||||
Changes TODO \
|
||||
MANIFEST.SKIP \
|
||||
bin/* \
|
||||
bin/verilator \
|
||||
bin/verilator_coverage \
|
||||
bin/verilator_difftree \
|
||||
bin/verilator_includer \
|
||||
bin/verilator_profcfunc \
|
||||
doxygen-mainpage doxygen.config veripool-logo.png \
|
||||
install-sh configure mkinstalldirs *.pod \
|
||||
include/*.[chv]* \
|
||||
@@ -124,11 +133,14 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
src/vlcovgen \
|
||||
src/.gdbinit \
|
||||
src/*.pl src/*.pod \
|
||||
examples/*/.*ignore examples/*/Makefile* \
|
||||
examples/*/*.[chv]* examples/*/*.pl \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||
test_verilated/vgen*.pl \
|
||||
test_regress/t/t*/*.sv* \
|
||||
test_regress/t/t*/*.v* \
|
||||
test_regress/t/t*/*/*.sv* \
|
||||
test_regress/t/t*/*/*.v* \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
@@ -148,9 +160,9 @@ INST_PROJ_FILES = \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
INST_PROJ_BIN_FILES = \
|
||||
verilator_bin \
|
||||
verilator_bin_dbg \
|
||||
verilator_coverage_bin_dbg \
|
||||
bin/verilator_bin \
|
||||
bin/verilator_bin_dbg \
|
||||
bin/verilator_coverage_bin_dbg \
|
||||
|
||||
DISTFILES := $(DISTFILES_INC)
|
||||
|
||||
@@ -177,40 +189,37 @@ verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg:
|
||||
msg_test: all_nomsg
|
||||
@echo "Build complete!"
|
||||
@echo
|
||||
@echo "Type 'make test' to test."
|
||||
@echo "Now type 'make test' to test."
|
||||
@echo
|
||||
|
||||
.PHONY:test
|
||||
.PHONY: test
|
||||
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
|
||||
test: test_c test_sc test_verilated test_regress
|
||||
test: smoke-test examples test_regress
|
||||
else
|
||||
test: test_c test_sc
|
||||
test: smoke-test examples
|
||||
endif
|
||||
@echo "Tests passed!"
|
||||
@echo
|
||||
@echo "Type 'make install' to install documentation."
|
||||
@echo "Now type 'make install' to install."
|
||||
@echo "Or type 'make' inside an examples subdirectory."
|
||||
@echo
|
||||
|
||||
test_c: all_nomsg
|
||||
@(cd test_c && $(MAKE))
|
||||
test_c_debug: all_nomsg
|
||||
@(cd test_c && $(MAKE) test_debug)
|
||||
test_sc: all_nomsg
|
||||
@(cd test_sc && $(MAKE))
|
||||
test_sc_debug: all_nomsg
|
||||
@(cd test_sc && $(MAKE) test_debug)
|
||||
test_verilated: all_nomsg
|
||||
@(cd test_verilated && $(MAKE))
|
||||
smoke-test: all_nomsg
|
||||
test_regress/t/t_a_first_cc.pl
|
||||
test_regress/t/t_a_first_sc.pl
|
||||
|
||||
test_regress: all_nomsg
|
||||
@(cd test_regress && $(MAKE))
|
||||
|
||||
examples: all_nomsg
|
||||
for p in examples/* ; do \
|
||||
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` ; \
|
||||
done
|
||||
|
||||
info: $(INFOS)
|
||||
|
||||
# Use --no-split to avoid creating filenames > 14 chars.
|
||||
verilator.1: ${srcdir}/bin/verilator
|
||||
pod2man $< $@
|
||||
|
||||
verilator_coverage.1: ${srcdir}/bin/verilator_coverage
|
||||
%.1: ${srcdir}/bin/%
|
||||
pod2man $< $@
|
||||
|
||||
verilator.txt: ${srcdir}/bin/verilator
|
||||
@@ -267,9 +276,10 @@ VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage
|
||||
# so they can be found by the user, and under $VERILATOR_ROOT.
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1
|
||||
|
||||
VL_INST_INC_BLDDIR_FILES = \
|
||||
include/verilated_config.h \
|
||||
include/verilated.mk \
|
||||
|
||||
# Files under srcdir, instead of build time
|
||||
@@ -278,18 +288,16 @@ VL_INST_INC_SRCDIR_FILES = \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
VL_INST_DATA_SRCDIR_FILES = \
|
||||
test_v/*.[chv]* \
|
||||
test_c/*.[chv]* test_c/Makefile test_c/Makefile_obj \
|
||||
test_sc/*.[chv]* test_sc/Makefile test_sc/Makefile_obj \
|
||||
examples/*/*.[chv]* examples/*/Makefile* \
|
||||
|
||||
installbin:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
|
||||
( $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
|
||||
( $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
|
||||
( $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg )
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
|
||||
|
||||
@@ -297,7 +305,8 @@ installbin:
|
||||
# So important we use $< so VPATH is searched
|
||||
installman: $(VL_INST_MAN_FILES)
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||
for p in $< ; do \
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
@@ -310,13 +319,16 @@ installdata:
|
||||
; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
done
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_c
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_sc
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_v
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/tracing_c
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/examples/$$p; \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
done
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgconfigdir)
|
||||
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
|
||||
uninstall:
|
||||
@@ -325,16 +337,18 @@ uninstall:
|
||||
-cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/examples && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
||||
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/bin
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_c
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_sc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_sp
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_v
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_c
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)
|
||||
-rmdir $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
install: all_nomsg install-all
|
||||
install-all: installbin installman installdata install-msg
|
||||
@@ -350,8 +364,8 @@ INST_PROJ_CVS = cp_if_cvs_diff
|
||||
|
||||
install-project: dist
|
||||
@echo "Install-project to $(DIRPROJECT)"
|
||||
strip verilator_bin*
|
||||
strip verilator_coverage_bin*
|
||||
strip bin/verilator_bin*
|
||||
strip bin/verilator_coverage_bin*
|
||||
$(MAKE) install-project-quick
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
||||
@@ -374,8 +388,8 @@ endif
|
||||
|
||||
install-cadtools: dist
|
||||
@echo "Install-project to $(CAD_DIR)"
|
||||
strip verilator_bin*
|
||||
strip verilator_coverage_bin*
|
||||
strip bin/verilator_bin*
|
||||
strip bin/verilator_coverage_bin*
|
||||
$(MAKE) install-cadtools-quick
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
@@ -413,14 +427,17 @@ CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||
|
||||
cppcheck: $(CPPCHECK_DEP)
|
||||
%.cppcheck: %.cpp
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 $(CPPCHECK_INC) $<
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $<
|
||||
|
||||
ftp: info
|
||||
|
||||
install-msg:
|
||||
@echo "Installed!"
|
||||
@echo
|
||||
@echo "Fod documentation see 'man verilator' or 'verilator --help'"
|
||||
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
|
||||
@echo "Installed man to $(DESTDIR)$(mandir)/man1"
|
||||
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
|
||||
@echo
|
||||
@echo "For documentation see 'man verilator' or 'verilator --help'"
|
||||
@echo "For forums and to report bugs see http://www.veripool.org/verilator"
|
||||
@echo
|
||||
|
||||
@@ -446,7 +463,7 @@ endif
|
||||
maintainer-clean::
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "rebuilding the deleted files requires makeinfo."
|
||||
rm -f *.info* $(INFOS) configure
|
||||
rm -f *.info* *.1 $(INFOS) configure
|
||||
|
||||
clean mostlyclean distclean maintainer-clean maintainer-copy::
|
||||
for dir in $(SUBDIRS); do \
|
||||
@@ -460,10 +477,13 @@ clean mostlyclean distclean maintainer-clean::
|
||||
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
||||
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
||||
rm -f *.tex
|
||||
rm -rf test_*/obj_dir
|
||||
rm -rf examples/*/obj_dir examples/*/logs
|
||||
|
||||
distclean maintainer-clean::
|
||||
rm -f Makefile config.status config.cache config.log TAGS
|
||||
rm -f verilator_bin* verilator_coverage_bin*
|
||||
rm -f bin/verilator_bin* bin/verilator_coverage_bin*
|
||||
rm -f include/verilated.mk include/verilated_config.h
|
||||
|
||||
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
|
||||
|
||||
+11
-7
@@ -11,7 +11,7 @@ This is the Verilator package README file.
|
||||
|
||||
http://www.veripool.org/verilator
|
||||
|
||||
This package is Copyright 2003-2015 by Wilson Snyder. (Report bugs to
|
||||
This package is Copyright 2003-2017 by Wilson Snyder. (Report bugs to
|
||||
L<http://www.veripool.org/>.)
|
||||
|
||||
Verilator is free software; you can redistribute it and/or modify it under
|
||||
@@ -51,7 +51,7 @@ output (not Verilator itself) compiles under MSVC++ 2008 and newer.
|
||||
|
||||
=head1 INSTALLATION
|
||||
|
||||
For more details see
|
||||
For more details see
|
||||
L<http://www.veripool.org/projects/verilator/wiki/Installing>.
|
||||
|
||||
If you will be modifying Verilator, you should use the "git" method as it
|
||||
@@ -117,9 +117,10 @@ and add it to path using Modules/modulecmd:
|
||||
After installing you'll want a module file like the following:
|
||||
|
||||
set install_root /CAD_DISK/verilator/{version-number-used-above}
|
||||
setenv VERILATOR_ROOT $install_root
|
||||
unsetenv VERILATOR_ROOT
|
||||
prepend-path PATH $install_root/bin
|
||||
prepend-path MANPATH $install_root/man
|
||||
prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
|
||||
|
||||
=item 3.
|
||||
|
||||
@@ -168,6 +169,9 @@ have the verilator binary directory in your PATH (this should already be
|
||||
true if using the default configure), and make sure VERILATOR_ROOT is not
|
||||
set.
|
||||
|
||||
You may now wish to consult the examples directory. Type C<make> inside any
|
||||
example directory to run the example.
|
||||
|
||||
=back
|
||||
|
||||
=head1 USAGE DOCUMENTATION
|
||||
@@ -189,10 +193,10 @@ The directories in the kit after de-taring are as follows:
|
||||
include/verilated.v => Stub defines for linting
|
||||
include/verilated.mk => Common makefile
|
||||
src/ => Translator source code
|
||||
test_v => Example Verilog code for other test dirs
|
||||
test_c => Example Verilog->C++ conversion
|
||||
test_sc => Example Verilog->SystemC conversion
|
||||
test_verilated => Internal tests
|
||||
examples/hello_world_c => Example simple Verilog->C++ conversion
|
||||
examples/hello_world_sc => Example simple Verilog->SystemC conversion
|
||||
examples/tracing_c => Example Verilog->C++ with tracing
|
||||
examples/tracing_sc => Example Verilog->SystemC with tracing
|
||||
test_regress => Internal tests
|
||||
|
||||
=head1 LIMITATIONS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// DESCRIPTION: Verilator: List of To Do issues.
|
||||
//
|
||||
// Copyright 2004-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2017 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,7 +41,7 @@ Testing:
|
||||
* // verilator debug in code so can see only tree affecting those nodes
|
||||
|
||||
Usability:
|
||||
* Detect and pre-remove most UNOPTFLATs (4.000)
|
||||
* Detect and pre-remove most UNOPTFLATs (4.000)
|
||||
* Better reporting of unopt problems, including what lines of code
|
||||
* Report more errors (all of them?) before exiting [Eugene Weber]
|
||||
* Auto-create scons config files
|
||||
|
||||
+513
-258
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2015 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2017 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.
|
||||
@@ -271,7 +271,7 @@ Specifies a module search directory.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2003-2017 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.
|
||||
|
||||
@@ -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-2015 by Wilson Snyder. This package is free software; you can
|
||||
Copyright 2005-2017 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-2015 by Wilson Snyder. This package is free software; you can
|
||||
# Copyright 2003-2017 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.
|
||||
######################################################################
|
||||
@@ -13,8 +13,8 @@ use warnings;
|
||||
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
|
||||
foreach my $param (@ARGV) {
|
||||
if ($param =~ /^-D([^=]+)=(.*)/) {
|
||||
print "#define $1 $2\n"
|
||||
print "#define $1 $2\n"
|
||||
} else {
|
||||
print "#include \"$param\"\n"
|
||||
print "#include \"$param\"\n"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ Displays this message and program version and exits.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2007-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2007-2017 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.
|
||||
|
||||
|
||||
+111
-34
@@ -1,19 +1,22 @@
|
||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
# Copyright 2003-2017 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],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.872 2015-04-05])
|
||||
AC_INIT([Verilator],[3.914 2017-10-14])
|
||||
# When releasing, also update header of Changes file
|
||||
# and commit using "devel release" or "Version bump" message
|
||||
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
|
||||
|
||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
|
||||
# Special Substitutions - CFG_WITH_DEFENV
|
||||
AC_MSG_CHECKING(whether to disable hardcoded paths)
|
||||
AC_MSG_CHECKING(whether to use hardcoded paths)
|
||||
AC_ARG_ENABLE([defenv],
|
||||
[AS_HELP_STRING([--disable-defenv],
|
||||
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
|
||||
@@ -40,7 +43,7 @@ AC_ARG_ENABLE([ccwarn],
|
||||
x) CFG_WITH_CCWARN=no ;;
|
||||
*) CFG_WITH_CCWARN=yes ;;
|
||||
esac]
|
||||
)
|
||||
)
|
||||
AC_SUBST(CFG_WITH_CCWARN)
|
||||
AC_MSG_RESULT($CFG_WITH_CCWARN)
|
||||
|
||||
@@ -58,7 +61,7 @@ AC_ARG_ENABLE([longtests],
|
||||
x) CFG_WITH_LONGTESTS=no ;;
|
||||
*) CFG_WITH_LONGTESTS=yes ;;
|
||||
esac]
|
||||
)
|
||||
)
|
||||
AC_SUBST(CFG_WITH_LONGTESTS)
|
||||
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
||||
|
||||
@@ -76,10 +79,10 @@ AC_PROG_INSTALL
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_MSG_CHECKING([that C++ compiler can compile simple program])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([int main() { return 0; }])],
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
|
||||
AC_MSG_RESULT(yes))
|
||||
[AC_LANG_SOURCE([int main() { return 0; }])],
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
|
||||
AC_MSG_RESULT(yes))
|
||||
|
||||
AC_PATH_PROG(PERL,perl)
|
||||
if test "x$PERL" = "x" ; then
|
||||
@@ -103,64 +106,138 @@ AC_TYPE_SIZE_T
|
||||
# Checks for compiler characteristics.
|
||||
AC_C_INLINE
|
||||
|
||||
AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([], [[int* a=new int; delete a; ]])],
|
||||
[], [AC_MSG_ERROR([$CXX does not seem to successfully compile a simple C++ program])])
|
||||
|
||||
AC_DEFUN([_MY_CXX_CHECK_FLAG],
|
||||
[# _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options
|
||||
# Set $_my_result appropriately
|
||||
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
# -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
|
||||
CXXFLAGS="$CXXFLAGS $2 -Werror"
|
||||
AC_MSG_CHECKING([whether $CXX accepts $2])
|
||||
# new/delete is needed to find -faligned-new link problem on Darwin
|
||||
CXXFLAGS="$CXXFLAGS $1 -Werror"
|
||||
AC_MSG_CHECKING([whether $CXX accepts $1])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([], [[int* a=new int; delete a; ]])],
|
||||
[_my_result=yes
|
||||
if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
# GCC is annoying, trying to be helpful, it postpones unknown -Wno-
|
||||
# options if there's no error We want to see them regardless, so try
|
||||
# forcing an error and see if we get a gcc warning
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([],[])],
|
||||
[_my_result=yes
|
||||
if test -s conftest.err; then
|
||||
if grep -e "$2" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
[AC_LANG_PROGRAM([[an_error "intentional-error-for-test.h"
|
||||
]],[])],
|
||||
[], # Ignore ok exit
|
||||
[if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_CXX_CHECK_SET],
|
||||
[# _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options
|
||||
# If it does, set variable to flag, only if not previously set
|
||||
if test "$$1" = ""; then
|
||||
_MY_CXX_CHECK_FLAG($2)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$2"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
|
||||
# If it does, append flag to variable
|
||||
_MY_CXX_CHECK_FLAG($2)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$$1 $2"
|
||||
fi
|
||||
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||
])# _MY_CXX_CHECK_OPT
|
||||
])
|
||||
|
||||
# Flags for compiling Verilator internals including parser
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-char-subscripts)
|
||||
# Flag to select newest language standard supported
|
||||
# Macros work such that first option that passes is the one we take
|
||||
# gnu++14 is the newest that Verilator supports
|
||||
# std++03 is the oldest that Verilator supports
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++03)
|
||||
AC_SUBST(CFG_CXXFLAGS_STD_NEWEST)
|
||||
# And likewise oldest standard (same list above, backwards)
|
||||
# This is used for internal testing
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++17)
|
||||
AC_SUBST(CFG_CXXFLAGS_STD_OLDEST)
|
||||
|
||||
# Flags for compiling Verilator internals including parser, and Verilated files
|
||||
# These turn on extra warnings and are only used with 'configure --enable-ccwarn'
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wextra)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wfloat-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wlogical-op)
|
||||
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
|
||||
|
||||
# Flags for compiling Verilator internals including parser always
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)
|
||||
AC_SUBST(CFG_CXXFLAGS_SRC)
|
||||
|
||||
# Flags for compiling Verilator parser
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
|
||||
# Flags for compiling Verilator parser always (in addition to above CFG_CXXFLAGS_SRC)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-char-subscripts)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
|
||||
AC_SUBST(CFG_CXXFLAGS_PARSER)
|
||||
|
||||
# Flags for Verilated makefile
|
||||
# For example, -Wno-div-by-zero isn't in 4.1.2
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-char-subscripts)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
||||
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
|
||||
# without this flag, even though there's a conditional to prevent the divide.
|
||||
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
||||
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
|
||||
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],
|
||||
[AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])],
|
||||
[], [#include <sys/stat.h>])
|
||||
|
||||
# Checks for system services
|
||||
|
||||
# Other install directories
|
||||
pkgdatadir=${datadir}/verilator
|
||||
AC_SUBST(pkgdatadir)
|
||||
pkgconfigdir=${datadir}/pkgconfig
|
||||
AC_SUBST(pkgconfigdir)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
+1
-2
@@ -635,8 +635,7 @@ INPUT = doxygen-mainpage \
|
||||
test_c \
|
||||
test_regress \
|
||||
test_sc \
|
||||
test_v \
|
||||
test_verilated
|
||||
test_v
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
project
|
||||
logs
|
||||
@@ -0,0 +1,52 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2017 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.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
|
||||
# This is intended to be a minimal example. Before copying this to start a
|
||||
# real project, it is better to start with a more complete example,
|
||||
# e.g. examples/tracing_c.
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
endif
|
||||
|
||||
default:
|
||||
@echo "-- Verilator hello-world simple example"
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) -cc --exe top.v sim_main.cpp
|
||||
@echo "-- COMPILE -----------------"
|
||||
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
@echo "-- RUN ---------------------"
|
||||
obj_dir/Vtop
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/tracing_c."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
|
||||
######################################################################
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir *.log *.dmp *.vpd core
|
||||
@@ -0,0 +1,41 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
// See a similar example walkthrough in the verilator manpage.
|
||||
|
||||
// This is intended to be a minimal example. Before copying this to start a
|
||||
// real project, it is better to start with a more complete example,
|
||||
// e.g. examples/c_tracing.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv && env) {}
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop;
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
|
||||
// Evaluate model
|
||||
top->eval();
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Destroy model
|
||||
delete top;
|
||||
|
||||
// Fin
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
module top;
|
||||
initial begin
|
||||
$display("Hello World!");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -1,8 +1,6 @@
|
||||
*.old
|
||||
*.dmp
|
||||
*.log
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
logs
|
||||
project
|
||||
@@ -0,0 +1,67 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2017 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.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
|
||||
# This is intended to be a minimal example. Before copying this to start a
|
||||
# real project, it is better to start with a more complete example,
|
||||
# e.g. examples/tracing_sc.
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
endif
|
||||
|
||||
# Check if SC exists via a verilator call (empty if not)
|
||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
|
||||
|
||||
ifneq ($(SYSTEMC_EXISTS),)
|
||||
default: run
|
||||
else
|
||||
default: nosc
|
||||
endif
|
||||
|
||||
run:
|
||||
@echo "-- Verilator hello-world simple example"
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) -sc --exe top.v sc_main.cpp
|
||||
@echo "-- COMPILE -----------------"
|
||||
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
@echo "-- RUN ---------------------"
|
||||
obj_dir/Vtop
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/tracing_sc."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
|
||||
######################################################################
|
||||
|
||||
nosc:
|
||||
@echo
|
||||
@echo "%Skip: SYSTEMC_INCLUDE not in environment"
|
||||
@echo "(If you have SystemC see the README, and rebuild Verilator)"
|
||||
@echo
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir *.log *.dmp *.vpd core
|
||||
@@ -0,0 +1,51 @@
|
||||
// -*- SystemC -*-
|
||||
// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// SystemC global header
|
||||
#include <systemc.h>
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
// See a similar example walkthrough in the verilator manpage.
|
||||
|
||||
// This is intended to be a minimal example. Before copying this to start a
|
||||
// real project, it is better to start with a more complete example,
|
||||
// e.g. examples/c_tracing.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv) {}
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop("top");
|
||||
|
||||
// Initialize SC model
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Fin
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
module top;
|
||||
initial begin
|
||||
$display("Hello World!");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,6 @@
|
||||
*.dmp
|
||||
*.log
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
logs
|
||||
@@ -0,0 +1,96 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2017 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.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Set up variables
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
VERILATOR_COVERAGE = verilator_coverage
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
endif
|
||||
|
||||
VERILATOR_FLAGS =
|
||||
# Generate C++ in executable form
|
||||
VERILATOR_FLAGS += -cc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -O2 -x-assign 0
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
VERILATOR_FLAGS += --trace
|
||||
# Check SystemVerilog assertions
|
||||
VERILATOR_FLAGS += --assert
|
||||
# Generate coverage analysis
|
||||
VERILATOR_FLAGS += --coverage
|
||||
# Run Verilator in debug mode
|
||||
#VERILATOR_FLAGS += --debug
|
||||
# Add this trace to get a backtrace in gdb
|
||||
#VERILATOR_FLAGS += --gdbbt
|
||||
|
||||
######################################################################
|
||||
default: run
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "-- Verilator tracing example"
|
||||
|
||||
@echo
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sim_main.cpp
|
||||
|
||||
@echo
|
||||
@echo "-- COMPILE -----------------"
|
||||
# To compile, we can either just do what Verilator asks,
|
||||
# or call a submakefile where we can override the rules ourselves
|
||||
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
$(MAKE) -j 4 -C obj_dir -f ../Makefile_obj
|
||||
|
||||
@echo
|
||||
@echo "-- RUN ---------------------"
|
||||
@mkdir -p logs
|
||||
obj_dir/Vtop | tee logs/sim.log
|
||||
|
||||
@echo
|
||||
@echo "-- COVERAGE ----------------"
|
||||
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||
|
||||
@echo
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
|
||||
@echo
|
||||
|
||||
|
||||
######################################################################
|
||||
# Other targets
|
||||
|
||||
show-config:
|
||||
$(VERILATOR) -V
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
|
||||
@@ -0,0 +1,55 @@
|
||||
# -*- Makefile -*-
|
||||
#######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Makefile for inside object directory
|
||||
#
|
||||
# This is executed in the object directory, and called by ../Makefile
|
||||
#
|
||||
# Copyright 2003-2017 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.
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
default: Vtop
|
||||
|
||||
# Include the rules made by Verilator
|
||||
include Vtop.mk
|
||||
|
||||
#######################################################################
|
||||
# Compile flags
|
||||
|
||||
# Override some default compile flags
|
||||
CPPFLAGS += -MMD -MP
|
||||
CPPFLAGS += -DVL_DEBUG=1
|
||||
# Turn on some more flags (when configured appropriately)
|
||||
# For testing inside Verilator, "configure --enable-ccwarn" will do this
|
||||
# automatically; otherwise you may want this unconditionally enabled
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
USER_CPPFLAGS_WALL += -W -Werror -Wall
|
||||
endif
|
||||
|
||||
# See the benchmarking section of bin/verilator.
|
||||
# Support class optimizations. This includes the tracing and symbol table.
|
||||
# SystemC takes minutes to optimize, thus it is off by default.
|
||||
OPT_SLOW =
|
||||
# Fast path optimizations. Most time is spent in these classes.
|
||||
OPT_FAST = -O2 -fstrict-aliasing
|
||||
#OPT_FAST = -O
|
||||
#OPT_FAST =
|
||||
|
||||
#######################################################################
|
||||
# Linking final exe -- presumes have a sim_main.cpp
|
||||
|
||||
# Special compile rule
|
||||
sim_main.o: sim_main.cpp $(VM_PREFIX).h
|
||||
|
||||
######################################################################
|
||||
######################################################################
|
||||
# Automatically understand dependencies
|
||||
|
||||
DEPS := $(wildcard *.d)
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
@@ -0,0 +1,2 @@
|
||||
// This file typically lists flags required by a large project, e.g. include directories
|
||||
+librescan +libext+.v+.sv+.vh+.svh -y .
|
||||
@@ -0,0 +1,114 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
|
||||
#include <sys/stat.h> // mkdir
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
// If "verilator --trace" is used, include the tracing class
|
||||
#if VM_TRACE
|
||||
# include <verilated_vcd_c.h>
|
||||
#endif
|
||||
|
||||
// Current simulation time (64-bit unsigned)
|
||||
vluint64_t main_time = 0;
|
||||
// Called by $time in Verilog
|
||||
double sc_time_stamp () {
|
||||
return main_time; // Note does conversion to real, to match SystemC
|
||||
}
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
// This is a more complicated example, please also see the simpler examples/hello_world_c.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv && env) {}
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Set debug level, 0 is off, 9 is highest presently used
|
||||
Verilated::debug(0);
|
||||
|
||||
// Randomization reset policy
|
||||
Verilated::randReset(2);
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
|
||||
|
||||
// If verilator was invoked with --trace, open trace
|
||||
#if VM_TRACE
|
||||
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
||||
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp, 99); // Trace 99 levels of hierarchy
|
||||
mkdir("logs", 0777);
|
||||
tfp->open("logs/vlt_dump.vcd"); // Open the dump file
|
||||
#endif
|
||||
|
||||
// Set some inputs
|
||||
top->reset_l = !0;
|
||||
top->fastclk = 0;
|
||||
top->clk = 0;
|
||||
top->in_small = 1;
|
||||
top->in_quad = 0x1234;
|
||||
top->in_wide[0] = 0x1;
|
||||
top->in_wide[1] = 0x22222222;
|
||||
top->in_wide[2] = 0x33333333;
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
main_time++; // Time passes...
|
||||
|
||||
// Toggle clocks and such
|
||||
top->fastclk = !top->fastclk;
|
||||
if ((main_time % 10) == 3) {
|
||||
top->clk = 1;
|
||||
}
|
||||
if ((main_time % 10) == 8) {
|
||||
top->clk = 0;
|
||||
}
|
||||
if (main_time > 1 && main_time < 10) {
|
||||
top->reset_l = !1; // Assert reset
|
||||
} else {
|
||||
top->reset_l = !0; // Deassert reset
|
||||
}
|
||||
|
||||
// Assign some other inputs
|
||||
top->in_quad += 0x12;
|
||||
|
||||
// Evaluate model
|
||||
top->eval();
|
||||
|
||||
// Read outputs
|
||||
VL_PRINTF ("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
|
||||
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
|
||||
main_time, top->clk, top->reset_l, top->in_quad,
|
||||
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Close trace if opened
|
||||
#if VM_TRACE
|
||||
if (tfp) { tfp->close(); }
|
||||
#endif
|
||||
|
||||
// Coverage analysis (since test passed)
|
||||
#if VM_COVERAGE
|
||||
mkdir("logs", 0777);
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
#endif
|
||||
|
||||
// Destroy model
|
||||
delete top; top = NULL;
|
||||
|
||||
// Fin
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
module sub
|
||||
(
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l
|
||||
);
|
||||
|
||||
// Example counter/flop
|
||||
reg [31:0] count_f;
|
||||
always_ff @ (posedge fastclk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_f <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_f <= count_f + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// Another example flop
|
||||
reg [31:0] count_c;
|
||||
always_ff @ (posedge clk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_c <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_c <= count_c + 1;
|
||||
if (count_c >= 3) begin
|
||||
$display("[%0t] fastclk is %0d times faster than clk\n",
|
||||
$time, count_f/count_c);
|
||||
// This write is a magic value the Makefile uses to make sure the
|
||||
// test completes successfully.
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// An example assertion
|
||||
always_ff @ (posedge clk) begin
|
||||
AssertionExample: assert (!reset_l || count_c<100);
|
||||
end
|
||||
|
||||
// And example coverage analysis
|
||||
cover property (@(posedge clk) count_c==3);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,42 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
// This is intended to be a complex example of several features, please also
|
||||
// see the simpler examples/hello_world_c.
|
||||
|
||||
module top
|
||||
(
|
||||
// Declare some signals so we can see how I/O works
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l,
|
||||
|
||||
output [1:0] out_small,
|
||||
output [39:0] out_quad,
|
||||
output [69:0] out_wide,
|
||||
input [1:0] in_small,
|
||||
input [39:0] in_quad,
|
||||
input [69:0] in_wide
|
||||
);
|
||||
|
||||
// Connect up the outputs, using some trivial logic
|
||||
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
||||
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
||||
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
||||
|
||||
// And an example sub module. The submodule will print stuff.
|
||||
sub sub (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.fastclk (fastclk),
|
||||
.reset_l (reset_l));
|
||||
|
||||
// Print some stuff as an example
|
||||
initial begin
|
||||
$display("[%0t] Model running...\n", $time);
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,6 @@
|
||||
*.dmp
|
||||
*.log
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
logs
|
||||
@@ -0,0 +1,109 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2017 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.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Set up variables
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
VERILATOR_COVERAGE = verilator_coverage
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
endif
|
||||
|
||||
VERILATOR_FLAGS =
|
||||
# Generate SystemC in executable form
|
||||
VERILATOR_FLAGS += -sc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -O2 -x-assign 0
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
VERILATOR_FLAGS += --trace
|
||||
# Check SystemVerilog assertions
|
||||
VERILATOR_FLAGS += --assert
|
||||
# Generate coverage analysis
|
||||
VERILATOR_FLAGS += --coverage
|
||||
# Run Verilator in debug mode
|
||||
#VERILATOR_FLAGS += --debug
|
||||
# Add this trace to get a backtrace in gdb
|
||||
#VERILATOR_FLAGS += --gdbbt
|
||||
|
||||
# Check if SC exists via a verilator call (empty if not)
|
||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
|
||||
|
||||
######################################################################
|
||||
|
||||
ifneq ($(SYSTEMC_EXISTS),)
|
||||
default: run
|
||||
else
|
||||
default: nosc
|
||||
endif
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "-- Verilator tracing example"
|
||||
|
||||
@echo
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sc_main.cpp
|
||||
|
||||
@echo
|
||||
@echo "-- COMPILE ----------------="
|
||||
# To compile, we can either just do what Verilator asks,
|
||||
# or call a submakefile where we can override the rules ourselves
|
||||
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
$(MAKE) -j 4 -C obj_dir -f ../Makefile_obj
|
||||
|
||||
@echo
|
||||
@echo "-- RUN ---------------------"
|
||||
@mkdir -p logs
|
||||
obj_dir/Vtop | tee logs/sim.log
|
||||
|
||||
@echo
|
||||
@echo "-- COVERAGE ----------------"
|
||||
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||
|
||||
@echo
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
|
||||
@echo
|
||||
|
||||
######################################################################
|
||||
# Other targets
|
||||
|
||||
nosc:
|
||||
@echo
|
||||
@echo "%Skip: SYSTEMC_INCLUDE not in environment"
|
||||
@echo "(If you have SystemC see the README, and rebuild Verilator)"
|
||||
@echo
|
||||
|
||||
show-config:
|
||||
$(VERILATOR) -V
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
|
||||
@@ -0,0 +1,63 @@
|
||||
# -*- Makefile -*-
|
||||
#######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Makefile for inside object directory
|
||||
#
|
||||
# This is executed in the object directory, and called by ../Makefile
|
||||
#
|
||||
# Copyright 2003-2017 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.
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
default: Vtop
|
||||
|
||||
# Include the rules made by Verilator
|
||||
include Vtop.mk
|
||||
|
||||
#######################################################################
|
||||
# Compile flags
|
||||
|
||||
# Override some default compile flags
|
||||
CPPFLAGS += -MMD -MP
|
||||
CPPFLAGS += -DVL_DEBUG=1
|
||||
# SystemC isn't too clean
|
||||
CPPFLAGS += -Wno-deprecated
|
||||
# Turn on some more flags (when configured appropriately)
|
||||
# For testing inside Verilator, "configure --enable-ccwarn" will do this
|
||||
# automatically; otherwise you may want this unconditionally enabled
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
USER_CPPFLAGS_WALL += -W -Werror -Wall
|
||||
endif
|
||||
|
||||
# If you build your own rules from scratch, note you need to include
|
||||
# SystemC as follows (Vtop.mk file includes verilated.mk with these
|
||||
# already).
|
||||
# CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
|
||||
# LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
|
||||
|
||||
# See the benchmarking section of bin/verilator.
|
||||
# Support class optimizations. This includes the tracing and symbol table.
|
||||
# SystemC takes minutes to optimize, thus it is off by default.
|
||||
OPT_SLOW =
|
||||
# Fast path optimizations. Most time is spent in these classes.
|
||||
OPT_FAST = -O2 -fstrict-aliasing
|
||||
#OPT_FAST = -O
|
||||
#OPT_FAST =
|
||||
|
||||
#######################################################################
|
||||
# Linking final exe -- presumes have a sim_main.cpp
|
||||
|
||||
# Special compile rule
|
||||
sim_main.o: sim_main.cpp $(VM_PREFIX).h
|
||||
|
||||
######################################################################
|
||||
######################################################################
|
||||
# Automatically understand dependencies
|
||||
|
||||
DEPS := $(wildcard *.d)
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
@@ -0,0 +1,2 @@
|
||||
// This file typically lists flags required by a large project, e.g. include directories
|
||||
+librescan +libext+.v+.sv+.vh+.svh -y .
|
||||
@@ -0,0 +1,136 @@
|
||||
// -*- SystemC -*-
|
||||
// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// SystemC global header
|
||||
#include <systemc.h>
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
#if VM_TRACE
|
||||
#include <verilated_vcd_sc.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h> // mkdir
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
// This is a more complicated example, please also see the simpler examples/hello_world_c.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv) {}
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Set debug level, 0 is off, 9 is highest presently used
|
||||
Verilated::debug(0);
|
||||
|
||||
// Randomization reset policy
|
||||
Verilated::randReset(2);
|
||||
|
||||
// General logfile
|
||||
ios::sync_with_stdio();
|
||||
|
||||
// Defaults time
|
||||
#if (SYSTEMC_VERSION>20011000)
|
||||
#else
|
||||
sc_time dut(1.0, sc_ns);
|
||||
sc_set_default_time_unit(dut);
|
||||
#endif
|
||||
|
||||
// Define clocks
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_clock clk ("clk", 10,SC_NS, 0.5, 3,SC_NS, true);
|
||||
sc_clock fastclk ("fastclk", 2,SC_NS, 0.5, 2,SC_NS, true);
|
||||
#else
|
||||
sc_clock clk ("clk", 10, 0.5, 3, true);
|
||||
sc_clock fastclk ("fastclk", 2, 0.5, 2, true);
|
||||
#endif
|
||||
|
||||
// Define interconnect
|
||||
sc_signal<bool> reset_l;
|
||||
sc_signal<vluint32_t> in_small;
|
||||
sc_signal<vluint64_t> in_quad;
|
||||
sc_signal<sc_bv<70> > in_wide;
|
||||
sc_signal<vluint32_t> out_small;
|
||||
sc_signal<vluint64_t> out_quad;
|
||||
sc_signal<sc_bv<70> > out_wide;
|
||||
|
||||
// Construct the Verilated model, from inside Vtop.h
|
||||
Vtop* top = new Vtop("top");
|
||||
// Attach signals to the model
|
||||
top->clk (clk);
|
||||
top->fastclk (fastclk);
|
||||
top->reset_l (reset_l);
|
||||
top->in_small (in_small);
|
||||
top->in_quad (in_quad);
|
||||
top->in_wide (in_wide);
|
||||
top->out_small (out_small);
|
||||
top->out_quad (out_quad);
|
||||
top->out_wide (out_wide);
|
||||
|
||||
#if VM_TRACE
|
||||
// Before any evaluation, need to know to calculate those signals only used for tracing
|
||||
Verilated::traceEverOn(true);
|
||||
#endif
|
||||
|
||||
// You must do one evaluation before enabling waves, in order to allow
|
||||
// SystemC to interconnect everything for testing.
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
|
||||
// Turn on waves
|
||||
#if VM_TRACE
|
||||
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
|
||||
VerilatedVcdSc* tfp = new VerilatedVcdSc;
|
||||
top->trace (tfp, 99);
|
||||
mkdir("logs", 0777);
|
||||
tfp->open ("logs/vlt_dump.vcd");
|
||||
#endif
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
#if VM_TRACE
|
||||
// Flush the wave files each cycle so we can immediately see the output
|
||||
// Don't do this in "real" programs, do it in an abort() handler instead
|
||||
if (tfp) tfp->flush();
|
||||
// Apply inputs
|
||||
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
|
||||
reset_l = !1; // Assert reset
|
||||
} else if (VL_TIME_Q() > 1) {
|
||||
reset_l = !0; // Deassert reset
|
||||
}
|
||||
#endif
|
||||
// Simulate 1ns
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Close Waves
|
||||
#if VM_TRACE
|
||||
if (tfp) tfp->close();
|
||||
#endif
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Coverage analysis (since test passed)
|
||||
#if VM_COVERAGE
|
||||
mkdir("logs", 0777);
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
#endif
|
||||
|
||||
// Fin
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
module sub
|
||||
(
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l
|
||||
);
|
||||
|
||||
// Example counter/flop
|
||||
reg [31:0] count_f;
|
||||
always_ff @ (posedge fastclk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_f <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_f <= count_f + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// Another example flop
|
||||
reg [31:0] count_c;
|
||||
always_ff @ (posedge clk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_c <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_c <= count_c + 1;
|
||||
if (count_c >= 3) begin
|
||||
$display("[%0t] fastclk is %0d times faster than clk\n",
|
||||
$time, count_f/count_c);
|
||||
// This write is a magic value the Makefile uses to make sure the
|
||||
// test completes successfully.
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// An example assertion
|
||||
always_ff @ (posedge clk) begin
|
||||
AssertionExample: assert (!reset_l || count_c<100);
|
||||
end
|
||||
|
||||
// And example coverage analysis
|
||||
cover property (@(posedge clk) count_c==3);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,42 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
// This is intended to be a complex example of several features, please also
|
||||
// see the simpler examples/hello_world_c.
|
||||
|
||||
module top
|
||||
(
|
||||
// Declare some signals so we can see how I/O works
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l,
|
||||
|
||||
output [1:0] out_small,
|
||||
output [39:0] out_quad,
|
||||
output [69:0] out_wide,
|
||||
input [1:0] in_small,
|
||||
input [39:0] in_quad,
|
||||
input [69:0] in_wide
|
||||
);
|
||||
|
||||
// Connect up the outputs, using some trivial logic
|
||||
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
||||
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
||||
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
||||
|
||||
// And an example sub module. The submodule will print stuff.
|
||||
sub sub (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.fastclk (fastclk),
|
||||
.reset_l (reset_l));
|
||||
|
||||
// Print some stuff as an example
|
||||
initial begin
|
||||
$display("[%0t] Model running...\n", $time);
|
||||
end
|
||||
|
||||
endmodule
|
||||
+379
-202
File diff suppressed because it is too large
Load Diff
+316
-202
File diff suppressed because it is too large
Load Diff
+27
-41
@@ -2,7 +2,7 @@
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
# Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
# Copyright 2003-2017 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.
|
||||
######################################################################
|
||||
@@ -16,13 +16,18 @@ RANLIB = ranlib
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
|
||||
# Select newest language
|
||||
CFG_CXXFLAGS_STD_NEWEST = @CFG_CXXFLAGS_STD_NEWEST@
|
||||
# Select oldest language (for Verilator internal testing only)
|
||||
CFG_CXXFLAGS_STD_OLDEST = @CFG_CXXFLAGS_STD_OLDEST@
|
||||
# Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero
|
||||
CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
|
||||
# Compiler flags that turn on extra warnings
|
||||
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
|
||||
|
||||
######################################################################
|
||||
# Programs
|
||||
|
||||
SP_PREPROC = sp_preproc
|
||||
SP_INCLUDER = $(VERILATOR_INCLUDER)
|
||||
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||
@@ -43,13 +48,13 @@ VK_CPPFLAGS_ALWAYS += \
|
||||
-I$(VERILATOR_ROOT)/include \
|
||||
-I$(VERILATOR_ROOT)/include/vltstd \
|
||||
-DVL_PRINTF=printf \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||
-DVM_SC=$(VM_SC) \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
VK_CPPFLAGS_WALL += -Wall \
|
||||
-Werror
|
||||
VK_CPPFLAGS_WALL += -Wall $(CFG_CXXFLAGS_WEXTRA) -Werror
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS)
|
||||
@@ -92,9 +97,9 @@ VM_CLASSES += $(VM_CLASSES_FAST) $(VM_CLASSES_SLOW)
|
||||
VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW)
|
||||
|
||||
#######################################################################
|
||||
##### SystemC or SystemPerl builds
|
||||
##### SystemC builds
|
||||
|
||||
ifeq ($(VM_SP_OR_SC),1)
|
||||
ifeq ($(VM_SC),1)
|
||||
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
|
||||
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
|
||||
SC_LIBS = -lsystemc
|
||||
@@ -105,41 +110,14 @@ ifeq ($(VM_SP_OR_SC),1)
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### SystemPerl builds
|
||||
##### Stub
|
||||
|
||||
ifeq ($(VM_SP),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE) -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
||||
|
||||
# This rule is called manually by the upper level makefile
|
||||
preproc:
|
||||
@echo " SP Preprocess" $(basename $(VM_CLASSES)) ...
|
||||
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
|
||||
--preproc $(VK_CLASSES_SP)
|
||||
else
|
||||
ifeq ($(VM_COVERAGE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
endif
|
||||
preproc:
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### SystemC w/o SystemPerl builds
|
||||
|
||||
ifeq ($(VM_SC),1)
|
||||
LIBS += -lm -lstdc++
|
||||
endif
|
||||
preproc:
|
||||
|
||||
#######################################################################
|
||||
##### C/H builds
|
||||
|
||||
ifeq ($(VM_PCLI),1)
|
||||
LIBS += -lm -lstdc++
|
||||
endif
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
#######################################################################
|
||||
# Overall Objects Linking
|
||||
@@ -175,16 +153,24 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS)
|
||||
######################################################################
|
||||
### Compile rules
|
||||
|
||||
#Default rule embedded in make: (Not defined so user makefiles can override it)
|
||||
#.cpp.o:
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
ifneq ($(VM_DEFAULT_RULES),0)
|
||||
$(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)%__Slow.o: $(VM_PREFIX)%__Slow.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)%.o: $(VM_PREFIX)%.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||
endif
|
||||
|
||||
#Default rule embedded in make:
|
||||
#.cpp.o:
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
######################################################################
|
||||
### Debugging
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
|
||||
+59
-55
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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.
|
||||
//
|
||||
@@ -50,7 +50,7 @@ public: // But only local to this file
|
||||
// CONSTRUCTORS
|
||||
// Derived classes should call zero() in their constructor
|
||||
VerilatedCovImpItem() {
|
||||
for (int i=0; i<MAX_KEYS; i++) {
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
m_keys[i]=KEY_UNDEF;
|
||||
m_vals[i]=0;
|
||||
}
|
||||
@@ -72,9 +72,11 @@ private:
|
||||
T* m_countp; ///< Count value
|
||||
public:
|
||||
// METHODS
|
||||
// cppcheck-suppress truncLongCastReturn
|
||||
virtual vluint64_t count() const { return *m_countp; }
|
||||
virtual void zero() const { *m_countp = 0; }
|
||||
// CONSTRUCTORS
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
VerilatedCoverItemSpec(T* countp) : m_countp(countp) { zero(); }
|
||||
virtual ~VerilatedCoverItemSpec() {}
|
||||
};
|
||||
@@ -88,9 +90,9 @@ public:
|
||||
class VerilatedCovImp : VerilatedCovImpBase {
|
||||
private:
|
||||
// TYPES
|
||||
typedef map<string,int> ValueIndexMap;
|
||||
typedef map<int,string> IndexValueMap;
|
||||
typedef deque<VerilatedCovImpItem*> ItemList;
|
||||
typedef std::map<std::string,int> ValueIndexMap;
|
||||
typedef std::map<int,std::string> IndexValueMap;
|
||||
typedef std::deque<VerilatedCovImpItem*> ItemList;
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
@@ -117,19 +119,19 @@ public:
|
||||
|
||||
private:
|
||||
// PRIVATE METHODS
|
||||
int valueIndex(const string& value) {
|
||||
int valueIndex(const std::string& value) {
|
||||
static int nextIndex = KEY_UNDEF+1;
|
||||
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
|
||||
if (iter != m_valueIndexes.end()) return iter->second;
|
||||
nextIndex++; assert(nextIndex>0);
|
||||
m_valueIndexes.insert(make_pair(value, nextIndex));
|
||||
m_indexValues.insert(make_pair(nextIndex, value));
|
||||
m_valueIndexes.insert(std::make_pair(value, nextIndex));
|
||||
m_indexValues.insert(std::make_pair(nextIndex, value));
|
||||
return nextIndex;
|
||||
}
|
||||
string dequote(const string& text) {
|
||||
static std::string dequote(const std::string& text) {
|
||||
// Quote any special characters
|
||||
string rtn;
|
||||
for (const char* pos = text.c_str(); *pos; pos++) {
|
||||
std::string rtn;
|
||||
for (const char* pos = text.c_str(); *pos; ++pos) {
|
||||
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
|
||||
char hex[10]; sprintf(hex,"%%%02X",pos[0]);
|
||||
rtn += hex;
|
||||
@@ -139,7 +141,7 @@ private:
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
bool legalKey(const string& key) {
|
||||
static bool legalKey(const std::string& key) {
|
||||
// Because we compress long keys to a single letter, and
|
||||
// don't want applications to either get confused if they use
|
||||
// a letter differently, nor want them to rely on our compression...
|
||||
@@ -148,17 +150,17 @@ private:
|
||||
if (key.length()==2 && isdigit(key[1])) return false;
|
||||
return true;
|
||||
}
|
||||
string keyValueFormatter (const string& key, const string& value) {
|
||||
string name;
|
||||
static std::string keyValueFormatter (const std::string& key, const std::string& value) {
|
||||
std::string name;
|
||||
if (key.length()==1 && isalpha(key[0])) {
|
||||
name += string("\001")+key;
|
||||
name += std::string("\001")+key;
|
||||
} else {
|
||||
name += string("\001")+dequote(key);
|
||||
name += std::string("\001")+dequote(key);
|
||||
}
|
||||
name += string("\002")+dequote(value);
|
||||
name += std::string("\002")+dequote(value);
|
||||
return name;
|
||||
}
|
||||
string combineHier (const string& old, const string& add) {
|
||||
static std::string combineHier (const std::string& old, const std::string& add) {
|
||||
// (foo.a.x, foo.b.x) => foo.*.x
|
||||
// (foo.a.x, foo.b.y) => foo.*
|
||||
// (foo.a.x, foo.b) => foo.*
|
||||
@@ -176,7 +178,7 @@ private:
|
||||
|
||||
// We used to backup and split on only .'s but it seems better to be verbose
|
||||
// and not assume . is the separator
|
||||
string prefix = string(a,apre-a);
|
||||
std::string prefix = std::string(a,apre-a);
|
||||
|
||||
// Scan backward to last mismatch
|
||||
const char* apost = a+strlen(a)-1;
|
||||
@@ -185,26 +187,26 @@ private:
|
||||
&& apost>apre && bpost>bpre) { apost--; bpost--; }
|
||||
|
||||
// Forward to . so we have a whole word
|
||||
string suffix = *bpost ? string(bpost+1) : "";
|
||||
std::string suffix = *bpost ? std::string(bpost+1) : "";
|
||||
|
||||
string out = prefix+"*"+suffix;
|
||||
std::string out = prefix+"*"+suffix;
|
||||
|
||||
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
|
||||
return out;
|
||||
}
|
||||
bool itemMatchesString(VerilatedCovImpItem* itemp, const string& match) {
|
||||
for (int i=0; i<MAX_KEYS; i++) {
|
||||
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) {
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||
// We don't compare keys, only values
|
||||
string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (string::npos != val.find(match)) { // Found
|
||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (std::string::npos != val.find(match)) { // Found
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void selftest() {
|
||||
static void selftest() {
|
||||
// Little selftest
|
||||
if (combineHier ("a.b.c","a.b.c") !="a.b.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier ("a.b.c","a.b") !="a.b*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
@@ -219,7 +221,7 @@ private:
|
||||
public:
|
||||
// PUBLIC METHODS
|
||||
void clear() {
|
||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
VerilatedCovImpItem* itemp = *(it);
|
||||
delete itemp;
|
||||
}
|
||||
@@ -242,7 +244,7 @@ public:
|
||||
}
|
||||
}
|
||||
void zero() {
|
||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
(*it)->zero();
|
||||
}
|
||||
}
|
||||
@@ -261,27 +263,27 @@ public:
|
||||
assert(m_insertp);
|
||||
// First two key/vals are filename
|
||||
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
|
||||
VlCovCvtToCStr linestrp (m_insertLineno);
|
||||
ckeyps[1]="lineno"; valps[1]=linestrp;
|
||||
std::string linestr = vlCovCvtToStr(m_insertLineno);
|
||||
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
|
||||
// Default page if not specified
|
||||
const char* fnstartp = m_insertFilenamep;
|
||||
while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1;
|
||||
const char* fnendp = fnstartp;
|
||||
while (*fnendp && *fnendp!='.') fnendp++;
|
||||
string page_default = "sp_user/"+string(fnstartp,fnendp-fnstartp);
|
||||
std::string page_default = "sp_user/"+std::string(fnstartp,fnendp-fnstartp);
|
||||
ckeyps[2]="page"; valps[2]=page_default.c_str();
|
||||
|
||||
// Keys -> strings
|
||||
string keys[MAX_KEYS];
|
||||
for (int i=0; i<MAX_KEYS; i++) {
|
||||
std::string keys[MAX_KEYS];
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (ckeyps[i] && ckeyps[i][0]) {
|
||||
keys[i] = ckeyps[i];
|
||||
}
|
||||
}
|
||||
// Ignore empty keys
|
||||
for (int i=0; i<MAX_KEYS; i++) {
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (keys[i]!="") {
|
||||
for (int j=i+1; j<MAX_KEYS; j++) {
|
||||
for (int j=i+1; j<MAX_KEYS; ++j) {
|
||||
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
|
||||
keys[i] = "";
|
||||
break;
|
||||
@@ -291,16 +293,16 @@ public:
|
||||
}
|
||||
// Insert the values
|
||||
int addKeynum=0;
|
||||
for (int i=0; i<MAX_KEYS; i++) {
|
||||
const string key = keys[i];
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
const std::string key = keys[i];
|
||||
if (keys[i]!="") {
|
||||
const string val = valps[i];
|
||||
const std::string val = valps[i];
|
||||
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
||||
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
||||
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
||||
addKeynum++;
|
||||
if (!legalKey(key)) {
|
||||
string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
|
||||
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
}
|
||||
}
|
||||
@@ -316,27 +318,27 @@ public:
|
||||
#endif
|
||||
selftest();
|
||||
|
||||
ofstream os (filename);
|
||||
std::ofstream os (filename);
|
||||
if (os.fail()) {
|
||||
string msg = (string)"%Error: Can't write '"+filename+"'";
|
||||
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
return;
|
||||
}
|
||||
os << "# SystemC::Coverage-3\n";
|
||||
|
||||
// Build list of events; totalize if collapsing hierarchy
|
||||
typedef map<string,pair<string,vluint64_t> > EventMap;
|
||||
EventMap eventCounts;
|
||||
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
|
||||
EventMap eventCounts;
|
||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
VerilatedCovImpItem* itemp = *(it);
|
||||
string name;
|
||||
string hier;
|
||||
std::string name;
|
||||
std::string hier;
|
||||
bool per_instance = false;
|
||||
|
||||
for (int i=0; i<MAX_KEYS; i++) {
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||
string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||
string val = m_indexValues[itemp->m_vals[i]];
|
||||
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (key == VL_CIK_PER_INSTANCE) {
|
||||
if (val != "0") per_instance = true;
|
||||
}
|
||||
@@ -361,21 +363,21 @@ public:
|
||||
// Find or insert the named event
|
||||
EventMap::iterator cit = eventCounts.find(name);
|
||||
if (cit != eventCounts.end()) {
|
||||
const string& oldhier = cit->second.first;
|
||||
const std::string& oldhier = cit->second.first;
|
||||
cit->second.second += itemp->count();
|
||||
cit->second.first = combineHier(oldhier, hier);
|
||||
} else {
|
||||
eventCounts.insert(make_pair(name, make_pair(hier,itemp->count())));
|
||||
eventCounts.insert(std::make_pair(name, make_pair(hier,itemp->count())));
|
||||
}
|
||||
}
|
||||
|
||||
// Output body
|
||||
for (EventMap::iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
||||
os<<"C '"<<dec;
|
||||
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
||||
os<<"C '"<<std::dec;
|
||||
os<<it->first;
|
||||
if (it->second.first != "") os<<keyValueFormatter(VL_CIK_HIER,it->second.first);
|
||||
os<<"' "<<it->second.second;
|
||||
os<<endl;
|
||||
os<<std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -439,9 +441,11 @@ void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||
}
|
||||
// Backward compatibility for Verilator
|
||||
void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3,
|
||||
K(4),const string& val4, A(5),A(6)) {
|
||||
K(4),const std::string& val4, A(5),A(6)) {
|
||||
std::string val2str = vlCovCvtToStr(val2);
|
||||
std::string val3str = vlCovCvtToStr(val3);
|
||||
_insertp(C(0),C(1),
|
||||
key2,VlCovCvtToCStr(val2), key3,VlCovCvtToCStr(val3), key4, val4.c_str(),
|
||||
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
|
||||
C(5),C(6),N(7),N(8),N(9),
|
||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||
|
||||
+5
-19
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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.
|
||||
//
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
/// Conditionally compile coverage code
|
||||
@@ -60,9 +59,9 @@ using namespace std;
|
||||
///
|
||||
/// vluint32_t m_cases[10];
|
||||
/// constructor {
|
||||
/// for (int i=0; i<10; i++) { m_cases[i]=0; }
|
||||
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
||||
/// }
|
||||
/// for (int i=0; i<10; i++) {
|
||||
/// for (int i=0; i<10; ++i) {
|
||||
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
||||
/// }
|
||||
|
||||
@@ -75,22 +74,9 @@ using namespace std;
|
||||
/// Convert VL_COVER_INSERT value arguments to strings
|
||||
|
||||
template< class T> std::string vlCovCvtToStr (const T& t) {
|
||||
ostringstream os; os<<t; return os.str();
|
||||
std::ostringstream os; os<<t; return os.str();
|
||||
}
|
||||
|
||||
/// Usage: something(VlCovCvtToCStr(i))
|
||||
/// Note the pointer will only be valid for as long as the object remains
|
||||
/// in scope!
|
||||
struct VlCovCvtToCStr {
|
||||
string m_str;
|
||||
// Casters
|
||||
template< class T> VlCovCvtToCStr (const T& t) {
|
||||
ostringstream os; os<<t; m_str=os.str();
|
||||
}
|
||||
~VlCovCvtToCStr() {}
|
||||
operator const char* () const { return m_str.c_str(); };
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCov
|
||||
/// Verilator coverage global class
|
||||
@@ -128,7 +114,7 @@ public:
|
||||
,A(20),D(21),D(22),D(23),D(24),D(25),D(26),D(27),D(28),D(29));
|
||||
// Backward compatibility for Verilator
|
||||
static void _insertp (A(0), A(1), K(2),int val2, K(3),int val3,
|
||||
K(4),const string& val4, A(5),A(6));
|
||||
K(4),const std::string& val4, A(5),A(6));
|
||||
|
||||
#undef K
|
||||
#undef A
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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,7 +25,6 @@
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
// Data used to edit below file, using vlcovgen
|
||||
@@ -105,7 +104,7 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr
|
||||
|
||||
class VerilatedCovKey {
|
||||
public:
|
||||
static string shortKey(const string& key) {
|
||||
static std::string shortKey(const std::string& key) {
|
||||
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
|
||||
if (key == "col0") return VL_CIK_COL0;
|
||||
if (key == "col0_name") return VL_CIK_COL0_NAME;
|
||||
|
||||
+16
-14
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 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.
|
||||
@@ -30,7 +30,9 @@
|
||||
|
||||
// On MSVC++ we need svdpi.h to declare exports, not imports
|
||||
#define DPI_PROTOTYPES
|
||||
#undef XXTERN
|
||||
#define XXTERN DPI_EXTERN DPI_DLLESPEC
|
||||
#undef EETERN
|
||||
#define EETERN DPI_EXTERN DPI_DLLESPEC
|
||||
|
||||
#include "vltstd/svdpi.h"
|
||||
@@ -40,7 +42,7 @@
|
||||
|
||||
// Not supported yet
|
||||
#define _VL_SVDPI_UNIMP() \
|
||||
vl_fatal(__FILE__,__LINE__,"",(string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
|
||||
vl_fatal(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
|
||||
|
||||
// Function requires a "context" in the import declaration
|
||||
#define _VL_SVDPI_CONTEXT_WARN() \
|
||||
@@ -58,31 +60,31 @@ const char* svDpiVersion() {
|
||||
//======================================================================
|
||||
// Bit-select utility functions.
|
||||
|
||||
svBit svGetBitselBit(const svBitVecVal* s, int i) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
|
||||
return VL_BITISSET_W(sp,bit);
|
||||
}
|
||||
svLogic svGetBitselLogic(const svLogicVecVal* s, int i) {
|
||||
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
}
|
||||
|
||||
void svPutBitselBit(svBitVecVal* d, int i, svBit s) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) {
|
||||
VL_ASSIGNBIT_WI(32, bit, dp, s);
|
||||
}
|
||||
void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s) {
|
||||
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
|
||||
void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w) {
|
||||
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
|
||||
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
|
||||
void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w) {
|
||||
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
|
||||
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
|
||||
@@ -261,13 +263,13 @@ svScope svGetScope() {
|
||||
|
||||
svScope svSetScope(const svScope scope) {
|
||||
const VerilatedScope* prevScopep = Verilated::dpiScope();
|
||||
const VerilatedScope* vscopep = (const VerilatedScope*)(scope);
|
||||
const VerilatedScope* vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
Verilated::dpiScope(vscopep);
|
||||
return (svScope)prevScopep;
|
||||
}
|
||||
|
||||
const char* svGetNameFromScope(const svScope scope) {
|
||||
const VerilatedScope* vscopep = (const VerilatedScope*)(scope);
|
||||
const VerilatedScope* vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
return vscopep->name();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -16,9 +16,9 @@
|
||||
/// \file
|
||||
/// \brief Verilator: Common include for all Verilated C files that use DPI
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates where DPI is used. It contains
|
||||
/// DPI interface functions required by the Verilated code.
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates where DPI is used. It contains
|
||||
/// DPI interface functions required by the Verilated code.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
@@ -37,25 +37,25 @@
|
||||
/// Return svBitVecVal from WData
|
||||
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
|
||||
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
|
||||
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
|
||||
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
|
||||
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, svLogicVecVal* lwp) {
|
||||
// Note we ignore X/Z in svLogicVecVal
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; i++) owp[i]=lwp[i].aval;
|
||||
for (int i=0; i<words-1; ++i) owp[i]=lwp[i].aval;
|
||||
owp[words-1] = lwp[words-1].aval & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) {
|
||||
// Note we don't create X/Z in svLogicVecVal
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words; i++) owp[i].bval=0;
|
||||
for (int i=0; i<words-1; i++) owp[i].aval=lwp[i];
|
||||
for (int i=0; i<words; ++i) owp[i].bval=0;
|
||||
for (int i=0; i<words-1; ++i) owp[i].aval=lwp[i];
|
||||
owp[words-1].aval = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
|
||||
|
||||
+36
-19
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2017 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.
|
||||
@@ -16,10 +16,10 @@
|
||||
/// \file
|
||||
/// \brief Verilator: String include for all Verilated C files
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates. It is used when strings or other
|
||||
/// heavyweight types are required; these contents are not part of
|
||||
/// verilated.h to save compile time when such types aren't used.
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates. It is used when strings or other
|
||||
/// heavyweight types are required; these contents are not part of
|
||||
/// verilated.h to save compile time when such types aren't used.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
@@ -36,32 +36,49 @@
|
||||
//======================================================================
|
||||
// Conversion functions
|
||||
|
||||
extern string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp);
|
||||
inline string VL_CVT_PACK_STR_NQ(QData lhs) {
|
||||
IData lw[2]; VL_SET_WQ(lw, lhs);
|
||||
extern std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp);
|
||||
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) {
|
||||
WData lw[2]; VL_SET_WQ(lw, lhs);
|
||||
return VL_CVT_PACK_STR_NW(2, lw);
|
||||
}
|
||||
inline string VL_CVT_PACK_STR_NN(const string& lhs) {
|
||||
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) {
|
||||
return lhs;
|
||||
}
|
||||
inline string VL_CVT_PACK_STR_NI(IData lhs) {
|
||||
IData lw[1]; lw[0] = lhs;
|
||||
inline std::string VL_CVT_PACK_STR_NI(IData lhs) {
|
||||
WData lw[1]; lw[0] = lhs;
|
||||
return VL_CVT_PACK_STR_NW(1, lw);
|
||||
}
|
||||
inline string VL_CONCATN_NNN(const string& lhs, const string& rhs) {
|
||||
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) {
|
||||
return lhs+rhs;
|
||||
}
|
||||
inline string VL_REPLICATEN_NNQ(int,int,int, const string& lhs, IData rep) {
|
||||
string out; out.reserve(lhs.length() * rep);
|
||||
for (unsigned times=0; times<rep; times++) out += lhs;
|
||||
inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) {
|
||||
std::string out; out.reserve(lhs.length() * rep);
|
||||
for (unsigned times=0; times<rep; ++times) out += lhs;
|
||||
return out;
|
||||
}
|
||||
inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs, IData rep) {
|
||||
inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const std::string& lhs, IData rep) {
|
||||
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
|
||||
}
|
||||
|
||||
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
|
||||
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
|
||||
extern string VL_SFORMATF_NX(const char* formatp, ...);
|
||||
extern IData VL_FOPEN_NI(const std::string& filename, IData mode);
|
||||
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
const std::string& ofilename, void* memp, IData start, IData end);
|
||||
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...);
|
||||
extern void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...);
|
||||
extern std::string VL_SFORMATF_NX(const char* formatp, ...);
|
||||
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rdp);
|
||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) {
|
||||
WData rwp[2]; // WData must always be at least 2
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||
if (got) rdr = rwp[0];
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) {
|
||||
WData rwp[2];
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||
if (got) rdr = VL_SET_QW(rwp);
|
||||
return got;
|
||||
}
|
||||
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr);
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+35
-29
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 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.
|
||||
@@ -47,10 +47,9 @@ class VerilatedImp {
|
||||
// Whole class is internal use only - Global information shared between verilated*.cpp files.
|
||||
|
||||
// TYPES
|
||||
typedef vector<string> ArgVec;
|
||||
typedef map<pair<const void*,void*>,void*> UserMap;
|
||||
typedef map<const char*, const VerilatedScope*, VerilatedCStrCmp> ScopeNameMap;
|
||||
typedef map<const char*, int, VerilatedCStrCmp> ExportNameMap;
|
||||
typedef std::vector<std::string> ArgVec;
|
||||
typedef std::map<std::pair<const void*,void*>,void*> UserMap;
|
||||
typedef std::map<const char*, int, VerilatedCStrCmp> ExportNameMap;
|
||||
|
||||
// MEMBERS
|
||||
static VerilatedImp s_s; ///< Static Singleton; One and only static this
|
||||
@@ -60,14 +59,14 @@ class VerilatedImp {
|
||||
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>
|
||||
VerilatedScopeNameMap m_nameMap; ///< Map of <scope_name, scope pointer>
|
||||
// Slow - somewhat static:
|
||||
ExportNameMap m_exportMap; ///< Map of <export_func_proto, func number>
|
||||
int m_exportNext; ///< Next export funcnum
|
||||
|
||||
// File I/O
|
||||
vector<FILE*> m_fdps; ///< File descriptors
|
||||
deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
|
||||
std::vector<FILE*> m_fdps; ///< File descriptors
|
||||
std::deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// CONSTRUCTORS
|
||||
@@ -81,7 +80,7 @@ public: // But only for verilated*.cpp
|
||||
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) {
|
||||
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
|
||||
VL_PRINTF(" %s",it->c_str());
|
||||
}
|
||||
VL_PRINTF("\n");
|
||||
@@ -93,11 +92,15 @@ public: // But only for verilated*.cpp
|
||||
|
||||
// METHODS - arguments
|
||||
static void commandArgs(int argc, const char** argv) {
|
||||
s_s.m_argVec.clear();
|
||||
for (int i=0; i<argc; i++) s_s.m_argVec.push_back(argv[i]);
|
||||
s_s.m_argVec.clear(); // Always clear
|
||||
commandArgsAdd(argc, argv);
|
||||
}
|
||||
static void commandArgsAdd(int argc, const char** argv) {
|
||||
if (!s_s.m_argVecLoaded) s_s.m_argVec.clear();
|
||||
for (int i=0; i<argc; ++i) s_s.m_argVec.push_back(argv[i]);
|
||||
s_s.m_argVecLoaded = true; // Can't just test later for empty vector, no arguments is ok
|
||||
}
|
||||
static string argPlusMatch(const char* prefixp) {
|
||||
static std::string argPlusMatch(const char* prefixp) {
|
||||
// Note prefixp does not include the leading "+"
|
||||
size_t len = strlen(prefixp);
|
||||
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
|
||||
@@ -106,7 +109,7 @@ public: // But only for verilated*.cpp
|
||||
"%Error: Verilog called $test$plusargs or $value$plusargs without"
|
||||
" testbench C first calling Verilated::commandArgs(argc,argv).");
|
||||
}
|
||||
for (ArgVec::iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
|
||||
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
|
||||
if ((*it)[0]=='+') {
|
||||
if (0==strncmp(prefixp, it->c_str()+1, len)) return *it;
|
||||
}
|
||||
@@ -119,13 +122,13 @@ public: // But only for verilated*.cpp
|
||||
// There's often many more scopes than userdata's and thus having a ~48byte
|
||||
// per map overhead * N scopes would take much more space and cache thrashing.
|
||||
static inline void userInsert(const void* scopep, void* userKey, void* userData) {
|
||||
UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey));
|
||||
UserMap::iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
|
||||
if (it != s_s.m_userMap.end()) it->second = userData;
|
||||
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
|
||||
else s_s.m_userMap.insert(it, make_pair(make_pair(scopep,userKey),userData));
|
||||
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep,userKey),userData));
|
||||
}
|
||||
static inline void* userFind(const void* scopep, void* userKey) {
|
||||
UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey));
|
||||
UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
|
||||
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
|
||||
else return NULL;
|
||||
}
|
||||
@@ -143,7 +146,7 @@ private:
|
||||
}
|
||||
static void userDump() {
|
||||
bool first = true;
|
||||
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
|
||||
for (UserMap::const_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);
|
||||
@@ -154,30 +157,33 @@ public: // But only for verilated*.cpp
|
||||
// METHODS - scope name
|
||||
static void scopeInsert(const VerilatedScope* scopep) {
|
||||
// Slow ok - called once/scope at construction
|
||||
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
||||
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
||||
if (it == s_s.m_nameMap.end()) {
|
||||
s_s.m_nameMap.insert(it, make_pair(scopep->name(),scopep));
|
||||
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep));
|
||||
}
|
||||
}
|
||||
static inline const VerilatedScope* scopeFind(const char* namep) {
|
||||
ScopeNameMap::iterator it=s_s.m_nameMap.find(namep);
|
||||
VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep);
|
||||
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
|
||||
else return NULL;
|
||||
}
|
||||
static void scopeErase(const VerilatedScope* scopep) {
|
||||
// Slow ok - called once/scope at destruction
|
||||
userEraseScope(scopep);
|
||||
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
||||
VerilatedScopeNameMap::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");
|
||||
for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
|
||||
for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
|
||||
const VerilatedScope* scopep = it->second;
|
||||
scopep->scopeDump();
|
||||
}
|
||||
VL_PRINTF("\n");
|
||||
}
|
||||
static const VerilatedScopeNameMap* scopeNameMap() {
|
||||
return &s_s.m_nameMap;
|
||||
}
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - export names
|
||||
@@ -192,30 +198,30 @@ public: // But only for verilated*.cpp
|
||||
// Slow ok - called once/function at creation
|
||||
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
|
||||
if (it == s_s.m_exportMap.end()) {
|
||||
s_s.m_exportMap.insert(it, make_pair(namep, s_s.m_exportNext++));
|
||||
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
|
||||
return s_s.m_exportNext++;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
static int exportFind(const char* namep) {
|
||||
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
|
||||
ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep);
|
||||
if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second;
|
||||
string msg = (string("%Error: Testbench C called ")+namep
|
||||
+" but no such DPI export function name exists in ANY model");
|
||||
std::string msg = (std::string("%Error: Testbench C called ")+namep
|
||||
+" but no such DPI export function name exists in ANY model");
|
||||
vl_fatal("unknown",0,"", msg.c_str());
|
||||
return -1;
|
||||
}
|
||||
static const char* exportName(int funcnum) {
|
||||
// Slowpath; find name for given export; errors only so no map to reverse-map it
|
||||
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
|
||||
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
|
||||
if (it->second == funcnum) return it->first;
|
||||
}
|
||||
return "*UNKNOWN*";
|
||||
}
|
||||
static void exportsDump() {
|
||||
bool first = true;
|
||||
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
|
||||
for (ExportNameMap::const_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);
|
||||
}
|
||||
@@ -232,7 +238,7 @@ public: // But only for verilated*.cpp
|
||||
// Need to create more space in m_fdps and m_fdFree
|
||||
size_t start = s_s.m_fdps.size();
|
||||
s_s.m_fdps.resize(start*2);
|
||||
for (size_t i=start; i<start*2; i++) s_s.m_fdFree.push_back((IData)i);
|
||||
for (size_t i=start; i<start*2; ++i) s_s.m_fdFree.push_back(static_cast<IData>(i));
|
||||
}
|
||||
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
|
||||
s_s.m_fdps[idx] = fp;
|
||||
|
||||
+13
-13
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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.
|
||||
//
|
||||
@@ -40,8 +40,8 @@
|
||||
#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
|
||||
static const char* const VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file
|
||||
static const char* const VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
@@ -60,8 +60,8 @@ bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t siz
|
||||
|
||||
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) {
|
||||
if (VL_UNLIKELY(readDiffers(datap,size))) {
|
||||
string fn = filename();
|
||||
string msg = (string)"Can't deserialize save-restore file as was made from different model";
|
||||
std::string fn = filename();
|
||||
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
||||
vl_fatal(fn.c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
@@ -81,8 +81,8 @@ void VerilatedSerialize::header() {
|
||||
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 fn = filename();
|
||||
string msg = (string)"Can't deserialize; file has wrong header signature";
|
||||
std::string fn = filename();
|
||||
std::string msg = std::string("Can't deserialize; file has wrong header signature");
|
||||
vl_fatal(fn.c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
@@ -98,8 +98,8 @@ void VerilatedSerialize::trailer() {
|
||||
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 fn = filename();
|
||||
string msg = (string)"Can't deserialize; file has wrong end-of-file signature";
|
||||
std::string fn = filename();
|
||||
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
|
||||
vl_fatal(fn.c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
@@ -187,7 +187,7 @@ void VerilatedSave::flush() {
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
string msg = string(__FUNCTION__)+": "+strerror(errno);
|
||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
close();
|
||||
break;
|
||||
@@ -201,10 +201,10 @@ 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
|
||||
for (vluint8_t* sp=m_cp; sp < 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
|
||||
// Read into buffer starting at m_endp
|
||||
while (1) {
|
||||
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
||||
if (remaining==0) break;
|
||||
@@ -215,7 +215,7 @@ void VerilatedRestore::fill() {
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
string msg = string(__FUNCTION__)+": "+strerror(errno);
|
||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
close();
|
||||
break;
|
||||
|
||||
+52
-42
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2012-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2012-2017 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,64 +25,40 @@
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSerialBase - internal base class for common code between VerilatedSerialize and VerilatedDeserialize
|
||||
// VerilatedSerialize - convert structures to a stream representation
|
||||
|
||||
class VerilatedSerialBase {
|
||||
class VerilatedSerialize {
|
||||
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;
|
||||
std::string m_filename; ///< Filename, for error messages
|
||||
|
||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||
|
||||
void header();
|
||||
void trailer();
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedSerialBase() {
|
||||
VerilatedSerialize() {
|
||||
m_isOpen = false;
|
||||
m_bufp = new vluint8_t [bufferSize()];
|
||||
m_cp = m_bufp;
|
||||
}
|
||||
public:
|
||||
// CREATORS
|
||||
virtual ~VerilatedSerialBase() {
|
||||
virtual ~VerilatedSerialize() {
|
||||
close();
|
||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
string filename() const { return m_filename; }
|
||||
std::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) {
|
||||
@@ -94,22 +70,54 @@ public:
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
private:
|
||||
VerilatedSerialize(const VerilatedSerialize& ); ///< N/A, no copy constructor
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedDeserial - load structures from a stream representation
|
||||
|
||||
class VerilatedDeserialize : public VerilatedSerialBase {
|
||||
class VerilatedDeserialize {
|
||||
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
|
||||
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
||||
bool m_isOpen; ///< True indicates open file/stream
|
||||
std::string m_filename; ///< Filename, for error messages
|
||||
|
||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||
|
||||
virtual void fill() = 0;
|
||||
void header();
|
||||
void trailer();
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedDeserialize() { m_endp = NULL; }
|
||||
virtual ~VerilatedDeserialize() { close(); }
|
||||
VerilatedDeserialize() {
|
||||
m_isOpen = false;
|
||||
m_bufp = new vluint8_t [bufferSize()];
|
||||
m_cp = m_bufp;
|
||||
m_endp = NULL;
|
||||
}
|
||||
virtual ~VerilatedDeserialize() {
|
||||
close();
|
||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
std::string filename() const { return m_filename; }
|
||||
virtual void close() { flush(); }
|
||||
virtual void flush() {}
|
||||
inline VerilatedDeserialize& read (void* __restrict datap, size_t size) {
|
||||
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
||||
while (size) {
|
||||
@@ -125,6 +133,8 @@ public:
|
||||
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)); }
|
||||
private:
|
||||
VerilatedDeserialize(const VerilatedDeserialize& ); ///< N/A, no copy constructor
|
||||
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
|
||||
@@ -148,7 +158,7 @@ public:
|
||||
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()); }
|
||||
void open(const std::string& filename) { open(filename.c_str()); }
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
};
|
||||
@@ -167,7 +177,7 @@ public:
|
||||
|
||||
// METHODS
|
||||
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
|
||||
void open(const string& filename) { open(filename.c_str()); }
|
||||
void open(const std::string& filename) { open(filename.c_str()); }
|
||||
virtual void close();
|
||||
virtual void flush() {}
|
||||
virtual void fill();
|
||||
@@ -217,13 +227,13 @@ inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) {
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) {
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::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;
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
|
||||
vluint32_t len=0;
|
||||
os>>len;
|
||||
rhs.resize(len);
|
||||
return os.read((void*)rhs.data(), len);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 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.
|
||||
@@ -16,8 +16,8 @@
|
||||
/// \file
|
||||
/// \brief Verilator: Common include for all Verilated SystemC files
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all SystemC files it generates.
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all SystemC files it generates.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
@@ -39,9 +39,9 @@
|
||||
#define VL_SC_BV_DATAP(bv) (VlScBvExposer::sp_datap(bv))
|
||||
class VlScBvExposer : public sc_bv_base {
|
||||
public:
|
||||
static vluint32_t* sp_datap(const sc_bv_base& base) {
|
||||
return static_cast<const VlScBvExposer*>(&base)->sp_datatp(); }
|
||||
vluint32_t* sp_datatp() const { return (vluint32_t*)(m_data); }
|
||||
static const vluint32_t* sp_datap(const sc_bv_base& base) {
|
||||
return static_cast<const VlScBvExposer*>(&base)->sp_datatp(); }
|
||||
const vluint32_t* sp_datatp() const { return reinterpret_cast<vluint32_t*>(m_data); }
|
||||
// Above reads this protected element in sc_bv_base:
|
||||
// sc_digit* m_data; // data array
|
||||
};
|
||||
|
||||
+19
-14
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -32,21 +32,11 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
//======================================================================
|
||||
// Types
|
||||
|
||||
struct VerilatedCStrCmp {
|
||||
/// Ordering maps keyed by const char*'s
|
||||
bool operator() (const char *a, const char *b) const {
|
||||
return std::strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
/// Verilator range
|
||||
|
||||
// See also V3Ast::VNumRange
|
||||
class VerilatedRange {
|
||||
class VerilatedRange {
|
||||
int m_left;
|
||||
int m_right;
|
||||
protected:
|
||||
@@ -81,7 +71,7 @@ public:
|
||||
~VerilatedVar() {}
|
||||
void* datap() const { return m_datap; }
|
||||
VerilatedVarType vltype() const { return m_vltype; }
|
||||
VerilatedVarFlags vldir() const { return (VerilatedVarFlags)((int)m_vlflags & VLVF_MASK_DIR); }
|
||||
VerilatedVarFlags vldir() const { return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
|
||||
vluint32_t entSize() const;
|
||||
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
|
||||
const VerilatedRange& range() const { return m_range; }
|
||||
@@ -93,7 +83,22 @@ public:
|
||||
//======================================================================
|
||||
/// Types
|
||||
|
||||
class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
|
||||
struct VerilatedCStrCmp {
|
||||
/// Ordering maps keyed by const char*'s
|
||||
bool operator() (const char *a, const char *b) const {
|
||||
return std::strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
class VerilatedScopeNameMap
|
||||
: public std::map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
|
||||
public:
|
||||
VerilatedScopeNameMap() {}
|
||||
~VerilatedScopeNameMap() {}
|
||||
};
|
||||
|
||||
class VerilatedVarNameMap
|
||||
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
|
||||
public:
|
||||
VerilatedVarNameMap() {}
|
||||
~VerilatedVarNameMap() {}
|
||||
|
||||
+65
-40
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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.
|
||||
//
|
||||
@@ -47,9 +47,32 @@
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Global
|
||||
// VerilatedVcdImp
|
||||
/// Base class to hold some static state
|
||||
/// This is an internally used class
|
||||
|
||||
vector<VerilatedVcd*> VerilatedVcd::s_vcdVecp; ///< List of all created traces
|
||||
class VerilatedVcdSingleton {
|
||||
private:
|
||||
typedef std::vector<VerilatedVcd*> VcdVec;
|
||||
struct Singleton {
|
||||
VcdVec s_vcdVecp; ///< List of all created traces
|
||||
};
|
||||
static Singleton& singleton() { static Singleton s; return s; }
|
||||
public:
|
||||
static void pushVcd(VerilatedVcd* vcdp) {
|
||||
singleton().s_vcdVecp.push_back(vcdp);
|
||||
}
|
||||
static void removeVcd(const VerilatedVcd* vcdp) {
|
||||
VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp);
|
||||
if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); }
|
||||
}
|
||||
static void flush_all() {
|
||||
for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) {
|
||||
VerilatedVcd* vcdp = *it;
|
||||
vcdp->flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcdCallInfo
|
||||
@@ -72,6 +95,7 @@ protected:
|
||||
VerilatedVcdCallback_t changecb,
|
||||
void* ut, vluint32_t code)
|
||||
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
|
||||
~VerilatedVcdCallInfo() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
@@ -79,7 +103,7 @@ protected:
|
||||
//=============================================================================
|
||||
// VerilatedVcdFile
|
||||
|
||||
bool VerilatedVcdFile::open(const string& name) {
|
||||
bool VerilatedVcdFile::open(const std::string& name) {
|
||||
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666);
|
||||
return (m_fd>=0);
|
||||
}
|
||||
@@ -121,7 +145,7 @@ void VerilatedVcd::open (const char* filename) {
|
||||
|
||||
// Set member variables
|
||||
m_filename = filename;
|
||||
s_vcdVecp.push_back(this);
|
||||
VerilatedVcdSingleton::pushVcd(this);
|
||||
|
||||
// SPDIFF_OFF
|
||||
// Set callback so an early exit will flush us
|
||||
@@ -150,7 +174,7 @@ void VerilatedVcd::openNext (bool incFilename) {
|
||||
closePrev(); // Close existing
|
||||
if (incFilename) {
|
||||
// Find _0000.{ext} in filename
|
||||
string name = m_filename;
|
||||
std::string name = m_filename;
|
||||
size_t pos=name.rfind(".");
|
||||
if (pos>8 && 0==strncmp("_cat",name.c_str()+pos-8,4)
|
||||
&& isdigit(name.c_str()[pos-4])
|
||||
@@ -204,19 +228,19 @@ void VerilatedVcd::makeNameMap() {
|
||||
// If no scope was specified, prefix everything with a "top"
|
||||
// This comes from user instantiations with no name - IE Vtop("").
|
||||
bool nullScope = false;
|
||||
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const string& hiername = it->first;
|
||||
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const std::string& hiername = it->first;
|
||||
if (hiername.size() >= 1 && hiername[0] == '\t') nullScope=true;
|
||||
}
|
||||
if (nullScope) {
|
||||
NameMap* newmapp = new NameMap;
|
||||
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const string& hiername = it->first;
|
||||
const string& decl = it->second;
|
||||
string newname = string("top");
|
||||
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const std::string& hiername = it->first;
|
||||
const std::string& decl = it->second;
|
||||
std::string newname = std::string("top");
|
||||
if (hiername[0] != '\t') newname += ' ';
|
||||
newname += hiername;
|
||||
newmapp->insert(make_pair(newname,decl));
|
||||
newmapp->insert(std::make_pair(newname,decl));
|
||||
}
|
||||
deleteNameMap();
|
||||
m_namemapp = newmapp;
|
||||
@@ -233,9 +257,11 @@ VerilatedVcd::~VerilatedVcd() {
|
||||
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
|
||||
deleteNameMap();
|
||||
if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; }
|
||||
// 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); }
|
||||
for (CallbackVec::const_iterator it=m_callbacks.begin(); it!=m_callbacks.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
m_callbacks.clear();
|
||||
VerilatedVcdSingleton::removeVcd(this);
|
||||
}
|
||||
|
||||
void VerilatedVcd::closePrev () {
|
||||
@@ -326,7 +352,7 @@ void VerilatedVcd::bufferFlush () {
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
string msg = (string)"VerilatedVcd::bufferFlush: "+strerror(errno);
|
||||
std::string msg = std::string("VerilatedVcd::bufferFlush: ")+strerror(errno);
|
||||
vl_fatal("",0,"",msg.c_str());
|
||||
closeErr();
|
||||
break;
|
||||
@@ -354,7 +380,7 @@ void VerilatedVcd::set_time_resolution (const char* unitp) {
|
||||
double VerilatedVcd::timescaleToDouble (const char* unitp) {
|
||||
char* endp;
|
||||
double value = strtod(unitp, &endp);
|
||||
if (!value) value=1; // On error so we allow just "ns" to return 1e-9.
|
||||
if (value==0.0 && endp==unitp) value=1; // On error so we allow just "ns" to return 1e-9.
|
||||
unitp=endp;
|
||||
while (*unitp && isspace(*unitp)) unitp++;
|
||||
switch (*unitp) {
|
||||
@@ -369,7 +395,7 @@ double VerilatedVcd::timescaleToDouble (const char* unitp) {
|
||||
return value;
|
||||
}
|
||||
|
||||
string VerilatedVcd::doubleToTimescale (double value) {
|
||||
std::string VerilatedVcd::doubleToTimescale (double value) {
|
||||
const char* suffixp = "s";
|
||||
if (value>=1e0) { suffixp="s"; value *= 1e0; }
|
||||
else if (value>=1e-3 ) { suffixp="ms"; value *= 1e3; }
|
||||
@@ -378,7 +404,7 @@ string VerilatedVcd::doubleToTimescale (double value) {
|
||||
else if (value>=1e-12) { suffixp="ps"; value *= 1e12; }
|
||||
else if (value>=1e-15) { suffixp="fs"; value *= 1e15; }
|
||||
else if (value>=1e-18) { suffixp="as"; value *= 1e18; }
|
||||
char valuestr[100]; sprintf(valuestr,"%d%s",(int)(value), suffixp);
|
||||
char valuestr[100]; sprintf(valuestr,"%3.0f%s", value, suffixp);
|
||||
return valuestr; // Gets converted to string, so no ref to stack
|
||||
}
|
||||
|
||||
@@ -398,7 +424,7 @@ void VerilatedVcd::dumpHeader () {
|
||||
printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n");
|
||||
|
||||
printStr("$timescale ");
|
||||
const string& timeResStr = doubleToTimescale(m_timeRes);
|
||||
const std::string& timeResStr = doubleToTimescale(m_timeRes);
|
||||
printStr(timeResStr.c_str());
|
||||
printStr(" $end\n");
|
||||
|
||||
@@ -412,13 +438,13 @@ void VerilatedVcd::dumpHeader () {
|
||||
// We detect the spaces in module names to determine hierarchy. This
|
||||
// allows signals to be declared without fixed ordering, which is
|
||||
// required as Verilog signals might be separately declared from
|
||||
// "SP_TRACE" signals.
|
||||
// SC module signals.
|
||||
|
||||
// Print the signal names
|
||||
const char* lastName = "";
|
||||
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const string& hiernamestr = it->first;
|
||||
const string& decl = it->second;
|
||||
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const std::string& hiernamestr = it->first;
|
||||
const std::string& decl = it->second;
|
||||
|
||||
// Determine difference between the old and new names
|
||||
const char* hiername = hiernamestr.c_str();
|
||||
@@ -472,7 +498,7 @@ void VerilatedVcd::dumpHeader () {
|
||||
deleteNameMap();
|
||||
}
|
||||
|
||||
void VerilatedVcd::module (const string& name) {
|
||||
void VerilatedVcd::module (const std::string& name) {
|
||||
m_modName = name;
|
||||
}
|
||||
|
||||
@@ -485,7 +511,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
|
||||
if (tri) codesNeeded *= 2; // Space in change array for __en signals
|
||||
|
||||
// Make sure array is large enough
|
||||
m_nextCode = max(nextCode(), code+codesNeeded);
|
||||
m_nextCode = std::max(nextCode(), code+codesNeeded);
|
||||
if (m_sigs.capacity() <= m_nextCode) {
|
||||
m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up
|
||||
}
|
||||
@@ -503,10 +529,10 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
|
||||
// Tab separates final scope from signal name
|
||||
// Tab sorts before spaces, so signals nicely will print before scopes
|
||||
// Note the hiername may be nothing, if so we'll add "\t{name}"
|
||||
string nameasstr = name;
|
||||
std::string nameasstr = name;
|
||||
if (m_modName!="") { nameasstr = m_modName+m_scopeEscape+nameasstr; } // Optional ->module prefix
|
||||
string hiername;
|
||||
string basename;
|
||||
std::string hiername;
|
||||
std::string basename;
|
||||
for (const char* cp=nameasstr.c_str(); *cp; cp++) {
|
||||
if (isScopeEscape(*cp)) {
|
||||
// Ahh, we've just read a scope, not a basename
|
||||
@@ -520,7 +546,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
|
||||
hiername += "\t"+basename;
|
||||
|
||||
// Print reference
|
||||
string decl = "$var ";
|
||||
std::string decl = "$var ";
|
||||
if (m_evcd) decl += "port"; else decl += wirep; // usually "wire"
|
||||
char buf [1000];
|
||||
sprintf(buf, " %2d ", bits);
|
||||
@@ -543,7 +569,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
|
||||
decl += buf;
|
||||
}
|
||||
decl += " $end\n";
|
||||
m_namemapp->insert(make_pair(hiername,decl));
|
||||
m_namemapp->insert(std::make_pair(hiername,decl));
|
||||
}
|
||||
|
||||
void VerilatedVcd::declBit (vluint32_t code, const char* name, int arraynum)
|
||||
@@ -570,7 +596,8 @@ void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum
|
||||
//=============================================================================
|
||||
|
||||
void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
|
||||
(*((double*)&m_sigs_oldvalp[code])) = newval;
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
(*(reinterpret_cast<double*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
// Buffer can't overflow before sprintf; we sized during declaration
|
||||
sprintf(m_writep, "r%.16g", newval);
|
||||
m_writep += strlen(m_writep);
|
||||
@@ -578,9 +605,10 @@ void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
|
||||
bufferCheck();
|
||||
}
|
||||
void VerilatedVcd::fullFloat (vluint32_t code, const float newval) {
|
||||
(*((float*)&m_sigs_oldvalp[code])) = newval;
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
(*(reinterpret_cast<float*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
// Buffer can't overflow before sprintf; we sized during declaration
|
||||
sprintf(m_writep, "r%.16g", (double)newval);
|
||||
sprintf(m_writep, "r%.16g", static_cast<double>(newval));
|
||||
m_writep += strlen(m_writep);
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
@@ -594,7 +622,7 @@ void VerilatedVcd::addCallback (
|
||||
void* userthis)
|
||||
{
|
||||
if (VL_UNLIKELY(isOpen())) {
|
||||
string msg = (string)"Internal: "+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
||||
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
||||
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
|
||||
}
|
||||
VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, nextCode());
|
||||
@@ -645,10 +673,7 @@ void VerilatedVcd::dumpDone () {
|
||||
// Static members
|
||||
|
||||
void VerilatedVcd::flush_all() {
|
||||
for (vluint32_t ent = 0; ent< s_vcdVecp.size(); ent++) {
|
||||
VerilatedVcd* vcdp = s_vcdVecp[ent];
|
||||
vcdp->flush();
|
||||
}
|
||||
VerilatedVcdSingleton::flush_all();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
+53
-40
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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,7 +28,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
class VerilatedVcd;
|
||||
class VerilatedVcdCallInfo;
|
||||
@@ -45,7 +44,7 @@ public:
|
||||
// METHODS
|
||||
VerilatedVcdFile() : m_fd(0) {}
|
||||
virtual ~VerilatedVcdFile() {}
|
||||
virtual bool open(const string& name);
|
||||
virtual bool open(const std::string& name);
|
||||
virtual void close();
|
||||
virtual ssize_t write(const char* bufp, ssize_t len);
|
||||
};
|
||||
@@ -80,13 +79,13 @@ private:
|
||||
bool m_fileNewed; ///< m_filep needs destruction
|
||||
bool m_isOpen; ///< True indicates open file
|
||||
bool m_evcd; ///< True for evcd format
|
||||
string m_filename; ///< Filename we're writing to (if open)
|
||||
std::string m_filename; ///< Filename we're writing to (if open)
|
||||
vluint64_t m_rolloverMB; ///< MB of file size to rollover at
|
||||
char m_scopeEscape; ///< Character to separate scope components
|
||||
int m_modDepth; ///< Depth of module hierarchy
|
||||
bool m_fullDump; ///< True indicates dump ignoring if changed
|
||||
vluint32_t m_nextCode; ///< Next code number to assign
|
||||
string m_modName; ///< Module name being traced now
|
||||
std::string m_modName; ///< Module name being traced now
|
||||
double m_timeRes; ///< Time resolution (ns/ms etc)
|
||||
double m_timeUnit; ///< Time units (ns/ms etc)
|
||||
vluint64_t m_timeLastDump; ///< Last time we did a dump
|
||||
@@ -97,12 +96,13 @@ private:
|
||||
vluint64_t m_wrChunkSize; ///< Output buffer size
|
||||
vluint64_t m_wroteBytes; ///< Number of bytes written to this file
|
||||
|
||||
vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values
|
||||
vector<VerilatedVcdSig> m_sigs; ///< Pointer to signal information
|
||||
vector<VerilatedVcdCallInfo*> m_callbacks; ///< Routines to perform dumping
|
||||
typedef map<string,string> NameMap;
|
||||
NameMap* m_namemapp; ///< List of names for the header
|
||||
static vector<VerilatedVcd*> s_vcdVecp; ///< List of all created traces
|
||||
vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values
|
||||
typedef std::vector<VerilatedVcdSig> SigVec;
|
||||
SigVec m_sigs; ///< Pointer to signal information
|
||||
typedef std::vector<VerilatedVcdCallInfo*> CallbackVec;
|
||||
CallbackVec m_callbacks; ///< Routines to perform dumping
|
||||
typedef std::map<std::string,std::string> NameMap;
|
||||
NameMap* m_namemapp; ///< List of names for the header
|
||||
|
||||
void bufferResize(vluint64_t minsize);
|
||||
void bufferFlush();
|
||||
@@ -131,26 +131,28 @@ private:
|
||||
// cppcheck-suppress functionConst
|
||||
void dumpDone ();
|
||||
inline void printCode (vluint32_t code) {
|
||||
if (code>=(94*94*94)) *m_writep++ = ((char)((code/94/94/94)%94+33));
|
||||
if (code>=(94*94)) *m_writep++ = ((char)((code/94/94)%94+33));
|
||||
if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33));
|
||||
*m_writep++ = ((char)((code)%94+33));
|
||||
if (code>=(94*94*94)) *m_writep++ = static_cast<char>((code/94/94/94)%94+33);
|
||||
if (code>=(94*94)) *m_writep++ = static_cast<char>((code/94/94)%94+33);
|
||||
if (code>=(94)) *m_writep++ = static_cast<char>((code/94)%94+33);
|
||||
*m_writep++ = static_cast<char>((code)%94+33);
|
||||
}
|
||||
static string stringCode (vluint32_t code) {
|
||||
string out;
|
||||
if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33));
|
||||
if (code>=(94*94)) out += ((char)((code/94/94)%94+33));
|
||||
if (code>=(94)) out += ((char)((code/94)%94+33));
|
||||
return out + ((char)((code)%94+33));
|
||||
static std::string stringCode (vluint32_t code) {
|
||||
std::string out;
|
||||
if (code>=(94*94*94)) out += static_cast<char>((code/94/94/94)%94+33);
|
||||
if (code>=(94*94)) out += static_cast<char>((code/94/94)%94+33);
|
||||
if (code>=(94)) out += static_cast<char>((code/94)%94+33);
|
||||
return out + static_cast<char>((code)%94+33);
|
||||
}
|
||||
|
||||
VerilatedVcd(const VerilatedVcd& ); ///< N/A, no copy constructor
|
||||
|
||||
protected:
|
||||
// METHODS
|
||||
void evcd(bool flag) { m_evcd = flag; }
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
VerilatedVcd(VerilatedVcdFile* filep=NULL);
|
||||
explicit VerilatedVcd(VerilatedVcdFile* filep=NULL);
|
||||
~VerilatedVcd();
|
||||
|
||||
// ACCESSORS
|
||||
@@ -173,18 +175,18 @@ public:
|
||||
void close (); ///< Close the file
|
||||
|
||||
void set_time_unit (const char* unit); ///< Set time units (s/ms, defaults to ns)
|
||||
void set_time_unit (const string& unit) { set_time_unit(unit.c_str()); }
|
||||
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
|
||||
void set_time_resolution (const char* unit); ///< Set time resolution (s/ms, defaults to ns)
|
||||
void set_time_resolution (const string& unit) { set_time_resolution(unit.c_str()); }
|
||||
void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
double timescaleToDouble (const char* unitp);
|
||||
string doubleToTimescale (double value);
|
||||
std::string doubleToTimescale (double value);
|
||||
|
||||
/// Inside dumping routines, called each cycle to make the dump
|
||||
void dump (vluint64_t timeui);
|
||||
/// Call dump with a absolute unscaled time in seconds
|
||||
void dumpSeconds (double secs) { dump((vluint64_t)(secs * m_timeRes)); }
|
||||
void dumpSeconds (double secs) { dump(static_cast<vluint64_t>(secs * m_timeRes)); }
|
||||
|
||||
/// Inside dumping routines, declare callbacks for tracings
|
||||
void addCallback (VerilatedVcdCallback_t init, VerilatedVcdCallback_t full,
|
||||
@@ -192,7 +194,7 @@ public:
|
||||
void* userthis);
|
||||
|
||||
/// Inside dumping routines, declare a module
|
||||
void module (const string& name);
|
||||
void module (const std::string& name);
|
||||
/// Inside dumping routines, declare a signal
|
||||
void declBit (vluint32_t code, const char* name, int arraynum);
|
||||
void declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
@@ -210,7 +212,7 @@ public:
|
||||
void fullBit (vluint32_t code, const vluint32_t newval) {
|
||||
// Note the &1, so we don't require clean input -- makes more common no change case faster
|
||||
m_sigs_oldvalp[code] = newval;
|
||||
*m_writep++=('0'+(char)(newval&1)); printCode(code); *m_writep++='\n';
|
||||
*m_writep++=('0'+static_cast<char>(newval&1)); printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullBus (vluint32_t code, const vluint32_t newval, int bits) {
|
||||
@@ -223,7 +225,7 @@ public:
|
||||
bufferCheck();
|
||||
}
|
||||
void fullQuad (vluint32_t code, const vluint64_t newval, int bits) {
|
||||
(*((vluint64_t*)&m_sigs_oldvalp[code])) = newval;
|
||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++=((newval&(1ULL<<bit))?'1':'0');
|
||||
@@ -262,8 +264,8 @@ public:
|
||||
bufferCheck();
|
||||
}
|
||||
void fullTriQuad (vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) {
|
||||
(*((vluint64_t*)&m_sigs_oldvalp[code])) = newval;
|
||||
(*((vluint64_t*)&m_sigs_oldvalp[code+1])) = newtri;
|
||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) = newtri;
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++ = "01zz"[((newval >> bit)&1ULL)
|
||||
@@ -327,7 +329,7 @@ public:
|
||||
}
|
||||
}
|
||||
inline void chgQuad (vluint32_t code, const vluint64_t newval, int bits) {
|
||||
vluint64_t diff = (*((vluint64_t*)&m_sigs_oldvalp[code])) ^ newval;
|
||||
vluint64_t diff = (*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval;
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
|
||||
fullQuad(code, newval, bits);
|
||||
@@ -362,8 +364,8 @@ public:
|
||||
}
|
||||
}
|
||||
inline void chgTriQuad (vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) {
|
||||
vluint64_t diff = ( ((*((vluint64_t*)&m_sigs_oldvalp[code])) ^ newval)
|
||||
| ((*((vluint64_t*)&m_sigs_oldvalp[code+1])) ^ newtri));
|
||||
vluint64_t diff = ( ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval)
|
||||
| ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) ^ newtri));
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
|
||||
fullTriQuad(code, newval, newtri, bits);
|
||||
@@ -380,12 +382,14 @@ public:
|
||||
}
|
||||
}
|
||||
inline void chgDouble (vluint32_t code, const double newval) {
|
||||
if (VL_UNLIKELY((*((double*)&m_sigs_oldvalp[code])) != newval)) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY((*(reinterpret_cast<double*>(&m_sigs_oldvalp[code]))) != newval)) {
|
||||
fullDouble (code, newval);
|
||||
}
|
||||
}
|
||||
inline void chgFloat (vluint32_t code, const float newval) {
|
||||
if (VL_UNLIKELY((*((float*)&m_sigs_oldvalp[code])) != newval)) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY((*(reinterpret_cast<float*>(&m_sigs_oldvalp[code]))) != newval)) {
|
||||
fullFloat (code, newval);
|
||||
}
|
||||
}
|
||||
@@ -399,7 +403,7 @@ class VerilatedVcdC {
|
||||
VerilatedVcd m_sptrace; ///< Trace file being created
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
|
||||
explicit VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
|
||||
~VerilatedVcdC() {}
|
||||
// ACCESSORS
|
||||
/// Is file open?
|
||||
@@ -423,9 +427,18 @@ public:
|
||||
void dump (vluint64_t timeui) { m_sptrace.dump(timeui); }
|
||||
/// Write one cycle of dump data - backward compatible and to reduce
|
||||
/// conversion warnings. It's better to use a vluint64_t time instead.
|
||||
void dump (double timestamp) { dump((vluint64_t)timestamp); }
|
||||
void dump (vluint32_t timestamp) { dump((vluint64_t)timestamp); }
|
||||
void dump (int timestamp) { dump((vluint64_t)timestamp); }
|
||||
void dump (double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
void dump (vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
void dump (int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
/// Set time units (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_unit (const char* unit) { m_sptrace.set_time_unit(unit); }
|
||||
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
/// Set time resolution (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_resolution (const char* unit) { m_sptrace.set_time_resolution(unit); }
|
||||
void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
/// Internal class access
|
||||
inline VerilatedVcd* spTrace () { return &m_sptrace; };
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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.
|
||||
//
|
||||
@@ -30,6 +30,7 @@
|
||||
//--------------------------------------------------
|
||||
#if (SYSTEMC_VERSION>=20050714)
|
||||
// SystemC 2.1.v1
|
||||
// cppcheck-suppress unusedFunction
|
||||
void VerilatedVcdSc::write_comment (const std::string &) {}
|
||||
void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const char **) {}
|
||||
|
||||
@@ -74,6 +75,7 @@ void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const cha
|
||||
//--------------------------------------------------
|
||||
#elif (SYSTEMC_VERSION>20011000)
|
||||
// SystemC 2.0.1
|
||||
// cppcheck-suppress unusedFunction
|
||||
void VerilatedVcdSc::write_comment (const sc_string &) {}
|
||||
void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {}
|
||||
|
||||
@@ -116,6 +118,7 @@ void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char
|
||||
//--------------------------------------------------
|
||||
#else
|
||||
// SystemC 1.2.1beta
|
||||
// cppcheck-suppress unusedFunction
|
||||
void VerilatedVcdSc::write_comment (const sc_string &) {}
|
||||
void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2015 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 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.
|
||||
//
|
||||
|
||||
+1051
-6
File diff suppressed because it is too large
Load Diff
+63
-1036
File diff suppressed because it is too large
Load Diff
+38
-11
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -46,6 +46,7 @@
|
||||
# define VL_FUNC __func__
|
||||
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
# define VL_UNREACHABLE __builtin_unreachable();
|
||||
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
|
||||
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
|
||||
#elif defined(_MSC_VER)
|
||||
@@ -57,6 +58,7 @@
|
||||
# define VL_FUNC __FUNCTION__
|
||||
# define VL_LIKELY(x) (!!(x))
|
||||
# define VL_UNLIKELY(x) (!!(x))
|
||||
# define VL_UNREACHABLE
|
||||
# define VL_PREFETCH_RD(p)
|
||||
# define VL_PREFETCH_RW(p)
|
||||
#else
|
||||
@@ -68,23 +70,25 @@
|
||||
# define VL_FUNC "__func__" ///< Name of current function for error macros
|
||||
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
|
||||
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
|
||||
# define VL_UNREACHABLE ///< Point that may never be reached
|
||||
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
|
||||
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
|
||||
#endif
|
||||
|
||||
#ifdef VL_THREADED
|
||||
# ifdef __GNUC__
|
||||
# define VL_THREAD __thread ///< Storage class for thread-local storage
|
||||
# if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING)
|
||||
# error "VL_THREADED support plans to move to C++-11 and later only; use newer --std to be ready"
|
||||
# endif
|
||||
# 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"
|
||||
# define VL_THREAD_LOCAL thread_local ///< Use new C++ static local thread
|
||||
#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"
|
||||
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
|
||||
#endif
|
||||
#define VL_THREAD ///< Deprecated
|
||||
#define VL_STATIC_OR_THREAD static ///< Deprecated
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
|
||||
@@ -93,16 +97,27 @@
|
||||
#endif
|
||||
|
||||
// This is not necessarily the same as #UL, depending on what the IData typedef is.
|
||||
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
|
||||
#define VL_UL(c) (static_cast<IData>(c##UL)) ///< Add appropriate suffix to 32-bit constant
|
||||
|
||||
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
|
||||
# define VL_DANGLING(v)
|
||||
#else
|
||||
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// C++-2011
|
||||
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define VL_HAS_UNIQUE_PTR
|
||||
# define VL_UNIQUE_PTR unique_ptr
|
||||
# define VL_HAS_UNORDERED_MAP
|
||||
# define VL_UNIQUE_PTR std::unique_ptr
|
||||
# define VL_UNORDERED_MAP std::unordered_map
|
||||
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
|
||||
#else
|
||||
# define VL_UNIQUE_PTR auto_ptr
|
||||
# define VL_UNIQUE_PTR std::auto_ptr
|
||||
# define VL_UNORDERED_MAP std::map
|
||||
# define VL_INCLUDE_UNORDERED_MAP <map>
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
@@ -139,7 +154,7 @@ typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward comp
|
||||
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
# ifdef __uint32_t_defined // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
||||
# if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
||||
typedef int32_t vlsint32_t; ///< 32-bit signed type
|
||||
typedef uint32_t vluint32_t; ///< 32-bit unsigned type
|
||||
# else // Older Cygwin has long==uint32_t
|
||||
@@ -207,6 +222,18 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# if (_MSC_VER < 1900)
|
||||
# define VL_SNPRINTF _snprintf
|
||||
# else
|
||||
# define VL_SNPRINTF snprintf
|
||||
# endif
|
||||
# define VL_VSNPRINTF vsnprintf
|
||||
#else
|
||||
# define VL_SNPRINTF snprintf
|
||||
# define VL_VSNPRINTF vsnprintf
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// File system functions
|
||||
|
||||
|
||||
@@ -105,10 +105,12 @@ typedef unsigned char PLI_UBYTE8;
|
||||
|
||||
/* object is defined imported by the application */
|
||||
|
||||
#undef XXTERN
|
||||
#define XXTERN PLI_EXTERN PLI_DLLISPEC
|
||||
|
||||
/* object is exported by the application */
|
||||
|
||||
#undef EETERN
|
||||
#define EETERN PLI_EXTERN PLI_DLLESPEC
|
||||
#endif
|
||||
|
||||
|
||||
+7
-7
@@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
@@ -134,7 +134,7 @@ else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
@@ -162,7 +162,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
@@ -201,17 +201,17 @@ else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
@@ -242,7 +242,7 @@ else
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
+10
-10
@@ -237,10 +237,10 @@ implementation is not found, the system will look in turn for overloaded
|
||||
implementations up the inheritance hierarchy. For example calling C<accept>
|
||||
on C<AstIf> will look in turn for:
|
||||
|
||||
void visit (AstIf* nodep, AstNUser* vup)
|
||||
void visit (AstNodeIf* nodep, AstNUser* vup)
|
||||
void visit (AstNodeStmt* nodep, AstNUser* vup)
|
||||
void visit (AstNode* nodep, AstNUser* vup)
|
||||
void visit (AstIf* nodep)
|
||||
void visit (AstNodeIf* nodep)
|
||||
void visit (AstNodeStmt* nodep)
|
||||
void visit (AstNode* nodep)
|
||||
|
||||
There are three ways data is passed between visitor functions.
|
||||
|
||||
@@ -485,10 +485,10 @@ be warning free.
|
||||
|
||||
=item --enable-longtests
|
||||
|
||||
In addition to the standard C, SystemC tests also run the tests in the
|
||||
C<test_verilated> and C<test_regress> directories when using I<make test>.
|
||||
This is disabled by default as SystemC installation problems would
|
||||
otherwise falsely indicate a Verilator problem.
|
||||
In addition to the standard C, SystemC examples, also run the tests in the
|
||||
C<test_regress> directory when using I<make test>. This is disabled by
|
||||
default as SystemC installation problems would otherwise falsely indicate a
|
||||
Verilator problem.
|
||||
|
||||
=back
|
||||
|
||||
@@ -709,7 +709,7 @@ Start GDB, then C<start> with the remaining arguments.
|
||||
Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
|
||||
at ../Verilator.cpp:615
|
||||
615 ios::sync_with_stdio();
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
You can then continue execution with breakpoints as required.
|
||||
|
||||
@@ -785,7 +785,7 @@ in C<src/Makefile_obj.in> and reconfigure.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2008-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2008-2017 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-2015 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2017 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-2015 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2017 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-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2017 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-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2017 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-2015 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2017 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
-2
@@ -115,7 +115,8 @@ sub write_verilog {
|
||||
|
||||
sub cleanenv {
|
||||
foreach my $var (keys %ENV) {
|
||||
if ($var eq "VERILATOR_ROOT") {
|
||||
if ($var eq "VERILATOR_ROOT"
|
||||
|| $var eq "VERILATOR_INCLUDE") {
|
||||
print "unset $var # Was '$ENV{$var}'\n";
|
||||
delete $ENV{$var}
|
||||
}
|
||||
@@ -183,7 +184,7 @@ Runs a specific test stage (see the script).
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2009-2015 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2009-2017 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-2015 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2017 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-2015 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2007-2017 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-2015 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2017 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.
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ use strict;
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
eval `modulecmd perl add synopsys-vcs_mx`;
|
||||
eval `modulecmd perl add synopsys-sim`;
|
||||
exec('vcs',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
@@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2015 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2017 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-2015 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2017 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,6 +1,6 @@
|
||||
# DESCRIPTION: Verilator: GDB startup file with useful defines
|
||||
#
|
||||
# Copyright 2012-2015 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2012-2017 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.
|
||||
|
||||
+10
-8
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2017 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.
|
||||
@@ -46,25 +46,27 @@ obj_opt:
|
||||
obj_dbg:
|
||||
mkdir $@
|
||||
|
||||
.PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg
|
||||
.SUFFIXES:
|
||||
|
||||
opt: ../verilator_bin
|
||||
.PHONY: ../bin/verilator_bin ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
|
||||
|
||||
opt: ../bin/verilator_bin
|
||||
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
|
||||
../verilator_bin: ../verilator_bin_dbg
|
||||
../bin/verilator_bin: ../bin/verilator_bin_dbg
|
||||
-rm -rf $@ $@.exe
|
||||
-cp -p $<$(EXEEXT) $@$(EXEEXT)
|
||||
else
|
||||
../verilator_bin: obj_opt prefiles
|
||||
../bin/verilator_bin: obj_opt prefiles
|
||||
cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial
|
||||
cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj
|
||||
endif
|
||||
|
||||
dbg: ../verilator_bin_dbg ../verilator_coverage_bin_dbg
|
||||
../verilator_bin_dbg: obj_dbg prefiles
|
||||
dbg: ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
|
||||
../bin/verilator_bin_dbg: obj_dbg prefiles
|
||||
cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
|
||||
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
|
||||
|
||||
../verilator_coverage_bin_dbg: obj_dbg prefiles
|
||||
../bin/verilator_coverage_bin_dbg: obj_dbg prefiles
|
||||
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj serial_vlcov
|
||||
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj
|
||||
|
||||
|
||||
+11
-12
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2017 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,8 @@ LDFLAGS += @LDFLAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@
|
||||
CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@
|
||||
# Compiler flags that turn on extra warnings
|
||||
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
@@ -73,7 +75,7 @@ TGT = ../../verilator_bin
|
||||
#################
|
||||
ifeq ($(VL_DEBUG),)
|
||||
# Optimize
|
||||
COPT = -O
|
||||
COPT = -O2
|
||||
else
|
||||
# Debug
|
||||
COPT = -ggdb -DVL_DEBUG
|
||||
@@ -97,18 +99,14 @@ CPPFLAGS += -DYYDEBUG # Required to get nice error messages
|
||||
CPPFLAGS += $(COPT)
|
||||
CPPFLAGS += -MP # Only works on recent GCC versions
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_SRC) -Werror
|
||||
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
|
||||
#CPPFLAGS += -pedantic-errors
|
||||
else
|
||||
CPPFLAGS += $(CFG_CXXFLAGS_SRC)
|
||||
endif
|
||||
CPPFLAGSWALL = $(CPPFLAGS)
|
||||
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)
|
||||
|
||||
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
|
||||
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
|
||||
#else if set, leave as-is.
|
||||
#else if SYSTEMPERL="" don't set _INCLUDE so source will figure it out
|
||||
endif
|
||||
|
||||
# Allow RPM builds to specify hardcoded data directories
|
||||
# To do this:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
@@ -116,8 +114,6 @@ ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL_INCLUDE=\"$(SYSTEMPERL_INCLUDE)\"
|
||||
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
|
||||
else
|
||||
@@ -164,6 +160,7 @@ RAW_OBJS = \
|
||||
V3Begin.o \
|
||||
V3Branch.o \
|
||||
V3Broken.o \
|
||||
V3CCtors.o \
|
||||
V3Case.o \
|
||||
V3Cast.o \
|
||||
V3Cdc.o \
|
||||
@@ -299,7 +296,7 @@ serial:: V3Ast__gen_classes.h V3ParseBison.c
|
||||
|
||||
serial_vlcov:: vlcovgen.d
|
||||
|
||||
vlcovgen.d: $(VLCOVGEN) $(srcdir)/include/verilated_cov_key.h
|
||||
vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
|
||||
$(PERL) $(VLCOVGEN) --srcdir $(srcdir)
|
||||
touch $@
|
||||
|
||||
@@ -327,6 +324,8 @@ V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS)
|
||||
V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX)
|
||||
$(PERL) $(FLEXFIX) V3PreLex <$< >$@
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
######################################################################
|
||||
######################################################################
|
||||
|
||||
|
||||
+38
-36
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
m_scopep->addActivep(nodep);
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
m_scopep = nodep;
|
||||
m_iActivep = NULL;
|
||||
m_cActivep = NULL;
|
||||
@@ -81,15 +81,15 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
// Don't clear scopep, the namer persists beyond this visit
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenTree* nodep) {
|
||||
// Simplify sensitivity list
|
||||
V3Const::constifyExpensiveEdit(nodep); nodep=NULL;
|
||||
V3Const::constifyExpensiveEdit(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
// Empty visitors, speed things up
|
||||
virtual void visit(AstNodeStmt* nodep, AstNUser*) { }
|
||||
virtual void visit(AstNodeStmt* nodep) { }
|
||||
//--------------------
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
@@ -169,14 +169,14 @@ private:
|
||||
AstNode* m_alwaysp; // Always we're under
|
||||
AstNode* m_assignp; // In assign
|
||||
// VISITORS
|
||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignDly* nodep) {
|
||||
if (m_check != CT_SEQ) {
|
||||
// Convert to a non-delayed assignment
|
||||
UINFO(5," ASSIGNDLY "<<nodep<<endl);
|
||||
if (m_check == CT_INITIAL) {
|
||||
nodep->v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=).");
|
||||
} else if (m_check == CT_LATCH) {
|
||||
// Suppress. Shouldn't matter that the interior of the latch races
|
||||
// Suppress. Shouldn't matter that the interior of the latch races
|
||||
} else {
|
||||
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
|
||||
}
|
||||
@@ -184,10 +184,10 @@ private:
|
||||
nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); nodep = NULL;
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssign* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssign* nodep) {
|
||||
if (m_check == CT_SEQ) {
|
||||
AstNode* las = m_assignp;
|
||||
m_assignp = nodep;
|
||||
@@ -195,7 +195,7 @@ private:
|
||||
m_assignp = las;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
AstVar* varp=nodep->varp();
|
||||
if (m_check == CT_SEQ
|
||||
&& m_assignp
|
||||
@@ -214,7 +214,7 @@ private:
|
||||
}
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -244,7 +244,7 @@ private:
|
||||
bool m_itemSequent; // Found a SenItem sequential
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
// Create required actives and add to scope
|
||||
UINFO(4," SCOPE "<<nodep<<endl);
|
||||
// Clear last scope's names, and collect this scope's existing names
|
||||
@@ -252,10 +252,10 @@ private:
|
||||
m_scopeFinalp = NULL;
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
// Actives are being formed, so we can ignore any already made
|
||||
}
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||
virtual void visit(AstInitial* nodep) {
|
||||
// Relink to IACTIVE, unless already under it
|
||||
UINFO(4," INITIAL "<<nodep<<endl);
|
||||
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
|
||||
@@ -263,32 +263,32 @@ private:
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignAlias* nodep) {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4," ASSIGNW "<<nodep<<endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignW* nodep) {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4," ASSIGNW "<<nodep<<endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
|
||||
virtual void visit(AstCoverToggle* nodep) {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4," COVERTOGGLE "<<nodep<<endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstFinal* nodep, AstNUser*) {
|
||||
virtual void visit(AstFinal* nodep) {
|
||||
// Relink to CFUNC for the final
|
||||
UINFO(4," FINAL "<<nodep<<endl);
|
||||
if (!nodep->bodysp()) { // Empty, Kill it.
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
|
||||
@@ -304,7 +304,7 @@ private:
|
||||
nodep->unlinkFrBack();
|
||||
m_scopeFinalp->addStmtsp(new AstComment(nodep->fileline(), nodep->typeName()));
|
||||
m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext());
|
||||
nodep->deleteTree(); nodep = NULL;
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
// METHODS
|
||||
@@ -316,20 +316,22 @@ private:
|
||||
&& oldsensesp->sensesp()->castSenItem()->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read sensitivitues
|
||||
m_itemCombo = false;
|
||||
m_itemSequent = false;
|
||||
oldsensesp->iterateAndNext(*this);
|
||||
if (oldsensesp) oldsensesp->iterateAndNext(*this);
|
||||
bool combo = m_itemCombo;
|
||||
bool sequent = m_itemSequent;
|
||||
|
||||
if (!combo && !sequent) combo=true; // If no list, Verilog 2000: always @ (*)
|
||||
if (combo && sequent) {
|
||||
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
|
||||
if (!v3Global.opt.bboxUnsup()) {
|
||||
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
|
||||
}
|
||||
sequent = false;
|
||||
}
|
||||
|
||||
@@ -351,7 +353,7 @@ private:
|
||||
|
||||
// Delete sensitivity list
|
||||
if (oldsensesp) {
|
||||
oldsensesp->unlinkFrBackWithNext()->deleteTree(); oldsensesp=NULL;
|
||||
oldsensesp->unlinkFrBackWithNext()->deleteTree(); VL_DANGLING(oldsensesp);
|
||||
}
|
||||
|
||||
// Move node to new active
|
||||
@@ -370,25 +372,25 @@ private:
|
||||
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
// Move always to appropriate ACTIVE based on its sense list
|
||||
UINFO(4," ALW "<<nodep<<endl);
|
||||
//if (debug()>=9) nodep->dumpTree(cout," Alw: ");
|
||||
|
||||
if (!nodep->bodysp()) {
|
||||
// Empty always. Kill it.
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
visitAlways(nodep, nodep->sensesp(), nodep->keyword());
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlwaysPublic* nodep) {
|
||||
// Move always to appropriate ACTIVE based on its sense list
|
||||
UINFO(4," ALWPub "<<nodep<<endl);
|
||||
//if (debug()>=9) nodep->dumpTree(cout," Alw: ");
|
||||
visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS);
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenGate* nodep) {
|
||||
AstSenItem* subitemp = nodep->sensesp();
|
||||
if (subitemp->edgeType() != AstEdgeType::ET_ANYEDGE
|
||||
&& subitemp->edgeType() != AstEdgeType::ET_POSEDGE
|
||||
@@ -397,12 +399,12 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenItem* nodep) {
|
||||
if (nodep->edgeType() == AstEdgeType::ET_ANYEDGE) {
|
||||
m_itemCombo = true;
|
||||
// Delete the sensitivity
|
||||
// We'll add it as a generic COMBO SenItem in a moment.
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
} else if (nodep->varrefp()) {
|
||||
// V3LinkResolve should have cleaned most of these up
|
||||
if (!nodep->varrefp()->width1()) nodep->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
|
||||
@@ -413,15 +415,15 @@ private:
|
||||
}
|
||||
|
||||
// Empty visitors, speed things up
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNodeMath* nodep) {}
|
||||
virtual void visit(AstVarScope* nodep) {}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
ActiveVisitor(AstNetlist* nodep) {
|
||||
explicit ActiveVisitor(AstNetlist* nodep) {
|
||||
m_scopeFinalp = NULL;
|
||||
m_itemCombo = false;
|
||||
m_itemSequent = false;
|
||||
@@ -436,5 +438,5 @@ public:
|
||||
void V3Active::activeAll(AstNetlist* nodep) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
ActiveVisitor visitor (nodep);
|
||||
V3Global::dumpCheckGlobalTree("active.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("active", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
|
||||
+17
-17
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -65,19 +65,19 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstTopScope* nodep) {
|
||||
m_topscopep = nodep;
|
||||
m_finder.main(m_topscopep);
|
||||
nodep->iterateChildren(*this);
|
||||
m_topscopep = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
// Create required actives and add to module
|
||||
// We can start ordering at a module, or a scope
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
UINFO(4," ACTIVE "<<nodep<<endl);
|
||||
V3Const::constifyExpensiveEdit(nodep); // Remove duplicate clocks and such; sensesp() may change!
|
||||
AstSenTree* sensesp = nodep->sensesp();
|
||||
@@ -87,7 +87,7 @@ private:
|
||||
&& sensesp->sensesp()->castSenItem()->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
// Copy combo tree to settlement tree with duplicated statements
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
// Move the active's contents to the other active
|
||||
UINFO(4," merge active "<<sensesp<<" into "<<wantp<<endl);
|
||||
if (nodep->sensesStorep()) {
|
||||
if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different\n");
|
||||
if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different");
|
||||
sensesp->unlinkFrBack();
|
||||
// There may be other references to same sense tree,
|
||||
// we'll be removing all references when we get to them,
|
||||
@@ -120,34 +120,34 @@ private:
|
||||
// No need to do statements under it, they're already moved.
|
||||
//nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||
virtual void visit(AstInitial* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignAlias* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignW* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlwaysPublic* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstFinal* nodep, AstNUser*) {
|
||||
virtual void visit(AstFinal* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been deleted");
|
||||
}
|
||||
// Empty visitors, speed things up
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNodeMath* nodep) {}
|
||||
virtual void visit(AstVarScope* nodep) {}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
ActiveTopVisitor(AstNetlist* nodep) {
|
||||
explicit ActiveTopVisitor(AstNetlist* nodep) {
|
||||
m_topscopep = NULL;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
@@ -160,5 +160,5 @@ public:
|
||||
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
ActiveTopVisitor visitor (nodep);
|
||||
V3Global::dumpCheckGlobalTree("activetop.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("activetop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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
-28
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 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.
|
||||
@@ -119,7 +119,7 @@ private:
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unknown node type");
|
||||
}
|
||||
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
|
||||
bodysp = ifp;
|
||||
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
@@ -138,7 +138,7 @@ private:
|
||||
nodep->replaceWith(newp);
|
||||
}
|
||||
// Bye
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
void newVAssertion(AstVAssert* nodep, AstNode* propp) {
|
||||
@@ -160,10 +160,10 @@ private:
|
||||
// Install it
|
||||
nodep->replaceWith(newp);
|
||||
// Bye
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstIf* nodep, AstNUser*) {
|
||||
|
||||
virtual void visit(AstIf* nodep) {
|
||||
if (nodep->user1SetOnce()) return;
|
||||
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
|
||||
AstNodeIf* ifp = nodep;
|
||||
@@ -177,12 +177,12 @@ private:
|
||||
|
||||
// Recurse into the true case.
|
||||
ifp->ifsp()->iterateAndNext(*this);
|
||||
|
||||
|
||||
// If the last else is not an else if, recurse into that too.
|
||||
if (ifp->elsesp() && !nextifp) {
|
||||
ifp->elsesp()->iterateAndNext(*this);
|
||||
}
|
||||
|
||||
|
||||
// Build a bitmask of the true predicates
|
||||
AstNode* predp = ifp->condp()->cloneTree(false);
|
||||
if (propp) {
|
||||
@@ -195,18 +195,18 @@ private:
|
||||
if (ifp->elsesp() && !nextifp) {
|
||||
hasDefaultElse = true;
|
||||
}
|
||||
|
||||
|
||||
ifp = nextifp;
|
||||
} while (ifp);
|
||||
|
||||
AstNode *newifp = nodep->cloneTree(false);
|
||||
bool allow_none = nodep->unique0Pragma();
|
||||
|
||||
|
||||
// Note: if this ends with an 'else', then we don't need to validate that one of the
|
||||
// predicates evaluates to true.
|
||||
AstNode* ohot = ((allow_none || hasDefaultElse)
|
||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||
AstIf* checkifp = new AstIf (nodep->fileline(),
|
||||
new AstLogNot (nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "'unique if' statement violated"),
|
||||
@@ -220,7 +220,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS //========== Case assertions
|
||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||
virtual void visit(AstCase* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
bool has_default=false;
|
||||
@@ -245,17 +245,24 @@ private:
|
||||
AstNode* propp = NULL;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
AstNode* onep = new AstEq(icondp->fileline(),
|
||||
nodep->exprp()->cloneTree(false),
|
||||
icondp->cloneTree(false));
|
||||
AstNode* onep;
|
||||
if (nodep->casex() || nodep->casez() || nodep->caseInside()) {
|
||||
onep = AstEqWild::newTyped(itemp->fileline(),
|
||||
nodep->exprp()->cloneTree(false),
|
||||
icondp->cloneTree(false));
|
||||
} else {
|
||||
onep = AstEq::newTyped(icondp->fileline(),
|
||||
nodep->exprp()->cloneTree(false),
|
||||
icondp->cloneTree(false));
|
||||
}
|
||||
if (propp) propp = new AstConcat(icondp->fileline(), onep, propp);
|
||||
else propp = onep;
|
||||
}
|
||||
}
|
||||
bool allow_none = has_default || nodep->unique0Pragma();
|
||||
AstNode* ohot = (allow_none
|
||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||
AstIf* ifp = new AstIf (nodep->fileline(),
|
||||
new AstLogNot (nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
|
||||
@@ -268,7 +275,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
virtual void visit(AstDisplay* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Replace the special types with standard text
|
||||
if (nodep->displayType()==AstDisplayType::DT_INFO) {
|
||||
@@ -281,27 +288,27 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslCover* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
|
||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
||||
nodep->stmtsp(), nodep->name()); nodep=NULL;
|
||||
nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep);
|
||||
++m_statAsCover;
|
||||
}
|
||||
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
||||
virtual void visit(AstVAssert* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
newVAssertion(nodep, nodep->propp()); nodep=NULL;
|
||||
newVAssertion(nodep, nodep->propp()); VL_DANGLING(nodep);
|
||||
++m_statAsSV;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
//
|
||||
nodep->iterateChildren(*this);
|
||||
// Reset defaults
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
// This code is needed rather than a visitor in V3Begin,
|
||||
// because V3Assert is called before V3Begin
|
||||
AstBegin* lastp = m_beginp;
|
||||
@@ -312,12 +319,12 @@ private:
|
||||
m_beginp = lastp;
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
AssertVisitor(AstNetlist* nodep) {
|
||||
explicit AssertVisitor(AstNetlist* nodep) {
|
||||
m_beginp = NULL;
|
||||
m_modp = NULL;
|
||||
// Process
|
||||
@@ -337,5 +344,5 @@ public:
|
||||
void V3Assert::assertAll(AstNetlist* nodep) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
AssertVisitor visitor (nodep);
|
||||
V3Global::dumpCheckGlobalTree("assert.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("assert", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 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.
|
||||
|
||||
+10
-10
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 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.
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
virtual void visit(AstClocking* nodep, AstNUser*) {
|
||||
virtual void visit(AstClocking* nodep) {
|
||||
UINFO(8," CLOCKING"<<nodep<<endl);
|
||||
// Store the new default clock, reset on new module
|
||||
m_seniDefaultp = nodep->sensesp();
|
||||
@@ -83,17 +83,17 @@ private:
|
||||
} else {
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslCover* nodep) {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
clearAssertInfo();
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstPslClocked* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslClocked* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_senip) {
|
||||
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion");
|
||||
@@ -109,20 +109,20 @@ private:
|
||||
// Unlink and just keep a pointer to it, convert to sentree as needed
|
||||
m_senip = nodep->sensesp();
|
||||
nodep->replaceWith(blockp);
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Reset defaults
|
||||
m_seniDefaultp = NULL;
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
AssertPreVisitor(AstNetlist* nodep) {
|
||||
explicit AssertPreVisitor(AstNetlist* nodep) {
|
||||
m_seniDefaultp = NULL;
|
||||
clearAssertInfo();
|
||||
// Process
|
||||
@@ -137,5 +137,5 @@ public:
|
||||
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
AssertPreVisitor visitor (nodep);
|
||||
V3Global::dumpCheckGlobalTree("assertpre.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("assertpre", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 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.
|
||||
|
||||
+168
-142
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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 @@
|
||||
#include "V3File.h"
|
||||
#include "V3Global.h"
|
||||
#include "V3Broken.h"
|
||||
#include "V3String.h"
|
||||
|
||||
//======================================================================
|
||||
// Statics
|
||||
@@ -79,30 +80,30 @@ void AstNode::init() {
|
||||
// Attributes
|
||||
m_didWidth = false;
|
||||
m_doingWidth = false;
|
||||
m_user1p = NULL;
|
||||
m_user1u = VNUser(0);
|
||||
m_user1Cnt = 0;
|
||||
m_user2p = NULL;
|
||||
m_user2u = VNUser(0);
|
||||
m_user2Cnt = 0;
|
||||
m_user3p = NULL;
|
||||
m_user3u = VNUser(0);
|
||||
m_user3Cnt = 0;
|
||||
m_user4p = NULL;
|
||||
m_user4u = VNUser(0);
|
||||
m_user4Cnt = 0;
|
||||
m_user5p = NULL;
|
||||
m_user5u = VNUser(0);
|
||||
m_user5Cnt = 0;
|
||||
}
|
||||
|
||||
string AstNode::encodeName(const string& namein) {
|
||||
// Encode signal name raw from parser, then not called again on same signal
|
||||
const char* start = namein.c_str();
|
||||
string out;
|
||||
for (const char* pos = start; *pos; pos++) {
|
||||
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
|
||||
for (string::const_iterator pos = namein.begin(); pos!=namein.end(); ++pos) {
|
||||
if ((pos==namein.begin()) ? isalpha(pos[0]) // digits can't lead identifiers
|
||||
: isalnum(pos[0])) {
|
||||
out += pos[0];
|
||||
} else if (pos[0]=='_') {
|
||||
if (pos[1]=='_') {
|
||||
out += "_"; out += "__05F"; // hex(_) = 0x5F
|
||||
pos++;
|
||||
++pos;
|
||||
if (pos==namein.end()) break;
|
||||
} else {
|
||||
out += pos[0];
|
||||
}
|
||||
@@ -115,6 +116,10 @@ string AstNode::encodeName(const string& namein) {
|
||||
out += hex;
|
||||
}
|
||||
}
|
||||
// Shorten names
|
||||
// TODO long term use VName in place of "string name"
|
||||
VName vname(out);
|
||||
out = vname.hashedName();
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -161,44 +166,53 @@ string AstNode::vcdName(const string& namein) {
|
||||
}
|
||||
|
||||
string AstNode::prettyName(const string& namein) {
|
||||
// This function is somewhat hot, so we short-circuit some compares
|
||||
string pretty;
|
||||
pretty = "";
|
||||
pretty.reserve(namein.length());
|
||||
for (const char* pos = namein.c_str(); *pos; ) {
|
||||
if (0==strncmp(pos,"__BRA__",7)) {
|
||||
pretty += "[";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__KET__",7)) {
|
||||
pretty += "]";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__DOT__",7)) {
|
||||
pretty += ".";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"->",2)) {
|
||||
if (pos[0]=='-' && pos[1]=='>') { // ->
|
||||
pretty += ".";
|
||||
pos += 2;
|
||||
continue;
|
||||
}
|
||||
else if (0==strncmp(pos,"__PVT__",7)) {
|
||||
pretty += "";
|
||||
pos += 7;
|
||||
}
|
||||
else if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
|
||||
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
|
||||
char value = 0;
|
||||
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
|
||||
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
|
||||
pretty += value;
|
||||
pos += 5;
|
||||
}
|
||||
else {
|
||||
pretty += pos[0];
|
||||
pos++;
|
||||
if (pos[0]=='_' && pos[1]=='_') { // Short-circuit
|
||||
if (0==strncmp(pos,"__BRA__",7)) {
|
||||
pretty += "[";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (0==strncmp(pos,"__KET__",7)) {
|
||||
pretty += "]";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (0==strncmp(pos,"__DOT__",7)) {
|
||||
pretty += ".";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (0==strncmp(pos,"__PVT__",7)) {
|
||||
pretty += "";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
|
||||
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
|
||||
char value = 0;
|
||||
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
|
||||
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
|
||||
pretty += value;
|
||||
pos += 5;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Default
|
||||
pretty += pos[0];
|
||||
++pos;
|
||||
}
|
||||
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
|
||||
if (pretty[0]=='T' && pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||
if (pretty[0]=='T' && pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
|
||||
return pretty;
|
||||
}
|
||||
|
||||
@@ -230,20 +244,20 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
|
||||
#endif
|
||||
}
|
||||
|
||||
AstNode* AstNode::addNext(AstNode* newp) {
|
||||
AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
|
||||
// Add to m_nextp, returns this
|
||||
UASSERT(newp,"Null item passed to addNext\n");
|
||||
this->debugTreeChange("-addNextThs: ", __LINE__, false);
|
||||
UDEBUGONLY(if (!newp) nodep->v3fatalSrc("Null item passed to addNext"););
|
||||
nodep->debugTreeChange("-addNextThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-addNextNew: ", __LINE__, true);
|
||||
if (this == NULL) {
|
||||
if (!nodep) { // verilog.y and lots of other places assume this
|
||||
return (newp);
|
||||
} else {
|
||||
// Find end of old list
|
||||
AstNode* oldtailp = this;
|
||||
AstNode* oldtailp = nodep;
|
||||
if (oldtailp->m_nextp) {
|
||||
if (oldtailp->m_headtailp) {
|
||||
oldtailp = oldtailp->m_headtailp; // This=beginning of list, jump to end
|
||||
UASSERT(!oldtailp->m_nextp, "Node had next, but headtail says it shouldn't");
|
||||
UDEBUGONLY(if (oldtailp->m_nextp) nodep->v3fatalSrc("Node had next, but headtail says it shouldn't"););
|
||||
} else {
|
||||
// Though inefficent, we are occasionally passed a addNext in the middle of a list.
|
||||
while (oldtailp->m_nextp != NULL) oldtailp = oldtailp->m_nextp;
|
||||
@@ -262,21 +276,21 @@ AstNode* AstNode::addNext(AstNode* newp) {
|
||||
newp->editCountInc();
|
||||
if (oldtailp->m_iterpp) *(oldtailp->m_iterpp) = newp; // Iterate on new item
|
||||
}
|
||||
this->debugTreeChange("-addNextOut:", __LINE__, true);
|
||||
return this;
|
||||
nodep->debugTreeChange("-addNextOut:", __LINE__, true);
|
||||
return nodep;
|
||||
}
|
||||
|
||||
AstNode* AstNode::addNextNull(AstNode* newp) {
|
||||
if (!newp) return this;
|
||||
return addNext(newp);
|
||||
AstNode* AstNode::addNextNull(AstNode* nodep, AstNode* newp) {
|
||||
if (!newp) return nodep;
|
||||
return addNext(nodep, newp);
|
||||
}
|
||||
|
||||
void AstNode::addNextHere(AstNode* newp) {
|
||||
// Add to m_nextp on exact node passed, not at the end.
|
||||
// This could be at head, tail, or both (single)
|
||||
// New could be head of single node, or list
|
||||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
UASSERT(newp,"Null item passed to addNext");
|
||||
UASSERT(this,"Null base node");
|
||||
UASSERT(newp->backp()==NULL,"New node (back) already assigned?");
|
||||
this->debugTreeChange("-addHereThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-addHereNew: ", __LINE__, true);
|
||||
@@ -600,12 +614,12 @@ void AstNode::swapWith (AstNode* bp) {
|
||||
// Clone
|
||||
|
||||
AstNode* AstNode::cloneTreeIter() {
|
||||
if (!this) return NULL;
|
||||
// private: Clone single node and children
|
||||
AstNode* newp = this->clone();
|
||||
newp->op1p(this->m_op1p->cloneTreeIterList());
|
||||
newp->op2p(this->m_op2p->cloneTreeIterList());
|
||||
newp->op3p(this->m_op3p->cloneTreeIterList());
|
||||
newp->op4p(this->m_op4p->cloneTreeIterList());
|
||||
if (this->m_op1p) newp->op1p(this->m_op1p->cloneTreeIterList());
|
||||
if (this->m_op2p) newp->op2p(this->m_op2p->cloneTreeIterList());
|
||||
if (this->m_op3p) newp->op3p(this->m_op3p->cloneTreeIterList());
|
||||
if (this->m_op4p) newp->op4p(this->m_op4p->cloneTreeIterList());
|
||||
newp->m_iterpp = NULL;
|
||||
newp->clonep(this); // Save pointers to/from both to simplify relinking.
|
||||
this->clonep(newp); // Save pointers to/from both to simplify relinking.
|
||||
@@ -613,10 +627,10 @@ AstNode* AstNode::cloneTreeIter() {
|
||||
}
|
||||
|
||||
AstNode* AstNode::cloneTreeIterList() {
|
||||
// Clone list of nodes, set m_headtailp
|
||||
if (!this) return NULL;
|
||||
// private: Clone list of nodes, set m_headtailp
|
||||
AstNode* newheadp = NULL;
|
||||
AstNode* newtailp = NULL;
|
||||
// Audited to make sure this is never NULL
|
||||
for (AstNode* oldp = this; oldp; oldp=oldp->m_nextp) {
|
||||
AstNode* newp = oldp->cloneTreeIter();
|
||||
newp->m_headtailp = NULL;
|
||||
@@ -631,7 +645,7 @@ AstNode* AstNode::cloneTreeIterList() {
|
||||
}
|
||||
|
||||
AstNode* AstNode::cloneTree(bool cloneNextLink) {
|
||||
if (!this) return NULL;
|
||||
if (!this) return NULL; // verilog.y relies on this
|
||||
this->debugTreeChange("-cloneThs: ", __LINE__, cloneNextLink);
|
||||
cloneClearTree();
|
||||
AstNode* newp;
|
||||
@@ -652,7 +666,7 @@ AstNode* AstNode::cloneTree(bool cloneNextLink) {
|
||||
// Delete
|
||||
|
||||
void AstNode::deleteNode() {
|
||||
if (!this) return;
|
||||
// private: Delete single node. Publicly call deleteTree() instead.
|
||||
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
|
||||
editCountInc();
|
||||
// Change links of old node so we coredump if used
|
||||
@@ -672,14 +686,15 @@ AstNode::~AstNode() {
|
||||
}
|
||||
|
||||
void AstNode::deleteTreeIter() {
|
||||
if (!this) return;
|
||||
// private: Delete list of nodes. Publicly call deleteTree() instead.
|
||||
// Audited to make sure this is never NULL
|
||||
for (AstNode* nodep=this, *nnextp; nodep; nodep=nnextp) {
|
||||
nnextp = nodep->m_nextp;
|
||||
// MUST be depth first!
|
||||
nodep->m_op1p->deleteTreeIter();
|
||||
nodep->m_op2p->deleteTreeIter();
|
||||
nodep->m_op3p->deleteTreeIter();
|
||||
nodep->m_op4p->deleteTreeIter();
|
||||
if (nodep->m_op1p) nodep->m_op1p->deleteTreeIter();
|
||||
if (nodep->m_op2p) nodep->m_op2p->deleteTreeIter();
|
||||
if (nodep->m_op3p) nodep->m_op3p->deleteTreeIter();
|
||||
if (nodep->m_op4p) nodep->m_op4p->deleteTreeIter();
|
||||
nodep->m_nextp = NULL;
|
||||
nodep->m_backp = NULL;
|
||||
nodep->deleteNode();
|
||||
@@ -689,7 +704,6 @@ void AstNode::deleteTreeIter() {
|
||||
void AstNode::deleteTree() {
|
||||
// deleteTree always deletes the next link, because you must have called
|
||||
// unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this.
|
||||
if (!this) return;
|
||||
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
|
||||
this->debugTreeChange("-delTree: ", __LINE__, true);
|
||||
this->editCountInc();
|
||||
@@ -702,6 +716,7 @@ void AstNode::deleteTree() {
|
||||
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
void* AstNode::operator new(size_t size) {
|
||||
// Optimization note: Aligning to cache line is a loss, due to lost packing
|
||||
AstNode* objp = static_cast<AstNode*>(::operator new(size));
|
||||
V3Broken::addNewed(objp);
|
||||
return objp;
|
||||
@@ -718,53 +733,51 @@ void AstNode::operator delete(void* objp, size_t size) {
|
||||
//======================================================================
|
||||
// Iterators
|
||||
|
||||
void AstNode::iterateChildren(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateChildren(AstNVisitor& v) {
|
||||
// This is a very hot function
|
||||
if (!this) return;
|
||||
// Optimization note: Grabbing m_op#p->m_nextp is a net loss
|
||||
ASTNODE_PREFETCH(m_op1p);
|
||||
ASTNODE_PREFETCH(m_op2p);
|
||||
ASTNODE_PREFETCH(m_op3p);
|
||||
ASTNODE_PREFETCH(m_op4p);
|
||||
// if () not needed since iterateAndNext accepts null this, but faster with it.
|
||||
if (m_op1p) m_op1p->iterateAndNext(v, vup);
|
||||
if (m_op2p) m_op2p->iterateAndNext(v, vup);
|
||||
if (m_op3p) m_op3p->iterateAndNext(v, vup);
|
||||
if (m_op4p) m_op4p->iterateAndNext(v, vup);
|
||||
if (m_op1p) m_op1p->iterateAndNext(v);
|
||||
if (m_op2p) m_op2p->iterateAndNext(v);
|
||||
if (m_op3p) m_op3p->iterateAndNext(v);
|
||||
if (m_op4p) m_op4p->iterateAndNext(v);
|
||||
}
|
||||
|
||||
void AstNode::iterateChildrenConst(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateChildrenConst(AstNVisitor& v) {
|
||||
// This is a very hot function
|
||||
if (!this) return;
|
||||
ASTNODE_PREFETCH(m_op1p);
|
||||
ASTNODE_PREFETCH(m_op2p);
|
||||
ASTNODE_PREFETCH(m_op3p);
|
||||
ASTNODE_PREFETCH(m_op4p);
|
||||
// if () not needed since iterateAndNext accepts null this, but faster with it.
|
||||
if (m_op1p) m_op1p->iterateAndNextConst(v, vup);
|
||||
if (m_op2p) m_op2p->iterateAndNextConst(v, vup);
|
||||
if (m_op3p) m_op3p->iterateAndNextConst(v, vup);
|
||||
if (m_op4p) m_op4p->iterateAndNextConst(v, vup);
|
||||
if (m_op1p) m_op1p->iterateAndNextConst(v);
|
||||
if (m_op2p) m_op2p->iterateAndNextConst(v);
|
||||
if (m_op3p) m_op3p->iterateAndNextConst(v);
|
||||
if (m_op4p) m_op4p->iterateAndNextConst(v);
|
||||
}
|
||||
|
||||
void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateAndNext(AstNVisitor& v) {
|
||||
// This is a very hot function
|
||||
// IMPORTANT: If you replace a node that's the target of this iterator,
|
||||
// then the NEW node will be iterated on next, it isn't skipped!
|
||||
// if (!this) return; // Part of for()
|
||||
// Future versions of this function may require the node to have a back to be iterated;
|
||||
// there's no lower level reason yet though the back must exist.
|
||||
AstNode* nodep=this;
|
||||
#ifdef VL_DEBUG // Otherwise too hot of a function for debug
|
||||
if (VL_UNLIKELY(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back");
|
||||
#endif
|
||||
while (nodep) {
|
||||
if (nodep) ASTNODE_PREFETCH(nodep->m_nextp);
|
||||
while (nodep) { // effectively: if (!this) return; // Callers rely on this
|
||||
if (nodep->m_nextp) ASTNODE_PREFETCH(nodep->m_nextp->m_nextp);
|
||||
AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited
|
||||
ASTNODE_PREFETCH(nodep->m_nextp);
|
||||
// Desirable check, but many places where multiple iterations are OK
|
||||
//if (VL_UNLIKELY(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits");
|
||||
// Optimization note: Doing PREFETCH_RW on m_iterpp is a net even
|
||||
// cppcheck-suppress nullPointer
|
||||
niterp->m_iterpp = &niterp;
|
||||
niterp->accept(v, vup);
|
||||
niterp->accept(v);
|
||||
// accept may do a replaceNode and change niterp on us...
|
||||
//if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep<<" now into "<<(void*)niterp<<endl); // niterp maybe NULL, so need cast
|
||||
if (!niterp) return; // Perhaps node deleted inside accept
|
||||
@@ -777,38 +790,37 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
}
|
||||
}
|
||||
|
||||
void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) {
|
||||
if (!this) return;
|
||||
void AstNode::iterateListBackwards(AstNVisitor& v) {
|
||||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
AstNode* nodep=this;
|
||||
while (nodep->m_nextp) nodep=nodep->m_nextp;
|
||||
while (nodep) {
|
||||
// Edits not supported: nodep->m_iterpp = &nodep;
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v);
|
||||
if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp();
|
||||
else nodep = NULL; // else: backp points up the tree.
|
||||
}
|
||||
}
|
||||
|
||||
void AstNode::iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup) {
|
||||
if (!this) return;
|
||||
this->op1p()->iterateListBackwards(v,vup);
|
||||
this->op2p()->iterateListBackwards(v,vup);
|
||||
this->op3p()->iterateListBackwards(v,vup);
|
||||
this->op4p()->iterateListBackwards(v,vup);
|
||||
void AstNode::iterateChildrenBackwards(AstNVisitor& v) {
|
||||
if (m_op1p) m_op1p->iterateListBackwards(v);
|
||||
if (m_op2p) m_op2p->iterateListBackwards(v);
|
||||
if (m_op3p) m_op3p->iterateListBackwards(v);
|
||||
if (m_op4p) m_op4p->iterateListBackwards(v);
|
||||
}
|
||||
|
||||
void AstNode::iterateAndNextConst(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateAndNextConst(AstNVisitor& v) {
|
||||
// Keep following the current list even if edits change it
|
||||
if (!this) return;
|
||||
for (AstNode* nodep=this; nodep; ) {
|
||||
if (!this) return; // A few cases could be cleaned up, but want symmetry with iterateAndNext
|
||||
for (AstNode* nodep=this; nodep; ) { // effectively: if (!this) return; // Callers rely on this
|
||||
AstNode* nnextp = nodep->m_nextp;
|
||||
ASTNODE_PREFETCH(nnextp);
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v);
|
||||
nodep = nnextp;
|
||||
}
|
||||
}
|
||||
|
||||
AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
|
||||
// Some visitors perform tree edits (such as V3Const), and may even
|
||||
// replace/delete the exact nodep that the visitor is called with. If
|
||||
// this happens, the parent will lose the handle to the node that was
|
||||
@@ -818,15 +830,15 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
AstNode* nodep = this; // Note "this" may point to bogus point later in this function
|
||||
if (nodep->castNetlist()) {
|
||||
// Calling on top level; we know the netlist won't get replaced
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v);
|
||||
} else if (!nodep->backp()) {
|
||||
// Calling on standalone tree; insert a shim node so we can keep track, then delete it on completion
|
||||
AstBegin* tempp = new AstBegin(nodep->fileline(),"[EditWrapper]",nodep);
|
||||
{
|
||||
tempp->stmtsp()->accept(v, vup); nodep=NULL; // nodep to null as may be replaced
|
||||
tempp->stmtsp()->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
}
|
||||
nodep = tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
tempp->deleteTree(); tempp=NULL;
|
||||
tempp->deleteTree(); VL_DANGLING(tempp);
|
||||
} else {
|
||||
// Use back to determine who's pointing at us (IE assume new node grafts into same place as old one)
|
||||
AstNode** nextnodepp = NULL;
|
||||
@@ -837,7 +849,7 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp);
|
||||
if (!nextnodepp) this->v3fatalSrc("Node's back doesn't point to forward to node itself");
|
||||
{
|
||||
nodep->accept(v, vup); nodep=NULL; // nodep to null as may be replaced
|
||||
nodep->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
}
|
||||
nodep = *nextnodepp; // Grab new node from point where old was connected
|
||||
}
|
||||
@@ -847,44 +859,54 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
//======================================================================
|
||||
|
||||
void AstNode::cloneRelinkTree() {
|
||||
if (!this) return;
|
||||
// private: Cleanup clone() operation on whole tree. Publicly call cloneTree() instead.
|
||||
for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) {
|
||||
if (m_dtypep && m_dtypep->clonep()) {
|
||||
m_dtypep = m_dtypep->clonep()->castNodeDType();
|
||||
m_dtypep = m_dtypep->clonep();
|
||||
}
|
||||
nodep->cloneRelink();
|
||||
nodep->m_op1p->cloneRelinkTree();
|
||||
nodep->m_op2p->cloneRelinkTree();
|
||||
nodep->m_op3p->cloneRelinkTree();
|
||||
nodep->m_op4p->cloneRelinkTree();
|
||||
if (nodep->m_op1p) nodep->m_op1p->cloneRelinkTree();
|
||||
if (nodep->m_op2p) nodep->m_op2p->cloneRelinkTree();
|
||||
if (nodep->m_op3p) nodep->m_op3p->cloneRelinkTree();
|
||||
if (nodep->m_op4p) nodep->m_op4p->cloneRelinkTree();
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Comparison
|
||||
|
||||
bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly) {
|
||||
// Return true if the two trees are identical
|
||||
if (this==NULL && node2p==NULL) return true;
|
||||
if (this==NULL || node2p==NULL) return false;
|
||||
if (this->type() != node2p->type()
|
||||
|| this->dtypep() != node2p->dtypep()
|
||||
|| !this->same(node2p)
|
||||
|| (gateOnly && !this->isGateOptimizable())) {
|
||||
bool AstNode::gateTreeIter() {
|
||||
// private: Return true if the two trees are identical
|
||||
if (!isGateOptimizable()) return false;
|
||||
if (m_op1p && !m_op1p->gateTreeIter()) return false;
|
||||
if (m_op2p && !m_op2p->gateTreeIter()) return false;
|
||||
if (m_op3p && !m_op3p->gateTreeIter()) return false;
|
||||
if (m_op4p && !m_op4p->gateTreeIter()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly) {
|
||||
// private: Return true if the two trees are identical
|
||||
if (!node1p && !node2p) return true;
|
||||
if (!node1p || !node2p) return false;
|
||||
if (node1p->type() != node2p->type()
|
||||
|| node1p->dtypep() != node2p->dtypep()
|
||||
|| !node1p->same(node2p)
|
||||
|| (gateOnly && !node1p->isGateOptimizable())) {
|
||||
return false;
|
||||
}
|
||||
return (this->op1p()->sameTreeIter(node2p->op1p(),false,gateOnly)
|
||||
&& this->op2p()->sameTreeIter(node2p->op2p(),false,gateOnly)
|
||||
&& this->op3p()->sameTreeIter(node2p->op3p(),false,gateOnly)
|
||||
&& this->op4p()->sameTreeIter(node2p->op4p(),false,gateOnly)
|
||||
&& (ignNext || this->nextp()->sameTreeIter(node2p->nextp(),false,gateOnly))
|
||||
return (sameTreeIter(node1p->m_op1p, node2p->m_op1p,false,gateOnly)
|
||||
&& sameTreeIter(node1p->m_op2p, node2p->m_op2p,false,gateOnly)
|
||||
&& sameTreeIter(node1p->m_op3p, node2p->m_op3p,false,gateOnly)
|
||||
&& sameTreeIter(node1p->m_op4p, node2p->m_op4p,false,gateOnly)
|
||||
&& (ignNext || sameTreeIter(node1p->m_nextp, node2p->m_nextp,false,gateOnly))
|
||||
);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Static utilities
|
||||
|
||||
ostream& operator<<(ostream& os, V3Hash rhs) {
|
||||
ostream& operator<<(ostream& os, const V3Hash& rhs) {
|
||||
return os<<hex<<setw(2)<<setfill('0')<<rhs.depth()
|
||||
<<"_"<<setw(6)<<setfill('0')<<rhs.hshval();
|
||||
}
|
||||
@@ -901,6 +923,7 @@ V3Hash::V3Hash(const string& name) {
|
||||
// Debugging
|
||||
|
||||
void AstNode::checkTreeIter(AstNode* backp) {
|
||||
// private: Check a tree and children
|
||||
if (backp != this->backp()) {
|
||||
this->v3fatalSrc("Back node inconsistent");
|
||||
}
|
||||
@@ -909,15 +932,15 @@ void AstNode::checkTreeIter(AstNode* backp) {
|
||||
if (op1p()||op2p()||op3p()||op4p())
|
||||
this->v3fatalSrc("Terminal operation with non-terminals");
|
||||
}
|
||||
if (op1p()) op1p()->checkTreeIterList(this);
|
||||
if (op2p()) op2p()->checkTreeIterList(this);
|
||||
if (op3p()) op3p()->checkTreeIterList(this);
|
||||
if (op4p()) op4p()->checkTreeIterList(this);
|
||||
if (m_op1p) m_op1p->checkTreeIterList(this);
|
||||
if (m_op2p) m_op2p->checkTreeIterList(this);
|
||||
if (m_op3p) m_op3p->checkTreeIterList(this);
|
||||
if (m_op4p) m_op4p->checkTreeIterList(this);
|
||||
}
|
||||
|
||||
void AstNode::checkTreeIterList(AstNode* backp) {
|
||||
// Check a (possible) list of nodes, this is always the head of the list
|
||||
if (!this) v3fatalSrc("Null nodep");
|
||||
// private: Check a (possible) list of nodes, this is always the head of the list
|
||||
// Audited to make sure this is never NULL
|
||||
AstNode* headp = this;
|
||||
AstNode* tailp = this;
|
||||
for (AstNode* nodep=headp; nodep; nodep=nodep->nextp()) {
|
||||
@@ -931,7 +954,6 @@ void AstNode::checkTreeIterList(AstNode* backp) {
|
||||
}
|
||||
|
||||
void AstNode::checkTree() {
|
||||
if (!this) return;
|
||||
if (!debug()) return;
|
||||
if (this->backp()) {
|
||||
// Linked tree- check only the passed node
|
||||
@@ -942,17 +964,17 @@ void AstNode::checkTree() {
|
||||
}
|
||||
|
||||
void AstNode::dumpGdb() { // For GDB only
|
||||
if (!this) { cout<<"This=NULL"<<endl; return; }
|
||||
if (!dynamic_cast<const AstNode*>(this)) { cout<<"This=NULL"<<endl; return; }
|
||||
dumpGdbHeader();
|
||||
cout<<" "; dump(cout); cout<<endl;
|
||||
}
|
||||
void AstNode::dumpGdbHeader() const { // For GDB only
|
||||
if (!this) { cout<<"This=NULL"<<endl; return; }
|
||||
if (!dynamic_cast<const AstNode*>(this)) { cout<<"This=NULL"<<endl; return; }
|
||||
dumpPtrs(cout);
|
||||
cout<<" Fileline = "<<fileline()<<endl;
|
||||
}
|
||||
void AstNode::dumpTreeGdb() { // For GDB only
|
||||
if (!this) { cout<<"This=NULL"<<endl; return; }
|
||||
if (!dynamic_cast<const AstNode*>(this)) { cout<<"This=NULL"<<endl; return; }
|
||||
dumpGdbHeader();
|
||||
dumpTree(cout);
|
||||
}
|
||||
@@ -992,7 +1014,6 @@ void AstNode::dumpPtrs(ostream& os) const {
|
||||
}
|
||||
|
||||
void AstNode::dumpTree(ostream& os, const string& indent, int maxDepth) {
|
||||
if (!this) return;
|
||||
os<<indent<<" "<<this<<endl;
|
||||
if (debug()>8) { os<<indent<<" "; dumpPtrs(os); }
|
||||
if (maxDepth==1) {
|
||||
@@ -1006,7 +1027,7 @@ void AstNode::dumpTree(ostream& os, const string& indent, int maxDepth) {
|
||||
}
|
||||
|
||||
void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) {
|
||||
if (!this) return;
|
||||
// Audited to make sure this is never NULL
|
||||
for (AstNode* nodep=this; nodep; nodep=nodep->nextp()) {
|
||||
nodep->dumpTree(os, indent, maxDepth);
|
||||
}
|
||||
@@ -1016,7 +1037,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
|
||||
if (doDump) {
|
||||
{ // Write log & close
|
||||
UINFO(2,"Dumping "<<filename<<endl);
|
||||
const auto_ptr<ofstream> logsp (V3File::new_ofstream(filename, append));
|
||||
const VL_UNIQUE_PTR<ofstream> logsp (V3File::new_ofstream(filename, append));
|
||||
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
|
||||
*logsp<<"Verilator Tree Dump (format 0x3900) from <e"<<dec<<editCountLast()<<">";
|
||||
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
|
||||
@@ -1040,8 +1061,16 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
|
||||
editCountSetLast();
|
||||
}
|
||||
|
||||
void AstNode::v3errorEndFatal(ostringstream& str) const { v3errorEnd(str); assert(0); }
|
||||
|
||||
void AstNode::v3errorEnd(ostringstream& str) const {
|
||||
if (this && m_fileline) {
|
||||
if (!dynamic_cast<const AstNode*>(this)) {
|
||||
// No known cases cause this, but better than a core dump
|
||||
if (debug()) UINFO(0, "-node: NULL. Please report this along with a --gdbbt backtrace as a Verilator bug.\n");
|
||||
V3Error::v3errorEnd(str);
|
||||
} else if (!m_fileline) {
|
||||
V3Error::v3errorEnd(str);
|
||||
} else {
|
||||
ostringstream nsstr;
|
||||
nsstr<<str.str();
|
||||
if (debug()) {
|
||||
@@ -1049,14 +1078,11 @@ void AstNode::v3errorEnd(ostringstream& str) const {
|
||||
nsstr<<"-node: "; ((AstNode*)this)->dump(nsstr); nsstr<<endl;
|
||||
}
|
||||
m_fileline->v3errorEnd(nsstr);
|
||||
} else {
|
||||
V3Error::v3errorEnd(str);
|
||||
}
|
||||
}
|
||||
|
||||
string AstNode::warnMore() const {
|
||||
if (this) return this->fileline()->warnMore();
|
||||
else return V3Error::warnMore();
|
||||
return fileline()->warnMore();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
+229
-155
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
enum en m_e;
|
||||
// cppcheck-suppress uninitVar // responsiblity of each subclass
|
||||
inline AstType () {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstType (en _e) : m_e(_e) {}
|
||||
explicit inline AstType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -60,7 +61,7 @@ public:
|
||||
inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstType::en lhs, AstType rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstType rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstType& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -81,13 +82,15 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"UNSIGNED","SIGNED","NOSIGN"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
inline AstNumeric () : m_e(UNSIGNED) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstNumeric (en _e) : m_e(_e) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstNumeric (VSignedState signst) {
|
||||
if (signst==signedst_UNSIGNED) m_e=UNSIGNED;
|
||||
else if (signst==signedst_SIGNED) m_e=SIGNED;
|
||||
@@ -104,7 +107,7 @@ public:
|
||||
inline bool operator== (AstNumeric lhs, AstNumeric rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstNumeric lhs, AstNumeric::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstNumeric::en lhs, AstNumeric rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstNumeric rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstNumeric& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -121,6 +124,7 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstPragmaType () : m_e(ILLEGAL) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstPragmaType (en _e) : m_e(_e) {}
|
||||
explicit inline AstPragmaType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -144,6 +148,7 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstCFuncType () : m_e(FT_NORMAL) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstCFuncType (en _e) : m_e(_e) {}
|
||||
explicit inline AstCFuncType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -198,20 +203,21 @@ public:
|
||||
return AstEdgeType::ET_ILLEGAL;
|
||||
}
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"%E-edge", "ANY", "BOTH", "POS", "NEG", "HIGH", "LOW",
|
||||
"COMBO","INITIAL","SETTLE","NEVER"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
const char* verilogKwd() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"%E-edge", "[any]", "edge", "posedge", "negedge", "[high]","[low]",
|
||||
"*","[initial]","[settle]","[never]"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
inline AstEdgeType () : m_e(ET_ILLEGAL) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstEdgeType (en _e) : m_e(_e) {}
|
||||
explicit inline AstEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -239,6 +245,7 @@ public:
|
||||
//
|
||||
DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic
|
||||
//
|
||||
ENUM_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
||||
ENUM_FIRST, // V3Width processes
|
||||
ENUM_LAST, // V3Width processes
|
||||
ENUM_NUM, // V3Width processes
|
||||
@@ -263,12 +270,12 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"%E-AT",
|
||||
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
|
||||
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
|
||||
"DT_PUBLIC",
|
||||
"ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
|
||||
"ENUM_BASE", "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
|
||||
"MEMBER_BASE",
|
||||
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
||||
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
||||
@@ -278,6 +285,7 @@ public:
|
||||
return names[m_e];
|
||||
};
|
||||
inline AstAttrType () : m_e(ILLEGAL) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstAttrType (en _e) : m_e(_e) {}
|
||||
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -307,7 +315,7 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"%E-unk",
|
||||
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
|
||||
"real", "shortint", "shortreal", "time",
|
||||
@@ -320,7 +328,7 @@ public:
|
||||
return names[m_e];
|
||||
};
|
||||
const char* dpiType() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"%E-unk",
|
||||
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
|
||||
"double", "short int", "float", "long long",
|
||||
@@ -337,6 +345,7 @@ public:
|
||||
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch");
|
||||
}
|
||||
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
||||
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -387,7 +396,7 @@ public:
|
||||
return (m_e==LOGIC || m_e==BIT);
|
||||
}
|
||||
bool isDpiUnsupported() const {
|
||||
return (m_e==LOGIC || m_e==TIME);
|
||||
return (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);
|
||||
@@ -418,6 +427,7 @@ public:
|
||||
SUPPLY0,
|
||||
SUPPLY1,
|
||||
WIRE,
|
||||
WREAL,
|
||||
IMPLICITWIRE,
|
||||
TRIWIRE,
|
||||
TRI0,
|
||||
@@ -431,20 +441,21 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstVarType () : m_e(UNKNOWN) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstVarType (en _e) : m_e(_e) {}
|
||||
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"?","GPARAM","LPARAM","GENVAR",
|
||||
"VAR","INPUT","OUTPUT","INOUT",
|
||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE",
|
||||
"SUPPLY0","SUPPLY1","WIRE","WREAL","IMPLICITWIRE",
|
||||
"TRIWIRE","TRI0","TRI1",
|
||||
"PORT",
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP",
|
||||
"IFACEREF"};
|
||||
return names[m_e]; }
|
||||
bool isSignal() const { return (m_e==WIRE || m_e==IMPLICITWIRE
|
||||
bool isSignal() const { return (m_e==WIRE || m_e==WREAL || m_e==IMPLICITWIRE
|
||||
|| m_e==TRIWIRE
|
||||
|| m_e==TRI0 || m_e==TRI1
|
||||
|| m_e==SUPPLY0 || m_e==SUPPLY1
|
||||
@@ -453,7 +464,7 @@ public:
|
||||
inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstVarType lhs, AstVarType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstVarType::en lhs, AstVarType rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstVarType rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstVarType& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -468,6 +479,7 @@ public:
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||
inline AstBranchPred () : m_e(BP_UNKNOWN) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstBranchPred (en _e) : m_e(_e) {}
|
||||
explicit inline AstBranchPred (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -477,14 +489,14 @@ public:
|
||||
else return m_e;
|
||||
}
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"","VL_LIKELY","VL_UNLIKELY"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
inline bool operator== (AstBranchPred lhs, AstBranchPred rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstBranchPred lhs, AstBranchPred::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstBranchPred& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -499,23 +511,25 @@ public:
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||
inline AstVarAttrClocker () : m_e(CLOCKER_UNKNOWN) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstVarAttrClocker (en _e) : m_e(_e) {}
|
||||
explicit inline AstVarAttrClocker (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
bool unknown() const { return m_e==CLOCKER_UNKNOWN; }
|
||||
AstVarAttrClocker invert() const {
|
||||
if (m_e==CLOCKER_YES) return CLOCKER_NO;
|
||||
else if (m_e==CLOCKER_NO) return CLOCKER_YES;
|
||||
else return m_e;
|
||||
}
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"","clker","non_clker"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstVarAttrClocker rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstVarAttrClocker& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -529,11 +543,12 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline VAlwaysKwd () : m_e(ALWAYS) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
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[] = {
|
||||
static const char* const names[] = {
|
||||
"always","always_ff","always_latch","always_comb"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
@@ -553,6 +568,7 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline VCaseType () : m_e(CT_CASE) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VCaseType (en _e) : m_e(_e) {}
|
||||
explicit inline VCaseType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
@@ -575,13 +591,14 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstDisplayType () : m_e(DT_DISPLAY) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstDisplayType (en _e) : m_e(_e) {}
|
||||
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
bool addNewline() const { return m_e!=DT_WRITE; }
|
||||
bool needScopeTracking() const { return m_e!=DT_DISPLAY && m_e!=DT_WRITE; }
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"display","write","info","error","warning","fatal"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
@@ -599,18 +616,19 @@ public:
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstParseRefExp() : m_e(PX_NONE) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline AstParseRefExp (en _e) : m_e(_e) {}
|
||||
explicit inline AstParseRefExp (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
const char* ascii() const {
|
||||
static const char* names[] = {
|
||||
static const char* const names[] = {
|
||||
"","TEXT","PREDOT"};
|
||||
return names[m_e]; }
|
||||
};
|
||||
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstParseRefExp& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
// VNumRange - Structure containing numberic range information
|
||||
@@ -662,7 +680,7 @@ struct VNumRange {
|
||||
{ return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); }
|
||||
void dump(ostream& str) const { if (ranged()) str<<"["<<left()<<":"<<right()<<"]"; else str<<"[norg]"; }
|
||||
};
|
||||
inline ostream& operator<<(ostream& os, VNumRange rhs) { rhs.dump(os); return os; }
|
||||
inline ostream& operator<<(ostream& os, const VNumRange& rhs) { rhs.dump(os); return os; }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -691,14 +709,14 @@ struct VBasicTypeKey {
|
||||
if (!(m_nrange == rhs.m_nrange)) return false; // lhs > rhs
|
||||
return false; }
|
||||
VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd,
|
||||
VNumRange nrange)
|
||||
const VNumRange& nrange)
|
||||
: m_width(width), m_widthMin(widthMin), m_numeric(numeric),
|
||||
m_keyword(kwd), m_nrange(nrange) {}
|
||||
~VBasicTypeKey() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// AstNUser - Generic pointer base class for AST User nodes.
|
||||
// AstNUser - Generic base class for AST User nodes.
|
||||
// - Also used to allow parameter passing up/down iterate calls
|
||||
|
||||
class WidthVP;
|
||||
@@ -707,26 +725,32 @@ class OrderBlockNU;
|
||||
class OrderVarNU;
|
||||
class V3GraphVertex;
|
||||
class VSymEnt;
|
||||
struct AstNUser {
|
||||
AstNUser* p() { return this; } // So can take address of temporary: iterate(...,AstNUser(args).p())
|
||||
|
||||
class VNUser {
|
||||
union {
|
||||
void* up;
|
||||
int ui;
|
||||
} m_u;
|
||||
public:
|
||||
VNUser() {}
|
||||
// non-explicit:
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
VNUser(int i) { m_u.up = 0; m_u.ui = i; }
|
||||
explicit VNUser(void* p) { m_u.up = p; }
|
||||
~VNUser() {}
|
||||
// Casters
|
||||
WidthVP* c() { return ((WidthVP*)this); }
|
||||
LinkVP* castLinkVP() { return ((LinkVP*)this); }
|
||||
VSymEnt* castSymEnt() { return ((VSymEnt*)this); }
|
||||
AstNode* castNode() { return ((AstNode*)this); }
|
||||
OrderBlockNU* castOrderBlock() { return ((OrderBlockNU*)this); }
|
||||
OrderVarNU* castOrderVar() { return ((OrderVarNU*)this); }
|
||||
V3GraphVertex* castGraphVertex() { return ((V3GraphVertex*)this); }
|
||||
inline int castInt() {
|
||||
union { AstNUser* up; int ui; } u;
|
||||
u.up = this;
|
||||
return u.ui;
|
||||
}
|
||||
static inline AstNUser* fromInt (int i) {
|
||||
union { AstNUser* up; int ui; } u;
|
||||
u.up=0; u.ui=i;
|
||||
return u.up;
|
||||
WidthVP* c() { return ((WidthVP*)m_u.up); }
|
||||
LinkVP* toLinkVP() { return ((LinkVP*)m_u.up); }
|
||||
VSymEnt* toSymEnt() { return ((VSymEnt*)m_u.up); }
|
||||
AstNode* toNodep() { return ((AstNode*)m_u.up); }
|
||||
OrderBlockNU* toOrderBlock() { return ((OrderBlockNU*)m_u.up); }
|
||||
OrderVarNU* toOrderVar() { return ((OrderVarNU*)m_u.up); }
|
||||
V3GraphVertex* toGraphVertex() { return ((V3GraphVertex*)m_u.up); }
|
||||
inline int toInt() {
|
||||
return m_u.ui;
|
||||
}
|
||||
static inline VNUser fromZero () { return VNUser(0); }
|
||||
static inline VNUser fromInt (int i) { return VNUser(i); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -845,7 +869,8 @@ public:
|
||||
}
|
||||
#include "V3Ast__gen_visitor.h" // From ./astgen
|
||||
// Things like:
|
||||
// virtual void visit(type*) = 0;
|
||||
// virtual void visit(AstBreak* nodep) { visit((AstNodeStmt*)(nodep)); }
|
||||
// virtual void visit(AstNodeStmt* nodep) { visit((AstNode*)(nodep)); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -868,7 +893,7 @@ public:
|
||||
AstNode* oldp() const { return m_oldp; }
|
||||
void dump(ostream& str=cout) const;
|
||||
};
|
||||
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
|
||||
inline ostream& operator<<(ostream& os, const AstNRelinker& rhs) { rhs.dump(os); return os;}
|
||||
|
||||
//######################################################################
|
||||
// V3Hash -- Node hashing for V3Combine
|
||||
@@ -880,7 +905,8 @@ class V3Hash {
|
||||
uint32_t m_both;
|
||||
static const uint32_t M24 = ((1<<24)-1);
|
||||
void setBoth(uint32_t depth, uint32_t hshval) {
|
||||
if (depth==0) depth=1; if (depth>255) depth=255;
|
||||
if (depth==0) depth=1;
|
||||
if (depth>255) depth=255;
|
||||
m_both = (depth<<24) | (hshval & M24);
|
||||
}
|
||||
public:
|
||||
@@ -896,16 +922,19 @@ public:
|
||||
// CREATORS
|
||||
class Illegal {}; // for creator type-overload selection
|
||||
class FullValue {}; // for creator type-overload selection
|
||||
V3Hash(Illegal) { m_both=0; }
|
||||
explicit V3Hash(Illegal) { m_both=0; }
|
||||
// Saving and restoring inside a userp
|
||||
V3Hash(AstNUser* up) { m_both=up->castInt(); }
|
||||
explicit V3Hash(VNUser u) { m_both=u.toInt(); }
|
||||
V3Hash operator+= (const V3Hash& rh) {
|
||||
setBoth(depth()+rh.depth(), (hshval()*31+rh.hshval()));
|
||||
return *this; };
|
||||
// Creating from raw data (sameHash functions)
|
||||
V3Hash() { setBoth(1,0); }
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
V3Hash(uint32_t val) { setBoth(1,val); }
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
V3Hash(const void* vp) { setBoth(1,cvtToHash(vp)); }
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
V3Hash(const string& name);
|
||||
V3Hash(V3Hash h1, V3Hash h2) {
|
||||
setBoth(1,h1.hshval()*31+h2.hshval()); }
|
||||
@@ -914,7 +943,7 @@ public:
|
||||
V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) {
|
||||
setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); }
|
||||
};
|
||||
ostream& operator<<(ostream& os, V3Hash rhs);
|
||||
ostream& operator<<(ostream& os, const V3Hash& rhs);
|
||||
|
||||
//######################################################################
|
||||
// AstNode -- Base type of all Ast types
|
||||
@@ -954,15 +983,15 @@ class AstNode {
|
||||
// // Space for more bools here
|
||||
|
||||
// This member ordering both allows 64 bit alignment and puts associated data together
|
||||
AstNUser* m_user1p; // Pointer to any information the user iteration routine wants
|
||||
VNUser m_user1u; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user1Cnt; // Mark of when userp was set
|
||||
uint32_t m_user2Cnt; // Mark of when userp was set
|
||||
AstNUser* m_user2p; // Pointer to any information the user iteration routine wants
|
||||
AstNUser* m_user3p; // Pointer to any information the user iteration routine wants
|
||||
VNUser m_user2u; // Contains any information the user iteration routine wants
|
||||
VNUser m_user3u; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user3Cnt; // Mark of when userp was set
|
||||
uint32_t m_user4Cnt; // Mark of when userp was set
|
||||
AstNUser* m_user4p; // Pointer to any information the user iteration routine wants
|
||||
AstNUser* m_user5p; // Pointer to any information the user iteration routine wants
|
||||
VNUser m_user4u; // Contains any information the user iteration routine wants
|
||||
VNUser m_user5u; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user5Cnt; // Mark of when userp was set
|
||||
|
||||
// METHODS
|
||||
@@ -972,14 +1001,17 @@ class AstNode {
|
||||
void op4p(AstNode* nodep) { m_op4p = nodep; if (nodep) nodep->m_backp = this; }
|
||||
|
||||
void init(); // initialize value of AstNode
|
||||
void iterateListBackwards(AstNVisitor& v, AstNUser* vup=NULL);
|
||||
void iterateListBackwards(AstNVisitor& v);
|
||||
private:
|
||||
AstNode* cloneTreeIter();
|
||||
AstNode* cloneTreeIterList();
|
||||
void checkTreeIter(AstNode* backp);
|
||||
void checkTreeIterList(AstNode* backp);
|
||||
bool sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly);
|
||||
bool gateTreeIter();
|
||||
bool sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly);
|
||||
void deleteTreeIter();
|
||||
void deleteNode();
|
||||
public:
|
||||
static void relinkOneLink(AstNode*& pointpr, AstNode* newp);
|
||||
// cppcheck-suppress functionConst
|
||||
void debugTreeChange(const char* prefix, int lineno, bool next);
|
||||
@@ -987,7 +1019,7 @@ class AstNode {
|
||||
protected:
|
||||
// CONSTUCTORS
|
||||
AstNode() {init(); }
|
||||
AstNode(FileLine* fileline) {init(); m_fileline = fileline; }
|
||||
explicit AstNode(FileLine* fileline) {init(); m_fileline = fileline; }
|
||||
virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead
|
||||
virtual void cloneRelink() {}
|
||||
void cloneRelinkTree();
|
||||
@@ -1056,6 +1088,8 @@ public:
|
||||
// ACCESSORS
|
||||
virtual string name() const { return ""; }
|
||||
virtual void name(const string& name) { this->v3fatalSrc("name() called on object without name() method"); }
|
||||
virtual void tag(const string& text) {}
|
||||
virtual string tag() const { return ""; }
|
||||
virtual string verilogKwd() const { return ""; }
|
||||
string shortName() const; // Name with __PVT__ removed for concatenating scopes
|
||||
static string dedotName(const string& namein); // Name with dots removed
|
||||
@@ -1079,6 +1113,7 @@ public:
|
||||
//TODO stomp these width functions out, and call via dtypep() instead
|
||||
int width() const;
|
||||
int widthMin() const;
|
||||
int widthMinV() const { return v3Global.widthMinUsage()==VWidthMinUsage::VERILOG_WIDTH ? widthMin() : width(); }
|
||||
int widthWords() const { return VL_WORDS_I(width()); }
|
||||
bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); }
|
||||
bool isWide() const { return (width()>VL_QUADSIZE); }
|
||||
@@ -1086,57 +1121,75 @@ public:
|
||||
bool isSigned() const;
|
||||
bool isString() const;
|
||||
|
||||
AstNUser* user1p() const {
|
||||
VNUser user1u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser1InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl)?m_user1p:NULL);
|
||||
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl) ? m_user1u : VNUser(0));
|
||||
}
|
||||
void user1p(void* userp) { m_user1p=(AstNUser*)(userp); m_user1Cnt=AstUser1InUse::s_userCntGbl; }
|
||||
int user1() const { return user1p()->castInt(); }
|
||||
void user1(int val) { user1p(AstNUser::fromInt(val)); }
|
||||
int user1Inc() { int v=user1(); user1(v+1); return v; }
|
||||
AstNode* user1p() const { return user1u().toNodep(); }
|
||||
void user1u(const VNUser& user) { m_user1u=user; m_user1Cnt=AstUser1InUse::s_userCntGbl; }
|
||||
void user1p(void* userp) { user1u(VNUser(userp)); }
|
||||
int user1() const { return user1u().toInt(); }
|
||||
void user1(int val) { user1u(VNUser(val)); }
|
||||
int user1Inc(int val=1) { int v=user1(); user1(v+val); return v; }
|
||||
int user1SetOnce() { int v=user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
|
||||
static void user1ClearTree() { AstUser1InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user2p() const {
|
||||
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "user2p set w/o busy");
|
||||
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl)?m_user2p:NULL); }
|
||||
void user2p(void* userp) { m_user2p=(AstNUser*)(userp); m_user2Cnt=AstUser2InUse::s_userCntGbl; }
|
||||
int user2() const { return user2p()->castInt(); }
|
||||
void user2(int val) { user2p(AstNUser::fromInt(val)); }
|
||||
int user2Inc() { int v=user2(); user2(v+1); return v; }
|
||||
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; }
|
||||
static void user2ClearTree() { AstUser2InUse::clear(); }
|
||||
VNUser user2u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl) ? m_user2u : VNUser(0));
|
||||
}
|
||||
AstNode* user2p() const { return user2u().toNodep(); }
|
||||
void user2u(const VNUser& user) { m_user2u=user; m_user2Cnt=AstUser2InUse::s_userCntGbl; }
|
||||
void user2p(void* userp) { user2u(VNUser(userp)); }
|
||||
int user2() const { return user2u().toInt(); }
|
||||
void user2(int val) { user2u(VNUser(val)); }
|
||||
int user2Inc(int val=1) { int v=user2(); user2(v+val); return v; }
|
||||
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
|
||||
static void user2ClearTree() { AstUser2InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user3p() const {
|
||||
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "user3p set w/o busy");
|
||||
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl)?m_user3p:NULL); }
|
||||
void user3p(void* userp) { m_user3p=(AstNUser*)(userp); m_user3Cnt=AstUser3InUse::s_userCntGbl; }
|
||||
int user3() const { return user3p()->castInt(); }
|
||||
void user3(int val) { user3p(AstNUser::fromInt(val)); }
|
||||
int user3Inc() { int v=user3(); user3(v+1); return v; }
|
||||
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; }
|
||||
static void user3ClearTree() { AstUser3InUse::clear(); }
|
||||
VNUser user3u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl) ? m_user3u : VNUser(0));
|
||||
}
|
||||
AstNode* user3p() const { return user3u().toNodep(); }
|
||||
void user3u(const VNUser& user) { m_user3u=user; m_user3Cnt=AstUser3InUse::s_userCntGbl; }
|
||||
void user3p(void* userp) { user3u(VNUser(userp)); }
|
||||
int user3() const { return user3u().toInt(); }
|
||||
void user3(int val) { user3u(VNUser(val)); }
|
||||
int user3Inc(int val=1) { int v=user3(); user3(v+val); return v; }
|
||||
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
|
||||
static void user3ClearTree() { AstUser3InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user4p() const {
|
||||
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "user4p set w/o busy");
|
||||
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl)?m_user4p:NULL); }
|
||||
void user4p(void* userp) { m_user4p=(AstNUser*)(userp); m_user4Cnt=AstUser4InUse::s_userCntGbl; }
|
||||
int user4() const { return user4p()->castInt(); }
|
||||
void user4(int val) { user4p(AstNUser::fromInt(val)); }
|
||||
int user4Inc() { int v=user4(); user4(v+1); return v; }
|
||||
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; }
|
||||
static void user4ClearTree() { AstUser4InUse::clear(); }
|
||||
VNUser user4u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl) ? m_user4u : VNUser(0));
|
||||
}
|
||||
AstNode* user4p() const { return user4u().toNodep(); }
|
||||
void user4u(const VNUser& user) { m_user4u=user; m_user4Cnt=AstUser4InUse::s_userCntGbl; }
|
||||
void user4p(void* userp) { user4u(VNUser(userp)); }
|
||||
int user4() const { return user4u().toInt(); }
|
||||
void user4(int val) { user4u(VNUser(val)); }
|
||||
int user4Inc(int val=1) { int v=user4(); user4(v+val); return v; }
|
||||
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
|
||||
static void user4ClearTree() { AstUser4InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user5p() const {
|
||||
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "user5p set w/o busy");
|
||||
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl)?m_user5p:NULL); }
|
||||
void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=AstUser5InUse::s_userCntGbl; }
|
||||
int user5() const { return user5p()->castInt(); }
|
||||
void user5(int val) { user5p(AstNUser::fromInt(val)); }
|
||||
int user5Inc() { int v=user5(); user5(v+1); return v; }
|
||||
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; }
|
||||
static void user5ClearTree() { AstUser5InUse::clear(); }
|
||||
VNUser user5u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl) ? m_user5u : VNUser(0));
|
||||
}
|
||||
AstNode* user5p() const { return user5u().toNodep(); }
|
||||
void user5u(const VNUser& user) { m_user5u=user; m_user5Cnt=AstUser5InUse::s_userCntGbl; }
|
||||
void user5p(void* userp) { user5u(VNUser(userp)); }
|
||||
int user5() const { return user5u().toInt(); }
|
||||
void user5(int val) { user5u(VNUser(val)); }
|
||||
int user5Inc(int val=1) { int v=user5(); user5(v+val); return v; }
|
||||
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } // Better for cache than user5Inc()
|
||||
static void user5ClearTree() { AstUser5InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
vluint64_t editCount() const { return m_editCount; }
|
||||
void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##"
|
||||
@@ -1182,14 +1235,17 @@ public:
|
||||
|
||||
// METHODS - dump and error
|
||||
void v3errorEnd(ostringstream& str) const;
|
||||
void v3errorEndFatal(ostringstream& str) const VL_ATTR_NORETURN;
|
||||
string warnMore() const;
|
||||
virtual void dump(ostream& str=cout);
|
||||
void dumpGdb(); // For GDB only
|
||||
void dumpGdbHeader() const;
|
||||
|
||||
// METHODS - Tree modifications
|
||||
AstNode* addNext(AstNode* newp); // Returns this, adds to end of list
|
||||
AstNode* addNextNull(AstNode* newp); // Returns this, adds to end of list, NULL is OK
|
||||
static AstNode* addNext(AstNode* nodep, AstNode* newp); // Returns nodep, adds newp to end of nodep's list
|
||||
static AstNode* addNextNull(AstNode* nodep, AstNode* newp); // Returns nodep, adds newp (maybe NULL) to end of nodep's list
|
||||
inline AstNode* addNext(AstNode* newp) { return addNext(this, newp); }
|
||||
inline AstNode* addNextNull(AstNode* newp) { return addNextNull(this, newp); }
|
||||
void addNextHere(AstNode* newp); // Adds after speced node
|
||||
void addPrev(AstNode* newp) { replaceWith(newp); newp->addNext(this); }
|
||||
void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next
|
||||
@@ -1205,6 +1261,7 @@ public:
|
||||
|
||||
// METHODS - Iterate on a tree
|
||||
AstNode* cloneTree(bool cloneNextLink);
|
||||
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
|
||||
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
|
||||
bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable
|
||||
void deleteTree(); // Always deletes the next link
|
||||
@@ -1237,18 +1294,16 @@ public:
|
||||
virtual const char* broken() const { return NULL; }
|
||||
|
||||
// INVOKERS
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0;
|
||||
void iterate(AstNVisitor& v, AstNUser* vup=NULL) { this->accept(v,vup); } // Does this; excludes following this->next
|
||||
void iterateAndNext(AstNVisitor& v, AstNUser* vup=NULL);
|
||||
void iterateAndNextConst(AstNVisitor& v, AstNUser* vup=NULL);
|
||||
void iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup=NULL) { iterateAndNextConst(v, vup); }
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
void iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
void iterateChildrenConst(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
AstNode* acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup=NULL); // Return edited nodep; see comments in V3Ast.cpp
|
||||
virtual void accept(AstNVisitor& v) = 0;
|
||||
void iterate(AstNVisitor& v) { this->accept(v); } // Does this; excludes following this->next
|
||||
void iterateAndNext(AstNVisitor& v);
|
||||
void iterateAndNextConst(AstNVisitor& v);
|
||||
void iterateChildren(AstNVisitor& v); // Excludes following this->next
|
||||
void iterateChildrenBackwards(AstNVisitor& v); // Excludes following this->next
|
||||
void iterateChildrenConst(AstNVisitor& v); // Excludes following this->next
|
||||
AstNode* iterateSubtreeReturnEdits(AstNVisitor& v); // Return edited nodep; see comments in V3Ast.cpp
|
||||
|
||||
// CONVERSION
|
||||
AstNode* castNode() { return this; }
|
||||
#include "V3Ast__gen_interface.h" // From ./astgen
|
||||
// Things like:
|
||||
// AstAlways* castAlways();
|
||||
@@ -1263,12 +1318,13 @@ inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
|
||||
|
||||
#define ASTNODE_BASE_FUNCS(name) \
|
||||
virtual ~Ast ##name() {} \
|
||||
Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); }
|
||||
Ast ##name * cloneTree(bool cloneNext) { return static_cast<Ast ##name *>(AstNode::cloneTree(cloneNext)); } \
|
||||
Ast ##name * clonep() const { return static_cast<Ast ##name *>(AstNode::clonep()); }
|
||||
|
||||
class AstNodeMath : public AstNode {
|
||||
// Math -- anything that's part of an expression tree
|
||||
public:
|
||||
AstNodeMath(FileLine* fl)
|
||||
explicit AstNodeMath(FileLine* fl)
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeMath)
|
||||
// METHODS
|
||||
@@ -1285,13 +1341,13 @@ public:
|
||||
class AstNodeTermop : public AstNodeMath {
|
||||
// Terminal operator -- a operator with no "inputs"
|
||||
public:
|
||||
AstNodeTermop(FileLine* fl)
|
||||
explicit AstNodeTermop(FileLine* fl)
|
||||
: AstNodeMath(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeTermop)
|
||||
// Know no children, and hot function, so skip iterator for speed
|
||||
// See checkTreeIter also that asserts no children
|
||||
// cppcheck-suppress functionConst
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||
void iterateChildren(AstNVisitor& v) { }
|
||||
};
|
||||
|
||||
class AstNodeUniop : public AstNodeMath {
|
||||
@@ -1302,7 +1358,7 @@ public:
|
||||
dtypeFrom(lhsp);
|
||||
setOp1p(lhsp); }
|
||||
ASTNODE_BASE_FUNCS(NodeUniop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
// METHODS
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs
|
||||
@@ -1323,8 +1379,10 @@ public:
|
||||
: AstNodeMath(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); }
|
||||
ASTNODE_BASE_FUNCS(NodeBiop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
|
||||
// ACCESSORS
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
// METHODS
|
||||
@@ -1348,9 +1406,9 @@ public:
|
||||
: AstNodeMath(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setOp3p(ths); }
|
||||
ASTNODE_BASE_FUNCS(NodeTriop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* thsp() const { return op3p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
void thsp(AstNode* nodep) { return setOp3p(nodep); }
|
||||
@@ -1392,9 +1450,9 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeCond)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
|
||||
if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); }
|
||||
AstNode* condp() const { return op1p()->castNode(); } // op1 = Condition
|
||||
AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false...
|
||||
AstNode* condp() const { return op1p(); } // op1 = Condition
|
||||
AstNode* expr1p() const { return op2p(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p(); } // op3 = If false...
|
||||
virtual string emitVerilog() { return "%k(%l %f? %r %k: %t)"; }
|
||||
virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
|
||||
virtual bool cleanOut() { return false; } // clean if e1 & e2 clean
|
||||
@@ -1403,6 +1461,7 @@ public:
|
||||
virtual bool sizeMattersLhs() { return false; } virtual bool sizeMattersRhs() { return false; }
|
||||
virtual bool sizeMattersThs() { return false; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) = 0;
|
||||
};
|
||||
|
||||
class AstNodePreSel : public AstNode {
|
||||
@@ -1412,10 +1471,10 @@ public:
|
||||
: AstNode(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); }
|
||||
ASTNODE_BASE_FUNCS(NodePreSel)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* fromp() const { return lhsp(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* thsp() const { return op3p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
AstAttrOf* attrp() const { return op4p()->castAttrOf(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
@@ -1429,7 +1488,7 @@ public:
|
||||
class AstNodeStmt : public AstNode {
|
||||
// Statement -- anything that's directly under a function
|
||||
public:
|
||||
AstNodeStmt(FileLine* fl)
|
||||
explicit AstNodeStmt(FileLine* fl)
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeStmt)
|
||||
// METHODS
|
||||
@@ -1447,8 +1506,8 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeAssign)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
|
||||
// So iteration hits the RHS which is "earlier" in execution order, it's op1, not op2
|
||||
AstNode* rhsp() const { return op1p()->castNode(); } // op1 = Assign from
|
||||
AstNode* lhsp() const { return op2p()->castNode(); } // op2 = Assign to
|
||||
AstNode* rhsp() const { return op1p(); } // op1 = Assign from
|
||||
AstNode* lhsp() const { return op2p(); } // op2 = Assign to
|
||||
void rhsp(AstNode* np) { setOp1p(np); }
|
||||
void lhsp(AstNode* np) { setOp2p(np); }
|
||||
virtual bool hasDType() const { return true; }
|
||||
@@ -1457,6 +1516,7 @@ public:
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode*) const { return true; }
|
||||
virtual string verilogKwd() const { return "="; }
|
||||
virtual bool brokeLhsMustBeLvalue() const = 0;
|
||||
};
|
||||
|
||||
class AstNodeFor : public AstNodeStmt {
|
||||
@@ -1467,10 +1527,10 @@ public:
|
||||
addNOp1p(initsp); setOp2p(condp); addNOp3p(incsp); addNOp4p(bodysp);
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeFor)
|
||||
AstNode* initsp() const { return op1p()->castNode(); } // op1= initial statements
|
||||
AstNode* condp() const { return op2p()->castNode(); } // op2= condition to continue
|
||||
AstNode* incsp() const { return op3p()->castNode(); } // op3= increment statements
|
||||
AstNode* bodysp() const { return op4p()->castNode(); } // op4= body of loop
|
||||
AstNode* initsp() const { return op1p(); } // op1= initial statements
|
||||
AstNode* condp() const { return op2p(); } // op2= condition to continue
|
||||
AstNode* incsp() const { return op3p(); } // op3= increment statements
|
||||
AstNode* bodysp() const { return op4p(); } // op4= body of loop
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
@@ -1509,9 +1569,9 @@ public:
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeCase)
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
AstNode* exprp() const { return op1p()->castNode(); } // op1 = case condition <expression>
|
||||
AstNode* exprp() const { return op1p(); } // op1 = case condition <expression>
|
||||
AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions
|
||||
AstNode* notParallelp() const { return op3p()->castNode(); } // op3 = assertion code for non-full case's
|
||||
AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's
|
||||
void addItemsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
|
||||
};
|
||||
@@ -1519,7 +1579,7 @@ public:
|
||||
class AstNodeSenItem : public AstNode {
|
||||
// An AstSenItem or AstSenGate
|
||||
public:
|
||||
AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
|
||||
explicit AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSenItem)
|
||||
virtual bool isClocked() const = 0;
|
||||
virtual bool isCombo() const = 0;
|
||||
@@ -1573,7 +1633,7 @@ public:
|
||||
// Know no children, and hot function, so skip iterator for speed
|
||||
// See checkTreeIter also that asserts no children
|
||||
// cppcheck-suppress functionConst
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||
void iterateChildren(AstNVisitor& v) { }
|
||||
};
|
||||
|
||||
class AstNodeText : public AstNode {
|
||||
@@ -1606,7 +1666,7 @@ private:
|
||||
static int s_uniqueNum; // Unique number assigned to each dtype during creation for IEEE matching
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
AstNodeDType(FileLine* fl) : AstNode(fl) {
|
||||
explicit AstNodeDType(FileLine* fl) : AstNode(fl) {
|
||||
m_width=0; m_widthMin=0; m_generic=false;
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeDType)
|
||||
@@ -1623,6 +1683,7 @@ public:
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function
|
||||
virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function
|
||||
virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling
|
||||
//
|
||||
// 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; }
|
||||
@@ -1672,6 +1733,9 @@ public:
|
||||
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
|
||||
virtual bool similarDType(AstNodeDType* samep) const {
|
||||
return this==samep; // We don't compare members, require exact equivalence
|
||||
}
|
||||
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
|
||||
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool packed() const { return m_packed; }
|
||||
@@ -1695,22 +1759,30 @@ 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) {
|
||||
explicit 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; }
|
||||
|| (!m_refDTypep && childDTypep()))); return NULL; }
|
||||
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
|
||||
m_refDTypep = m_refDTypep->clonep()->castNodeDType();
|
||||
m_refDTypep = m_refDTypep->clonep();
|
||||
}}
|
||||
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 bool similarDType(AstNodeDType* samep) const {
|
||||
AstNodeArrayDType* sp = samep->castNodeArrayDType();
|
||||
return (sp
|
||||
&& type() == samep->type()
|
||||
&& msb() == sp->msb()
|
||||
&& rangenp()->sameTree(sp->rangenp())
|
||||
&& subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
|
||||
}
|
||||
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
|
||||
@@ -1740,9 +1812,9 @@ public:
|
||||
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
||||
:AstNodeBiop(fl, fromp, bitp) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSel)
|
||||
AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
||||
AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression
|
||||
AstNode* bitp() const { return op2p(); } // op2 = Msb selection expression
|
||||
void bitp(AstNode* nodep) { setOp2p(nodep); }
|
||||
int bitConst() const;
|
||||
virtual bool hasDType() const { return true; }
|
||||
@@ -1788,16 +1860,17 @@ public:
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool isGateOptimizable() const { return !((m_dpiExport || m_dpiImport) && !m_pure); }
|
||||
// {AstFunc only} op1 = Range output variable
|
||||
virtual void name(const string& name) { m_name = name; }
|
||||
string cname() const { return m_cname; }
|
||||
void cname(const string& cname) { m_cname = cname; }
|
||||
// op1 = Output variable (functions only, NULL for tasks)
|
||||
AstNode* fvarp() const { return op1p()->castNode(); }
|
||||
AstNode* fvarp() const { return op1p(); }
|
||||
void addFvarp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool isFunction() const { return fvarp()!=NULL; }
|
||||
// op3 = Statements/Ports/Vars
|
||||
AstNode* stmtsp() const { return op3p()->castNode(); } // op3 = List of statements
|
||||
AstNode* stmtsp() const { return op3p(); } // op3 = List of statements
|
||||
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
|
||||
// op4 = scope name
|
||||
AstScopeName* scopeNamep() const { return op4p()->castScopeName(); }
|
||||
@@ -1842,10 +1915,11 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeFTaskRef)
|
||||
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();
|
||||
m_taskp = m_taskp->clonep();
|
||||
}}
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual bool isGateOptimizable() const { return m_taskp && m_taskp->isGateOptimizable(); }
|
||||
string dotted() const { return m_dotted; } // * = Scope name or ""
|
||||
string prettyDotted() const { return prettyName(dotted()); }
|
||||
string inlinedDots() const { return m_inlinedDots; }
|
||||
@@ -1859,7 +1933,7 @@ public:
|
||||
// op1 = namep
|
||||
AstNode* namep() const { return op1p(); }
|
||||
// op2 = Pin interconnection list
|
||||
AstNode* pinsp() const { return op2p()->castNode(); }
|
||||
AstNode* pinsp() const { return op2p(); }
|
||||
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
// op3 = scope tracking
|
||||
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
|
||||
@@ -1891,7 +1965,7 @@ public:
|
||||
virtual void dump(ostream& str);
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual string name() const { return m_name; }
|
||||
AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements
|
||||
AstNode* stmtsp() const { return op2p(); } // op2 = List of statements
|
||||
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
|
||||
// METHODS
|
||||
void addInlinesp(AstNode* nodep) { addOp1p(nodep); }
|
||||
@@ -1941,8 +2015,8 @@ inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst
|
||||
inline bool AstNode::isOne() { return (this->castConst() && this->castConst()->num().isEqOne()); }
|
||||
inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); }
|
||||
inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); }
|
||||
inline bool AstNode::sameTree(AstNode* node2p) { return sameTreeIter(node2p, true, false); }
|
||||
inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(node2p, true, true); }
|
||||
inline bool AstNode::sameTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, false); }
|
||||
inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, true); }
|
||||
|
||||
inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); }
|
||||
|
||||
@@ -1953,8 +2027,8 @@ inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsC
|
||||
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(); }
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep(); }
|
||||
|
||||
#endif // Guard
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
|
||||
+27
-32
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -53,7 +53,7 @@ const char* AstNodeVarRef::broken() const {
|
||||
}
|
||||
|
||||
void AstNodeVarRef::cloneRelink() {
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); }
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); }
|
||||
}
|
||||
|
||||
int AstNodeSel::bitConst() const {
|
||||
@@ -140,6 +140,13 @@ AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
}
|
||||
}
|
||||
|
||||
AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
if (lhsp->isDouble() && rhsp->isDouble()) {
|
||||
return new AstEqD(fl, lhsp, rhsp);
|
||||
} else {
|
||||
return new AstEqWild(fl, lhsp, rhsp);
|
||||
}
|
||||
}
|
||||
|
||||
bool AstVar::isSigPublic() const {
|
||||
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
|
||||
@@ -195,6 +202,8 @@ string AstVar::verilogKwd() const {
|
||||
return "tri";
|
||||
} else if (varType()==AstVarType::WIRE) {
|
||||
return "wire";
|
||||
} else if (varType()==AstVarType::WREAL) {
|
||||
return "wreal";
|
||||
} else {
|
||||
return dtypep()->name();
|
||||
}
|
||||
@@ -217,7 +226,7 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
|
||||
arg += "float";
|
||||
} else if (strtype) {
|
||||
if (isInOnly()) arg += "const ";
|
||||
arg += "string";
|
||||
arg += "std::string";
|
||||
} else if (widthMin() <= 8) {
|
||||
arg += "CData";
|
||||
} else if (widthMin() <= 16) {
|
||||
@@ -386,6 +395,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
||||
// TODO this function should be removed in favor of recursing the dtype(),
|
||||
// as that allows for more complicated data types.
|
||||
int dim = 0;
|
||||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
@@ -420,6 +430,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
||||
|
||||
uint32_t AstNodeDType::arrayUnpackedElements() {
|
||||
uint32_t entries=1;
|
||||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
|
||||
@@ -438,6 +449,7 @@ 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;
|
||||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
@@ -492,9 +504,9 @@ const char* AstScope::broken() const {
|
||||
}
|
||||
|
||||
void AstScope::cloneRelink() {
|
||||
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep()->castScope();
|
||||
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep()->castCell();
|
||||
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep()->castNodeModule();
|
||||
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep();
|
||||
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep();
|
||||
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep();
|
||||
}
|
||||
|
||||
string AstScope::nameDotless() const {
|
||||
@@ -506,9 +518,9 @@ string AstScope::nameDotless() const {
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstScopeName::scopePrettyName() const {
|
||||
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
// TOP will be replaced by top->name()
|
||||
@@ -518,27 +530,9 @@ string AstScopeName::scopePrettyName() const {
|
||||
return AstNode::prettyName(out);
|
||||
}
|
||||
|
||||
string AstScopeName::scopeSymName() const {
|
||||
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
|
||||
if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
|
||||
if (out.substr(0,1) == ".") out.replace(0,1,"");
|
||||
string::size_type pos;
|
||||
while ((pos=out.find(".")) != string::npos) {
|
||||
out.replace(pos, 1, "__");
|
||||
}
|
||||
while ((pos=out.find("__DOT__")) != string::npos) {
|
||||
out.replace(pos, 7, "__");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstScopeName::scopeDpiName() const {
|
||||
string out;
|
||||
for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) {
|
||||
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
|
||||
@@ -769,10 +763,6 @@ void AstAlways::dump(ostream& str) {
|
||||
if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
|
||||
}
|
||||
|
||||
void AstArraySel::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" [start:"<<start()<<"] [length:"<<length()<<"]";
|
||||
}
|
||||
void AstAttrOf::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" ["<<attrType().ascii()<<"]";
|
||||
@@ -897,6 +887,10 @@ void AstNodeModule::dump(ostream& str) {
|
||||
if (inLibrary()) str<<" [LIB]";
|
||||
if (dead()) str<<" [DEAD]";
|
||||
}
|
||||
void AstPackageExport::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<packagep();
|
||||
}
|
||||
void AstPackageImport::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<packagep();
|
||||
@@ -992,6 +986,7 @@ void AstVar::dump(ostream& str) {
|
||||
if (attrFileDescr()) str<<" [aFD]";
|
||||
if (isFuncReturn()) str<<" [FUNCRTN]";
|
||||
else if (isFuncLocal()) str<<" [FUNC]";
|
||||
if (!attrClocker().unknown()) str<<" ["<<attrClocker().ascii()<<"] ";
|
||||
str<<" "<<varType();
|
||||
}
|
||||
void AstSenTree::dump(ostream& str) {
|
||||
|
||||
+695
-391
File diff suppressed because it is too large
Load Diff
+41
-16
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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,7 +56,7 @@ public:
|
||||
m_anyFuncInBegin = false;
|
||||
}
|
||||
~BeginState() {}
|
||||
void userMarkChanged(AstNodeFTask* nodep) {
|
||||
void userMarkChanged(AstNode* nodep) {
|
||||
nodep->user1(true);
|
||||
m_anyFuncInBegin = true;
|
||||
}
|
||||
@@ -84,13 +84,13 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
m_repeatNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
// Rename it
|
||||
if (m_unnamedScope != "") {
|
||||
@@ -113,7 +113,7 @@ private:
|
||||
m_namedScope = oldScope;
|
||||
m_unnamedScope = oldUnnamed;
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
// Begin blocks were only useful in variable creation, change names and delete
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
string oldScope = m_namedScope;
|
||||
@@ -160,21 +160,23 @@ private:
|
||||
} else {
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar* nodep) {
|
||||
if (m_unnamedScope != "") {
|
||||
// Rename it
|
||||
nodep->name(m_unnamedScope+"__DOT__"+nodep->name());
|
||||
m_statep->userMarkChanged(nodep);
|
||||
// Move to module
|
||||
nodep->unlinkFrBack();
|
||||
if (m_ftaskp) m_ftaskp->addStmtsp(nodep); // Begins under funcs just move into the func
|
||||
else m_modp->addStmtp(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
virtual void visit(AstCell* nodep) {
|
||||
UINFO(8," CELL "<<nodep<<endl);
|
||||
if (m_namedScope != "") {
|
||||
m_statep->userMarkChanged(nodep);
|
||||
// Rename it
|
||||
nodep->name(m_namedScope+"__DOT__"+nodep->name());
|
||||
UINFO(8," rename to "<<nodep->name()<<endl);
|
||||
@@ -182,8 +184,16 @@ private:
|
||||
nodep->unlinkFrBack();
|
||||
m_modp->addStmtp(nodep);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarXRef* nodep) {
|
||||
UINFO(9, " VARXREF "<<nodep<<endl);
|
||||
if (m_namedScope != "" && nodep->inlinedDots() == "") {
|
||||
nodep->inlinedDots(m_namedScope);
|
||||
UINFO(9, " rescope to "<<nodep<<endl);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) {
|
||||
// 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
|
||||
@@ -196,13 +206,13 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
|
||||
virtual void visit(AstCoverDecl* nodep) {
|
||||
// Don't need to fix path in coverage statements, they're not under
|
||||
// any BEGINs, but V3Coverage adds them all under the module itself.
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
// VISITORS - LINT CHECK
|
||||
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
|
||||
virtual void visit(AstIf* nodep) { // Note not AstNodeIf; other types don't get covered
|
||||
// Check IFDEPTH warning - could be in other transform files if desire
|
||||
int prevIfDepth = m_ifDepth;
|
||||
if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off
|
||||
@@ -215,8 +225,8 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
m_ifDepth = prevIfDepth;
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -242,15 +252,30 @@ private:
|
||||
// AstNodeFTask::user1p // Node replaced, rename it
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeFTaskRef* nodep) {
|
||||
if (nodep->taskp()->user1()) { // It was converted
|
||||
UINFO(9, " relinkFTask "<<nodep<<endl);
|
||||
nodep->name(nodep->taskp()->name());
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->varp()->user1()) { // It was converted
|
||||
UINFO(9, " relinVarRef "<<nodep<<endl);
|
||||
nodep->name(nodep->varp()->name());
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstIfaceRefDType* nodep) {
|
||||
// May have changed cell names
|
||||
// TypeTable is always after all modules, so names are stable
|
||||
UINFO(8," IFACEREFDTYPE "<<nodep<<endl);
|
||||
if (nodep->cellp()) nodep->cellName(nodep->cellp()->name());
|
||||
UINFO(8," rename to "<<nodep<<endl);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -271,5 +296,5 @@ void V3Begin::debeginAll(AstNetlist* nodep) {
|
||||
if (state.anyFuncInBegin()) {
|
||||
BeginRelinkVisitor brvisitor (nodep,&state);
|
||||
}
|
||||
V3Global::dumpCheckGlobalTree("begin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("begin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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
-6
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
UINFO(4," IF: "<<nodep<<endl);
|
||||
int lastLikely = m_likely;
|
||||
int lastUnlikely = m_unlikely;
|
||||
@@ -101,17 +101,17 @@ private:
|
||||
m_likely = lastLikely;
|
||||
m_unlikely = lastUnlikely;
|
||||
}
|
||||
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||
virtual void visit(AstCCall* nodep) {
|
||||
checkUnlikely(nodep);
|
||||
nodep->funcp()->user1Inc();
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
checkUnlikely(nodep);
|
||||
m_cfuncsp.push_back(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
checkUnlikely(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
BranchVisitor(AstNetlist* nodep) {
|
||||
explicit BranchVisitor(AstNetlist* nodep) {
|
||||
reset();
|
||||
nodep->iterateChildren(*this);
|
||||
calc_tasks();
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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
-24
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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,7 +31,7 @@
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include VL_INCLUDE_UNORDERED_MAP
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3Broken.h"
|
||||
@@ -47,7 +47,7 @@ class BrokenTable : public AstNVisitor {
|
||||
private:
|
||||
// MEMBERS
|
||||
// For each node, we keep if it exists or not.
|
||||
typedef map<const AstNode*,int> NodeMap;
|
||||
typedef VL_UNORDERED_MAP<const AstNode*,int> NodeMap; // Performance matters (when --debug)
|
||||
static NodeMap s_nodes; // Set of all nodes that exist
|
||||
// BITMASK
|
||||
enum { FLAG_ALLOCATED = 0x01 }; // new() and not delete()ed
|
||||
@@ -62,16 +62,20 @@ public:
|
||||
if (debug()>=9) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
|
||||
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n");
|
||||
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted");
|
||||
}
|
||||
if (iter!=s_nodes.end()) s_nodes.erase(iter);
|
||||
}
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
|
||||
// GCC 4.4.* compiler warning bug, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390
|
||||
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
static void addNewed(const AstNode* nodep) {
|
||||
// Called by operator new on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()>=9) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
|
||||
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n");
|
||||
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
|
||||
}
|
||||
if (iter == s_nodes.end()) {
|
||||
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
|
||||
@@ -94,16 +98,16 @@ public:
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter == s_nodes.end()) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
} else {
|
||||
if (!(iter->second & FLAG_ALLOCATED)) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
}
|
||||
if (iter->second & FLAG_IN_TREE) {
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location\n");
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location");
|
||||
}
|
||||
}
|
||||
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
|
||||
@@ -186,14 +190,18 @@ private:
|
||||
// NODE STATE
|
||||
// Nothing! // This may be called deep inside other routines
|
||||
// // so userp and friends may not be used
|
||||
// VISITORS
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// METHODS
|
||||
void processAndIterate(AstNode* nodep) {
|
||||
BrokenTable::addInTree(nodep, nodep->maybePointedTo());
|
||||
nodep->iterateChildrenConst(*this);
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstNode* nodep) {
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
BrokenMarkVisitor(AstNetlist* nodep) {
|
||||
explicit BrokenMarkVisitor(AstNetlist* nodep) {
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~BrokenMarkVisitor() {}
|
||||
@@ -204,7 +212,13 @@ public:
|
||||
|
||||
class BrokenCheckVisitor : public AstNVisitor {
|
||||
private:
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
void checkWidthMin(AstNode* nodep) {
|
||||
if (nodep->width() != nodep->widthMin()
|
||||
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
}
|
||||
void processAndIterate(AstNode* nodep) {
|
||||
BrokenTable::setUnder(nodep,true);
|
||||
if (const char* whyp=nodep->broken()) {
|
||||
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
|
||||
@@ -220,24 +234,27 @@ private:
|
||||
if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<<nodep->prettyTypeName());
|
||||
}
|
||||
if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed");
|
||||
if (AstNodeDType* dnodep = nodep->castNodeDType()) {
|
||||
if (dnodep->width() != dnodep->widthMin()
|
||||
&& v3Global.assertWidthsMatch()) {
|
||||
dnodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v3Global.assertWidthsMatch()) {
|
||||
if (nodep->width() != nodep->widthMin()) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep);
|
||||
}
|
||||
checkWidthMin(nodep);
|
||||
nodep->iterateChildrenConst(*this);
|
||||
BrokenTable::setUnder(nodep,false);
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
processAndIterate(nodep);
|
||||
if (v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& nodep->lhsp()->castNodeVarRef()
|
||||
&& !nodep->lhsp()->castNodeVarRef()->lvalue()) {
|
||||
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
BrokenCheckVisitor(AstNetlist* nodep) {
|
||||
explicit BrokenCheckVisitor(AstNetlist* nodep) {
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~BrokenCheckVisitor() {}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generate C language constructors and AstCReset nodes.
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2017 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.
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3CCtors's Transformations:
|
||||
// Iterates over all modules and
|
||||
// for all AstVar, create a creates a AstCReset node in an _ctor_var_reset AstCFunc.
|
||||
// for all AstCoverDecl, move the declaration into a _configure_coverage AstCFunc.
|
||||
// For each variable that needs reset, add a AstCReset node.
|
||||
//
|
||||
// This transformation honors outputSplitCFuncs.
|
||||
//*************************************************************************
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3EmitCBase.h"
|
||||
#include "V3CCtors.h"
|
||||
|
||||
class V3CCtorsVisitor {
|
||||
private:
|
||||
string m_basename;
|
||||
string m_argsp;
|
||||
string m_callargsp;
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstCFunc* m_tlFuncp; // Top level function being built
|
||||
AstCFunc* m_funcp; // Current function
|
||||
int m_numStmts; // Number of statements output
|
||||
int m_funcNum; // Function number being built
|
||||
|
||||
public:
|
||||
void add(AstNode* nodep) {
|
||||
if (v3Global.opt.outputSplitCFuncs()
|
||||
&& v3Global.opt.outputSplitCFuncs() < m_numStmts) {
|
||||
m_funcp = NULL;
|
||||
}
|
||||
if (!m_funcp) {
|
||||
m_funcp = new AstCFunc(m_modp->fileline(), m_basename + "_" + cvtToStr(++m_funcNum), NULL, "void");
|
||||
m_funcp->isStatic(false);
|
||||
m_funcp->declPrivate(true);
|
||||
m_funcp->slow(true);
|
||||
m_funcp->argTypes(m_argsp);
|
||||
m_modp->addStmtp(m_funcp);
|
||||
|
||||
// Add a top call to it
|
||||
AstCCall* callp = new AstCCall(m_modp->fileline(), m_funcp);
|
||||
callp->argTypes(m_callargsp);
|
||||
|
||||
m_tlFuncp->addStmtsp(callp);
|
||||
m_numStmts = 0;
|
||||
}
|
||||
m_funcp->addStmtsp(nodep);
|
||||
m_numStmts += 1;
|
||||
}
|
||||
|
||||
V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="",
|
||||
const string& stmt="") {
|
||||
m_basename = basename;
|
||||
m_argsp = argsp;
|
||||
m_callargsp = callargsp;
|
||||
m_modp = nodep;
|
||||
m_numStmts = 0;
|
||||
m_funcNum = 0;
|
||||
m_tlFuncp = new AstCFunc(nodep->fileline(), basename, NULL, "void");
|
||||
m_tlFuncp->declPrivate(true);
|
||||
m_tlFuncp->isStatic(false);
|
||||
m_tlFuncp->slow(true);
|
||||
m_tlFuncp->argTypes(m_argsp);
|
||||
if (stmt != "") {
|
||||
m_tlFuncp->addStmtsp(new AstCStmt(nodep->fileline(), stmt));
|
||||
}
|
||||
m_funcp = m_tlFuncp;
|
||||
m_modp->addStmtp(m_tlFuncp);
|
||||
}
|
||||
~V3CCtorsVisitor() {}
|
||||
private:
|
||||
explicit V3CCtorsVisitor(const V3CCtorsVisitor&); ///< N/A, no copy constructor
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
void V3CCtors::cctorsAll() {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
|
||||
// Process each module in turn
|
||||
{
|
||||
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstVar* varp = np->castVar()) {
|
||||
var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v3Global.opt.coverage()) {
|
||||
V3CCtorsVisitor configure_coverage
|
||||
(modp, "_configure_coverage", EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first",
|
||||
"if (0 && vlSymsp && first) {} // Prevent unused\n");
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstCoverDecl* coverp = np->castCoverDecl()) {
|
||||
AstNode* backp = coverp->backp();
|
||||
coverp->unlinkFrBack();
|
||||
configure_coverage.add(coverp);
|
||||
np = backp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit CFunc's for class construction and configuration
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2017 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.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _V3CCTORS_H_
|
||||
#define _V3CCTORS_H_ 1
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include "V3Error.h"
|
||||
#include "V3Ast.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
class V3CCtors {
|
||||
public:
|
||||
static void cctorsAll();
|
||||
};
|
||||
|
||||
|
||||
#endif // Guard
|
||||
+22
-24
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
return level;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeCase* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeCase* nodep) {
|
||||
if (nodep->castCase() && nodep->castCase()->casex()) {
|
||||
nodep->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)");
|
||||
}
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
m_caseExprp = NULL;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
virtual void visit(AstConst* nodep) {
|
||||
// See also neverItem
|
||||
if (m_caseExprp && nodep->num().isFourState()) {
|
||||
if (m_caseExprp->castGenCase()) {
|
||||
@@ -107,12 +107,12 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
CaseLintVisitor(AstNodeCase* nodep) {
|
||||
explicit CaseLintVisitor(AstNodeCase* nodep) {
|
||||
m_caseExprp = NULL;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
@@ -174,7 +174,7 @@ private:
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
//if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n");
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
|
||||
if (neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
} else {
|
||||
@@ -246,7 +246,7 @@ private:
|
||||
if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
|
||||
}
|
||||
if (same) {
|
||||
tree1p->deleteTree(); tree1p=NULL;
|
||||
tree1p->deleteTree(); VL_DANGLING(tree1p);
|
||||
return tree0p;
|
||||
}
|
||||
|
||||
@@ -295,8 +295,8 @@ private:
|
||||
|
||||
if (ifrootp) nodep->replaceWith(ifrootp);
|
||||
else nodep->unlinkFrBack();
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
cexprp->deleteTree(); cexprp=NULL;
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
cexprp->deleteTree(); VL_DANGLING(cexprp);
|
||||
if (debug()>=9) ifrootp->dumpTree(cout," _simp: ");
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ private:
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
if (iconstp && neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
|
||||
// For simplicity, make expression that is not equal, and let later
|
||||
// optimizations remove it
|
||||
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
|
||||
@@ -351,7 +351,7 @@ private:
|
||||
AstNode* and2p = new AstAnd(itemp->fileline(),
|
||||
new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
|
||||
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
|
||||
} else {
|
||||
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
|
||||
@@ -369,7 +369,7 @@ private:
|
||||
itemp->condsp(ifexprp);
|
||||
}
|
||||
}
|
||||
cexprp->deleteTree(); cexprp=NULL;
|
||||
cexprp->deleteTree(); VL_DANGLING(cexprp);
|
||||
if (!hadDefault) {
|
||||
// If there was no default, add a empty one, this greatly simplifies below code
|
||||
// and constant propagation will just eliminate it for us later.
|
||||
@@ -408,10 +408,9 @@ private:
|
||||
}
|
||||
}
|
||||
{ // Make the new lower IF and attach in the tree
|
||||
AstNode* itemexprp = ifexprp; ifexprp=NULL;
|
||||
AstNode* itemexprp = ifexprp; VL_DANGLING(ifexprp);
|
||||
if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition
|
||||
itemexprp->deleteTree(); itemexprp=NULL;
|
||||
// cppcheck-suppress redundantAssignment
|
||||
itemexprp->deleteTree(); VL_DANGLING(itemexprp);
|
||||
itemexprp = new AstConst(itemp->fileline(), AstConst::LogicTrue());
|
||||
}
|
||||
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL);
|
||||
@@ -424,10 +423,10 @@ private:
|
||||
// Handle any assertions
|
||||
replaceCaseParallel(nodep, false);
|
||||
// Replace the CASE... with IF...
|
||||
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
|
||||
if (debug()>=9 && grouprootp) grouprootp->dumpTree(cout," _new: ");
|
||||
if (grouprootp) nodep->replaceWith(grouprootp);
|
||||
else nodep->unlinkFrBack();
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
|
||||
@@ -452,7 +451,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||
virtual void visit(AstCase* nodep) {
|
||||
V3Case::caseLint(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
if (debug()>=9) nodep->dumpTree(cout," case_old: ");
|
||||
@@ -460,22 +459,21 @@ private:
|
||||
// It's a simple priority encoder or complete statement
|
||||
// we can make a tree of statements to avoid extra comparisons
|
||||
++m_statCaseFast;
|
||||
replaceCaseFast(nodep); nodep=NULL;
|
||||
replaceCaseFast(nodep); VL_DANGLING(nodep);
|
||||
} else {
|
||||
++m_statCaseSlow;
|
||||
// cppcheck-supporess uselessAssignmentPtrArg
|
||||
replaceCaseComplicated(nodep); nodep=NULL;
|
||||
replaceCaseComplicated(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
}
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
CaseVisitor(AstNetlist* nodep) {
|
||||
explicit CaseVisitor(AstNetlist* nodep) {
|
||||
m_caseNoOverlapsAllCovered = false;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
@@ -491,7 +489,7 @@ public:
|
||||
void V3Case::caseAll(AstNetlist* nodep) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
CaseVisitor visitor (nodep);
|
||||
V3Global::dumpCheckGlobalTree("case.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("case", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
void V3Case::caseLint(AstNodeCase* nodep) {
|
||||
UINFO(4,__FUNCTION__<<": "<<endl);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 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.
|
||||
|
||||
+12
-12
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2017 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.
|
||||
@@ -107,19 +107,19 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeUniop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeBiop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1()
|
||||
| nodep->rhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeTriop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1()
|
||||
| nodep->rhsp()->user1()
|
||||
@@ -128,12 +128,12 @@ private:
|
||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstCCast* nodep, AstNUser*) {
|
||||
virtual void visit(AstCCast* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureLower32Cast(nodep);
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstNegate* nodep, AstNUser*) {
|
||||
virtual void visit(AstNegate* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->lhsp()->widthMin()==1) {
|
||||
@@ -145,7 +145,7 @@ private:
|
||||
insureCast(nodep->lhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (!nodep->lvalue()
|
||||
&& !nodep->backp()->castCCast()
|
||||
&& nodep->backp()->castNodeMath()
|
||||
@@ -158,7 +158,7 @@ private:
|
||||
}
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
virtual void visit(AstConst* nodep) {
|
||||
// Constants are of unknown size if smaller than 33 bits, becase
|
||||
// we're too lazy to wrap every constant in the universe in
|
||||
// ((IData)#).
|
||||
@@ -166,17 +166,17 @@ private:
|
||||
}
|
||||
|
||||
// NOPs
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {}
|
||||
virtual void visit(AstVar* nodep) {}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
CastVisitor(AstNetlist* nodep) {
|
||||
explicit CastVisitor(AstNetlist* nodep) {
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~CastVisitor() {}
|
||||
@@ -188,5 +188,5 @@ public:
|
||||
void V3Cast::castAll(AstNetlist* nodep) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
CastVisitor visitor (nodep);
|
||||
V3Global::dumpCheckGlobalTree("cast.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
V3Global::dumpCheckGlobalTree("cast", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2015 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2017 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