Compare commits

...
107 Commits
Author SHA1 Message Date
Wilson Snyder 344248cea0 Version bump 2011-06-28 20:52:04 -04:00
Wilson Snyder 2789e3dba5 Fix 96 bit DPI input/outputs, bug359 2011-06-28 20:45:50 -04:00
Wilson Snyder cca759a41e Tests: Example embedding 2011-05-22 08:43:36 -04:00
Wilson Snyder 4f7b3d8882 Fix out of memory on slice syntax error, bug354. 2011-05-21 08:19:33 -04:00
Wilson Snyder 2b330b78b7 Support bit vectors > 64 bits wide in DPI import and exports. 2011-05-20 21:33:31 -04:00
Wilson Snyder d47ca1912b tests: Fix invocation scripts for new site standard 2011-05-20 20:47:15 -04:00
Wilson Snyder cdf18c96f4 driver: Allow getting verilator flags in tests 2011-05-19 21:25:23 -04:00
Wilson Snyder 53acaa05b8 Commentary 2011-05-18 07:10:12 -04:00
Wilson Snyder fb85679068 Fix DPI bit vector compile errors, bug347. 2011-05-12 07:35:28 -04:00
Wilson Snyder 9558e14479 Fix DPI undeclared svBitVecVal compile error, bug346. Additional change. 2011-05-12 06:59:13 -04:00
Wilson Snyder 4af0af93bf Fix DPI undeclared svBitVecVal compile error, bug346. 2011-05-12 06:32:29 -04:00
Wilson Snyder df4bc950fe Cleanup trailing whitespace 2011-05-09 23:58:38 -04:00
Wilson Snyder 250394f72b Fix compiler warnings on SPARC, bug288 2011-05-09 23:49:17 -04:00
Wilson Snyder d5e9e7cd2b Remove dead code 2011-04-19 19:02:03 -05:00
Wilson Snyder 9a96f621ef Fix CDCRSTLOGIC report showing endpoint flops without resets. 2011-04-18 10:47:02 -04:00
Wilson Snyder 5d7ce096c6 Fix error on enum references to other packages, bug339. 2011-04-13 19:34:14 -04:00
Wilson Snyder c9f8109c06 Pre-version 2011-04-13 19:33:58 -04:00
Wilson Snyder a20b4f2864 Version bump 2011-04-06 07:33:44 -04:00
Wilson Snyder 44a19d2a0a Fix missing test files 2011-04-06 07:33:32 -04:00
Wilson Snyder 02f3beb8db Add V3Number rotate functions; unused as yet 2011-03-30 21:31:29 -04:00
Wilson Snyder 3269cc3d90 Add +libext+.sv default 2011-03-30 21:30:36 -04:00
Wilson Snyder fb70a1f4ab Add --Wno-fatal to turn off abort on warnings. 2011-03-22 18:09:39 -04:00
Wilson Snyder df0aa483ce Support ${...} and $(...) env variables in .vc files 2011-03-21 12:25:31 -04:00
Wilson Snyder c83f12a55c Support simple cast operators, bug335. 2011-03-17 22:25:49 -04:00
Wilson Snyder 9704f59566 Internals: Rename AstCast to AstCCast 2011-03-17 21:09:52 -04:00
Wilson Snyder 2923893d34 Support loop unrolling on width mismatches, bug 333 2011-03-12 07:45:04 -05:00
Wilson Snyder 890dab0742 Write logfile on each failure 2011-03-12 07:44:29 -05:00
Wilson Snyder 607e26b041 Commentary 2011-03-08 06:49:45 -05:00
Wilson Snyder ea75290f65 Add error on circular parameter definitions, bug329 2011-03-07 20:44:19 -05:00
Wilson Snyder a176054118 Add --trace-max-width and --trace-max-array, bug 319. 2011-02-23 21:58:27 -05:00
Wilson Snyder 9a697dc5f5 Accelerate bit-selected inversions. 2011-02-23 21:36:38 -05:00
Wilson Snyder cfdb852843 Fix concatenates and vectored bufif1, bug326. 2011-02-23 21:21:59 -05:00
Wilson Snyder 2e67a91982 Support $bits(data_type), bug327. 2011-02-23 19:04:15 -05:00
Wilson Snyder 074ca9330d Make width violation on function outputs a fatal error 2011-02-18 20:52:26 -05:00
Wilson Snyder f0d7cdcb20 Commentary 2011-02-18 07:11:03 -05:00
Wilson Snyder 40d961e059 Version bump 2011-02-14 19:05:55 -05:00
Wilson Snyder e5de759236 Report error on function call output tied to constant.
Fix internal error on functions called as SV tasks.
2011-02-14 19:25:30 -05:00
Wilson Snyder e26a75c59d Fix internal error on non-inlined inout pins. 2011-02-07 19:15:58 -05:00
Wilson Snyder 8701145b40 Fix error on constants connected to outputs, bug323. 2011-01-31 07:05:04 -05:00
Wilson Snyder a2558886c8 Report errors on empty pins, bug321 2011-01-29 18:00:48 -05:00
Wilson Snyder f818ee86ae Report errors on duplicated pins, bug321. 2011-01-29 17:01:06 -05:00
Wilson Snyder ad0dbdaa9c CDC: Print nice net names instead of ___5f 2011-01-19 11:44:23 -05:00
Wilson Snyder a9f14b294f Internals: Cdc notes; marking submodules won't work 2011-01-18 21:37:53 -05:00
Wilson Snyder a435ae98f9 Throw UNUSED/UNDRIVEN only once per net in a parametrized module. 2011-01-18 21:28:51 -05:00
Wilson Snyder 481b261458 Internals: add a few userIncs, No functional change 2011-01-18 21:19:12 -05:00
Wilson Snyder 48df52d743 Reduce use of CRELINE so line numbers more closely match first parsed location 2011-01-18 21:12:31 -05:00
Wilson Snyder 0af0d3b171 Cleanup CDC reports, remove TOP-> signal prefixes 2011-01-17 14:58:58 -05:00
Wilson Snyder 8287cf35e7 Fix warnings to point to lowest net usage, not upper level ports. 2011-01-17 14:10:01 -05:00
Wilson Snyder fab7924cc2 Fix block comment not separating identifiers, bug311. 2011-01-11 18:46:21 -05:00
Wilson Snyder 0ab739e8b1 Fix false BLKSEQ on non-unrolled for loop indexes. 2011-01-06 06:46:19 -05:00
Wilson Snyder 2dcd4d171b Version bump 2011-01-03 13:32:16 -05:00
Wilson Snyder e7f4d18c3d First test is verilator -V 2011-01-03 13:30:33 -05:00
Wilson Snyder 1611362c22 Add --unused-regexp 2011-01-01 19:43:22 -05:00
Wilson Snyder 2327698160 driver: Allow --site specific tests 2011-01-01 19:18:32 -05:00
Wilson Snyder 71c1f00ec2 Copyright year update 2011-01-01 18:21:19 -05:00
Wilson Snyder 6574a126ef spdiff: Ignore copyright differences 2011-01-01 18:20:30 -05:00
Wilson Snyder 1e68086355 Fix defparam test failing after make clean 2011-01-01 18:12:29 -05:00
Wilson Snyder 326cc8fd67 Fix DLYSYNC with for loop variables 2010-12-31 20:18:21 -05:00
Wilson Snyder 4afcb421bd With --Wall, add BLKSEQ warning on blocking assignments in seq blocks. 2010-12-31 18:36:29 -05:00
Wilson Snyder 8d21917035 Add SYNCASYNCNET 2010-12-31 07:51:14 -05:00
Wilson Snyder 4ca7f8834c Fix test ignores 2010-12-30 21:20:58 -05:00
Wilson Snyder b43299c8da Fix suppression of messages under debug 2010-12-30 08:41:23 -05:00
Wilson Snyder b763809f5e Fix last commit; allow multiple exprs 2010-12-30 08:26:36 -05:00
Wilson Snyder 2cb97f7475 For UNUSED, ignore black boxed sys calls 2010-12-30 07:55:31 -05:00
Wilson Snyder 6283df7491 Vlt lint off now has optional msgname 2010-12-30 06:58:02 -05:00
Wilson Snyder acc4490370 For UNUSED, skip primitive tables 2010-12-29 20:24:31 -05:00
Wilson Snyder f85c1a995a For UNUSED, better by-bit warnings 2010-12-29 19:59:07 -05:00
Wilson Snyder 809e5fda8a Ignore DECLFILENAME on library files 2010-12-29 19:34:33 -05:00
Wilson Snyder dce245da5a Allow wildcards in vlt config files 2010-12-29 19:14:49 -05:00
Wilson Snyder d261c4cd27 For UNUSED warning, ignore genvars 2010-12-29 18:10:02 -05:00
Wilson Snyder c33299d542 Add UNUSED and UNDRIVEN warnings 2010-12-29 08:06:05 -05:00
Wilson Snyder ebdf8a5f3c Internals: Constify tristates with ConstLive, unused so no functional change 2010-12-29 07:56:22 -05:00
Wilson Snyder c8852d183f Internals: Add V3Const preserving liveness, no functional change 2010-12-28 21:23:16 -05:00
Wilson Snyder 9f161b20ef Internals: Avoid passing vars from V3Const visitor; no functional change 2010-12-28 20:46:13 -05:00
Wilson Snyder 40f9d64973 Commentary 2010-12-27 17:25:28 -05:00
Wilson Snyder 4a2e68a0fd Avoid -wall 2010-12-26 15:26:04 -05:00
Wilson Snyder bcd90d3401 Constify LSB subtractions immediately, no functional change intended 2010-12-26 15:20:57 -05:00
Wilson Snyder 114af7d33f Make UNUSED/UNDRIVEN -Wall only 2010-12-26 10:17:35 -05:00
Wilson Snyder 7b83d2de49 Commentary 2010-12-26 09:40:17 -05:00
Wilson Snyder 850de5913d With --Wall, add IFDEPTH warning on deep if statements. 2010-12-26 09:31:09 -05:00
Wilson Snyder bb9ee46f40 Use 'suggest' in INCABSPATH warning 2010-12-26 08:19:45 -05:00
Wilson Snyder e94fc1305b Support unique0; track internally with new attributes 2010-12-26 08:09:25 -05:00
Wilson Snyder 3e4e8feb29 With --Wall, add DECLFILENAME warning on modules not matching filename. 2010-12-25 16:31:22 -05:00
Wilson Snyder fedf347b1a With --Wall, add INCABSPATH warning on `include with absolute paths. 2010-12-25 15:50:07 -05:00
Wilson Snyder 285277a50b Add -Wall; move VARHIDDEN to style warnings 2010-12-25 15:28:13 -05:00
Wilson Snyder 323c96f42f Add -Wwarn-style, -Wno-style, and DEFPARAM warnings 2010-12-25 15:13:56 -05:00
Wilson Snyder 7dee344ea9 Add limited support for VPI access to public signals, see docs. 2010-12-25 14:39:41 -05:00
Wilson Snyder 65bce588e4 Add fatalSrc debug dump check 2010-12-24 13:15:46 -05:00
Wilson Snyder 233ff1b744 --gdbbt now documented, and uses return-child-results
Use this in first test_c to backtrace if any problems.
2010-12-17 20:14:25 -05:00
Wilson Snyder 0837e39787 With -V, print VERILATOR_BIN env var 2010-12-17 19:40:08 -05:00
Wilson Snyder 86db565a21 Fix extra / in binary name 2010-12-14 18:08:41 -05:00
Wilson Snyder d6ac5e5001 Support ++,--,+= etc as standalone statements. 2010-12-07 20:18:47 -05:00
Wilson Snyder e6443f1981 Fix manifest tsub error, broke earlier 2010-12-07 11:45:31 -05:00
Wilson Snyder d13e6c73db When running with VERILATOR_ROOT, optionally find binaries under bin. 2010-12-07 11:43:43 -05:00
Wilson Snyder 79ca7f3cb5 Commentary 2010-12-07 09:30:52 -05:00
Wilson Snyder cfd07ccd34 Suppress WIDTH warnings when adding/subtracting 1'b1. 2010-12-02 14:00:43 -05:00
Wilson Snyder 48047d523a Remove dead code ifdef, bug299 2010-11-03 12:38:26 -04:00
Wilson Snyder eeb8fc2626 Add -F option to read relative option files, bug297. 2010-11-03 07:21:34 -04:00
Wilson Snyder 3d1baf3f2f Version bump 2010-11-02 21:11:02 -04:00
Wilson Snyder 4e382d6765 tests: add --golden flag 2010-11-02 21:10:52 -04:00
Wilson Snyder 582963375d tests: fix pipe bad golden 2010-11-02 21:10:44 -04:00
Wilson Snyder 56c7c1bcc8 Add warning when directory contains spaces, msg378 2010-10-28 09:51:36 -04:00
Wilson Snyder f88e57ddb8 Fix DPI export name not found, msg369. 2010-10-22 13:10:31 -04:00
Wilson Snyder 9d98e012e4 Fix segfault on SystemVerilog "output wire foo=0", bug291. 2010-10-04 07:48:09 -04:00
Wilson Snyder d305a774f0 Fix wrong filename on include file errors, bug289 2010-09-28 09:33:59 -04:00
Wilson Snyder 16b0c8d353 Commentary 2010-09-25 07:59:18 -04:00
Wilson Snyder 55da4fdbf6 Typo fixes. 2010-09-25 07:46:09 -04:00
341 changed files with 6526 additions and 1299 deletions
+100 -1
View File
@@ -3,6 +3,105 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.813 2011/06/28
*** Support bit vectors > 64 bits wide in DPI import and exports.
*** Fix out of memory on slice syntax error, bug354. [Alex Solomatnikov]
**** Fix error on enum references to other packages, bug339. [Alex Solomatnikov]
**** Fix DPI undeclared svBitVecVal compile error, bug346. [Chandan Egbert]
**** Fix DPI bit vector compile errors, bug347, bug359. [Chandan Egbert]
**** Fix CDCRSTLOGIC report showing endpoint flops without resets.
**** Fix compiler warnings on SPARC, bug288. [Ahmed El-Mahmoudy]
* Verilator 3.812 2011/04/06
*** Add --trace-max-width and --trace-max-array, bug319. [Alex Solomatnikov]
*** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz]
**** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz]
**** Support $bits(data_type), bug327. [Alex Solomatnikov]
**** Support loop unrolling on width mismatches, bug333. [Joe Eiler]
**** Support simple cast operators, bug335. [Alex Solomatnikov]
**** Accelerate bit-selected inversions.
**** Add error on circular parameter definitions, bug329. [Alex Solomatnikov]
**** Fix concatenates and vectored bufif1, bug326. [Iztok Jeras]
* Verilator 3.811 2011/02/14
**** Report errors on duplicated or empty pins, bug321. [Christian Leber]
**** Report error on function call output tied to constant. [Bernard Deadman]
**** Throw UNUSED/UNDRIVEN only once per net in a parametrized module.
**** Fix internal error on functions called as SV tasks. [Bernard Deadman]
**** Fix internal error on non-inlined inout pins. [Jeff Winston]
**** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston]
**** Fix block comment not separating identifiers, bug311. [Gene Sullivan]
**** Fix warnings to point to lowest net usage, not upper level ports.
**** Fix error on constants connected to outputs, bug323. [Christian Leber]
* Verilator 3.810 2011/01/03
** Add limited support for VPI access to public signals, see docs.
*** Add -F option to read relative option files, bug297. [Neil Hamilton]
*** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov]
**** When running with VERILATOR_ROOT, optionally find binaries under bin.
**** Suppress WIDTH warnings when adding/subtracting 1'b1.
** Add -Wall, -Wwarn-style, -Wno-style to enable code style warnings
that have been added to this release, and disabled by default:
*** With --Wall, add BLKSEQ warning on blocking assignments in seq blocks.
*** With --Wall, add DECLFILENAME warning on modules not matching filename.
*** With --Wall, add DEFPARAM warning on deprecated defparam statements.
*** With --Wall, add IFDEPTH warning on deep if statements.
*** With --Wall, add INCABSPATH warning on `include with absolute paths.
*** With --Wall, add SYNCASYNCNET warning on mixed sync/async reset nets.
*** With --Wall, add UNDRIVEN warning on undriven nets.
*** With --Wall, add UNUSED warning on unused nets.
*** The VARHIDDEN warning is now disabled by default, use -Wall to enable.
* Verilator 3.805 2010/11/02
**** Add warning when directory contains spaces, msg378. [Salman Sheikh]
**** Fix wrong filename on include file errors, bug289. [Brad Parker]
**** Fix segfault on SystemVerilog "output wire foo=0", bug291. [Joshua Wise]
**** Fix DPI export name not found, msg369. [Terry Chen]
* Verilator 3.804 2010/09/20
*** Support tracing/coverage of underscore signals, bug280. [by Jason McMullan]
@@ -1649,7 +1748,7 @@ of input ports exists for tracing.
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2010 by Wilson Snyder. This program is free software; you
Copyright 2001-2011 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -1
View File
@@ -9,7 +9,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -120,6 +120,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
test_verilated/vgen*.pl \
test_regress/t/tsub/*.v* \
test_regress/t/*.cpp \
test_regress/t/*.h \
test_regress/t/*.dat \
+6 -2
View File
@@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -62,11 +62,15 @@ Usability:
* Print version/etc message at runtime. (4.000?)
Include number of lines of code, percent comments, code complexity measurement
<-80chars------------------------------------------------------------------->
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2010.
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2011.
Verilated #### modules, #### instances, ##### sigs,
#### non-comment lines, ##### ops, ### KB model size
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
Lint:
* CDCRSTLOGIC should allow filtering with paths
"waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR"
Internal Code:
* Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
and removing it will speed up and simplify all the other code.
+386 -72
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
######################################################################
#
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -78,15 +78,17 @@ if (! GetOptions (
}
# Determine runtime flags and run
if ($opt_gdbbt && !gdb_works()) {
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
$opt_gdbbt = 0;
}
if ($opt_gdbbt && !$opt_gdb && $Debug) {
# Run under GDB to get gdbbt
run ("gdb ".verilator_bin()
." --batch --quiet"
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'"
." -ex 'c'");
die "%Error: --gdbbt looses the exit status; so must assume run went badly...";
." -ex 'bt'");
} else {
# Normal, non gdb
run (($opt_gdb?"$opt_gdb ":"")
@@ -113,9 +115,18 @@ sub debug {
sub verilator_bin {
my $bin = "";
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
$bin .= $ENV{VERILATOR_ROOT}."/" if defined($ENV{VERILATOR_ROOT});
$bin .= ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
my $basename = ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
if (defined($ENV{VERILATOR_ROOT})) {
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
} else {
$bin = $basename;
}
return $bin;
}
@@ -123,9 +134,21 @@ sub verilator_bin {
#######################################################################
# Utilities
sub gdb_works {
$! = undef; # Cleanup -x
system("gdb /bin/echo"
." --batch-silent --quiet --return-child-result"
." -ex 'run -n'" # `echo -n`
." -ex 'set width 0'"
." -ex 'bt'");
my $status = $?;
return $status==0;
}
sub run {
# Run command, check errors
my $command = shift;
$! = undef; # Cleanup -x
print "\t$command\n" if $Debug>=3;
system($command);
my $status = $?;
@@ -208,7 +231,7 @@ descriptions in the next sections for more information.
--bbox-sys Blackbox unknown $system calls
--bbox-unsup Blackbox unsupported language features
--bin <filename> Override Verilator binary
-CFLAGS <flags> C++ Compiler flags for makefile
-CFLAGS <flags> C++ Compiler flags for makefile
--cc Create C++ output
--cdc Clock domain crossing analysis
--compiler <compiler-name> Tune for specified C++ compiler
@@ -224,17 +247,20 @@ descriptions in the next sections for more information.
--debugi-<srcfile> <level> Enable debugging a source file at a level
+define+<var>+<value> Set preprocessor define
--dump-tree Enable dumping .tree files
-E Preprocess, but do not compile
-E Preprocess, but do not compile
--error-limit <value> Abort after this number of errors
--exe Link to create executable
-F <file> Parse options from a file, relatively
-f <file> Parse options from a file
--help Display this help.
--gdbbt Run Verilator under GDB for backtrace
--help Display this help
-I<dir> Directory to search for includes
--if-depth <value> Tune IFDEPTH warning
+incdir+<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining
-LDFLAGS <flags> Linker pre-object flags for makefile
-LDLIBS <flags> Linker library flags for makefile
-LDFLAGS <flags> Linker pre-object flags for makefile
-LDLIBS <flags> Linker library flags for makefile
--language <lang> Language standard to parse
+libext+<ext>+[ext]... Extensions for finding modules
--lint-only Lint, but do not make output
@@ -248,12 +274,12 @@ descriptions in the next sections for more information.
-O0 Disable optimizations
-O3 High performance optimizations
-O<optimization-letter> Selectable optimizations
-o <executable> Name of final executable
-o <executable> Name of final executable
--output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .ccp functions
--pins-bv <bits> Specify types for top level ports
--pins-uint8 Specify types for top level ports
--pipe-filter <command> Filter all input through a script
--pipe-filter <command> Filter all input through a script
--prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling
--private Debugging; see docs
@@ -266,16 +292,21 @@ descriptions in the next sections for more information.
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
--trace-max-array <bits> Maximum bit width for tracing
--trace-max-width <depth> Maximum array depth for tracing
--trace-underscore Enable tracing of _signals
-U<var> Undefine preprocessor define
--unroll-count <loops> Tune maximum loop iterations
--unroll-stmts <stmts> Tune maximum loop body size
--unused-regexp <regexp> Tune UNUSED lint signals
-V Verbose version and config
-v <filename> Verilog library
-Werror-<message> Convert warning to error
-Wfuture-<message> Disable unknown message warnings
-Wno-<message> Disable warning
-Wno-lint Disable all lint warnings
-Wno-style Disable all style warnings
-Wno-fatal Disable fatal exit on warnings
-x-assign <mode> Initially assign Xs to this value
-y <dir> Directory to search for modules
@@ -502,10 +533,28 @@ After this number of errors or warnings are encountered, exit. Defaults to
Generate a executable. You will also need to pass additional .cpp files on
the command line that implement the main loop for your simulation.
=item -F I<file>
Read the specified file, and act as if all text inside it was specified as
command line parameters. Any relative paths are relative to the directory
containing the specified file. See also -f. Note -F is fairly standard
across Verilog tools.
=item -f I<file>
Read the specified file, and act as if all text inside it was specified as
command line parameters. Note -f is fairly standard across Verilog tools.
command line parameters. Any relative paths are relative to the current
directory. See also -F. Note -f is fairly standard across Verilog tools.
The file may contain // comments which are ignored to the end of the line.
Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment
variable.
=item --gdbbt
If --debug is specified, run Verilator underneath a GDB process and print
a backtrace on exit. Without --debug or if GDB doesn't seem to work, this
flag is ignored.
=item --help
@@ -518,6 +567,11 @@ include directories or libraries. Same as +incdir and -y; +incdir and -y
are fairly standard across Verilog tools while -I is an alias for GCC
compatibility.
=item --if-depth I<value>
Rarely needed. Set the depth at which the IFDEPTH warning will fire,
defaults to 0 which disables this warning.
=item +incdir+I<dir>
Add the directory to the list of directories that should be searched for
@@ -563,12 +617,15 @@ appropriate `begin_keywords.
Specify the extensions that should be used for finding modules. If for
example module I<x> is referenced, look in I<x>.I<ext>. Note +libext+ is
fairly standard across Verilog tools.
fairly standard across Verilog tools. Defaults to .v and .sv.
=item --lint-only
Check the files for lint violations only, do not create any other output.
You may also want the -Wall option to enable messages that are considered
stylistic and not enabled by default.
If the design is not to be completely Verilated see also the --bbox-sys and
--bbox-unsup options.
@@ -766,6 +823,18 @@ Specify the number of levels deep to enable tracing, for example
entire model. Using a small number will decrease visibility, but greatly
improve runtime and trace file size.
=item --trace-max-array I<bits>
Rarely needed. Specify the maximum array depth of a signal that may be
traced. Defaults to 32, as tracing large arrays may greatly slow traced
simulations.
=item --trace-max-width I<depth>
Rarely needed. Specify the maximum bit width of a signal that may be
traced. Defaults to 256, as tracing large vectors may greatly slow traced
simulations.
=item --trace-underscore
Enable tracing of signals that start with an underscore. Normally, these
@@ -785,6 +854,12 @@ unrolled. See also BLKLOOPINIT warning.
Rarely needed. Specifies the maximum number of statements in a loop for
that loop to be unrolled. See also BLKLOOPINIT warning.
=item --unused-regexp I<regexp>
Rarely needed. Specifies a simple regexp with * and ? that if a signal
name matches will suppress the UNUSED warning. Defaults to "*unused*".
Setting it to "" disables matching.
=item -V
Shows the verbose version, including configuration information compiled
@@ -796,6 +871,11 @@ Read the filename as a Verilog library. Any modules in the file may be
used to resolve cell instantiations in the top level module, else ignored.
Note -v is fairly standard across Verilog tools.
=item -Wall
Enable all warnings, including code style warnings that are normally
disabled by default.
=item -Werror-I<message>
Convert the specified warning message into a error message. This is
@@ -804,11 +884,11 @@ example C<-Werror-NOUNOPTFLAT>.
=item -Wfuture-I<message>
Suppress unknown Verilator comments or warning messages with the given
message code. This is used to allow code written with pragmas for a later
version of Verilator to run under a older version; add -Wfuture- arguments
for each message code or comment that the new version supports which the
older version does not support.
Rarely needed. Suppress unknown Verilator comments or warning messages
with the given message code. This is used to allow code written with
pragmas for a later version of Verilator to run under a older version; add
-Wfuture- arguments for each message code or comment that the new version
supports which the older version does not support.
=item -Wno-I<message>
@@ -816,19 +896,49 @@ Disable the specified warning message.
=item -Wno-lint
Disable all lint related warning messages. This is equivalent to
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX
-Wno-CMPCONST -Wno-IMPLICIT -Wno-LITENDIAN -Wno-UNDRIVEN -Wno-UNSIGNED
-Wno-UNUSED -Wno-VARHIDDEN -Wno-WIDTH".
Disable all lint related warning messages, and all style warnings. This is
equivalent to "-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX
-Wno-CASEWITHX -Wno-CMPCONST -Wno-IMPLICIT -Wno-LITENDIAN -Wno-SYNCASYNCNET
-Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for
Wno-style.
It is strongly recommended you cleanup your code rather than using this
option, it is only intended to be use when running test-cases of code
received from third parties.
=item -Wno-style
Disable all code style related warning messages (note by default they are
already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM
-Wno-INCABSPATH -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED
-Wno-VARHIDDEN".
=item -Wno-fatal
When warnings are detected, print them, but do not exit the simulator.
Having warning messages in builds is sloppy. It is strongly recommended
you cleanup your code, use inline lint_off, or use -Wno-... flags rather
than using this option.
=item -Wwarn-I<message>
Enables the specified warning message.
=item -Wwarn-lint
Enable all lint related warning messages (note by default they are already
enabled), but do not affect style messages. This is equivalent to
"-Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX
-Wwarn-CMPCONST -Wwarn-IMPLICIT -Wwarn-LITENDIAN -Wwarn-UNSIGNED
-Wwarn-WIDTH".
=item -Wwarn-style
Enable all code style related warning messages. This is equivalent to
"-Wwarn-DECLFILENAME -Wwarn-DEFPARAM -Wwarn-INCABSPATH -Wwarn-SYNCASYNCNET
-Wwarn-UNDRIVEN -Wwarn-UNUSED -Wwarn-VARHIDDEN".
=item -x-assign 0
=item -x-assign 1
@@ -871,7 +981,7 @@ We'll compile this example into C++.
cat <<EOF >our.v
module our;
initial begin \$display("Hello World"); \$finish; end
initial begin $display("Hello World"); $finish; end
endmodule
EOF
@@ -886,10 +996,15 @@ We'll compile this example into C++.
}
EOF
Now we run Verilator on our little example.
If you installed Verilator from sources, or a tarball, but not as part of
your operating system (as an RPM), first you need to point to the kit:
export VERILATOR_ROOT=/path/to/where/verilator/was/installed
$VERILATOR_ROOT/bin/verilator --cc our.v --exe sim_main.cpp
export PATH=$VERILATOR_ROOT/bin:$PATH
Now we run Verilator on our little example.
verilator -Wall --cc our.v --exe sim_main.cpp
We can see the source code under the "obj_dir" directory. See the FILES
section below for descriptions of some of the files that were created.
@@ -931,7 +1046,7 @@ This is an example similar to the above, but using SystemPerl.
module our (clk);
input clk; // Clock is required to get initial activation
always @ (posedge clk)
begin \$display("Hello World"); \$finish; end
begin $display("Hello World"); $finish; end
endmodule
EOF
@@ -948,10 +1063,15 @@ This is an example similar to the above, but using SystemPerl.
}
EOF
Now we run Verilator on our little example.
If you installed Verilator from sources, or a tarball, but not as part of
your operating system (as an RPM), first you need to point to the kit:
export VERILATOR_ROOT=/path/to/where/verilator/was/installed
$VERILATOR_ROOT/bin/verilator --sp our.v
export PATH=$VERILATOR_ROOT/bin:$PATH
Now we run Verilator on our little example.
verilator -Wall --sp our.v
Then we convert the SystemPerl output to SystemC.
@@ -1162,7 +1282,8 @@ for debugging and selecting between multiple operating system builds.
Specifies the directory containing the distribution kit. This is used to
find the executable, Perl library, and include files. If not specified, it
will come from a default optionally specified at configure time (before
Verilator was compiled).
Verilator was compiled). It should not be specified if using a pre-compiled
Verilator RPM as the hardcoded value should be correct.
=back
@@ -1316,6 +1437,38 @@ The /*verilator sformat*/ indicates that this function accepts a $display
like format specifier followed by any number of arguments to satisfy the
format.
=head2 DPI Context Functions
Verilator supports IEEE DPI Context Functions. Context imports pass the
simulator context, including calling scope name, and filename and line
number to the C code. For example, in Verilog:
import "DPI-C" context function int dpic_line();
initial $display("This is line %d, again, line %d\n", `line, dpic_line());
This will call C++ code which may then use the svGet* functions to read
information, in this case the line number of the Verilog statement that
invoked the dpic_line function:
int dpic_line() {
// Get a scope: svScope scope = svGetScope();
const char* scopenamep = svGetNameFromScope(scope);
assert(scopenamep);
const char* filenamep = "";
int lineno = 0;
if (svGetCallerInfo(&filenamep, &lineno)) {
printf("dpic_line called from scope %s on line %d\n",
scopenamep, lineno);
return lineno;
} else {
return 0;
}
}
See the IEEE Standard for more information.
=head2 DPI Header Isolation
Verilator places the IEEE standard header files such as svdpi.h into a
@@ -1327,12 +1480,64 @@ svdpi.h and similar standard files with different contents, the vltstd
directory should not be included to prevent picking up incompatible
definitions.
=head2 Public Functions
=head2 Public Functions
Instead of DPI exporting, there's also Verilator public functions, which
are slightly faster, but less compatible.
=head1 VERIFICATION PROCEDURAL INTERFACE (VPI)
Verilator supports a very limited subset of the VPI. This subset allows
inspection, examination, value change callbacks, and depositing of values
to public signals only.
To access signals via the VPI, Verilator must be told exactly which signals
are to be accessed. This is done using the Verilator public pragmas
documented below.
Verilator has an important difference from an event based simulator; signal
values that are changed by the VPI will not immediately propagate their
values, instead the top level header file's eval() method must be called.
Normally this would be part of the normal evaluation (IE the next clock
edge), not as part of the value change. This makes the performance of VPI
routines extremely fast compared to event based simulators, but can confuse
some test-benches that expect immediate propagation.
Note the VPI by it's specified implementation will always be much slower
than accessing the Verilator values by direct reference
(structure->module->signame), as the VPI accessors perform lookup in
functions at runtime requiring at best hundreds of instructions, while the
direct references are evaluated by the compiler and result in only a couple
of instructions.
=head2 VPI Example
In the below example, we have readme marked read-only, and writeme which if
written from outside the model will have the same semantics as if it
changed on the specified clock edge.
module t;
reg readme /*verilator public_flat_rd*/;
reg writeme /*verilator public_flat_rw @(posedge clk) */;
endmodule
There are many online tutorials and books on the VPI, but an example that
accesses the above would be:
void read_and_check() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL);
if (!vh1) { error... }
const char* name = vpi_get_str(vpiName, vh1);
printf("Module name: %s\n"); // Prints "readme"
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh1, &v);
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
}
=head1 CROSS COMPILATION
Verilator supports cross-compiling Verilated code. This is generally used
@@ -1410,20 +1615,25 @@ Verilator configuration commands.
=item coverage_off [-file "<filename>" [-lines <line> [ - <line> ]]]
Disable coverage for the specified filename (or all files if omitted) and
range of line numbers (or all lines if omitted). Often used to ignore an
entire module for coverage analysis purposes.
Disable coverage for the specified filename (or wildcard with '*' or '?',
or all files if omitted) and range of line numbers (or all lines if
omitted). Often used to ignore an entire module for coverage analysis
purposes.
=item lint_off -msg <message> [-file "<filename>" [-lines <line> [ - <line>]]]
=item lint_off [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
Disables the specified lint warning in the specified filename (or all files
if omitted) and range of line numbers (or all lines if omitted).
Disables the specified lint warning, in the specified filename (or wildcard
with '*' or '?', or all files if omitted) and range of line numbers (or all
lines if omitted).
If the -msg is omitted, all lint warnings are disabled. This will override
all later lint warning enables for the specified region.
=item tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
Disable waveform tracing for all future signals declared in the specified
filename (or all files if omitted) and range of line numbers (or all lines
if omitted).
filename (or wildcard with '*' or '?', or all files if omitted) and range
of line numbers (or all lines if omitted).
=back
@@ -1929,7 +2139,7 @@ of the form:
inout driver;
wire driver = (enable) ? output_value : 1'bz;
Will be converted to
input driver__in; // Value being driven in from "external" drivers
@@ -2032,6 +2242,17 @@ supply1, task, time, tri, typedef, var, vectored, while, wire, xnor, xor
Generally supported.
=item ++, -- operators
Increment/decrement can only be used as standalone statements or in for
loops. They cannot be used as side effect operators inside more complicate
expressions ("a = b++;").
=item cast operator
Casting is supported only between simple scalar types, signed and unsigned,
not arrays nor structs.
=item chandle
Treated as a "longint"; does not yet warn about operations that are
@@ -2179,6 +2400,20 @@ inside a public task.
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item BLKSEQ
This indicates that a blocking assignment (=) is used in a sequential
block. Generally non-blocking/delayed assignments (<=) are used in
sequential blocks, to avoid the possibility of simulator races. It can be
reasonable to do this if the generated signal is used ONLY later in the
same block, however this style is generally discouraged as it is error
prone.
always @ (posedge clk) foo = ...
Disabled by default as this is a code style warning; it will simulate
correctly.
=item BLKLOOPINIT
This indicates that the initialization of an array needs to use non-delayed
@@ -2263,6 +2498,26 @@ L<http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf>
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item DECLFILENAME
Warns that a module or other declaration's name doesn't match the filename
with path and extension stripped that it is declared in. The filename a
modules/interfaces/programs is declared in should match the name of the
module etc. so that -y directory searching will work. This warning is
printed for only the first mismatching module in any given file, and -v
library files are ignored.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item DEFPARAM
Warns that the "defparam" statement was deprecated in Verilog 2001 and all
designs should now be using the #(...) format to specify parameters.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item GENCLK
Warns that the specified signal is generated, but is also being used as a
@@ -2276,6 +2531,16 @@ additional ones.)
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item IFDEPTH
Warns that if/if else statements have exceeded the depth specified with
--if-depth, as they are likely to result in slow priority encoders. Unique
and priority if statements are ignored. Solutions include changing the
code to a case statement, or a SystemVerilog 'unique if' or 'priority if'.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item IMPERFECTSCH
Warns that the scheduling of the model is not absolutely perfect, and some
@@ -2304,6 +2569,17 @@ Verilator cannot schedule these variables correctly.
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item INCABSPATH
Warns that an `include filename specifies an absolute path. This means the
code will not work on any other system with a different file system layout.
Instead of using absolute paths, relative paths (preferably without any
directory specified whatever) should be used, and +include used on the
command line to specify the top include source directory.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item LITENDIAN
Warns that a vector is declared with little endian bit numbering
@@ -2375,6 +2651,18 @@ name would result in odd C compiler errors. You may disable this error
message as you would disable warnings, but the symbol will be renamed by
Verilator to avoid the conflict.
=item SYNCASYNCNET
Warns that the specified net is used in at least two different always
statements with posedge/negedges (i.e. a flop). One usage has the signal
in the sensitivity list and body, probably as a async reset, and the other
usage has the signal only in the body, probably as a sync reset. Mixing
sync and async resets is usually a mistake. The warning may be disabled
with a lint_off pragma around the net, or either flopped block.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item TASKNSVAR
Error when a call to a task or function has a output from that task tied to
@@ -2400,9 +2688,11 @@ cases would result in simulator mismatches.
=item UNDRIVEN
Warns that the specified signal is never sourced.
Warns that the specified signal is never sourced. Verilator is fairly
liberal in the usage calculations; making a signal public, or loading only
a single array element marks the entire signal as driven.
Ignoring this warning will only suppress the lint check, it will simulate
Disabled by default as this is a code style warning; it will simulate
correctly.
=item UNOPT
@@ -2485,12 +2775,31 @@ correctly.
=item UNUSED
Warns that the specified signal is never sinked. This is a future message,
currently Verilator will not produce this warning.
Warns that the specified signal is never sinked. Verilator is fairly
liberal in the usage calculations; making a signal public, a signal
matching --unused-regexp ("*unused*") or accessing only a single array
element marks the entire signal as used.
Ignoring this warning will only suppress the lint check, it will simulate
Disabled by default as this is a code style warning; it will simulate
correctly.
A recommended style for unused nets is to put at the bottom of a file code
similar to the following:
wire _unused_ok = &{1'b0,
sig_not_used_a,
sig_not_used_yet_b, // To be fixed
1'b0};
The reduction AND and constant zeros mean the net will always be zero, so
won't use simulation time. The redundant leading and trailing zeros avoid
syntax errors if there are no signals between them. The magic name
"unused" (-unused-regexp) is recognized by Verilator and suppresses
warnings; if using other lint tools, either teach to tool to ignore signals
with "unused" in the name, or put the appropriate lint_off around the wire.
Having unused signals in one place makes it easy to find what is unused,
and reduces the number of lint_off pragmas, reducing bugs.
=item VARHIDDEN
Warns that a task, function, or begin/end block is declaring a variable by
@@ -2498,7 +2807,7 @@ the same name as a variable in the upper level module or begin/end block
(thus hiding the upper variable from being able to be used.) Rename the
variable to avoid confusion when reading the code.
Ignoring this warning will only suppress the lint check, it will simulate
Disabled by default as this is a code style warning; it will simulate
correctly.
=item WIDTH
@@ -2811,11 +3120,11 @@ Makefile's link rule.
=item Is the PLI supported?
No, but the DPI is.
Only somewhat. More specifically, the common PLI-ish calls $display,
$finish, $stop, $time, $write are converted to C++ equivalents. You can
also use the "import DPI" SystemVerilog feature to call C code (see the
chapter above). There is also limited VPI access to public signals.
More specifically, the common PLI-ish calls $display, $finish, $stop,
$time, $write are converted to C++ equivalents. You can also use the
"import DPI" SystemVerilog feature to call C code (see the chapter above).
If you want something more complex, since Verilator emits standard C++
code, you can simply write your own C++ routines that can access and modify
signal values without needing any PLI interface code, and call it with
@@ -2987,25 +3296,30 @@ Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include
Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels, and Gene Weber.
Some of the people who have provided ideas and feedback for Verilator
include David Addison, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, J
include: David Addison, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, J
Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot,
Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher,
Chris Candler, Lauren Carlson, Donal Casey, Robert A. Clark, Allan
Cochrane, Gunter Dannoritzer, Bernard Deadman, John Deroo, John Dickol,
Danny Ding, Alex Duller, Jeff Dutton, Robert Farrell, Eugen Fekete, Andrea
Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone, Chitlesh Goorah, Thomas
Hawkins, David Hewson, Jae Hossell, Ben Jackson, Mike Kagen, Guy-Armand
Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman,
Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, Steve Lang,
Stephane Laurent, Charlie Lind, Dan Lussier, Fred Ma, Duraid Madina, Mark
Marshall, Wim Michiels, Dennis Muhlestein, John Murphy, Richard Myers,
Dimitris Nalbantis, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine,
Andreas Olofsson, Niranjan Prabhu, Oleg Rodionov, John Sanguinetti, Mike
Shinkarovsky, Rafael Shirakawa, Rodney Sinclair, Brian Small, Art Stamness,
John Stroebel, Emerson Suguimoto, Renga Sundararajan, Stefan Thiede, Gary
Thomas, Steve Tong, Holger Waechtler, Shawn Wang, Greg Waters, Eugene
Weber, Leon Wildman, Gerald Williams, Jeff Winston, Johan Wouters, and Ding
Xiaoliang.
Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee,
Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen,
Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard
Deadman, John Deroo, John Dickol, Danny Ding, Ivan Djordjevic, Alex Duller,
Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell,
Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone,
Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson,
Jae Hossell, Ben Jackson, Iztok Jeras, Mike Kagen, Guy-Armand Kamendje,
Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan
Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, Steve Lang, Stephane
Laurent, Christian Leber, Charlie Lind, Paul Liu, Dan Lussier, Fred Ma,
Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis
Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza,
Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic
Plunkett, Niranjan Prabhu, Usha Priyadharshini, Oleg Rodionov, John
Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey
Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John
Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan
Thiede, Gary Thomas, Steve Tong, Holger Waechtler, Stefan Wallentowitz,
Shawn Wang, Greg Waters, Eugene Weber, David Welch, Leon Wildman, Gerald
Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and
Ding Xiaoliang.
Thanks all.
@@ -3014,7 +3328,7 @@ Thanks all.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2003-2010 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify the Verilator internals under the terms of
either the GNU Lesser General Public License Version 3 or the Perl Artistic
License Version 2.0.
+1 -1
View File
@@ -177,7 +177,7 @@ Do not show differences in line numbering.
The latest version is available from L<http://www.veripool.org/verilator>.
Copyright 2005-2010 by Wilson Snyder. This package is free software; you can
Copyright 2005-2011 by Wilson Snyder. This package is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2010 by Wilson Snyder. This package is free software; you can
# Copyright 2003-2011 by Wilson Snyder. This package is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
######################################################################
+1 -1
View File
@@ -208,7 +208,7 @@ Displays this message and program version and exits.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2007-2010 by Wilson Snyder. Verilator is free software; you can
Copyright 2007-2011 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,6 +1,6 @@
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
dnl
dnl Copyright 2003-2010 by Wilson Snyder. Verilator is free software; you can
dnl Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
dnl redistribute it and/or modify it under the terms of either the GNU Lesser
dnl General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+8 -8
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -391,6 +391,9 @@ void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp);
//=========================================================================
// Pli macros
#ifndef VL_TIME_PRECISION
# define VL_TIME_PRECISION -12 ///< Timescale units only for for VPI return - picoseconds
#endif
#ifndef VL_TIME_MULTIPLIER
# define VL_TIME_MULTIPLIER 1
#endif
@@ -942,14 +945,11 @@ static inline WDataOutP VL_SUB_W(int words, WDataOutP owp,WDataInP lwp,WDataInP
return(owp);
}
// Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround
#if 1 //defined(__GNUC__) && __GNUC__ < 3
// Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround,
// we can't just
//# define VL_UNARYMIN_I(data) (-(data))
static inline IData VL_UNARYMIN_I(IData data) { return -data; }
static inline QData VL_UNARYMIN_Q(QData data) { return -data; }
#else
# define VL_UNARYMIN_I(IData data) (-(data))
# define VL_UNARYMIN_Q(QData data) (-(data))
#endif
static inline WDataOutP VL_UNARYMIN_W(int words, WDataOutP owp,WDataInP lwp){
QData carry = 0;
@@ -1633,6 +1633,6 @@ static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
#undef _END
// Debugging
//======================================================================
#endif /*_VERILATED_H_*/
+8 -1
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2010 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
######################################################################
@@ -19,6 +19,13 @@ RANLIB = ranlib
SP_PREPROC = sp_preproc
SP_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
######################################################################
# Make checks
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# C Preprocessor flags
+1 -1
View File
@@ -5,7 +5,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+2 -1
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2009-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -25,6 +25,7 @@
#define _VERILATED_DPI_CPP_
#include "verilatedos.h"
#include "verilated_dpi.h"
#include "verilated_imp.h"
// On MSVC++ we need svdpi.h to declare exports, not imports
+64
View File
@@ -0,0 +1,64 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
///
/// \file
/// \brief Verilator: Common include for all Verilated C files that use DPI
///
/// This file is included automatically by Verilator at the top of
/// all C++ files it generates where DPI is used. It contains
/// DPI interface functions required by the Verilated code.
///
/// Code available from: http://www.veripool.org/verilator
///
//*************************************************************************
#ifndef _VERILATED_DPI_H_
#define _VERILATED_DPI_H_ 1 ///< Header Guard
#include "verilated.h" // Presumed done by caller
#include "svdpi.h"
//===================================================================
// SETTING OPERATORS
/// Return svBitVecVal from WData
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) {
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
}
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) {
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
}
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, svLogicVecVal* lwp) {
// Note we ignore X/Z in svLogicVecVal
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; i++) owp[i]=lwp[i].aval;
owp[words-1] = lwp[words-1].aval & VL_MASK_I(obits);
}
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) {
// Note we don't create X/Z in svLogicVecVal
int words = VL_WORDS_I(obits);
for (int i=0; i<words; i++) owp[i].bval=0;
for (int i=0; i<words-1; i++) owp[i].aval=lwp[i];
owp[words-1].aval = lwp[words-1] & VL_MASK_I(obits);
}
//======================================================================
#endif // _VERILATED_DPI_H_
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2010-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+2 -2
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2009-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -49,7 +49,7 @@ class VerilatedImp {
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> ExportNameMap;
typedef map<const char*, int, VerilatedCStrCmp> ExportNameMap;
// MEMBERS
static VerilatedImp s_s; ///< Static Singleton; One and only static this
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2009-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2010 by Wilson Snyder. This program is free software;
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
+33
View File
@@ -0,0 +1,33 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//=========================================================================
///
/// \file
/// \brief Verilator: VPI implementation code
///
/// This file must be compiled and linked against all objects
/// created from Verilator or called by Verilator that use the VPI.
///
/// Code available from: http://www.veripool.org/verilator
///
//=========================================================================
#include "verilated_vpi.h"
//======================================================================
VerilatedVpi VerilatedVpi::s_s; // Singleton
vluint8_t* VerilatedVpio::s_freeHead = NULL;
//======================================================================
+835
View File
@@ -0,0 +1,835 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//=========================================================================
///
/// \file
/// \brief Verilator: VPI implementation code
///
/// This file must be compiled and linked against all objects
/// created from Verilator or called by Verilator that use the VPI.
///
/// "//-" indicates features that are as yet unimplemented.
///
/// Code available from: http://www.veripool.org/verilator
///
//=========================================================================
#ifndef CHPI_VERILATED_VPI_H
#define CHPI_VERILATED_VPI_H 1
#include "verilated.h"
#include "verilated_syms.h"
//======================================================================
// From IEEE 1800-2009 annex K
#include "vltstd/vpi_user.h"
//======================================================================
// Internal macros
// Not supported yet
#define _VL_VPI_UNIMP() \
vl_fatal(__FILE__,__LINE__,"",Verilated::catName("Unsupported VPI function: ",VL_FUNC))
//======================================================================
// Implementation
#include <set>
#define VL_DEBUG_IF_PLI VL_DEBUG_IF
// Base VPI handled object
class VerilatedVpio {
// MEM MANGLEMENT
static vluint8_t* s_freeHead;
public:
// CONSTRUCTORS
VerilatedVpio() {}
virtual ~VerilatedVpio() {}
inline static void* operator new(size_t size) {
// We new and delete tons of vpi structures, so keep them around
// To simplify our free list, we use a size large enough for all derived types
// We reserve word zero for the next pointer, as that's safer in case a
// dangling reference to the original remains around.
static size_t chunk = 96;
if (VL_UNLIKELY(size>chunk)) vl_fatal(__FILE__,__LINE__,"", "increase chunk");
if (VL_LIKELY(s_freeHead)) {
vluint8_t* newp = s_freeHead;
s_freeHead = *((vluint8_t**)newp);
return newp+8;
} else {
// +8: 8 bytes for next
vluint8_t* newp = (vluint8_t*)(::operator new(chunk+8));
return newp+8;
}
}
inline static void operator delete(void* obj, size_t size) {
vluint8_t* oldp = ((vluint8_t*)obj)-8;
*((void**)oldp) = s_freeHead;
s_freeHead = oldp;
}
// MEMBERS
static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast<VerilatedVpio*>((VerilatedVpio*)h); }
inline vpiHandle castVpiHandle() { return (vpiHandle)(this); }
// ACCESSORS
virtual const char* name() { return "<null>"; }
virtual const char* fullname() { return "<null>"; }
virtual const char* defname() { return "<null>"; }
virtual vpiHandle dovpi_scan() { return 0; }
};
typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *);
class VerilatedVpioCb : public VerilatedVpio {
t_cb_data m_cbData;
QData m_time;
public:
VerilatedVpioCb(const t_cb_data* cbDatap, QData time) : m_cbData(*cbDatap), m_time(time) {}
virtual ~VerilatedVpioCb() {}
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
vluint32_t reason() const { return m_cbData.reason; }
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
t_cb_data* cb_datap() { return &(m_cbData); }
QData time() const { return m_time; }
};
class VerilatedVpioConst : public VerilatedVpio {
vlsint32_t m_num;
public:
VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
virtual ~VerilatedVpioConst() {}
static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
vlsint32_t num() const { return m_num; }
};
class VerilatedVpioRange : public VerilatedVpio {
vlsint32_t m_lhs; // Ranges can be signed
vlsint32_t m_rhs;
bool m_iteration;
public:
VerilatedVpioRange(vlsint32_t lhs, vlsint32_t rhs) : m_lhs(lhs), m_rhs(rhs), m_iteration(0) {}
virtual ~VerilatedVpioRange() {}
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
vlsint32_t lhs() const { return m_lhs; }
vlsint32_t rhs() const { return m_rhs; }
int iteration() const { return m_iteration; }
void iterationInc() { ++m_iteration; }
virtual vpiHandle dovpi_scan() {
if (!iteration()) {
VerilatedVpioRange* nextp = new VerilatedVpioRange(*this);
nextp->iterationInc();
return ((nextp)->castVpiHandle());
} else {
return 0; // End of list - only one deep
}
}
};
class VerilatedVpioScope : public VerilatedVpio {
const VerilatedScope* m_scopep;
public:
VerilatedVpioScope(const VerilatedScope* scopep)
: m_scopep(scopep) {}
virtual ~VerilatedVpioScope() {}
static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
const VerilatedScope* scopep() const { return m_scopep; }
virtual const char* name() { return m_scopep->name(); }
virtual const char* fullname() { return m_scopep->name(); }
};
class VerilatedVpioVar : public VerilatedVpio {
const VerilatedVar* m_varp;
const VerilatedScope* m_scopep;
vluint8_t* m_prevDatap; // Previous value of data, for cbValueChange
vluint32_t m_mask; // memoized variable mask
vluint32_t m_entSize; // memoized variable size
protected:
void* m_varDatap; // varp()->datap() adjusted for array entries
vlsint32_t m_index;
public:
VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep)
: m_varp(varp), m_scopep(scopep), m_index(0) {
m_prevDatap = NULL;
m_mask = VL_MASK_I(varp->range().bits());
m_entSize = varp->entSize();
m_varDatap = varp->datap();
}
virtual ~VerilatedVpioVar() {
if (m_prevDatap) { delete [] m_prevDatap; m_prevDatap = NULL; }
}
static inline VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVar*>((VerilatedVpio*)h); }
const VerilatedVar* varp() const { return m_varp; }
const VerilatedScope* scopep() const { return m_scopep; }
vluint32_t mask() const { return m_mask; }
vluint32_t entSize() const { return m_entSize; }
virtual const char* name() { return m_varp->name(); }
virtual const char* fullname() {
static VL_THREAD string out;
out = string(m_scopep->name())+"."+name();
return out.c_str();
}
void* prevDatap() const { return m_prevDatap; }
void* varDatap() const { return m_varDatap; }
void createPrevDatap() {
if (VL_UNLIKELY(!m_prevDatap)) {
m_prevDatap = new vluint8_t [entSize()];
memcpy(prevDatap(), varp()->datap(), entSize());
}
}
};
class VerilatedVpioVarIndex : public VerilatedVpioVar {
public:
VerilatedVpioVarIndex(const VerilatedVar* varp, const VerilatedScope* scopep,
vlsint32_t index, int offset)
: VerilatedVpioVar(varp, scopep) {
m_index = index;
m_varDatap = ((vluint8_t*)varp->datap()) + entSize()*offset;
}
virtual ~VerilatedVpioVarIndex() {}
static inline VerilatedVpioVarIndex* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIndex*>((VerilatedVpio*)h); }
virtual const char* fullname() {
static VL_THREAD string out;
char num[20]; sprintf(num,"%d",m_index);
out = string(scopep()->name())+"."+name()+"["+num+"]";
return out.c_str();
}
};
class VerilatedVpioVarIter : public VerilatedVpio {
const VerilatedScope* m_scopep;
VerilatedVarNameMap::iterator m_it;
bool m_started;
public:
VerilatedVpioVarIter(const VerilatedScope* scopep)
: m_scopep(scopep), m_started(false) { }
virtual ~VerilatedVpioVarIter() {}
static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
virtual vpiHandle dovpi_scan() {
if (VL_LIKELY(m_scopep->varsp())) {
if (VL_UNLIKELY(!m_started)) { m_it = m_scopep->varsp()->begin(); m_started=true; }
else if (VL_UNLIKELY(m_it == m_scopep->varsp()->end())) return 0;
else ++m_it;
if (m_it == m_scopep->varsp()->end()) return 0;
return ((new VerilatedVpioVar(&(m_it->second), m_scopep))
->castVpiHandle());
} else {
return 0; // End of list - only one deep
}
}
};
//======================================================================
struct VerilatedVpiTimedCbsCmp {
/// Ordering sets keyed by time, then callback descriptor
bool operator() (const pair<QData,VerilatedVpioCb*>& a,
const pair<QData,VerilatedVpioCb*>& b) const {
if (a.first < b.first) return 1;
if (a.first > b.first) return 0;
return a.second < b.second;
}
};
class VerilatedVpi {
enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason
typedef set<VerilatedVpioCb*> VpioCbSet;
typedef set<pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
VpioCbSet m_cbObjSets[CB_ENUM_MAX_VALUE]; // Callbacks for each supported reason
VpioTimedCbs m_timedCbs; // Time based callbacks
static VerilatedVpi s_s; // Singleton
public:
VerilatedVpi() {}
~VerilatedVpi() {}
static void cbReasonAdd(VerilatedVpioCb* vop) {
if (vop->reason() == cbValueChange) {
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
varop->createPrevDatap();
}
}
if (VL_UNLIKELY(vop->reason() >= CB_ENUM_MAX_VALUE)) vl_fatal(__FILE__,__LINE__,"", "vpi bb reason too large");
s_s.m_cbObjSets[vop->reason()].insert(vop);
}
static void cbTimedAdd(VerilatedVpioCb* vop) {
s_s.m_timedCbs.insert(make_pair(vop->time(), vop));
}
static void cbReasonRemove(VerilatedVpioCb* cbp) {
VpioCbSet& cbObjSet = s_s.m_cbObjSets[cbp->reason()];
VpioCbSet::iterator it=cbObjSet.find(cbp);
if (VL_LIKELY(it != cbObjSet.end())) {
cbObjSet.erase(it);
}
}
static void cbTimedRemove(VerilatedVpioCb* cbp) {
VpioTimedCbs::iterator it=s_s.m_timedCbs.find(make_pair(cbp->time(),cbp));
if (VL_LIKELY(it != s_s.m_timedCbs.end())) {
s_s.m_timedCbs.erase(it);
}
}
static void callTimedCbs() {
QData time = VL_TIME_Q();
for (VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); it!=s_s.m_timedCbs.end(); ) {
if (VL_UNLIKELY(it->first <= time)) {
VerilatedVpioCb* vop = it->second;
++it; // iterator may be deleted by callback
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: timed_callback %p\n",vop););
(vop->cb_rtnp()) (vop->cb_datap());
}
else { ++it; }
}
}
static QData cbNextDeadline() {
VpioTimedCbs::iterator it=s_s.m_timedCbs.begin();
if (VL_LIKELY(it!=s_s.m_timedCbs.end())) {
return it->first;
} else {
return ~VL_ULL(0); // maxquad
}
}
static void callCbs(vluint32_t reason) {
VpioCbSet& cbObjSet = s_s.m_cbObjSets[reason];
for (VpioCbSet::iterator it=cbObjSet.begin(); it!=cbObjSet.end();) {
VerilatedVpioCb* vop = *it;
++it; // iterator may be deleted by callback
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: reason_callback %d %p\n",reason,vop););
(vop->cb_rtnp()) (vop->cb_datap());
}
}
static void callValueCbs() {
VpioCbSet& cbObjSet = s_s.m_cbObjSets[cbValueChange];
for (VpioCbSet::iterator it=cbObjSet.begin(); it!=cbObjSet.end();) {
VerilatedVpioCb* vop = *it;
++it; // iterator may be deleted by callback
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
void* newDatap = varop->varDatap();
void* prevDatap = varop->prevDatap(); // Was malloced when we added the callback
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_test %s v[0]=%d/%d %p %p\n",
varop->fullname(), *((CData*)newDatap), *((CData*)prevDatap),
newDatap, prevDatap););
if (memcmp(prevDatap, newDatap, varop->entSize())) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_callback %p %s v[0]=%d\n",
vop,varop->fullname(), *((CData*)newDatap)););
memcpy(prevDatap, newDatap, varop->entSize());
(vop->cb_rtnp()) (vop->cb_datap());
}
}
}
}
};
// callback related
vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
if (VL_UNLIKELY(!cb_data_p)) return NULL;
switch (cb_data_p->reason) {
case cbAfterDelay: {
QData time = 0;
if (cb_data_p->time) time = _VL_SET_QII(cb_data_p->time->high, cb_data_p->time->low);
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, VL_TIME_Q()+time);
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p delay=%" VL_PRI64 "d\n",cb_data_p->reason,vop,time););
VerilatedVpi::cbTimedAdd(vop);
return vop->castVpiHandle();
}
case cbReadWriteSynch: // FALLTHRU // Supported via vlt_main.cpp
case cbReadOnlySynch: // FALLTHRU // Supported via vlt_main.cpp
case cbNextSimTime: // FALLTHRU // Supported via vlt_main.cpp
case cbStartOfSimulation: // FALLTHRU // Supported via vlt_main.cpp
case cbEndOfSimulation: // FALLTHRU // Supported via vlt_main.cpp
case cbValueChange: // FALLTHRU // Supported via vlt_main.cpp
case cbEnterInteractive: // FALLTHRU // NOP, but need to return handle, so make object
case cbExitInteractive: // FALLTHRU // NOP, but need to return handle, so make object
case cbInteractiveScopeChange: { // FALLTHRU // NOP, but need to return handle, so make object
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, 0);
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p\n",cb_data_p->reason,vop););
VerilatedVpi::cbReasonAdd(vop);
return vop->castVpiHandle();
}
default:
_VL_VPI_UNIMP(); return NULL;
};
}
PLI_INT32 vpi_remove_cb(vpiHandle object) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_remove_cb %p\n",object););
VerilatedVpioCb* vop = VerilatedVpioCb::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (vop->cb_datap()->reason == cbAfterDelay) {
VerilatedVpi::cbTimedRemove(vop);
} else {
VerilatedVpi::cbReasonRemove(vop);
}
return 1;
}
//-void vpi_get_cb_info(vpiHandle object, p_cb_data cb_data_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-vpiHandle vpi_register_systf(p_vpi_systf_data systf_data_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-void vpi_get_systf_info(vpiHandle object, p_vpi_systf_data systf_data_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
// for obtaining handles
vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
if (VL_UNLIKELY(!namep)) return NULL;
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle_by_name %s %p\n",namep,scope););
VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope);
const VerilatedVar* varp;
const VerilatedScope* scopep;
string scopeAndName = namep;
if (voScopep) {
scopeAndName = string(voScopep->fullname()) + "." + namep;
namep = (PLI_BYTE8*)scopeAndName.c_str();
}
{
// This doesn't yet follow the hierarchy in the proper way
scopep = Verilated::scopeFind(namep);
if (scopep) { // Whole thing found as a scope
return (new VerilatedVpioScope(scopep))->castVpiHandle();
}
const char* baseNamep = scopeAndName.c_str();
string scopename;
const char* dotp = strrchr(namep, '.');
if (VL_LIKELY(dotp)) {
baseNamep = dotp+1;
scopename = string(namep,dotp-namep);
}
scopep = Verilated::scopeFind(scopename.c_str());
if (!scopep) return NULL;
varp = scopep->varFind(baseNamep);
}
if (!varp) return NULL;
return (new VerilatedVpioVar(varp, scopep))->castVpiHandle();
}
vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
// Used to get array entries
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle_by_index %p %d\n",object, indx););
VerilatedVpioVar* varop = VerilatedVpioVar::castp(object);
if (VL_LIKELY(varop)) {
if (varop->varp()->dims()<2) return 0;
if (VL_LIKELY(varop->varp()->array().lhs() >= varop->varp()->array().rhs())) {
if (VL_UNLIKELY(indx > varop->varp()->array().lhs() || indx < varop->varp()->array().rhs())) return 0;
return (new VerilatedVpioVarIndex(varop->varp(), varop->scopep(), indx,
indx - varop->varp()->array().rhs()))
->castVpiHandle();
} else {
if (VL_UNLIKELY(indx < varop->varp()->array().lhs() || indx > varop->varp()->array().rhs())) return 0;
return (new VerilatedVpioVarIndex(varop->varp(), varop->scopep(), indx,
indx - varop->varp()->array().lhs()))
->castVpiHandle();
}
} else {
_VL_VPI_UNIMP(); return 0;
}
}
// for traversing relationships
vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle %d %p\n",type,object););
switch (type) {
case vpiLeftRange: // FALLTHRU
case vpiRightRange: {
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
vluint32_t num = ((type==vpiLeftRange)
? vop->varp()->range().lhs()
: vop->varp()->range().rhs());
return (new VerilatedVpioConst(num))->castVpiHandle();
} else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) {
vluint32_t num = ((type==vpiLeftRange)
? vop->lhs()
: vop->rhs());
return (new VerilatedVpioConst(num))->castVpiHandle();
} else {
return 0;
}
}
default:
_VL_VPI_UNIMP();
return 0;
}
}
//-vpiHandle vpi_handle_multi(PLI_INT32 type, vpiHandle refHandle1, vpiHandle refHandle2, ... ) {
//- _VL_VPI_UNIMP(); return 0;
//-}
vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_iterate %d %p\n",type,object););
switch (type) {
case vpiMemoryWord: {
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (vop->varp()->dims() < 2) return 0;
// Unsupported is multidim list
return ((new VerilatedVpioRange(vop->varp()->array().lhs(),
vop->varp()->array().rhs()))
->castVpiHandle());
}
case vpiReg: {
VerilatedVpioScope* vop = VerilatedVpioScope::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
return ((new VerilatedVpioVarIter(vop->scopep()))
->castVpiHandle());
}
case vpiIODecl: // Skipping - we'll put under reg
case vpiNet: // Skipping - we'll put under reg
return 0;
default:
_VL_VPI_UNIMP(); return 0;
}
}
vpiHandle vpi_scan(vpiHandle object) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_scan %p\n",object););
VerilatedVpio* vop = VerilatedVpio::castp(object);
if (VL_UNLIKELY(!vop)) return NULL;
return vop->dovpi_scan();
}
// for processing properties
PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
// Leave this in the header file - in many cases the compiler can constant propagate "object"
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get %d %p\n",property,object););
switch (property) {
case vpiTimePrecision: {
return VL_TIME_PRECISION;
}
case vpiType: {
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
return ((vop->varp()->dims()>1) ? vpiMemory : vpiReg);
}
case vpiDirection: {
// By forthought, the directions already are vpi enumerated
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
return vop->varp()->vldir();
}
case vpiVector: {
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (vop->varp()->dims()==0) return 0;
else return 1;
}
default:
_VL_VPI_UNIMP();
return 0;
}
}
//-PLI_INT64 vpi_get64(PLI_INT32 property, vpiHandle object) {
//- _VL_VPI_UNIMP(); return 0;
//-}
PLI_BYTE8 *vpi_get_str(PLI_INT32 property, vpiHandle object) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_str %d %p\n",property,object););
VerilatedVpio* vop = VerilatedVpio::castp(object);
if (VL_UNLIKELY(!vop)) return NULL;
switch (property) {
case vpiName: {
return (PLI_BYTE8*)vop->name();
}
case vpiFullName: {
return (PLI_BYTE8*)vop->fullname();
}
case vpiDefName: {
return (PLI_BYTE8*)vop->defname();
}
default:
_VL_VPI_UNIMP();
return 0;
}
}
// delay processing
//-void vpi_get_delays(vpiHandle object, p_vpi_delay delay_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-void vpi_put_delays(vpiHandle object, p_vpi_delay delay_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
// value processing
void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_value %p\n",object););
if (VL_UNLIKELY(!value_p)) return;
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
// We presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal
if (value_p->format == vpiVectorVal) {
// Vector pointer must come from our memory pool
// It only needs to persist until the next vpi_get_value
static VL_THREAD t_vpi_vecval out[VL_MULS_MAX_WORDS*2];
value_p->value.vector = out;
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
out[0].aval = *((CData*)(vop->varDatap()));
out[0].bval = 0;
return;
case VLVT_UINT16:
out[0].aval = *((SData*)(vop->varDatap()));
out[0].bval = 0;
return;
case VLVT_UINT32:
out[0].aval = *((IData*)(vop->varDatap()));
out[0].bval = 0;
return;
case VLVT_WDATA: {
int words = VL_WORDS_I(vop->varp()->range().bits());
if (VL_UNLIKELY(words >= VL_MULS_MAX_WORDS)) {
vl_fatal(__FILE__,__LINE__,"", "vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile");
}
WDataInP datap = ((IData*)(vop->varDatap()));
for (int i=0; i<words; i++) {
out[i].aval = datap[i];
out[i].bval = 0;
}
return;
}
case VLVT_UINT64: {
QData data = *((QData*)(vop->varDatap()));
out[1].aval = (IData)(data>>VL_ULL(32));
out[1].bval = 0;
out[0].aval = (IData)(data);
out[0].bval = 0;
return;
}
default: {
_VL_VPI_UNIMP();
return;
}
}
} else {
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
value_p->value.integer = *((CData*)(vop->varDatap()));
return;
case VLVT_UINT16:
value_p->value.integer = *((SData*)(vop->varDatap()));
return;
case VLVT_UINT32:
value_p->value.integer = *((IData*)(vop->varDatap()));
return;
case VLVT_WDATA:
case VLVT_UINT64:
// Not legal
value_p->value.integer = 0;
default:
_VL_VPI_UNIMP();
return;
}
}
}
else if (VerilatedVpioConst* vop = VerilatedVpioConst::castp(object)) {
value_p->value.integer = vop->num();
return;
}
_VL_VPI_UNIMP();
}
vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
p_vpi_time time_p, PLI_INT32 flags) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_put_value %p %p\n",object, value_p););
if (VL_UNLIKELY(!value_p)) return 0;
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
// We presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_put_value name=%s fmt=%d vali=%d\n",
vop->fullname(), value_p->format, value_p->value.integer);
VL_PRINTF("-vltVpi: varp=%p putatp=%p\n",
vop->varp()->datap(), vop->varDatap()););
if (VL_UNLIKELY(!vop->varp()->isPublicRW())) {
VL_PRINTF("%%Warning: Ignoring vpi_put_value to signal marked read-only, use public_flat_rw instead: %s\n",
vop->fullname());
return 0;
}
if (value_p->format == vpiVectorVal) {
if (VL_UNLIKELY(!value_p->value.vector)) return NULL;
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
*((CData*)(vop->varDatap())) = value_p->value.vector[0].aval;
return object;
case VLVT_UINT16:
*((SData*)(vop->varDatap())) = value_p->value.vector[0].aval;
return object;
case VLVT_UINT32:
*((IData*)(vop->varDatap())) = value_p->value.vector[0].aval;
return object;
case VLVT_WDATA: {
int words = VL_WORDS_I(vop->varp()->range().bits());
WDataOutP datap = ((IData*)(vop->varDatap()));
for (int i=0; i<words; i++) {
datap[i] = value_p->value.vector[i].aval;
}
return object;
}
case VLVT_UINT64: {
*((QData*)(vop->varDatap())) = _VL_SET_QII(
value_p->value.vector[1].aval,
value_p->value.vector[0].aval);
return object;
}
default: {
_VL_VPI_UNIMP();
return NULL;
}
}
} else {
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
*((CData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
return object;
case VLVT_UINT16:
*((SData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
return object;
case VLVT_UINT32:
*((IData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
return object;
case VLVT_WDATA: // FALLTHRU
case VLVT_UINT64: // FALLTHRU
default:
_VL_VPI_UNIMP();
return 0;
}
}
}
_VL_VPI_UNIMP(); return NULL;
}
//-void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p,
//- PLI_INT32 *index_p, PLI_UINT32 num) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p,
//- PLI_INT32 *index_p, PLI_UINT32 num) {
//- _VL_VPI_UNIMP(); return 0;
//-}
// time processing
//-void vpi_get_time(vpiHandle object, p_vpi_time time_p) {
//- _VL_VPI_UNIMP();
//-}
// I/O routines
//-PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *fileName) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 cd) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, PLI_BYTE8 *format, ...) {
//- _VL_VPI_UNIMP(); return 0;
//-}
PLI_INT32 vpi_printf(PLI_BYTE8 *formatp, ...) {
va_list ap;
va_start(ap,formatp);
int chars = vpi_vprintf(formatp, ap);
va_end(ap);
return chars;
}
PLI_INT32 vpi_vprintf(PLI_BYTE8* formatp, va_list ap) {
return VL_VPRINTF(formatp, ap);
}
//-PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_INT32 vpi_flush(void) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) {
//- _VL_VPI_UNIMP(); return 0;
//-}
// utility routines
//-PLI_INT32 vpi_compare_objects(vpiHandle object1, vpiHandle object2) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_INT32 vpi_chk_error(p_vpi_error_info error_info_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
PLI_INT32 vpi_free_object(vpiHandle object) {
return vpi_release_handle(object); // Deprecated
}
PLI_INT32 vpi_release_handle (vpiHandle object) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_release_handle %p\n",object););
VerilatedVpio* vop = VerilatedVpio::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
vpi_remove_cb(object); // May not be a callback, but that's ok
delete vop;
return 1;
}
//-PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p) {
//- _VL_VPI_UNIMP(); return 0;
//-}
// routines added with 1364-2001
//-PLI_INT32 vpi_get_data(PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_INT32 vpi_put_data(PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-void *vpi_get_userdata(vpiHandle obj) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//-PLI_INT32 vpi_put_userdata(vpiHandle obj, void *userdata) {
//- _VL_VPI_UNIMP(); return 0;
//-}
PLI_INT32 vpi_control(PLI_INT32 operation, ...) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_control %d\n",operation););
switch (operation) {
case vpiFinish: {
vl_finish(__FILE__,__LINE__,"*VPI*");
return 1;
}
case vpiStop: {
vl_stop(__FILE__,__LINE__,"*VPI*");
return 1;
}
}
_VL_VPI_UNIMP(); return 0;
}
//-vpiHandle vpi_handle_by_multi_index(vpiHandle obj, PLI_INT32 num_index, PLI_INT32 *index_array) {
//- _VL_VPI_UNIMP(); return 0;
//-}
//======================================================================
#endif // Guard
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+1 -1
View File
@@ -250,7 +250,7 @@ what made a <e####> line in the tree dumps):
The latest version is available from L<http://www.veripool.org/>.
Copyright 2008-2010 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2011 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2007-2010 by Wilson Snyder. This package is free software; you
# Copyright 2007-2011 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2007-2010 by Wilson Snyder. This package is free software; you
# Copyright 2007-2011 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -143,7 +143,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2010 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2011 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -184,7 +184,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2010 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2011 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2007-2010 by Wilson Snyder. This package is free software; you
# Copyright 2007-2011 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -117,7 +117,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2009-2010 by Wilson Snyder. This package is free software; you
Copyright 2009-2011 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -14
View File
@@ -8,21 +8,9 @@ use strict;
#======================================================================
# main
delete $ENV{MODULE_VERSION};
_setup_modules();
module('add','axiom-athdl');
eval `modulecmd perl add axiom-athdl`;
exec('atsim',@ARGV);
#######################################################################
# Modules package
sub _setup_modules {
# Load the 'module' command into the environment
my $init = "$ENV{MODULESHOME}/init/perl";
(-f $init) or die "%Error: Script not found: $init,";
require $init;
}
#######################################################################
__END__
@@ -40,7 +28,7 @@ invoke_atsim - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2010 by Wilson Snyder. This package is free software; you
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -14
View File
@@ -8,21 +8,9 @@ use strict;
#======================================================================
# main
delete $ENV{MODULE_VERSION};
_setup_modules();
module('add','cadence-ius');
eval `modulecmd perl add cds-ius`;
exec('iccr',@ARGV);
#######################################################################
# Modules package
sub _setup_modules {
# Load the 'module' command into the environment
my $init = "$ENV{MODULESHOME}/init/perl";
(-f $init) or die "%Error: Script not found: $init,";
require $init;
}
#######################################################################
__END__
@@ -40,7 +28,7 @@ invoke_iccr - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2007-2010 by Wilson Snyder. This package is free software; you
Copyright 2007-2011 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -14
View File
@@ -8,21 +8,9 @@ use strict;
#======================================================================
# main
delete $ENV{MODULE_VERSION};
_setup_modules();
module('add','cadence-ius');
eval `modulecmd perl add cds-ius`;
exec('ncverilog',@ARGV);
#######################################################################
# Modules package
sub _setup_modules {
# Load the 'module' command into the environment
my $init = "$ENV{MODULESHOME}/init/perl";
(-f $init) or die "%Error: Script not found: $init,";
require $init;
}
#######################################################################
__END__
@@ -40,7 +28,7 @@ invoke_ncverilog - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2010 by Wilson Snyder. This package is free software; you
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -14
View File
@@ -8,21 +8,9 @@ use strict;
#======================================================================
# main
delete $ENV{MODULE_VERSION};
_setup_modules();
module('add','synopsys-vcs');
eval `modulecmd perl add synopsys-vcs`;
exec('vcs',@ARGV);
#######################################################################
# Modules package
sub _setup_modules {
# Load the 'module' command into the environment
my $init = "$ENV{MODULESHOME}/init/perl";
(-f $init) or die "%Error: Script not found: $init,";
require $init;
}
#######################################################################
__END__
@@ -40,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2010 by Wilson Snyder. This package is free software; you
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2010-2010 by Wilson Snyder. This package is free software; you
# Copyright 2010-2011 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -81,6 +81,7 @@ sub prep {
$line =~ s/SP_NOTICE.*// if $sp;
$line =~ s/vl_fatal.*// if !$sp;
$line =~ s/VL_PRINT.*// if !$sp;
$line =~ s/Copyright \d+-\d+/Copyright #-#/g;
push @wf, $line;
+1 -1
View File
@@ -331,7 +331,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2010 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2011 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+44 -21
View File
@@ -9,7 +9,7 @@ This is the Verilator Package README file.
=head1 DISTRIBUTION
This package is Copyright 2003-2010 by Wilson Snyder. (Report bugs to
This package is Copyright 2003-2011 by Wilson Snyder. (Report bugs to
L<http://www.veripool.org/>.)
Verilator is free software; you can redistribute it and/or modify it under
@@ -72,15 +72,14 @@ Download the latest package from that site, and decompress.
If you will be using SystemC (vs straight C++ output), download SystemC
2.0.1 from L<http://www.systemc.org>. Follow their installation
instructions. As described in the System-Perl README, you will need to set
SYSTEMC and/or SYSTEMC_KIT to point to this download. Also, set
SYSTEMC_ARCH to the architecture name you used with SystemC, generally
'linux' or 'cygwin'.
instructions. You will need to set the SYSTEMC environment variable to
point to this download. Also, setenv SYSTEMC_ARCH to the architecture name
you used with SystemC, generally 'linux' or 'cygwin'.
=item
If you will be using SystemPerl or coverage, download and install
Verilog-Perl, L<http://www.veripool.org/verilog-perl>.
Verilator assumes you did a make in the SystemC kit directory and SYSTEMC
points to that directory. There must be appropriate files in
C<$SYSTEMC/include> and C<$SYSTEMC/lib-linux> for SystemC compilation to
work.
=item
@@ -98,20 +97,49 @@ C<cd> to the Verilator directory containing this README.
You now have to decide how you're going to eventually install the kit.
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC,
SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
executable, so try to have them correct before configuring.
=over 4
=item 1.
Our personal favorite is to always run Verilator from the kit directory.
This allows the easiest experimentation and upgrading. It's also how most
EDA tools operate; you just point to the tarball.
EDA tools operate; to run any of them you point to the tarball.
export VERILATOR_ROOT=`pwd` # if your shell is bash
setenv VERILATOR_ROOT `pwd` # if your shell is csh
./configure
=item 2.
To install globally onto a "cad" disk with multiple versions of every tool,
and add it to path using Modules/modulecmd:
unset VERILATOR_ROOT # if your shell is bash
unsetenv VERILATOR_ROOT # if your shell is csh
# For the tarball, use the version number instead of git describe
./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
After installing you'll want a module file like the following:
set install_root /CAD_DISK/verilator/{version-number-used-above}
setenv VERILATOR_ROOT $install_root
prepend-path PATH $install_root/bin
prepend-path MANPATH $install_root/man
=item 3.
The next option is to install it globally, using the normal system paths:
unset VERILATOR_ROOT # if your shell is bash
unsetenv VERILATOR_ROOT # if your shell is csh
./configure
=item 4.
Alternatively you can configure a prefix that install will populate, as
most GNU tools support:
@@ -119,11 +147,7 @@ most GNU tools support:
unsetenv VERILATOR_ROOT # if your shell is csh
./configure --prefix /opt/verilator-VERSION
Finally, if you are configuring Verilator to be part of a RPM or other
distribution package system, you may want to tune the various install
directories and use the --enable-defenv configure flag. This will take the
current value of VERILATOR_ROOT, SYSTEMC, SYSTEMC_ARCH, SYSTEMPERL, and
SYSTEMPERL_INCLUDE and build them as defaults into the executable.
=back
=item
@@ -141,16 +165,15 @@ unsigned long uint32_t;}.
=item
If you used the VERILATOR_ROOT sheme you're done. Programs should set the
If you used the VERILATOR_ROOT scheme you're done. Programs should set the
environment variable VERILATOR_ROOT to point to this distribution, then
execute $VERILATOR_ROOT/bin/verilator, which will find the path to all
needed files.
If you used the prefix scheme, now do a C<make install>.
Verilator assumes you did a make in the SystemC kit directory. If not, you
will need to populate C<$SYSTEMC/include> and C<$SYSTEMC/lib-linux>
appropriately.
If you used the prefix scheme, now do a C<make install>. To run verilator,
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.
=back
+1 -1
View File
@@ -26,7 +26,7 @@ This is the Verilator Package.
@node Copyright, Description, Top, Top
@section Copyright
This package is Copyright 2003-2010 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
This package is Copyright 2003-2011 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
Verilator is free software; you can redistribute it and/or modify it
under the terms of either the GNU Lesser General Public License
+5 -1
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -46,6 +46,10 @@ export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
endif
endif
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
UNDER_GIT = $(wildcard ../.git/logs/HEAD)
#*********************************************************************
+2 -1
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -221,6 +221,7 @@ RAW_OBJS = \
V3Trace.o \
V3TraceDecl.o \
V3Tristate.o \
V3Undriven.o \
V3Unknown.o \
V3Unroll.o \
V3Width.o \
+48 -13
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -160,26 +160,58 @@ public:
class ActiveDlyVisitor : public ActiveBaseVisitor {
private:
bool m_combo; // Combo logic
AstNode* m_alwaysp; // Always we're under
AstNode* m_assignp; // In assign
// VISITORS
virtual void visit(AstAssignDly* nodep, AstNUser*) {
// Convert to a non-delayed assignment
UINFO(5," ASSIGNDLY "<<nodep<<endl);
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) blocks should be non-delayed assignments (=).");
AstNode* newp = new AstAssign (nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
nodep->replaceWith(newp);
nodep->deleteTree(); nodep = NULL;
if (m_combo) {
// Convert to a non-delayed assignment
UINFO(5," ASSIGNDLY "<<nodep<<endl);
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
AstNode* newp = new AstAssign (nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
nodep->replaceWith(newp);
nodep->deleteTree(); nodep = NULL;
}
}
virtual void visit(AstAssign* nodep, AstNUser*) {
if (!m_combo) {
AstNode* las = m_assignp;
m_assignp = nodep;
nodep->lhsp()->iterateAndNext(*this);
m_assignp = las;
}
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
AstVar* varp=nodep->varp();
if (!m_combo
&& m_assignp
&& !varp->isUsedLoopIdx() // Ignore loop indicies
&& !varp->isTemp()
) {
// Allow turning off warnings on the always, or the variable also
if (!m_alwaysp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
&& !m_assignp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
&& !varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
) {
m_alwaysp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always
varp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
nodep->v3warn(BLKSEQ,"Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).");
}
}
}
// Empty visitors, speed things up
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ActiveDlyVisitor(AstNode* nodep) {
ActiveDlyVisitor(AstNode* nodep, bool combo) {
m_alwaysp = nodep;
m_combo = combo;
m_assignp = NULL;
nodep->accept(*this);
}
virtual ~ActiveDlyVisitor() {}
@@ -317,7 +349,10 @@ private:
// Warn and/or convert any delayed assignments
if (combo && !sequent) {
ActiveDlyVisitor dlyvisitor (nodep);
ActiveDlyVisitor dlyvisitor (nodep, true);
}
else if (!combo && sequent) {
ActiveDlyVisitor dlyvisitor (nodep, false);
}
}
virtual void visit(AstAlways* nodep, AstNUser*) {
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+5 -4
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -182,7 +182,7 @@ private:
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (itemp->isDefault()) has_default=true;
}
if (nodep->fullPragma()) {
if (nodep->fullPragma() || nodep->priorityPragma()) {
// Simply need to add a default if there isn't one already
m_statAsFull++;
if (!has_default) {
@@ -190,7 +190,7 @@ private:
newFireAssert(nodep, "synthesis full_case, but non-match found")));
}
}
if (nodep->parallelPragma()) {
if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) {
// Need to check that one, and only one of the case items match at any moment
// If there's a default, we allow none to match, else exactly one must match
m_statAsFull++;
@@ -207,7 +207,8 @@ private:
else propp = onep;
}
}
AstNode* ohot = (has_default
bool allow_none = has_default || nodep->unique0Pragma();
AstNode* ohot = (allow_none
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
: (new AstOneHot (nodep->fileline(), propp))->castNode());
AstIf* ifp = new AstIf (nodep->fileline(),
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+3 -2
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -192,6 +192,7 @@ string AstNode::prettyName(const string& namein) {
}
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
return pretty;
}
@@ -813,7 +814,7 @@ void AstNode::iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup) {
AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
// 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 loose the handle to the node that was
// this happens, the parent will lose the handle to the node that was
// processed.
// To solve this, this function returns the pointer to the replacement node,
// which in many cases is just the same node that was passed in.
+2 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -976,6 +976,7 @@ struct AstNodeUniop : public AstNodeMath {
setOp1p(lhsp); }
ASTNODE_BASE_FUNCS(NodeUniop)
AstNode* lhsp() const { return op1p()->castNode(); }
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
virtual bool cleanLhs() = 0;
+3 -3
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -202,7 +202,6 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
if (forReturn) named=false;
string arg;
if (!basicp()) arg = "UNKNOWN";
if (isWide()) v3error("Unsupported: DPI functions with vectored outputs > 32-bits");
if (basicp()->isBitLogic()) {
if (widthMin() == 1) {
arg = "unsigned char";
@@ -522,7 +521,7 @@ void AstBasicDType::dump(ostream& str) {
str<<" ["<<keyword().ascii()<<"]";
if (implicit()) str<<" [IMPLICIT]";
}
void AstCast::dump(ostream& str) {
void AstCCast::dump(ostream& str) {
this->AstNode::dump(str);
str<<" sz"<<size();
}
@@ -611,6 +610,7 @@ void AstVar::dump(ostream& str) {
}
if (isUsedClock()) str<<" [C]";
if (isSigPublic()) str<<" [P]";
if (isUsedLoopIdx()) str<<" [LOOP]";
if (attrClockEn()) str<<" [aCLKEN]";
if (attrIsolateAssign()) str<<" [aISO]";
if (attrFileDescr()) str<<" [aFD]";
+93 -12
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -364,9 +364,10 @@ public:
struct AstEnumItemRef : public AstNodeMath {
private:
AstEnumItem* m_itemp; // [AfterLink] Pointer to item
AstPackage* m_packagep; // Package hierarchy
public:
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp)
: AstNodeMath(fl), m_itemp(itemp) {
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstPackage* packagep)
: AstNodeMath(fl), m_itemp(itemp), m_packagep(packagep) {
if (m_itemp) widthSignedFrom(m_itemp);
}
ASTNODE_NODE_FUNCS(EnumItemRef, ENUMITEMREF)
@@ -381,6 +382,8 @@ public:
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep=nodep; }
};
struct AstEnumDType : public AstNodeDType {
@@ -553,11 +556,14 @@ private:
bool m_sigUserRWPublic:1; // User C code accesses this signal, read-write
bool m_usedClock:1; // Signal used as a clock
bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup)
bool m_usedLoopIdx:1; // Variable subject of for unrolling
bool m_funcLocal:1; // Local variable for a function
bool m_funcReturn:1; // Return variable for a function
bool m_attrClockEn:1;// User clock enable attribute
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
bool m_attrSFormat:1;// User sformat attribute
bool m_didSigning:1; // V3Signed completed; can skip iteration
bool m_didWidth:1; // V3Width completed; can skip iteration
bool m_fileDescr:1; // File descriptor
bool m_isConst:1; // Table contains constant data
bool m_isStatic:1; // Static variable
@@ -567,10 +573,11 @@ private:
m_input=false; m_output=false; m_tristate=false;
m_primaryIO=false;
m_sc=false; m_scClocked=false; m_scSensitive=false;
m_usedClock=false; m_usedParam=false;
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrSFormat=false;
m_didSigning=false; m_didWidth=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false;
m_trace=false;
}
@@ -633,8 +640,13 @@ public:
void attrScClocked(bool flag) { m_scClocked = flag; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
void attrSFormat(bool flag) { m_attrSFormat = flag; }
void didSigning(bool flag) { m_didSigning=flag; }
bool didSigning() const { return m_didSigning; }
void didWidth(bool flag) { m_didWidth=flag; }
bool didWidth() const { return m_didWidth; }
void usedClock(bool flag) { m_usedClock = flag; }
void usedParam(bool flag) { m_usedParam = flag; }
void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; }
void sigPublic(bool flag) { m_sigPublic = flag; }
void sigModPublic(bool flag) { m_sigModPublic = flag; }
void sigUserRdPublic(bool flag) { m_sigUserRdPublic = flag; if (flag) sigPublic(true); }
@@ -675,6 +687,7 @@ public:
bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); }
bool isUsedClock() const { return m_usedClock; }
bool isUsedParam() const { return m_usedParam; }
bool isUsedLoopIdx() const { return m_usedLoopIdx; }
bool isSc() const { return m_sc; }
bool isScQuad() const;
bool isScBv() const;
@@ -909,7 +922,9 @@ public:
,m_name(name), m_svImplicit(false) {
m_pinNum = pinNum;
m_modVarp = NULL;
setNOp1p(exprp); }
setNOp1p(exprp);
if (exprp) widthSignedFrom(exprp);
}
ASTNODE_NODE_FUNCS(Pin, PIN)
virtual void dump(ostream& str);
virtual bool broken() const { return (m_modVarp && !m_modVarp->brokeExists()); }
@@ -918,7 +933,7 @@ public:
bool dotStar() const { return name() == ".*"; } // Special fake name for .* connections until linked
int pinNum() const { return m_pinNum; }
void exprp(AstNode* nodep) { addOp1p(nodep); }
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin, NULL if unconnected
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
void modVarp(AstVar* varp) { m_modVarp=varp; }
bool svImplicit() const { return m_svImplicit; }
@@ -1538,11 +1553,15 @@ private:
AstCaseType m_casex; // 0=case, 1=casex, 2=casez
bool m_fullPragma; // Synthesis full_case
bool m_parallelPragma; // Synthesis parallel_case
bool m_uniquePragma; // unique case
bool m_unique0Pragma; // unique0 case
bool m_priorityPragma; // priority case
public:
AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp)
: AstNodeCase(fileline, exprp, casesp) {
m_casex=casex;
m_fullPragma=false; m_parallelPragma=false;
m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false;
}
ASTNODE_NODE_FUNCS(Case, CASE)
virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; }
@@ -1554,6 +1573,12 @@ public:
void fullPragma(bool flag) { m_fullPragma=flag; }
bool parallelPragma() const { return m_parallelPragma; }
void parallelPragma(bool flag) { m_parallelPragma=flag; }
bool uniquePragma() const { return m_uniquePragma; }
void uniquePragma(bool flag) { m_uniquePragma=flag; }
bool unique0Pragma() const { return m_unique0Pragma; }
void unique0Pragma(bool flag) { m_unique0Pragma=flag; }
bool priorityPragma() const { return m_priorityPragma; }
void priorityPragma(bool flag) { m_priorityPragma=flag; }
};
struct AstCaseItem : public AstNode {
@@ -1669,6 +1694,22 @@ struct AstSFormat : public AstNode {
void lhsp(AstNode* nodep) { setOp3p(nodep); }
};
struct AstSysIgnore : public AstNode {
// Parents: stmtlist
// Children: varrefs or exprs
AstSysIgnore(FileLine* fileline, AstNode* exprsp)
: AstNode (fileline) { addNOp1p(exprsp); }
ASTNODE_NODE_FUNCS(SysIgnore, SYSIGNORE)
virtual string verilogKwd() const { return "$ignored"; }
virtual bool isGateOptimizable() const { return false; } // Though deleted before opt
virtual bool isPredictOptimizable() const { return false; } // Though deleted before opt
virtual bool isSplittable() const { return false; } // Though deleted before opt
virtual bool isOutputter() const { return true; } // Though deleted before opt
virtual int instrCount() const { return instrCountPli(); }
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
};
struct AstFClose : public AstNodeStmt {
// Parents: stmtlist
// Children: file which must be a varref
@@ -1952,10 +1993,22 @@ struct AstGenIf : public AstNodeIf {
};
struct AstIf : public AstNodeIf {
private:
bool m_uniquePragma; // unique case
bool m_unique0Pragma; // unique0 case
bool m_priorityPragma; // priority case
public:
AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp)
: AstNodeIf(fileline, condp, ifsp, elsesp) {
m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false;
}
ASTNODE_NODE_FUNCS(If, IF)
bool uniquePragma() const { return m_uniquePragma; }
void uniquePragma(bool flag) { m_uniquePragma=flag; }
bool unique0Pragma() const { return m_unique0Pragma; }
void unique0Pragma(bool flag) { m_unique0Pragma=flag; }
bool priorityPragma() const { return m_priorityPragma; }
void priorityPragma(bool flag) { m_priorityPragma=flag; }
};
struct AstJumpLabel : public AstNodeStmt {
@@ -2572,27 +2625,42 @@ struct AstOneHot0 : public AstNodeUniop {
virtual int instrCount() const { return widthInstrs()*3; }
};
struct AstCast : public AstNodeUniop {
// Cast to appropriate data type
struct AstCast : public AstNode {
// Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc
AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtypep) : AstNode(fl) {
setOp1p(lhsp); setOp2p(dtypep);
if (dtypep) { widthSignedFrom(dtypep); }
}
ASTNODE_NODE_FUNCS(Cast, CAST)
virtual string emitVerilog() { return "((%r)'(%l))"; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;}
AstNode* lhsp() const { return op1p(); }
AstNodeDType* dtypep() const { return op2p()->castNodeDType(); }
};
struct AstCCast : public AstNodeUniop {
// Cast to C-based data type
private:
int m_size;
public:
AstCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
AstCCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
m_size=setwidth;
if (setwidth) { width(setwidth,setwidth); }
}
AstCast(FileLine* fl, AstNode* lhsp, AstNode* widthFromp) : AstNodeUniop(fl, lhsp) {
AstCCast(FileLine* fl, AstNode* lhsp, AstNode* widthFromp) : AstNodeUniop(fl, lhsp) {
if (widthFromp) { widthSignedFrom(widthFromp); }
m_size=width();
}
ASTNODE_NODE_FUNCS(Cast, CAST)
ASTNODE_NODE_FUNCS(CCast, CCAST)
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
virtual string emitVerilog() { return "%f$_CAST(%l)"; }
virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast
virtual V3Hash sameHash() const { return V3Hash(size()); }
virtual bool same(AstNode* samep) const { return size()==samep->castCast()->size(); }
virtual bool same(AstNode* samep) const { return size()==samep->castCCast()->size(); }
virtual void dump(ostream& str=cout);
//
int size() const { return m_size; }
@@ -3109,6 +3177,19 @@ struct AstReplicate : public AstNodeBiop {
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual int instrCount() const { return widthInstrs()*2; }
};
struct AstBufIf1 : public AstNodeBiop {
// lhs is enable, rhs is data to drive
AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
if (lhsp) widthSignedFrom(lhsp); }
ASTNODE_NODE_FUNCS(BufIf1, BUFIF1)
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); }
virtual string emitVerilog() { return "bufif(%r,%l)"; }
virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean
virtual string emitSimpleOperator() { V3ERROR_NA; return false;} // Lclean || Rclean
virtual bool cleanOut() {V3ERROR_NA; return "";} // Lclean || Rclean
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstFGetS : public AstNodeBiop {
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(FGetS, FGETS)
+18 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -53,6 +53,7 @@ private:
string m_namedScope; // Name of begin blocks above us
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
int m_repeatNum; // Repeat counter
int m_ifDepth; // Current if depth
// METHODS
static int debug() {
@@ -152,6 +153,21 @@ private:
// 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
// Check IFDEPTH warning - could be in other transform files if desire
int prevIfDepth = m_ifDepth;
if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off
} else if (nodep->uniquePragma() || nodep->unique0Pragma() || nodep->priorityPragma()) {
m_ifDepth = -1;
} else if (++m_ifDepth > v3Global.opt.ifDepth()) {
nodep->v3warn(IFDEPTH,"Deep 'if' statement; suggest unique/priority to avoid slow logic");
nodep->fileline()->modifyWarnOff(V3ErrorCode::IFDEPTH, true); // Warn only once
m_ifDepth = -1;
}
nodep->iterateChildren(*this);
m_ifDepth = prevIfDepth;
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
@@ -161,6 +177,7 @@ public:
m_modp = NULL;
m_ftaskp = NULL;
m_repeatNum = 0;
m_ifDepth = 0;
nodep->accept(*this);
}
virtual ~BeginVisitor() {}
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+6 -6
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -77,7 +77,7 @@ private:
AstNRelinker relinkHandle;
nodep->unlinkFrBack(&relinkHandle);
//
AstCast* castp = new AstCast (nodep->fileline(), nodep, needsize);
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize);
castp->width(needsize, nodep->widthMin());
relinkHandle.relink(castp);
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
@@ -97,13 +97,13 @@ private:
insertCast(nodep, castSize(nodep->backp()));
}
}
void insureLower32Cast(AstCast* nodep) {
void insureLower32Cast(AstCCast* nodep) {
// If we have uint64 = CAST(uint64(x)) then the upcasting
// really needs to be CAST(uint64(CAST(uint32(x))).
// Otherwise a (uint64)(a>b) would return wrong value, as
// less than has undeterministic signedness.
if (nodep->isQuad() && !nodep->lhsp()->isQuad()
&& !nodep->lhsp()->castCast()) {
&& !nodep->lhsp()->castCCast()) {
insertCast(nodep->lhsp(), VL_WORDSIZE);
}
}
@@ -130,7 +130,7 @@ private:
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
}
virtual void visit(AstCast* nodep, AstNUser*) {
virtual void visit(AstCCast* nodep, AstNUser*) {
nodep->iterateChildren(*this);
insureLower32Cast(nodep);
nodep->user1(1);
@@ -149,7 +149,7 @@ private:
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (!nodep->lvalue()
&& !nodep->backp()->castCast()
&& !nodep->backp()->castCCast()
&& nodep->backp()->castNodeMath()
&& nodep->backp()->width()
&& castSize(nodep) != castSize(nodep->varp())) {
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+35 -16
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -46,6 +46,8 @@
#include "V3EmitV.h"
#include "V3File.h"
#define CDC_WEIGHT_ASYNC 0x1000 // Weight for edges that feed async logic
//######################################################################
class CdcBaseVisitor : public AstNVisitor {
@@ -65,9 +67,9 @@ class CdcEitherVertex : public V3GraphVertex {
AstNode* m_nodep;
AstSenTree* m_srcDomainp;
AstSenTree* m_dstDomainp;
bool m_srcDomainSet;
bool m_dstDomainSet;
bool m_asyncPath;
bool m_srcDomainSet:1;
bool m_dstDomainSet:1;
bool m_asyncPath:1;
public:
CdcEitherVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep)
: V3GraphVertex(graphp), m_scopep(scopep), m_nodep(nodep)
@@ -109,11 +111,12 @@ public:
};
class CdcLogicVertex : public CdcEitherVertex {
bool m_hazard;
bool m_isFlop;
bool m_hazard:1;
bool m_isFlop:1;
public:
CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep)
: CdcEitherVertex(graphp,scopep,nodep), m_hazard(false), m_isFlop(false)
: CdcEitherVertex(graphp,scopep,nodep)
, m_hazard(false), m_isFlop(false)
{ srcDomainp(sensenodep); dstDomainp(sensenodep); }
virtual ~CdcLogicVertex() {}
// Accessors
@@ -132,7 +135,7 @@ class CdcDumpVisitor : public CdcBaseVisitor {
private:
// NODE STATE
//Entire netlist:
// {statement}Node::user3p -> bool, indicating not hazard
// {statement}Node::user3 -> bool, indicating not hazard
ofstream* m_ofp; // Output file
string m_prefix;
@@ -290,9 +293,12 @@ private:
void setNodeHazard(AstNode* nodep) {
// Need to not clear if warnings are off (rather than when report it)
// as bypassing this warning may turn up another path that isn't warning off'ed.
// We can't modifyWarnOff here, as one instantiation might not be an issue until we find a hitting flop
// Furthermore, a module like a "Or" module would only get flagged once,
// even though the signals feeding it are radically different.
if (!m_domainp || m_domainp->hasCombo()) { // Source flop logic in a posedge block is OK for reset (not async though)
if (m_logicVertexp && !nodep->fileline()->warnIsOff(V3ErrorCode::CDCRSTLOGIC)) {
UINFO(9,"Set hazard "<<nodep<<endl);
UINFO(8,"Set hazard "<<nodep<<endl);
m_logicVertexp->setHazard(nodep);
}
}
@@ -310,7 +316,9 @@ private:
UINFO(3,__FUNCTION__<<": "<<endl);
//if (debug()>6) m_graph.dump();
if (debug()>6) m_graph.dumpDotFilePrefixed("cdc_pre");
m_graph.removeRedundantEdgesSum(&V3GraphEdge::followAlwaysTrue);
//
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // This will MAX across edge weights
//
m_graph.dumpDotFilePrefixed("cdc_simp");
//
analyzeReset();
@@ -335,7 +343,7 @@ private:
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
if (vvertexp->cntAsyncRst()) {
m_userGeneration++; // Effectively a userClearVertices()
UINFO(9, " Trace One async: "<<vvertexp<<endl);
UINFO(8, " Trace One async: "<<vvertexp<<endl);
// Twice, as we need to detect, then propagate
CdcEitherVertex* markp = traceAsyncRecurse(vvertexp, false);
if (markp) { // Mark is non-NULL if something bad on this path
@@ -351,7 +359,8 @@ private:
}
CdcEitherVertex* traceAsyncRecurse(CdcEitherVertex* vertexp, bool mark) {
// Return vertex of any hazardous stuff attached, or NULL if OK
// First pass: Return vertex of any hazardous stuff attached, or NULL if OK
// If first pass returns true, second pass calls asyncPath() on appropriate nodes
if (vertexp->user()>=m_userGeneration) return false; // Processed - prevent loop
vertexp->user(m_userGeneration);
@@ -406,12 +415,15 @@ private:
CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top();
if (!eToVertexp) targetp = eToVertexp;
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
if (vvertexp->isFlop()) {
if (vvertexp->isFlop() // IE the target flop that is upsetting us
&& edgep->weight() >= CDC_WEIGHT_ASYNC) { // And this signal feeds an async reset line
targetp = eToVertexp;
//UINFO(9," targetasync "<<targetp->name()<<" "<<" from "<<vertexp->name()<<endl);
break;
}
} // else it might be random logic that's not relevant
}
//UINFO(9," finalflop "<<targetp->name()<<" "<<targetp->nodep()->fileline()<<endl);
warnAndFile(markp->nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName());
dumpAsyncRecurse(targetp, "", " ",0);
}
@@ -613,8 +625,9 @@ private:
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
CdcVarVertex* varvertexp = makeVarVertex(varscp);
UINFO(5," VARREF to "<<varscp<<endl);
// We use weight of one; if we ref the var more than once, when we simplify,
// the weight will increase
// We use weight of one for normal edges,
// Weight of CDC_WEIGHT_ASYNC to indicate feeds async (for reporting)
// When simplify we'll take the MAX weight
if (nodep->lvalue()) {
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
if (m_inDly) {
@@ -623,7 +636,13 @@ private:
varvertexp->srcDomainSet(true);
}
} else {
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
if (varvertexp->cntAsyncRst()) {
//UINFO(9," edgeasync "<<varvertexp->name()<<" to "<<m_logicVertexp<<endl);
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, CDC_WEIGHT_ASYNC);
} else {
//UINFO(9," edgena "<<varvertexp->name()<<" to "<<m_logicVertexp<<endl);
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
}
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2008-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2008-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+30 -17
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2010-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -60,7 +60,8 @@ class V3ConfigIgnores {
IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number
IgnLines::const_iterator m_lastEnd; // Point with end()
IgnFiles m_ignFiles; // Ignores for each filename
IgnFiles m_ignWilds; // Ignores for each wildcarded filename
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
@@ -68,13 +69,13 @@ class V3ConfigIgnores {
~V3ConfigIgnores() {}
// METHODS
inline IgnLines* findLines(const string& filename) {
IgnFiles::iterator it = m_ignFiles.find(filename);
if (it != m_ignFiles.end()) {
inline IgnLines* findWilds(const string& wildname) {
IgnFiles::iterator it = m_ignWilds.find(wildname);
if (it != m_ignWilds.end()) {
return &(it->second);
} else {
m_ignFiles.insert(make_pair(filename, IgnLines()));
it = m_ignFiles.find(filename);
m_ignWilds.insert(make_pair(wildname, IgnLines()));
it = m_ignWilds.find(wildname);
return &(it->second);
}
}
@@ -82,23 +83,35 @@ class V3ConfigIgnores {
// Given a filename, find all wildcard matches against it and build
// hash with the specific filename. This avoids having to wildmatch
// more than once against any filename.
IgnLines* linesp = findLines(filename);
m_lastIt = linesp->begin();
m_lastEnd = linesp->end();
IgnFiles::iterator it = m_ignFiles.find(filename);
if (it == m_ignFiles.end()) {
// Haven't seen this filename before
m_ignFiles.insert(make_pair(filename, IgnLines()));
it = m_ignFiles.find(filename);
// Make new list for this file of all matches
for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) {
if (V3Options::wildmatch(filename.c_str(), fnit->first.c_str())) {
for (IgnLines::iterator lit = fnit->second.begin(); lit != fnit->second.end(); ++lit) {
it->second.insert(*lit);
}
}
}
}
m_lastIt = it->second.begin();
m_lastEnd = it->second.end();
}
public:
inline static V3ConfigIgnores& singleton() { return s_singleton; }
void addIgnore(V3ErrorCode code, string filename, int lineno, bool on) {
void addIgnore(V3ErrorCode code, string wildname, int lineno, bool on) {
// Insert
IgnLines* linesp = findLines(filename);
UINFO(9,"config addIgnore "<<filename<<":"<<lineno<<", "<<code<<", "<<on<<endl);
IgnLines* linesp = findWilds(wildname);
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl);
linesp->insert(V3ConfigLine(code, lineno, on));
if (m_lastFilename == filename) {
// Flush the match cache, due to a change in the rules.
m_lastFilename = " ";
}
// Flush the match cache, due to a change in the rules.
m_ignFiles.clear();
m_lastFilename = " ";
}
inline void applyIgnores(FileLine* filelinep) {
// HOT routine, called each parsed token line
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2010-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+367 -216
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -93,7 +93,7 @@ public:
class ConstVisitor : public AstNVisitor {
private:
// NODE STATE
// ** only when m_warn/m_expensive is set. If state is needed other times,
// ** only when m_warn/m_doExpensive is set. If state is needed other times,
// ** must track down everywhere V3Const is called and make sure no overlaps.
// AstVar::user4p -> Used by ConstVarMarkVisitor/ConstVarFindVisitor
// AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label
@@ -103,8 +103,9 @@ private:
bool m_required; // If true, must become a constant
bool m_wremove; // Inside scope, no assignw removal
bool m_warn; // Output warnings
bool m_cpp; // C++ conversions only
bool m_expensive; // Enable computationally expensive optimizations
bool m_doExpensive; // Enable computationally expensive optimizations
bool m_doNConst; // Enable non-constant-child simplifications
bool m_doV; // Verilog, not C++ conversion
AstNodeModule* m_modp; // Current module
AstNode* m_scopep; // Current scope
@@ -289,13 +290,61 @@ private:
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
// Since select's return unsigned, this is always an extend
AstExtend* extendp = nodep->fromp()->castExtend();
return (!m_cpp
&& extendp
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
&& (int)nodep->widthConst()==extendp->lhsp()->width()
);
if (!(m_doV
&& extendp
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
&& (int)nodep->widthConst()==extendp->lhsp()->width()
)) return false;
replaceWChild(nodep, extendp->lhsp()); nodep=NULL;
return true;
}
bool operandSelBiLower(AstSel* nodep) {
// SEL(ADD(a,b),(width-1),0) -> ADD(SEL(a),SEL(b))
// Add or any operation which doesn't care if we discard top bits
AstNodeBiop* bip = nodep->fromp()->castNodeBiop();
if (!(m_doV
&& bip
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
)) return false;
if (debug()>=9) nodep->dumpTree(cout,"SEL(BI)-in:");
AstNode* bilhsp = bip->lhsp()->unlinkFrBack();
AstNode* birhsp = bip->rhsp()->unlinkFrBack();
bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst()));
bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst()));
if (debug()>=9) bip->dumpTree(cout,"SEL(BI)-ou:");
replaceWChild(nodep, bip); nodep=NULL;
return true;
}
bool operandBiExtendConst(AstNodeBiop* nodep) {
// Loop unrolling likes standalone compares
// EQ(EXTEND(xx{width3}), const{width32}) -> EQ(xx{3},const{3})
// Beware that the constant must have zero bits (+ 1 if signed) or compare
// would be incorrect
AstExtend* extendp = nodep->lhsp()->castExtend();
if (!extendp) return false;
AstNode* smallerp = extendp->lhsp();
int subsize = smallerp->width();
AstConst* constp = nodep->rhsp()->castConst();
if (!constp) return false;
if (!constp->num().isBitsZero(constp->width()-1, subsize)) return false;
//
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-in:");
smallerp->unlinkFrBack();
extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp.
nodep->lhsp(smallerp);
constp->unlinkFrBack();
V3Number num (constp->fileline(), subsize);
num.opAssign(constp->num());
nodep->rhsp(new AstConst(constp->fileline(), num));
constp->deleteTree(); constp=NULL;
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:");
return true;
}
AstNode* afterComment(AstNode* nodep) {
@@ -724,7 +773,7 @@ private:
return true;
}
}
else if (!m_cpp && nodep->lhsp()->castConcat()) {
else if (m_doV && nodep->lhsp()->castConcat()) {
bool need_temp = false;
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
// Note only do this (need user4) when m_warn, which is
@@ -855,10 +904,10 @@ private:
// Run it - may be unoptimizable due to large for loop, etc
simvis.mainParamEmulate(nodep);
if (!simvis.optimizable()) {
AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep;
AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep;
nodep->v3error("Expecting expression to be constant, but can't determine constant for "
<<nodep->prettyTypeName()<<endl
<<V3Error::msgPrefix()<<errorp->fileline()<<"... Location of non-constant "
<<V3Error::msgPrefix(V3ErrorCode::EC_ERROR,false)<<errorp->fileline()<<"... Location of non-constant "
<<errorp->prettyTypeName()<<": "<<simvis.whyNotMessage());
replaceZero(nodep); nodep=NULL;
} else {
@@ -1060,16 +1109,50 @@ private:
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceSelIntoBiop(AstSel* nodep) {
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
AstNodeBiop* fromp = nodep->fromp()->unlinkFrBack()->castNodeBiop();
if (!fromp) nodep->v3fatalSrc("Called on non biop");
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
//
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
AstNode* birhsp = fromp->rhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel(nodep->fileline(),
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
fromp->rhsp(new AstSel(nodep->fileline(),
birhsp, lsbp, widthp));
fromp->widthSignedFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
}
void replaceSelIntoUniop(AstSel* nodep) {
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
AstNodeUniop* fromp = nodep->fromp()->unlinkFrBack()->castNodeUniop();
if (!fromp) nodep->v3fatalSrc("Called on non biop");
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
//
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel(nodep->fileline(),
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
fromp->widthSignedFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
bool did=false;
if (!m_cpp && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
if (m_doV && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
//if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: ");
nodep->varp()->valuep()->iterateAndNext(*this);
if (operandConst(nodep->varp()->valuep())
&& !nodep->lvalue()
&& ((v3Global.opt.oConst() && !m_params // Can reduce constant wires into equations
&& ((!m_params // Can reduce constant wires into equations
&& m_doNConst
&& v3Global.opt.oConst()
&& !nodep->varp()->isSigPublic())
|| nodep->varp()->isParam())) {
AstConst* constp = nodep->varp()->valuep()->castConst();
@@ -1106,7 +1189,7 @@ private:
// Someday if lower is constant, convert to quoted "string".
virtual void visit(AstAttrOf* nodep, AstNUser*) {
// Don't iterate children, don't want to loose VarRef.
// Don't iterate children, don't want to lose VarRef.
if (nodep->attrType()==AstAttrType::EXPR_BITS) {
if (!nodep->fromp() || !nodep->fromp()->widthMin()) nodep->v3fatalSrc("Unsized expression");
V3Number num (nodep->fileline(), 32, nodep->fromp()->widthMin());
@@ -1121,8 +1204,9 @@ private:
}
virtual void visit(AstSenItem* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->sensp()->castConst()
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
if (m_doNConst
&& (nodep->sensp()->castConst()
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam()))) {
// Constants in sensitivity lists may be removed (we'll simplify later)
if (nodep->isClocked()) { // A constant can never get a pos/negexge
if (onlySenItemInSenTree(nodep)) {
@@ -1135,7 +1219,7 @@ private:
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
nodep->deleteTree(); nodep=NULL;
}
} else if (nodep->sensp()->castNot()) {
} else if (m_doNConst && nodep->sensp()->castNot()) {
// V3Gate may propagate NOTs into clocks... Just deal with it
AstNode* sensp = nodep->sensp();
AstNode* lastSensp = sensp;
@@ -1202,7 +1286,7 @@ private:
virtual void visit(AstSenTree* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_expensive) {
if (m_doExpensive) {
//cout<<endl; nodep->dumpTree(cout,"ssin: ");
// Optimize ideas for the future:
// SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b))
@@ -1305,22 +1389,21 @@ private:
// Zero elimination
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
nodep->iterateChildren(*this);
replaceNodeAssign(nodep);
if (m_doNConst && replaceNodeAssign(nodep)) return;
}
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
// Don't perform any optimizations, keep the alias around
}
virtual void visit(AstAssignW* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (replaceNodeAssign(nodep)) return;
if (m_doNConst && replaceNodeAssign(nodep)) return;
AstNodeVarRef* varrefp = nodep->lhsp()->castVarRef(); // Not VarXRef, as different refs may set different values to each hierarchy
if (m_wremove
if (m_wremove && !m_params && m_doNConst
&& m_modp && operandConst(nodep->rhsp())
&& !nodep->rhsp()->castConst()->num().isFourState()
&& varrefp // Don't do messes with BITREFs/ARRAYREFs
&& !varrefp->varp()->valuep() // Not already constified
&& !varrefp->varScopep() // Not scoped (or each scope may have different initial value)
&& !m_params) {
&& !varrefp->varScopep()) { // Not scoped (or each scope may have different initial value)
// ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) )
UINFO(4,"constAssignW "<<nodep<<endl);
// Make a initial assignment
@@ -1340,77 +1423,79 @@ private:
virtual void visit(AstNodeIf* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (AstConst* constp = nodep->condp()->castConst()) {
AstNode* keepp = NULL;
if (constp->isZero()) {
UINFO(4,"IF(0,{any},{x}) => {x}: "<<nodep<<endl);
keepp = nodep->elsesp();
} else {
UINFO(4,"IF(!0,{x},{any}) => {x}: "<<nodep<<endl);
keepp = nodep->ifsp();
if (m_doNConst) {
if (AstConst* constp = nodep->condp()->castConst()) {
AstNode* keepp = NULL;
if (constp->isZero()) {
UINFO(4,"IF(0,{any},{x}) => {x}: "<<nodep<<endl);
keepp = nodep->elsesp();
} else {
UINFO(4,"IF(!0,{x},{any}) => {x}: "<<nodep<<endl);
keepp = nodep->ifsp();
}
if (keepp) {
keepp->unlinkFrBackWithNext();
nodep->replaceWith(keepp);
} else {
nodep->unlinkFrBack();
}
nodep->deleteTree(); nodep=NULL;
}
if (keepp) {
keepp->unlinkFrBackWithNext();
nodep->replaceWith(keepp);
} else {
nodep->unlinkFrBack();
else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) {
// Empty block, remove it
// Note if we support more C++ then there might be side effects in the condition itself
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
else if (!afterComment(nodep->ifsp())) {
UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<<nodep<<endl);
AstNode* condp = nodep->condp();
AstNode* elsesp = nodep->elsesp();
condp->unlinkFrBackWithNext();
elsesp->unlinkFrBackWithNext();
if (nodep->ifsp()) { nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); } // Must have been comment
nodep->condp(new AstLogNot(condp->fileline(), condp)); // LogNot, as C++ optimization also possible
nodep->addIfsp(elsesp);
}
else if (((nodep->condp()->castNot() && nodep->condp()->width()==1)
|| (nodep->condp()->castLogNot()))
&& nodep->ifsp() && nodep->elsesp()) {
UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl);
AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext();
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext();
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
ifp->branchPred(nodep->branchPred().invert());
nodep->replaceWith(ifp);
nodep->deleteTree(); nodep=NULL;
}
else if (ifSameAssign(nodep)) {
UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<<endl);
AstNodeAssign* ifp = nodep->ifsp()->castNodeAssign();
AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign();
ifp->unlinkFrBack();
AstNode* condp = nodep->condp()->unlinkFrBack();
AstNode* truep = ifp->rhsp()->unlinkFrBack();
AstNode* falsep = elsep->rhsp()->unlinkFrBack();
ifp->rhsp(new AstCond(truep->fileline(),
condp, truep, falsep));
nodep->replaceWith(ifp);
nodep->deleteTree(); nodep=NULL;
}
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
&& operandIfIf(nodep)) {
UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl);
AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf();
AstNode* condp = nodep->condp()->unlinkFrBack();
AstNode* lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext();
AstNode* lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
nodep->condp(new AstLogAnd(lowerIfp->fileline(),
condp, lowerCondp));
lowerIfp->replaceWith(lowerIfsp);
lowerIfp->deleteTree(); lowerIfp=NULL;
}
else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp());
}
nodep->deleteTree(); nodep=NULL;
}
else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) {
// Empty block, remove it
// Note if we support more C++ then there might be side effects in the condition itself
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
else if (!afterComment(nodep->ifsp())) {
UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<<nodep<<endl);
AstNode* condp = nodep->condp();
AstNode* elsesp = nodep->elsesp();
condp->unlinkFrBackWithNext();
elsesp->unlinkFrBackWithNext();
if (nodep->ifsp()) { nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); } // Must have been comment
nodep->condp(new AstLogNot(condp->fileline(), condp)); // LogNot, as C++ optimization also possible
nodep->addIfsp(elsesp);
}
else if (((nodep->condp()->castNot() && nodep->condp()->width()==1)
|| (nodep->condp()->castLogNot()))
&& nodep->ifsp() && nodep->elsesp()) {
UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl);
AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext();
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext();
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
ifp->branchPred(nodep->branchPred().invert());
nodep->replaceWith(ifp);
nodep->deleteTree(); nodep=NULL;
}
else if (ifSameAssign(nodep)) {
UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<<endl);
AstNodeAssign* ifp = nodep->ifsp()->castNodeAssign();
AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign();
ifp->unlinkFrBack();
AstNode* condp = nodep->condp()->unlinkFrBack();
AstNode* truep = ifp->rhsp()->unlinkFrBack();
AstNode* falsep = elsep->rhsp()->unlinkFrBack();
ifp->rhsp(new AstCond(truep->fileline(),
condp, truep, falsep));
nodep->replaceWith(ifp);
nodep->deleteTree(); nodep=NULL;
}
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
&& operandIfIf(nodep)) {
UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl);
AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf();
AstNode* condp = nodep->condp()->unlinkFrBack();
AstNode* lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext();
AstNode* lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
nodep->condp(new AstLogAnd(lowerIfp->fileline(),
condp, lowerCondp));
lowerIfp->replaceWith(lowerIfsp);
lowerIfp->deleteTree(); lowerIfp=NULL;
}
else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp());
}
}
@@ -1423,7 +1508,7 @@ private:
for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) {
if (argp->castConst()) { anyconst=true; break; }
}
if (anyconst) {
if (m_doNConst && anyconst) {
//UINFO(9," Display in "<<nodep->text()<<endl);
string dispout = "";
string fmt = "";
@@ -1486,14 +1571,16 @@ private:
virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->condp()->isZero()) {
UINFO(4,"WHILE(0) => nop "<<nodep<<endl);
if (nodep->precondsp()) nodep->replaceWith(nodep->precondsp());
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
}
else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp());
if (m_doNConst) {
if (nodep->condp()->isZero()) {
UINFO(4,"WHILE(0) => nop "<<nodep<<endl);
if (nodep->precondsp()) nodep->replaceWith(nodep->precondsp());
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
}
else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp());
}
}
}
@@ -1501,12 +1588,20 @@ private:
// If output of a presel didn't get consted, chances are V3Param didn't visit properly
virtual void visit(AstNodePreSel* nodep, AstNUser*) {}
// Ignored, can eliminate early
virtual void visit(AstSysIgnore* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_doNConst) {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
}
//-----
// Jump elimination
virtual void visit(AstJumpGo* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_expensive) { nodep->labelp()->user4(true); }
if (m_doExpensive) { nodep->labelp()->user4(true); }
}
virtual void visit(AstJumpLabel* nodep, AstNUser*) {
@@ -1515,7 +1610,7 @@ private:
// Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
nodep->iterateChildren(*this);
// AstJumpGo's below here that point to this node will set user4
if (m_expensive && !nodep->user4()) {
if (m_doExpensive && !nodep->user4()) {
UINFO(4,"JUMPLABEL => unused "<<nodep<<endl);
AstNode* underp = NULL;
if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext();
@@ -1546,78 +1641,81 @@ private:
// Lint Checks
// v--- *1* These ops are always first, as we warn before replacing
// v--- *V* This op is a verilog op, ignore when in m_cpp mode
// v--- *V* This op is a verilog op, only in m_doV mode
// v--- *C* This op works on all constant children, allowed in m_doConst mode
TREEOP1("AstSel{warnSelect(nodep)}", "NEVER");
// Generic constants on both side. Do this first to avoid other replacements
TREEOP("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)");
TREEOP("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)");
TREEOPC("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)");
TREEOPC("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)");
// Zero on one side or the other
TREEOP("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstAnd {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstDiv {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstDivS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstMul {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstMulS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstPow {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstPowS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
TREEOP("AstSub {$lhsp.isZero, $rhsp}", "AstUnaryMin{$rhsp}");
TREEOP("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstAnd {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstMul {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP("AstMulS {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}");
TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstAnd {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstPow {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstPowS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstUnaryMin{$rhsp}");
TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}");
// Non-zero on one side or the other
TREEOP("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstOr {$lhsp.isAllOnes, $rhsp}", "replaceWLhs(nodep)"); //->allOnes
TREEOP("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)");
TREEOP("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
TREEOP("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)");
TREEOP("AstOr {$lhsp, $rhsp.isAllOnes}", "replaceWRhs(nodep)"); //->allOnes
TREEOP("AstLogOr {$lhsp, $rhsp.isNeqZero}", "replaceNum(nodep,1)");
TREEOP("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
TREEOP("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
TREEOP("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
TREEOP("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
TREEOP("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
TREEOP("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP("AstPowS {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp}", "replaceWLhs(nodep)"); //->allOnes
TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)");
TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)");
TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes}", "replaceWRhs(nodep)"); //->allOnes
TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero}", "replaceNum(nodep,1)");
TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
TREEOP ("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
TREEOP ("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
TREEOP ("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP ("AstPowS {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
// Trinary ops
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
TREEOP("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");
TREEOP("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)");
TREEOP("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)");
TREEOP("AstCond{$condp->castNot(), $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}");
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstOr {$condp, $expr2p}"); // a?1:b == a|b
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstAnd{$condp, $expr1p}"); // a?b:0 == a&b
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a|b
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&b
TREEOP("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");
TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)");
TREEOPC("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)");
TREEOPC("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)");
TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)");
TREEOP ("AstCond{$condp->castNot(), $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}");
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstOr {$condp, $expr2p}"); // a?1:b == a|b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstAnd{$condp, $expr1p}"); // a?b:0 == a&b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a|b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&b
TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
// Prefer constants on left, since that often needs a shift, it lets constant red remove the shift
TREEOP("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
TREEOP ("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
// v--- *1* as These ops are always first, as we warn before replacing
TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)");
TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)");
@@ -1666,33 +1764,40 @@ private:
TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
// Compress out EXTENDs to appease loop unroller
TREEOPV("AstEq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstNeq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
// Identical operands on both sides
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
// AstAdd->ShiftL(#,1) but uncommon
TREEOP("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
TREEOP("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
TREEOP("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)");
TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP ("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
TREEOP ("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
TREEOP ("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)");
TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP ("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
///=== Verilog operators
// Comparison against 1'b0/1'b1; must be careful about widths.
// These use Not, so must be Verilog only
@@ -1743,18 +1848,33 @@ private:
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
// Next rule because AUTOINST puts the width of bits in
// to pins, even when the widths are exactly the same across the hierarchy.
TREEOPV("AstSel{operandSelExtend(nodep)}", "replaceWChild(nodep, nodep->fromp()->castExtend()->lhsp())");
TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE");
TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())");
TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)");
TREEOPV("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
TREEOPV("AstSel{$fromp.castAdd, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castAnd, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castOr, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXnor,operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE");
TREEOPC("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)");
// V3Tristate requires selects below BufIf1.
// Also do additional operators that are bit-independent, but only definite
// win if bit select is a constant (otherwise we may need to compute bit index several times)
TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)");
TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castAnd,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castOr,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castXor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castXnor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
// Conversions
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
// Strings
TREEOP ("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())");
TREEOPC("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())");
// Possible futures:
@@ -1781,15 +1901,37 @@ private:
}
public:
// Processing Mode Enum
enum ProcMode {
PROC_PARAMS,
PROC_LIVE,
PROC_V_WARN,
PROC_V_NOWARN,
PROC_V_EXPENSIVE,
PROC_CPP
};
// CONSTUCTORS
ConstVisitor(bool params, bool expensive, bool warn, bool cpp) {
m_params = params; m_required = params;
m_expensive = expensive;
m_warn = warn;
m_cpp = cpp;
m_wremove = true;
ConstVisitor(ProcMode pmode) {
m_params = false;
m_required = false;
m_doExpensive = false;
m_doNConst = false;
m_doV = false;
m_warn = false;
m_wremove = true; // Overridden in visitors
m_modp = NULL;
m_scopep = NULL;
//
switch (pmode) {
case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true; m_required = true; break;
case PROC_LIVE: break;
case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; break;
case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break;
case PROC_V_EXPENSIVE: m_doV = true; m_doNConst = true; m_doExpensive = true; break;
case PROC_CPP: m_doV = false; m_doNConst = true; break;
default: v3fatalSrc("Bad case"); break;
}
}
virtual ~ConstVisitor() {}
AstNode* mainAcceptEdit(AstNode* nodep) {
@@ -1806,7 +1948,7 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
// Resize even if the node already has a width, because burried in the treee we may
// have a node we just created with signing, etc, that isn't sized yet.
nodep = V3Width::widthParamsEdit(nodep); // Make sure we've sized everything first
ConstVisitor visitor (true,false,false,false);
ConstVisitor visitor (ConstVisitor::PROC_PARAMS);
if (AstVar* varp=nodep->castVar()) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
@@ -1820,34 +1962,43 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
return nodep;
}
void V3Const::constifyAll(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,true,false,false);
(void)visitor.mainAcceptEdit(nodep);
}
void V3Const::constifyAllLint(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,false,true,false);
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
(void)visitor.mainAcceptEdit(nodep);
}
void V3Const::constifyCpp(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,false,false,true);
ConstVisitor visitor (ConstVisitor::PROC_CPP);
(void)visitor.mainAcceptEdit(nodep);
}
AstNode* V3Const::constifyEdit(AstNode* nodep) {
ConstVisitor visitor (false,false,false,false);
ConstVisitor visitor (ConstVisitor::PROC_V_NOWARN);
nodep = visitor.mainAcceptEdit(nodep);
return nodep;
}
void V3Const::constifyAllLive(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
// This only pushes constants up, doesn't make any other edits
// IE doesn't prune dead statements, as we need to do some usability checks after this
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_LIVE);
(void)visitor.mainAcceptEdit(nodep);
}
void V3Const::constifyAll(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
(void)visitor.mainAcceptEdit(nodep);
}
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
ConstVisitor visitor (false,true,false,false);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
nodep = visitor.mainAcceptEdit(nodep);
return nodep;
}
+3 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -34,6 +34,8 @@ public:
// Force this cell node's parameter list to become a constant
// Return new node that may have replaced nodep
static AstNode* constifyParamsEdit(AstNode* nodep);
// Only do constant pushing, without removing dead logic
static void constifyAllLive(AstNetlist* nodep);
// Everything that's possible
static void constifyAll(AstNetlist* nodep);
// Also, warn
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+7 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -122,6 +122,12 @@ private:
nodep->packagep()->user1Inc();
}
}
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->packagep()) {
nodep->packagep()->user1Inc();
}
}
virtual void visit(AstVarScope* nodep, AstNUser*) {
nodep->iterateChildren(*this);
m_vscsp.push_back(nodep);
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -4
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -345,9 +345,7 @@ private:
m_nextDlyp = NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (!nodep->user2()) { // Not done yet
nodep->user2(true);
if (!nodep->user2Inc()) { // Not done yet
if (m_inDly && nodep->lvalue()) {
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
markVarUsage(nodep->varScopep(), VU_DLY);
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+12 -4
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -127,6 +127,7 @@ public:
nodep->lhsp()->iterateAndNext(*this); puts(", ");
} else if (nodep->isWide()
&& nodep->lhsp()->castVarRef()
&& !nodep->rhsp()->castCMath()
&& !nodep->rhsp()->castVarRef()
&& !nodep->rhsp()->castArraySel()) {
// Wide functions assign into the array directly, don't need separate assign statement
@@ -475,7 +476,7 @@ public:
}
visit(nodep->castNodeBiop(), vup);
}
virtual void visit(AstCast* nodep, AstNUser*) {
virtual void visit(AstCCast* nodep, AstNUser*) {
// Extending a value of the same word width is just a NOP.
if (nodep->size()>VL_WORDSIZE) {
puts("(QData)(");
@@ -1619,7 +1620,12 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
puts("#include \""+topClassName()+"__Inlines.h\"\n");
}
// No __Dpi.h needed, we've shimmed it all into the interface
if (v3Global.dpi()) {
// do this before including our main .h file so that any references to
// types defined in svdpi.h are available
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
puts("\n");
}
// Declare foreign instances up front to make C++ happy
puts("class "+symClassName()+";\n");
@@ -1797,8 +1803,10 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
// Us
puts("#include \""+ symClassName() +".h\"\n");
if (v3Global.dpi()) {
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
puts("\n");
puts("#include \"verilated_dpi.h\"\n");
}
if (optSystemPerl() && (splitFilenum() || !m_fast)) {
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+3 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -519,6 +519,8 @@ void EmitCSyms::emitDpiHdr() {
puts("// Manually include this file where DPI .c import functions are declared to insure\n");
puts("// the C functions match the expectations of the DPI imports.\n");
puts("\n");
puts("#include \"svdpi.h\"\n");
puts("\n");
puts("#ifdef __cplusplus\n");
puts("extern \"C\" {\n");
puts("#endif\n");
+1 -1
View File
@@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2004-2010 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// 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