Compare commits

...
29 Commits
Author SHA1 Message Date
Wilson Snyder c4b1bc2506 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@950 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-08-01 13:44:45 +00:00
Wilson Snyder 551393d443 Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@949 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-31 14:47:21 +00:00
Wilson Snyder 79d305f3e8 Match Verilog-Perl: Remove preprocessor adding newlines before `line.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@948 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-30 15:00:21 +00:00
Wilson Snyder 822956e769 Add SystemVerilog end labels
git-svn-id: file://localhost/svn/verilator/trunk/verilator@947 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 17:58:53 +00:00
Wilson Snyder a681a6a6d5 Make -> a token to match verilog-perl
git-svn-id: file://localhost/svn/verilator/trunk/verilator@946 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 17:26:12 +00:00
Wilson Snyder 5f6d69affd Support SystemVerilog ==? and !=? operators.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@945 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 15:01:39 +00:00
Wilson Snyder 4a9bea6980 Version bump; commentary
git-svn-id: file://localhost/svn/verilator/trunk/verilator@942 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-21 21:00:38 +00:00
Wilson Snyder bfddd80f43 Support V2K function/task argument lists.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@941 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-19 23:43:14 +00:00
Wilson Snyder 84a778719a Fix constification removing continuous always blocks
git-svn-id: file://localhost/svn/verilator/trunk/verilator@940 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-15 14:39:52 +00:00
Wilson Snyder 829d80d5b5 Fix display constanting of neg quads. Part of previous checkin
git-svn-id: file://localhost/svn/verilator/trunk/verilator@939 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 21:27:40 +00:00
Wilson Snyder d6a5c97f3a Fix last change: percents must be literalized
git-svn-id: file://localhost/svn/verilator/trunk/verilator@938 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 18:34:08 +00:00
Wilson Snyder 4ba00bd256 Propagate constants into displays
git-svn-id: file://localhost/svn/verilator/trunk/verilator@937 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 17:29:37 +00:00
Wilson Snyder c18f9da400 Put display scope tracking under special node type
git-svn-id: file://localhost/svn/verilator/trunk/verilator@936 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 16:41:32 +00:00
Wilson Snyder 5b620a8dc5 Add V3Number display function, unused as yet
git-svn-id: file://localhost/svn/verilator/trunk/verilator@935 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 14:24:21 +00:00
Wilson Snyder 9c968c590c Fix Preprocessor dropping some line directives
git-svn-id: file://localhost/svn/verilator/trunk/verilator@934 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-13 17:34:09 +00:00
Wilson Snyder dff5d5c4e4 Report as many warning types as possible before exiting.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@933 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-12 19:39:10 +00:00
Wilson Snyder 1265e8cce8 Support V2K portlists with input a,b,...
git-svn-id: file://localhost/svn/verilator/trunk/verilator@932 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-12 13:58:56 +00:00
Wilson Snyder 2b5d7eeb50 Lesser license for verilated files
git-svn-id: file://localhost/svn/verilator/trunk/verilator@931 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-11 17:07:11 +00:00
Wilson Snyder bb9ae89049 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@928 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-22 12:15:01 +00:00
Wilson Snyder 72832a2810 Support empty module declarations
git-svn-id: file://localhost/svn/verilator/trunk/verilator@927 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-18 18:48:22 +00:00
Wilson Snyder 18cb210eac Ignore protect, and allow empty case
git-svn-id: file://localhost/svn/verilator/trunk/verilator@926 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-18 14:03:50 +00:00
Wilson Snyder 2c5a183368 Ignore ctrl-Zs in preprocessor
git-svn-id: file://localhost/svn/verilator/trunk/verilator@925 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-17 16:15:24 +00:00
Wilson Snyder 386f0a75df Support automatic and additional v2k timing statements
git-svn-id: file://localhost/svn/verilator/trunk/verilator@924 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-16 19:27:29 +00:00
Wilson Snyder ea26482154 Support functions which return integers
git-svn-id: file://localhost/svn/verilator/trunk/verilator@923 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-16 18:19:23 +00:00
Wilson Snyder 3aee7f918a More cleanup to match VParse, and support celldefine properly
git-svn-id: file://localhost/svn/verilator/trunk/verilator@922 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-16 12:55:25 +00:00
Wilson Snyder b3dd18b215 More bison cleanup; no functional change
git-svn-id: file://localhost/svn/verilator/trunk/verilator@921 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-14 20:59:58 +00:00
Wilson Snyder a77e331e89 Standardize flex->bison token names. No functional change.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@920 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-12 16:29:25 +00:00
Wilson Snyder 6f414ee9e2 Add unsigned keyword
git-svn-id: file://localhost/svn/verilator/trunk/verilator@919 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-12 15:31:04 +00:00
Wilson Snyder 8d56b498d1 Warn if flex is not installed.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@918 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-24 17:03:52 +00:00
63 changed files with 1806 additions and 582 deletions
+32
View File
@@ -3,6 +3,38 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...] The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks! indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.653 8/1/2007
**** Support SystemVerilog ==? and !=? operators.
**** Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
* Verilator 3.652 6/21/2007
**** Report as many warning types as possible before exiting.
**** Support V2K portlists with "input a,b,...". [Mark Nodine]
**** Support V2K function/task argument lists.
**** Optimize constant $display arguments.
**** Fix Preprocessor dropping some `line directives. [Mark Nodine]
* Verilator 3.651 5/22/2007
*** Added verilator_profcfunc utility. [Gene Weber]
*** Treat modules within `celldefine and `endcelldefine as if in library.
*** Support functions which return integers. [Mark Nodine]
**** Warn if flex is not installed. [Ralf Karge]
**** Ignore `protect and `endprotect.
**** Allow empty case/endcase blocks.
* Verilator 3.650 4/20/2007 * Verilator 3.650 4/20/2007
** Add --compiler msvc option. This is now required when Verilated code ** Add --compiler msvc option. This is now required when Verilated code
+1 -1
View File
@@ -4,7 +4,7 @@
# #
# This file is part of Verilator. # This file is part of Verilator.
# #
# Author: Wilson Snyder <[email protected]> or <[email protected]> # Author: Wilson Snyder <[email protected]>
# #
# Code available from: http://www.veripool.com/verilator # Code available from: http://www.veripool.com/verilator
# #
+7 -1
View File
@@ -26,11 +26,11 @@ Features:
Points should be per-scope like everything else rather then per-module Points should be per-scope like everything else rather then per-module
Expression coverage (see notes) Expression coverage (see notes)
More Verilog 2001 Support More Verilog 2001 Support
C-style function and task arguments. [Wim Michiels]
(* *) Attributes (just ignore -- preprocessor?) (* *) Attributes (just ignore -- preprocessor?)
Real numbers (NEVER) Real numbers (NEVER)
Recursive functions (NEVER) Recursive functions (NEVER)
Verilog configuration files (NEVER) Verilog configuration files (NEVER)
DPI to define C/C++ calls from Verilog
Long-term Features Long-term Features
Assertions Assertions
@@ -103,6 +103,12 @@ Performance:
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b). If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal) Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
All of the temp vars that get set, exp pre_ vars and never feedback
(not flops) don't need to be stored in the structs, but instead can
be per-invocation, and even better register-colored-like to reuse
the space. This will greatly reduce the data footprint.
//********************************************************************** //**********************************************************************
//* Detailed notes on 'todo' features //* Detailed notes on 'todo' features
+110 -14
View File
@@ -214,6 +214,66 @@ C++, and linked with the Verilated files.
The resulting executable will perform the actual simulation. The resulting executable will perform the actual simulation.
=head1 ARGUMENT SUMMARY
This is a short summary of the arguments to Verilator. See the detailed
descriptions in the next sections for more information.
{file.v} Verilog top level filenames
{file.c/cc/cpp} Optional C++ files to link in
--assert Enable all assertions
--bin <filename> Override Verilator binary
--cc Create C++ output
--compiler <compiler-name> Tune for specified C++ compiler
--coverage Enable all coverage
--coverage-line Enable line coverage
--coverage-user Enable PSL/SVL user coverage
-D<var>[=<value>] Set preprocessor define
--debug Enable debugging
--debug-check Enable debugging assertions
--dump-tree Enable dumping .tree files
-E Preprocess, but do not compile
--exe Link to create executable
-f <file> Parse options from a file
--help Display this help.
-I<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining
--lint-only Lint, but do not make output
--MMD Create .d dependency files
--MP Create phony dependency targets
--Mdir <directory> Name of output object directory
--mod-prefix <topname> Name to prepend to lower classes
--no-skip-identical Disable skipping identical output
-O0 Disable optimizations
-O3 High performance optimizations
-O<optimization-letter> Selectable optimizations
--output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .ccp functions
--pins64 Use uint64_t's for 33-64 bit sigs
--prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling
--private Debugging; see docs
--psl Enable PSL parsing
--public Debugging; see docs
--sc Create SystemC output
--sp Create SystemPerl output
--stats Create statistics file
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
-U<var> Undefine preprocessor define
--underline-zero Zero signals with leading _'s
-v <filename> Verilog library
-Werror-<message> Convert warning to error
-Wno-<message> Disable warning
-x-assign <mode> Initially assign Xs to this value
-y <dir> Directory to search for modules
+define+<var>+<value> Set preprocessor define
+incdir+<dir> Directory to search for includes
+libext+<ext>+[ext]... Extensions for finding modules
=head1 ARGUMENTS =head1 ARGUMENTS
=over 4 =over 4
@@ -320,6 +380,12 @@ internal assertions, debugging messages, and intermediate form dump files.
Rarely needed. Enable internal debugging assertion checks, without Rarely needed. Enable internal debugging assertion checks, without
changing debug verbosity. Enabled automatically when --debug specified. changing debug verbosity. Enabled automatically when --debug specified.
=item --dump-tree
Rarely needed. Enable writing .tree debug files. This is enabled with
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
large and not desired.
=item -E =item -E
Preprocess the source code, but do not compile, as with 'gcc -E'. Output Preprocess the source code, but do not compile, as with 'gcc -E'. Output
@@ -577,7 +643,7 @@ We'll compile this example into C++.
int main(int argc, char **argv, char **env) { int main(int argc, char **argv, char **env) {
Vour* top = new Vour; Vour* top = new Vour;
while (!Verilated::gotFinish()) { top->eval(); } while (!Verilated::gotFinish()) { top->eval(); }
exit(0); exit(0);
} }
EOF EOF
@@ -637,7 +703,7 @@ This is an example similar to the above, but using SystemPerl.
top = new Vour("top"); // SP_CELL (top, Vour); top = new Vour("top"); // SP_CELL (top, Vour);
top->clk(clk); // SP_PIN (top, clk, clk); top->clk(clk); // SP_PIN (top, clk, clk);
while (!Verilated::gotFinish()) { sc_start(1); } while (!Verilated::gotFinish()) { sc_start(1); }
exit(0); exit(0);
} }
EOF EOF
@@ -730,9 +796,9 @@ feedback driven compilation. With GCC, using -fprofile-arcs, then
You may uncover further tuning possibilities by profiling the Verilog code. You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code, and by looking at either oprofile or gprof to see where in the C++ code the time is spent.
the mangled function name where in the Verilog code most of the time is Run the gprof output through verilator_profcfunc and it will tell you what
being spent. Verilog line numbers on which most of the time is being spent.
When done, please let the author know the results. I like to keep tabs on When done, please let the author know the results. I like to keep tabs on
how Verilator compares, and may be able to suggest additional improvements. how Verilator compares, and may be able to suggest additional improvements.
@@ -944,12 +1010,14 @@ Verilator currently has very minimal support for SystemVerilog. As
SystemVerilog features enter common usage they will be added. Contact the SystemVerilog features enter common usage they will be added. Contact the
author if a feature you need is missing. author if a feature you need is missing.
Verilator implements the full SystemVerilog 1800-2005 preprocessor subset, Verilator implements the full SystemVerilog 1800-2005 preprocessor,
including function call-like preprocessor defines. including function call-like preprocessor defines.
Verilator supports $bits, $countones, $error, $fatal, $info, $isunknown, Verilator supports ==? and !=? operators, $bits, $countones, $error,
$onehot, $onehot0, $warning, always_comb, always_ff, always_latch, $fatal, $info, $isunknown, $onehot, $onehot0, $warning, always_comb,
do-while, and final. It also supports .name and .* interconnection. always_ff, always_latch, do-while, and final.
It also supports .name and .* interconnection.
Verilator partially supports assert. Verilator partially supports assert.
@@ -1195,7 +1263,7 @@ lint_restore*/. For example:
If SOME_WARNING was on before the lint_off, it will now be restored to on, If SOME_WARNING was on before the lint_off, it will now be restored to on,
and if it was off before the lint_off it will remain off. and if it was off before the lint_off it will remain off.
=item /*verilator no_inline_task*/ =item /*verilator no_inline_task*/
Used in a function or task variable definition section to specify the Used in a function or task variable definition section to specify the
function or task should not be inlined into where it is used. This may function or task should not be inlined into where it is used. This may
@@ -1434,6 +1502,14 @@ This section describes specific limitations for each language keyword.
=over 4 =over 4
=item `__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords,
`begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords,
`endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor,
`systemc_dtor, `systemc_header, `systemc_imp_header,
`systemc_implementation, `systemc_interface, `timescale, `undef, `verilog
Fully supported.
=item always, always_comb, always_ff, always_latch, and, assign, begin, =item always, always_comb, always_ff, always_latch, and, assign, begin,
buf, case, casex, casez, default, defparam, do-while, else, end, endcase, buf, case, casex, casez, default, defparam, do-while, else, end, endcase,
endfunction, endgenerate, endmodule, endspecify, endtask, final, for, endfunction, endgenerate, endmodule, endspecify, endtask, final, for,
@@ -1453,8 +1529,9 @@ All specify blocks and timing checks are ignored.
Verilator does not perform warning checking on uwires, it treats the uwire Verilator does not perform warning checking on uwires, it treats the uwire
keyword as if it were the normal wire keyword. keyword as if it were the normal wire keyword.
=item $bits, $countones, $finish, $isunknown, $onehot, $onehot0, $readmemb, =item $bits, $countones, $error, $fatal, $finish, $info, $isunknown,
$readmemh, $signed, $stop, $time, $unsigned $onehot, $onehot0, $readmemb, $readmemh, $signed, $stop, $time, $unsigned,
$warning.
Generally supported. Generally supported.
@@ -1861,6 +1938,25 @@ so your simulator shouldn't have to be -- and Verilator is closer to the
synthesis interpretation, so this is a good thing for getting working synthesis interpretation, so this is a good thing for getting working
silicon. silicon.
=item May programs I create with Verilator remain under my own copyright?
Yes, it's just like using GCC on your programs. If you change Verilator
itself, you must make the source code available under the GNU Public
License. However, the include and generated files use the GNU Lesser
Public License, which means that files using them are NOT required to be released.
You also have the option of using the Perl Artistic License, which again
does not require you release your Verilog or generated code.
=item Why is running Verilator so slow?
Verilator needs more memory then the resulting simulator will require, as
Verilator creates internally all of the state of the resulting simulator in
order to optimize it. If it takes more then a minute or so (and you're not
using --debug), see if your machine is paging; most likely you need to run
it on a machine with more memory. Verilator is a full 64 bit application
and may use more then 4GB, but about 1GB is the maximum typically needed.
=item How do I generate waveforms (traces) in C++? =item How do I generate waveforms (traces) in C++?
See the next question for SystemC mode. See the next question for SystemC mode.
@@ -2069,7 +2165,7 @@ Communications, Sun Microsystems, Nauticus Networks, and SiCortex.
The people who have contributed code or other major functionality are Paul The people who have contributed code or other major functionality are Paul
Wasson, Duane Galbi, and Wilson Snyder. Major testers include Jeff Dutton, Wasson, Duane Galbi, and Wilson Snyder. Major testers include Jeff Dutton,
Ralf Karge and Wim Michiels. Ralf Karge, David Hewson, Wim Michiels, and Gene Weber.
Some of the people who have provided ideas and feedback for Verilator Some of the people who have provided ideas and feedback for Verilator
include Hans Van Antwerpen, Jens Arm, David Black, Gregg Bouchard, Chris include Hans Van Antwerpen, Jens Arm, David Black, Gregg Bouchard, Chris
@@ -2096,7 +2192,7 @@ Major concepts by Paul Wasson and Duane Galbi.
=head1 SEE ALSO =head1 SEE ALSO
L<systemperl>, L<vcoverage>, L<make> L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>
=cut =cut
+2 -1
View File
@@ -35,12 +35,13 @@ my $Opt_A;
my $Opt_B; my $Opt_B;
autoflush STDOUT 1; autoflush STDOUT 1;
autoflush STDERR 1; autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions ( if (! GetOptions (
"help" => \&usage, "help" => \&usage,
"debug" => \&debug, "debug" => \&debug,
"<>" => \&parameter, "<>" => \&parameter,
)) { )) {
usage(); die "%Error: Bad usage, try 'verilator_difftree --help'\n";
} }
defined $Opt_A or die "%Error: No old diff filename\n"; defined $Opt_A or die "%Error: No old diff filename\n";
+211
View File
@@ -0,0 +1,211 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# $Id$
######################################################################
#
# Copyright 2007-2007 by Wilson Snyder <[email protected]>. This
# program is free software; you can redistribute it and/or modify it under
# the terms of either the GNU Lesser General Public License or the Perl
# Artistic License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
######################################################################
require 5.006_001;
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug);
#======================================================================
#======================================================================
# main
$Debug = 0;
my $Opt_File;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
die "%Error: Bad usage, try 'verilator_profcfunc --help'\n";
}
defined $Opt_File or die "%Error: No filename given\n";
profcfunc($Opt_File);
#----------------------------------------------------------------------
sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2);
exit (1);
}
sub debug {
$Debug = 1;
}
sub parameter {
my $param = shift;
if (!defined $Opt_File) {
$Opt_File = $param;
} else {
die "%Error: Unknown parameter: $param\n";
}
}
#######################################################################
sub profcfunc {
my $filename = shift;
# Remove hex numbers before diffing
my $fh = IO::File->new ($filename) or die "%Error: $! $filename,";
my %funcs;
while (defined (my $line=$fh->getline())) {
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+.*\s+(\S+)\s*$/) {
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
$funcs{$func}{pct} += $pct;
$funcs{$func}{sec} += $sec;
$funcs{$func}{calls} += $calls;
}
}
$fh->close;
# Find modules
my %verilated_mods;
foreach my $func (keys %funcs) {
if ($func =~ /(.*)::_eval\(.*__Syms.*\)$/) {
$verilated_mods{$1} = qr/^$1/;
}
}
# Resort by Verilog name
my %vfuncs;
my %groups;
foreach my $func (keys %funcs) {
my $vfunc = $func;
my $design;
foreach my $vde (keys %verilated_mods) {
if ($func =~ /$verilated_mods{$vde}/) {
$design=$vde;
last;
}
}
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__([0-9]+)\(/) {
$vfunc = sprintf("VBlock %s:%d", $1, $2);
$groups{"Verilog Blocks under $design"} += $funcs{$func}{pct};
} else {
if ($design) {
$vfunc = sprintf("VCommon %s", $func);
$groups{"Common code under $design"} += $funcs{$func}{pct};
} else {
$vfunc = sprintf("C++ %s", $func);
$groups{'C++'} += $funcs{$func}{pct};
}
}
$vfuncs{$vfunc} = $funcs{$func};
}
print("Overall summary:\n");
print(" % time\n");
foreach (sort (keys %groups)) {
printf(" %6.2f In all %s\n", $groups{$_}, $_);
}
print("\n");
print("Verilog code profile:\n");
print(" These are split into three categories:\n");
print(" C++: Time in non-Verilated C++ code\n");
print(" VBlock: Time attributable to a block in a Verilog file and line\n");
print(" VCommon: Time in a Verilated module, due to all parts of the design\n");
print("\n");
print(" % cumulative self \n");
print(" time seconds seconds calls type filename and line number\n");
my $cume = 0;
foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec}
|| $a cmp $b}
(keys %vfuncs)) {
$cume += $vfuncs{$func}{sec};
printf +("%6.2f %9.2f %8.2f %8d %s\n",
$vfuncs{$func}{pct},
$cume, $vfuncs{$func}{sec},
$vfuncs{$func}{calls},
$func);
}
}
#######################################################################
__END__
=pod
=head1 NAME
verilator_profcfunc - Read gprof report created with --profile-cfuncs
=head1 SYNOPSIS
verilator --profile-cfuncs ....
gcc --ggdb -pg ....
{run executable}
gprof
verilator_profcfuncs gprof.out
=head1 DESCRIPTION
Verilator_profcfunc reads a profile report created by gprof. The names of
the functions are then transformed, assuming the user used verilator's
--profile-cfuncs, and a report printed showing the percentage of time, etc,
in each Verilog block.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=back
=head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.com/>.
Copyright 2007-2007 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License or the Perl Artistic License.
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
C<verilator>
=cut
######################################################################
### Local Variables:
### compile-command: "$V4/bin/verilator_profcfunc $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
### End:
+10 -1
View File
@@ -16,8 +16,17 @@ AC_PROG_CC
AC_PROG_CXX AC_PROG_CXX
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PATH_PROG(PERL,perl) AC_PATH_PROG(PERL,perl)
AC_PATH_PROG(YACC,bison) if test "x$PERL" = "x" ; then
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
fi
AC_PATH_PROG(LEX,flex) AC_PATH_PROG(LEX,flex)
if test "x$LEX" = "x" ; then
AC_MSG_ERROR([Cannot find "flex" in your PATH, please install it])
fi
AC_PATH_PROG(YACC,bison)
if test "x$YACC" = "x" ; then
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
fi
dnl Checks for libraries. dnl Checks for libraries.
+2 -2
View File
@@ -3,7 +3,7 @@
// //
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // Lesser General Public License or the Perl Artistic License.
// //
// Verilator is distributed in the hope that it will be useful, // Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -31,7 +31,7 @@
//=========================================================================== //===========================================================================
// Global variables // Global variables
int Verilated::s_randReset = false; int Verilated::s_randReset = 0;
int Verilated::s_debug = 1; int Verilated::s_debug = 1;
bool Verilated::s_calcUnusedSigs = false; bool Verilated::s_calcUnusedSigs = false;
bool Verilated::s_gotFinish = false; bool Verilated::s_gotFinish = false;
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // Lesser General Public License or the Perl Artistic License.
// //
// Verilator is distributed in the hope that it will be useful, // Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
+1 -1
View File
@@ -4,7 +4,7 @@
# #
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can # Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU # redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License. # Lesser General Public License or the Perl Artistic License.
###################################################################### ######################################################################
PERL = @PERL@ PERL = @PERL@
+1 -1
View File
@@ -7,7 +7,7 @@
// //
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // Lesser General Public License or the Perl Artistic License.
// //
// This is distributed in the hope that it will be useful, // This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
+1 -1
View File
@@ -3,7 +3,7 @@
// //
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // Lesser General Public License or the Perl Artistic License.
// //
// Verilator is distributed in the hope that it will be useful, // Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/perl -w
#$Id$
######################################################################
#
# Copyright 2007-2007 by Wilson Snyder.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of either the GNU General Public License or the
# Perl Artistic License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the Perl Artistic License
# along with this module; see the file COPYING. If not, see
# www.cpan.org
#
######################################################################
# DESCRIPTION: Debugging of bison output
use strict;
my $Debug;
my %declared;
my %used;
my $body = 0;
my $rule = "";
my $lineno = 0;
foreach my $line (<STDIN>) {
$lineno++;
chomp $line;
$line =~ s!//.*$!!g;
$line =~ s!\s+! !g;
next if $line eq '';
if ($line =~ m!^\%\%!) {
$body++;
} elsif ($body == 1) {
$rule .= $line;
if ($line =~ m!^\s*;\s*$!) {
#print "Rule: $rule\n";
($rule =~ /^([a-zA-Z0-9_]+):(.*)$/) or die "%Error: No rule name: $1\n";
my $rulename = $1; my $preaction = $2;
$declared{$rulename} = $lineno;
$preaction =~ s/\{[^\}]*\}/ /g;
#print "RULEN $rulename PA $preaction\n" if $Debug;
$rule = '';
foreach my $ref (split /\s+/, $preaction) {
next if $ref !~ /^[a-zA-Z]/;
next if $ref eq $rulename;
if (!$used{$ref} && $declared{$ref}) {
print " %Warning: $lineno: $ref used by $rulename after declaration\n";
}
$used{$ref} = $lineno;
print " ref $ref\n" if $Debug;
}
}
}
}
# Local Variables:
# compile-command: "./bisonreader < verilog.y"
# End:
+3
View File
@@ -63,6 +63,9 @@ private:
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack(); AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
timesp = timesp->addNext(new AstTime(nodep->fileline())); timesp = timesp->addNext(new AstTime(nodep->fileline()));
nodep->exprsp(timesp); nodep->exprsp(timesp);
if (!nodep->scopeNamep() && nodep->name().find("%m") != string::npos) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
}
} }
AstNode* newIfAssertOn(AstNode* nodep) { AstNode* newIfAssertOn(AstNode* nodep) {
+1 -1
View File
@@ -999,7 +999,7 @@ private:
AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced
string m_name; // Name of variable string m_name; // Name of variable
string m_dotted; // Dotted part of scope to task or "" string m_dotted; // Dotted part of scope to task or ""
string m_inlinedDots; // Dotted hiearchy flattened out string m_inlinedDots; // Dotted hierarchy flattened out
public: public:
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp) AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
:AstNode(fl) :AstNode(fl)
+53 -7
View File
@@ -421,7 +421,7 @@ struct AstScope : public AstNode {
private: private:
string m_name; // Name string m_name; // Name
AstScope* m_aboveScopep; // Scope above this one in the hierarchy (NULL if top) AstScope* m_aboveScopep; // Scope above this one in the hierarchy (NULL if top)
AstCell* m_aboveCellp; // Cell above this in the hiearchy (NULL if top) AstCell* m_aboveCellp; // Cell above this in the hierarchy (NULL if top)
AstModule* m_modp; // Module scope corresponds to AstModule* m_modp; // Module scope corresponds to
public: public:
AstScope(FileLine* fl, AstModule* modp, const string& name, AstScope(FileLine* fl, AstModule* modp, const string& name,
@@ -540,7 +540,7 @@ struct AstVarXRef : public AstNodeVarRef {
// Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope // Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope
private: private:
string m_dotted; // Scope name to connected to string m_dotted; // Scope name to connected to
string m_inlinedDots; // Dotted hiearchy flattened out string m_inlinedDots; // Dotted hierarchy flattened out
public: public:
AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue) AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue)
:AstNodeVarRef(fl, name, NULL, lvalue) :AstNodeVarRef(fl, name, NULL, lvalue)
@@ -1271,11 +1271,8 @@ public:
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
AstNode* filep() const { return op2p(); } AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
AstNode* scopeAttrp() const { return op3p(); } AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
AstText* scopeTextp() const { return op3p()->castText(); } void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
bool needScopeTracking() { return (displayType().needScopeTracking()
|| name().find("%m") != string::npos); }
}; };
struct AstFClose : public AstNodeStmt { struct AstFClose : public AstNodeStmt {
@@ -1726,6 +1723,22 @@ public:
int dimension() const { return m_dimension; } int dimension() const { return m_dimension; }
}; };
struct AstScopeName : public AstNode {
// For display %m
// Parents: DISPLAY
// Children: TEXT
AstScopeName(FileLine* fl)
: AstNode(fl) {}
virtual ~AstScopeName() {}
virtual AstType type() const { return AstType::SCOPENAME;}
virtual AstNode* clone() { return new AstScopeName(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstText* scopeAttrp() const { return op1p()->castText(); }
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
};
//====================================================================== //======================================================================
// non-ary ops // non-ary ops
@@ -2593,6 +2606,39 @@ struct AstNeqCase : public AstNodeBiCom {
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
}; };
struct AstEqWild : public AstNodeBiop {
// Note wildcard operator rhs differs from lhs
AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
width(1,1); }
virtual ~AstEqWild() {}
virtual AstType type() const { return AstType::EQWILD;}
virtual AstNode* clone() { return new AstEqWild(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k==? %r)"; }
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways
virtual string emitSimpleOperator() { return "=="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstNeqWild : public AstNodeBiop {
AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
width(1,1); }
virtual ~AstNeqWild() {}
virtual AstType type() const { return AstType::NEQWILD;}
virtual AstNode* clone() { return new AstNeqWild(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k!=? %r)"; }
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways
virtual string emitSimpleOperator() { return "!="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstConcat : public AstNodeBiop { struct AstConcat : public AstNodeBiop {
// If you're looking for {#{}}, see AstReplicate // If you're looking for {#{}}, see AstReplicate
AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+2 -2
View File
@@ -131,10 +131,10 @@ private:
nodep->replaceWith(newp); nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL; nodep->deleteTree(); nodep=NULL;
} }
virtual void visit(AstDisplay* nodep, AstNUser*) { virtual void visit(AstScopeName* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name() // If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Inline // Similar code in V3Inline
if (m_beginScope != "" && nodep->needScopeTracking()) { if (m_beginScope != "") {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
-3
View File
@@ -62,9 +62,6 @@ private:
//int debug() { return 9; } //int debug() { return 9; }
virtual void visit(AstNodeCase* nodep, AstNUser*) { virtual void visit(AstNodeCase* nodep, AstNUser*) {
// We report a syntax error on empty "case (x) endcase" blocks, so never no items at all
if (!nodep->itemsp()) nodep->v3fatalSrc("No items (not even default) under case statement?\n");
// Detect multiple defaults // Detect multiple defaults
bool hitDefault = false; bool hitDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
+3
View File
@@ -196,6 +196,9 @@ private:
virtual void visit(AstText* nodep, AstNUser*) { virtual void visit(AstText* nodep, AstNUser*) {
setClean (nodep, true); setClean (nodep, true);
} }
virtual void visit(AstScopeName* nodep, AstNUser*) {
setClean (nodep, true);
}
virtual void visit(AstSel* nodep, AstNUser*) { virtual void visit(AstSel* nodep, AstNUser*) {
operandTriop(nodep); operandTriop(nodep);
setClean (nodep, nodep->cleanOut()); setClean (nodep, nodep->cleanOut());
+69 -1
View File
@@ -802,7 +802,12 @@ private:
if (nodep->sensp()->castConst() if (nodep->sensp()->castConst()
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) { || (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
// Constants in sensitivity lists may be removed (we'll simplify later) // Constants in sensitivity lists may be removed (we'll simplify later)
AstSenItem* newp = new AstSenItem(nodep->fileline(), AstSenItem::Never()); AstSenItem* newp;
if (nodep->isClocked()) { // A constant can never get a pos/negexge
newp = new AstSenItem(nodep->fileline(), AstSenItem::Never());
} else { // Otherwise it may compute a result that needs to settle out
newp = new AstSenItem(nodep->fileline(), AstSenItem::Combo());
}
nodep->replaceWith(newp); nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL; nodep->deleteTree(); nodep=NULL;
} else if (nodep->sensp()->castNot()) { } else if (nodep->sensp()->castNot()) {
@@ -938,6 +943,63 @@ private:
} }
} }
virtual void visit(AstDisplay* nodep, AstNUser*) {
// Substitute constants into displays. The main point of this is to
// simplify assertion methodologies which call functions with display's.
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.
nodep->iterateChildren(*this);
bool anyconst = false;
for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) {
if (argp->castConst()) { anyconst=true; break; }
}
if (anyconst) {
//UINFO(9," Display in "<<nodep->text()<<endl);
string dispout = "";
string fmt = "";
bool inPct = false;
AstNode* argp = nodep->exprsp();
for (const char* inp = nodep->text().c_str(); *inp; inp++) {
char ch = *inp; // Breaks with iterators...
if (!inPct && ch=='%') {
inPct = true;
fmt = ch;
} else if (inPct && isdigit(ch)) {
fmt += ch;
} else if (inPct) {
inPct = false;
fmt += ch;
switch (tolower(ch)) {
case '%': break; // %% - just output a %
case 'm': break; // %m - auto insert "name"
default: // Most operators, just move to next argument
if (argp) {
AstNode* nextp=argp->nextp();
if (argp && argp->castConst()) { // Convert it
string out = argp->castConst()->num().displayed(fmt);
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
{ // fmt = out w/ replace % with %% as it must be literal.
fmt = "";
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
if (*pos == '%') fmt += '%';
fmt += *pos;
}
}
argp->unlinkFrBack()->deleteTree();
}
argp=nextp;
}
break;
} // switch
dispout += fmt;
} else {
dispout += ch;
}
}
nodep->text(dispout);
//UINFO(9," Display out "<<nodep->text()<<endl);
}
}
virtual void visit(AstWhile* nodep, AstNUser*) { virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
if (nodep->condp()->isZero()) { if (nodep->condp()->isZero()) {
@@ -1048,6 +1110,10 @@ private:
TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}");
@@ -1089,6 +1155,7 @@ private:
TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
@@ -1099,6 +1166,7 @@ private:
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqCase{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("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
///=== Verilog operators ///=== Verilog operators
+4 -3
View File
@@ -388,7 +388,7 @@ public:
} }
virtual void visit(AstMulS* nodep, AstNUser* vup) { virtual void visit(AstMulS* nodep, AstNUser* vup) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) { if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h\n"); nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h\n");
} }
visit(nodep->castNodeBiop(), vup); visit(nodep->castNodeBiop(), vup);
} }
@@ -1052,16 +1052,17 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
// Spec: h d o b c l // Spec: h d o b c l
case 'b': displayArg(nodep,&elistp,fmt,'b'); break; case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
case 'c': displayArg(nodep,&elistp,fmt,'c'); break; case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
case 't':
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
case 'o': displayArg(nodep,&elistp,fmt,'o'); break; case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
case 'h': case 'h':
case 'x': displayArg(nodep,&elistp,fmt,'x'); break; case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
case 's': displayArg(nodep,&elistp,fmt,'s'); break; case 's': displayArg(nodep,&elistp,fmt,'s'); break;
case 't': displayArg(nodep,&elistp,fmt,'u'); break;
case 'm': { case 'm': {
emitDispState.pushFormat("%s"); emitDispState.pushFormat("%s");
emitDispState.pushArg(NULL, "vlSymsp->name("); emitDispState.pushArg(NULL, "vlSymsp->name(");
for (AstText* textp=nodep->scopeTextp(); textp; textp=textp->nextp()->castText()) { if (!nodep->scopeNamep()) nodep->v3fatalSrc("Display with %m but no AstScopeName");
for (AstText* textp=nodep->scopeNamep()->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
emitDispState.pushFormat(textp->text()); emitDispState.pushFormat(textp->text());
} }
break; break;
+1 -1
View File
@@ -138,7 +138,7 @@ public:
of.puts("\n# Link rules...\n"); of.puts("\n# Link rules...\n");
of.puts(v3Global.opt.prefix()+": $(VK_USER_OBJS) $(SP_SRCS) $(VM_PREFIX)__ALL.a\n"); of.puts(v3Global.opt.prefix()+": $(VK_USER_OBJS) $(SP_SRCS) $(VM_PREFIX)__ALL.a\n");
of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt\n"); of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS) 2>&1 | c++filt\n");
of.puts("\n"); of.puts("\n");
} }
+2
View File
@@ -246,6 +246,8 @@ public:
virtual void visit(AstText* nodep, AstNUser*) { virtual void visit(AstText* nodep, AstNUser*) {
ofp()->putsNoTracking(nodep->text()); ofp()->putsNoTracking(nodep->text());
} }
virtual void visit(AstScopeName* nodep, AstNUser*) {
}
virtual void visit(AstCStmt* nodep, AstNUser*) { virtual void visit(AstCStmt* nodep, AstNUser*) {
putbs("$_CSTMT("); putbs("$_CSTMT(");
nodep->bodysp()->iterateAndNext(*this); nodep->bodysp()->iterateAndNext(*this);
+30 -7
View File
@@ -34,7 +34,8 @@
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret()); FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret());
int V3Error::s_errcnt = 0; int V3Error::s_errCount = 0;
int V3Error::s_warnCount = 0;
int V3Error::s_debugDefault = 0; int V3Error::s_debugDefault = 0;
ostringstream V3Error::s_errorStr; // Error string being formed ostringstream V3Error::s_errorStr; // Error string being formed
V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL; V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL;
@@ -187,25 +188,46 @@ string V3Error::lineStr (const char* filename, int lineno) {
return out.str(); return out.str();
} }
void V3Error::incWarnings() {
s_warnCount++;
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n");
}
}
void V3Error::incErrors() { void V3Error::incErrors() {
s_errcnt++; s_errCount++;
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n"); v3fatal ("Exiting due to too many errors encountered\n");
} }
} }
void V3Error::abortIfErrors() { void V3Error::abortIfErrors() {
if (errorCount()) { if (errorCount()) {
v3fatal ("Exiting due to "<<dec<<errorCount()<<" warning(s)\n"); v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
} }
} }
void V3Error::abortIfWarnings() {
if (errorOrWarnCount()) {
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
}
}
bool V3Error::isError(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return false;
else if (code==V3ErrorCode::FATAL) return true;
else if (code==V3ErrorCode::ERROR) return true;
else if (code<V3ErrorCode::FIRST_WARN
|| s_pretendError[code]) return true;
else return false;
}
string V3Error::msgPrefix(V3ErrorCode code) { string V3Error::msgPrefix(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: "; if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
else if (code==V3ErrorCode::FATAL) return "%Error: "; else if (code==V3ErrorCode::FATAL) return "%Error: ";
else if (code==V3ErrorCode::ERROR) return "%Error: "; else if (code==V3ErrorCode::ERROR) return "%Error: ";
else if (code<V3ErrorCode::FIRST_WARN else if (isError(code)) return "%Error-"+(string)code.ascii()+": ";
|| s_pretendError[code]) return "%Error-"+(string)code.ascii()+": ";
else return "%Warning-"+(string)code.ascii()+": "; else return "%Warning-"+(string)code.ascii()+": ";
} }
@@ -258,7 +280,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl; cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl;
} }
} }
incErrors(); if (isError(s_errorCode)) incErrors();
else incWarnings();
if (s_errorCode==V3ErrorCode::FATAL) { if (s_errorCode==V3ErrorCode::FATAL) {
static bool inFatal = false; static bool inFatal = false;
if (!inFatal) { if (!inFatal) {
+8 -2
View File
@@ -104,11 +104,13 @@ class V3Error {
static bool s_describedEachWarn[V3ErrorCode::MAX]; // Told user specifics about this warning static bool s_describedEachWarn[V3ErrorCode::MAX]; // Told user specifics about this warning
static bool s_pretendError[V3ErrorCode::MAX]; // Pretend this warning is an error static bool s_pretendError[V3ErrorCode::MAX]; // Pretend this warning is an error
static int s_debugDefault; // Default debugging level static int s_debugDefault; // Default debugging level
static int s_errcnt; // Error count static int s_errCount; // Error count
static int s_warnCount; // Error count
static ostringstream s_errorStr; // Error string being formed static ostringstream s_errorStr; // Error string being formed
static V3ErrorCode s_errorCode; // Error string being formed will abort static V3ErrorCode s_errorCode; // Error string being formed will abort
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
static void incErrors(); static void incErrors();
static void incWarnings();
V3Error() { cerr<<("Static class"); abort(); } V3Error() { cerr<<("Static class"); abort(); }
@@ -118,12 +120,16 @@ class V3Error {
static void debugDefault(int level) { s_debugDefault = level; } static void debugDefault(int level) { s_debugDefault = level; }
static int debugDefault() { return s_debugDefault; } static int debugDefault() { return s_debugDefault; }
static string msgPrefix(V3ErrorCode code=s_errorCode); // returns %Error/%Warn static string msgPrefix(V3ErrorCode code=s_errorCode); // returns %Error/%Warn
static int errorCount() { return s_errcnt; } static int errorCount() { return s_errCount; }
static int warnCount() { return s_warnCount; }
static int errorOrWarnCount() { return errorCount()+warnCount(); }
// METHODS // METHODS
static void init(); static void init();
static void abortIfErrors(); static void abortIfErrors();
static void abortIfWarnings();
static void suppressThisWarning(); // Suppress next %Warn if user has it off static void suppressThisWarning(); // Suppress next %Warn if user has it off
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; } static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
static bool isError(V3ErrorCode code);
static string v3sform (const char* format, ...); static string v3sform (const char* format, ...);
static string lineStr (const char* filename, int lineno); static string lineStr (const char* filename, int lineno);
static V3ErrorCode errorCode() { return s_errorCode; } static V3ErrorCode errorCode() { return s_errorCode; }
+2 -2
View File
@@ -233,10 +233,10 @@ private:
} }
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
virtual void visit(AstDisplay* nodep, AstNUser*) { virtual void visit(AstScopeName* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name() // If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Begin // Similar code in V3Begin
if (m_cellp && nodep->needScopeTracking()) { if (m_cellp) {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
+7 -7
View File
@@ -21,7 +21,7 @@
// LinkDot TRANSFORMATIONS: // LinkDot TRANSFORMATIONS:
// Top-down traversal // Top-down traversal
// Cells: // Cells:
// Make graph of cell hiearchy // Make graph of cell hierarchy
// Var/Funcs's: // Var/Funcs's:
// Collect all names into symtable under appropriate cell // Collect all names into symtable under appropriate cell
// Top-down traversal // Top-down traversal
@@ -180,7 +180,7 @@ private:
// TYPES // TYPES
typedef std::multimap<string,LinkDotCellVertex*> NameScopeMap; typedef std::multimap<string,LinkDotCellVertex*> NameScopeMap;
// MEMBERS // MEMBERS
LinkDotGraph m_graph; // Graph of hiearchy LinkDotGraph m_graph; // Graph of hierarchy
NameScopeMap m_nameScopeMap; // Hash of scope referenced by non-pretty textual name NameScopeMap m_nameScopeMap; // Hash of scope referenced by non-pretty textual name
bool m_forPrearray; // Compress cell__[array] refs bool m_forPrearray; // Compress cell__[array] refs
bool m_forScopeCreation; // Remove VarXRefs for V3Scope bool m_forScopeCreation; // Remove VarXRefs for V3Scope
@@ -277,7 +277,7 @@ private:
public: public:
LinkDotBaseVertex* findDotted(LinkDotBaseVertex* cellVxp, const string& dotname, LinkDotBaseVertex* findDotted(LinkDotBaseVertex* cellVxp, const string& dotname,
string& baddot, LinkDotBaseVertex*& okVxp) { string& baddot, LinkDotBaseVertex*& okVxp) {
// Given a dotted hiearchy name, return where in scope it is // Given a dotted hierarchy name, return where in scope it is
// Note when dotname=="" we just fall through and return cellVxp // Note when dotname=="" we just fall through and return cellVxp
UINFO(8," dottedFind "<<dotname<<endl); UINFO(8," dottedFind "<<dotname<<endl);
bool firstId = true; bool firstId = true;
@@ -520,8 +520,8 @@ private:
virtual void visit(AstScope* nodep, AstNUser*) { virtual void visit(AstScope* nodep, AstNUser*) {
UINFO(8," SCOPE "<<nodep<<endl); UINFO(8," SCOPE "<<nodep<<endl);
if (!m_statep->forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope"); if (!m_statep->forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope");
// Using the CELL names, we created all hiearchy. We now need to match this Scope // Using the CELL names, we created all hierarchy. We now need to match this Scope
// up with the hiearchy created by the CELL names. // up with the hierarchy created by the CELL names.
m_cellVxp = m_statep->findScope(nodep); m_cellVxp = m_statep->findScope(nodep);
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
m_cellVxp = NULL; m_cellVxp = NULL;
@@ -610,7 +610,7 @@ private:
UINFO(8," "<<nodep<<endl); UINFO(8," "<<nodep<<endl);
if (!m_cellVxp) { if (!m_cellVxp) {
UINFO(9,"Dead module for "<<nodep<<endl); UINFO(9,"Dead module for "<<nodep<<endl);
nodep->varp(NULL); // Module that is not in hiearchy. We'll be dead code eliminating it later. nodep->varp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later.
} else { } else {
string baddot; string baddot;
LinkDotBaseVertex* okVxp; LinkDotBaseVertex* okVxp;
@@ -657,7 +657,7 @@ private:
UINFO(8," "<<nodep<<endl); UINFO(8," "<<nodep<<endl);
if (!m_cellVxp) { if (!m_cellVxp) {
UINFO(9,"Dead module for "<<nodep<<endl); UINFO(9,"Dead module for "<<nodep<<endl);
nodep->taskp(NULL); // Module that is not in hiearchy. We'll be dead code eliminating it later. nodep->taskp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later.
} else { } else {
string baddot; string baddot;
LinkDotBaseVertex* okVxp; LinkDotBaseVertex* okVxp;
+4
View File
@@ -335,6 +335,10 @@ private:
|| nodep->displayType() == AstDisplayType::FATAL)) { || nodep->displayType() == AstDisplayType::FATAL)) {
nodep->v3error(nodep->verilogKwd()+" only allowed under a assertion."); nodep->v3error(nodep->verilogKwd()+" only allowed under a assertion.");
} }
if (nodep->displayType().needScopeTracking()
|| nodep->name().find("%m") != string::npos) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
}
} }
virtual void visit(AstScCtor* nodep, AstNUser*) { virtual void visit(AstScCtor* nodep, AstNUser*) {
+136 -27
View File
@@ -303,7 +303,7 @@ V3Number& V3Number::setMask(int nbits) {
} }
//====================================================================== //======================================================================
// ACCESSORS // ACCESSORS - as strings
string V3Number::ascii(bool prefixed, bool cleanVerilog) const { string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
ostringstream out; ostringstream out;
@@ -334,34 +334,115 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
if (binary) { if (binary) {
out<<"b"; out<<"b";
int bit=width()-1; out<<displayed("%0b");
while (bit && bitIs0(bit)) bit--;
for(; bit>=0; --bit) {
if (bitIs0(bit)) out<<'0';
else if (bitIs1(bit)) out<<'1';
else if (bitIsZ(bit)) out<<'z';
else out<<'x';
}
} }
else { else {
if (prefixed) out<<"h"; if (prefixed) out<<"h";
// Always deal with 4 bits at once. Note no 4-state, it's above. // Always deal with 4 bits at once. Note no 4-state, it's above.
int hexStart = width()-1; out<<displayed("%0h");
while (hexStart && bitIs0(hexStart)) hexStart--;
while ((hexStart&3)!=3) hexStart++;
for(int bit=hexStart; bit>0; ) {
int v = 0;
if (bitIs1(bit)) v |= 8; bit--;
if (bitIs1(bit)) v |= 4; bit--;
if (bitIs1(bit)) v |= 2; bit--;
if (bitIs1(bit)) v |= 1; bit--;
if (v>=10) out<<(char)('a'+v-10);
else out<<(char)('0'+v);
}
} }
return out.str(); return out.str();
} }
string V3Number::displayed(const string& vformat) const {
string::const_iterator pos = vformat.begin();
UASSERT(pos != vformat.end() && pos[0]=='%', "display with non format argument "<<*this);
pos++;
string fmtsize;
for (; pos != vformat.end() && isdigit(pos[0]); pos++) {
fmtsize += pos[0];
}
string str;
char code = tolower(pos[0]);
switch (code) {
case 'b': {
int bit = width()-1;
if (fmtsize == "0") while (bit && bitIs0(bit)) bit--;
for (; bit>=0; bit--) {
if (bitIs0(bit)) str+='0';
else if (bitIs1(bit)) str+='1';
else if (bitIsZ(bit)) str+='z';
else str+='x';
}
return str;
}
case 'o': {
int bit = width()-1;
if (fmtsize == "0") while (bit && bitIs0(bit)) bit--;
while ((bit%3)!=2) bit++;
for (; bit>0; bit -= 3) {
int v = bitsValue(bit-2, 3);
str += (char)('0'+v);
}
return str;
}
case 'h':
case 'x': {
int bit = width()-1;
if (fmtsize == "0") while (bit && bitIs0(bit)) bit--;
while ((bit%4)!=3) bit++;
for (; bit>0; bit -= 4) {
int v = bitsValue(bit-3, 4);
if (v>=10) str += (char)('a'+v-10);
else str += (char)('0'+v);
}
return str;
}
case 'c': {
if (this->width()>8) m_fileline->v3error("$display of char format of > 8 bit value");
int v = bitsValue(0, 8);
str += (char)(v);
return str;
}
case 's': {
// Spec says always drop leading zeros, this isn't quite right, we space pad.
int bit=this->width()-1;
bool start=true;
while ((bit%8)!=7) bit++;
for (; bit>=0; bit -= 8) {
int v = bitsValue(bit-7, 8);
if (!start || v) {
str += (char)((v==0)?' ':v);
start = false; // Drop leading 0s
} else {
if (fmtsize != "0") str += ' ';
}
}
return str;
}
case '~': // Signed decimal
case 't':
case 'd': { // Unsigned decimal
bool issigned = (code == '~');
if (fmtsize == "") {
double mantissabits = this->width() - (issigned?1:0);
double maxval = pow(2.0, mantissabits);
double dchars = log10(maxval)+1.0;
if (issigned) dchars++; // space for sign
fmtsize = cvtToStr(int(dchars));
}
if (width() > 64) {
m_fileline->v3error("Unsupported: $display of dec format of > 64 bit results (use hex format instead)");
return "ERR";
}
if (issigned) {
str = cvtToStr(asSQuad());
} else {
str = cvtToStr(asQuad());
}
int intfmtsize = atoi(fmtsize.c_str());
while ((int)(str.length()) < intfmtsize) str = " "+str;
return str;
}
default:
m_fileline->v3fatalSrc("Unknown $display format code for number: %"<<pos[0]);
return "ERR";
}
}
//======================================================================
// ACCESSORS - as numbers
uint32_t V3Number::asInt() const { uint32_t V3Number::asInt() const {
UASSERT(!isFourState(),"asInt with 4-state "<<*this); UASSERT(!isFourState(),"asInt with 4-state "<<*this);
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this); UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
@@ -369,18 +450,24 @@ uint32_t V3Number::asInt() const {
} }
vlsint32_t V3Number::asSInt() const { vlsint32_t V3Number::asSInt() const {
UASSERT(!isFourState(),"asSInt with 4-state "<<*this); uint32_t v = asInt();
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this); uint32_t signExtend = (-(v & (1UL<<(width()-1))));
uint32_t signExtend = (-((m_value[0]) & (1UL<<(width()-1)))); uint32_t extended = v | signExtend;
uint32_t extended = m_value[0] | signExtend;
return (vlsint32_t)(extended); return (vlsint32_t)(extended);
} }
vluint64_t V3Number::asQuad() const { vluint64_t V3Number::asQuad() const {
UASSERT(!isFourState(),"asQuad with 4-state "<<*this); UASSERT(!isFourState(),"asQuad with 4-state "<<*this);
UASSERT(width()<65, "Value too wide "<<*this); UASSERT(width()<65, "Value too wide "<<*this);
if (width()<=32) return ((vluint64_t)m_value[0]); if (width()<=32) return ((vluint64_t)(asInt()));
else return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]); return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
}
vlsint64_t V3Number::asSQuad() const {
vluint64_t v = asQuad();
vluint64_t signExtend = (-(v & (VL_ULL(1)<<(width()-1))));
vluint64_t extended = v | signExtend;
return (vlsint64_t)(extended);
} }
uint32_t V3Number::asHash() const { uint32_t V3Number::asHash() const {
@@ -727,6 +814,28 @@ last:
return setSingleBits(outc); return setSingleBits(outc);
} }
V3Number& V3Number::opWildEq (const V3Number& lhs, const V3Number& rhs) {
char outc = 1;
for (int bit=0; bit<max(lhs.width(),rhs.width()); bit++) {
if (!rhs.bitIsXZ(bit)
&& lhs.bitIs(bit) != rhs.bitIs(bit)) { outc=0; goto last; }
if (lhs.bitIsXZ(bit)) outc='x';
}
last:
return setSingleBits(outc);
}
V3Number& V3Number::opWildNeq (const V3Number& lhs, const V3Number& rhs) {
char outc = 0;
for (int bit=0; bit<max(lhs.width(),rhs.width()); bit++) {
if (!rhs.bitIsXZ(bit)
&& lhs.bitIs(bit) != rhs.bitIs(bit)) { outc=1; goto last; }
if (lhs.bitIsXZ(bit)) outc='x';
}
last:
return setSingleBits(outc);
}
V3Number& V3Number::opGt (const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opGt (const V3Number& lhs, const V3Number& rhs) {
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend. // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
char outc = 0; char outc = 0;
+10
View File
@@ -94,6 +94,12 @@ private:
bool bitIsZ (int bit) const { bool bitIsZ (int bit) const {
if (bit>=m_width) return bitIsZ(m_width-1); if (bit>=m_width) return bitIsZ(m_width-1);
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); } return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
uint32_t bitsValue(int lsb, int nbits) const {
uint32_t v=0;
for (int bitn=0; bitn<nbits; bitn++) { v |= (bitIs1(lsb+bitn)<<bitn); }
return v;
}
int words() const { return ((width()+31)/32); } int words() const { return ((width()+31)/32); }
public: public:
@@ -112,6 +118,7 @@ public:
// ACCESSORS // ACCESSORS
string ascii(bool prefixed=true, bool cleanVerilog=false) const; string ascii(bool prefixed=true, bool cleanVerilog=false) const;
string displayed(const string& format) const;
int width() const { return m_width; } int width() const { return m_width; }
int minWidth() const; // Minimum width that can represent this number (~== log2(num)+1) int minWidth() const; // Minimum width that can represent this number (~== log2(num)+1)
bool sized() const { return m_sized; } bool sized() const { return m_sized; }
@@ -129,6 +136,7 @@ public:
uint32_t asInt() const; uint32_t asInt() const;
vlsint32_t asSInt() const; vlsint32_t asSInt() const;
vluint64_t asQuad() const; vluint64_t asQuad() const;
vlsint64_t asSQuad() const;
uint32_t asHash() const; uint32_t asHash() const;
uint32_t dataWord(int word) const; uint32_t dataWord(int word) const;
uint32_t countOnes() const; uint32_t countOnes() const;
@@ -166,6 +174,8 @@ public:
V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs); V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs);
V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs);
V3Number& opWildEq (const V3Number& lhs, const V3Number& rhs);
V3Number& opWildNeq (const V3Number& lhs, const V3Number& rhs);
// "standard" math // "standard" math
V3Number& opNot (const V3Number& lhs); V3Number& opNot (const V3Number& lhs);
V3Number& opLogNot (const V3Number& lhs); V3Number& opLogNot (const V3Number& lhs);
+3
View File
@@ -65,7 +65,10 @@ void test(string lhss, string op, string rhss, string exps) {
else if (op=="<<") gotnum.opShiftL (lhnum,rhnum); else if (op=="<<") gotnum.opShiftL (lhnum,rhnum);
else if (op=="==") gotnum.opEq (lhnum,rhnum); else if (op=="==") gotnum.opEq (lhnum,rhnum);
else if (op=="===") gotnum.opCaseEq (lhnum,rhnum); else if (op=="===") gotnum.opCaseEq (lhnum,rhnum);
else if (op=="==?") gotnum.opWildEq (lhnum,rhnum);
else if (op=="!=") gotnum.opNeq (lhnum,rhnum); else if (op=="!=") gotnum.opNeq (lhnum,rhnum);
else if (op=="!==") gotnum.opCaseNeq (lhnum,rhnum);
else if (op=="!=?") gotnum.opWildNeq (lhnum,rhnum);
else if (op=="<=") gotnum.opLte (lhnum,rhnum); else if (op=="<=") gotnum.opLte (lhnum,rhnum);
else if (op==">=") gotnum.opGte (lhnum,rhnum); else if (op==">=") gotnum.opGte (lhnum,rhnum);
else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum); else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum);
+1
View File
@@ -40,6 +40,7 @@
#define VP_DEFINE 261 #define VP_DEFINE 261
#define VP_ELSE 262 #define VP_ELSE 262
#define VP_ELSIF 263 #define VP_ELSIF 263
#define VP_LINE 264
#define VP_SYMBOL 300 #define VP_SYMBOL 300
#define VP_STRING 301 #define VP_STRING 301
+17 -2
View File
@@ -57,6 +57,9 @@ static void pslMoreNeeded(bool flag) { V3PreLex::s_currentLexp->m_pslMoreNeeded
%x DEFMODE %x DEFMODE
%x ARGMODE %x ARGMODE
%x INCMODE %x INCMODE
%x PRTMODE
/* drop: Drop Ctrl-Z - can't pass thru or may EOF the output too soon */
ws [ \t\f\r] ws [ \t\f\r]
wsn [ \t\f] wsn [ \t\f]
@@ -64,12 +67,14 @@ crnl [\r]*[\n]
quote [\"] quote [\"]
backslash [\\] backslash [\\]
symb [a-zA-Z_][a-zA-Z0-9_$]* symb [a-zA-Z_][a-zA-Z0-9_$]*
drop [\032]
psl [p]sl psl [p]sl
/**************************************************************/ /**************************************************************/
%% %%
<INITIAL>^{ws}*"`line"{ws}+.*{crnl} { V3PreLex::s_currentLexp->lineDirective(yytext); } <INITIAL>^{ws}*"`line"{ws}+.*{crnl} { V3PreLex::s_currentLexp->lineDirective(yytext);
return(VP_LINE); }
/* Special directives we recognise */ /* Special directives we recognise */
<INITIAL>"`include" { return(VP_INCLUDE); } <INITIAL>"`include" { return(VP_INCLUDE); }
@@ -103,6 +108,13 @@ psl [p]sl
if (V3PreLex::s_currentLexp->m_parenLevel) appendDefValue(yytext,yyleng); if (V3PreLex::s_currentLexp->m_parenLevel) appendDefValue(yytext,yyleng);
else return (VP_STRING); } else return (VP_STRING); }
/* Protected blocks */
<INITIAL>"`protected" { yy_push_state(PRTMODE); yymore(); }
<PRTMODE><<EOF>> { linenoInc(); yyerror("EOF in `protected"); yyleng=0; yyterminate(); }
<PRTMODE>{crnl} { linenoInc(); yymore(); }
<PRTMODE>. { yymore(); }
<PRTMODE>"`endprotected" { yy_pop_state(); return (VP_TEXT); }
/* Pass-through include <> filenames */ /* Pass-through include <> filenames */
<INCMODE><<EOF>> { linenoInc(); yyerror("EOF in unterminated include filename"); yyleng=0; yyterminate(); } <INCMODE><<EOF>> { linenoInc(); yyerror("EOF in unterminated include filename"); yyleng=0; yyterminate(); }
<INCMODE>{crnl} { linenoInc(); yyerror("Unterminated include filename"); BEGIN(INITIAL); } <INCMODE>{crnl} { linenoInc(); yyerror("Unterminated include filename"); BEGIN(INITIAL); }
@@ -113,6 +125,7 @@ psl [p]sl
/* Reading definition */ /* Reading definition */
<DEFMODE>"/*" { yy_push_state(CMTMODE); yymore(); } <DEFMODE>"/*" { yy_push_state(CMTMODE); yymore(); }
<DEFMODE>"//"[^\n\r]* { return (VP_COMMENT);} <DEFMODE>"//"[^\n\r]* { return (VP_COMMENT);}
<DEFMODE>{drop} { }
<DEFMODE><<EOF>> { linenoInc(); yyerror("EOF (missing return?) in define value"); yyleng=0; yyterminate(); } <DEFMODE><<EOF>> { linenoInc(); yyerror("EOF (missing return?) in define value"); yyleng=0; yyterminate(); }
<DEFMODE>{crnl} { linenoInc(); yy_pop_state(); yytext="\n"; yyleng=1; return (VP_DEFVALUE); } <DEFMODE>{crnl} { linenoInc(); yy_pop_state(); yytext="\n"; yyleng=1; return (VP_DEFVALUE); }
<DEFMODE>[\\]{crnl} { linenoInc(); appendDefValue("\n",1); } /* Include return so can maintain output line count */ <DEFMODE>[\\]{crnl} { linenoInc(); appendDefValue("\n",1); } /* Include return so can maintain output line count */
@@ -123,6 +136,7 @@ psl [p]sl
/* Define arguments */ /* Define arguments */
<ARGMODE>"/*" { yy_push_state(CMTMODE); yymore(); } <ARGMODE>"/*" { yy_push_state(CMTMODE); yymore(); }
<ARGMODE>"//"[^\n\r]* { return (VP_COMMENT);} <ARGMODE>"//"[^\n\r]* { return (VP_COMMENT);}
<ARGMODE>{drop} { }
<ARGMODE><<EOF>> { yyerror("EOF in define argument list\n"); yyleng = 0; yyterminate(); } <ARGMODE><<EOF>> { yyerror("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
<ARGMODE>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); } <ARGMODE>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
<ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); } <ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); }
@@ -179,8 +193,9 @@ psl [p]sl
/* Generics */ /* Generics */
<INITIAL,PSLMULM>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); } <INITIAL,PSLMULM>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM>{symb} { return (VP_SYMBOL); } <INITIAL,PSLMULM,PSLONEM>{symb} { return (VP_SYMBOL); }
<INITIAL,PSLMULM,PSLONEM>[\r] { }
<INITIAL,PSLMULM,PSLONEM>{wsn}+ { return (VP_WHITE); } <INITIAL,PSLMULM,PSLONEM>{wsn}+ { return (VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM>{drop} { }
<INITIAL,PSLMULM,PSLONEM>[\r] { }
<INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); } <INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); }
%% %%
+39 -6
View File
@@ -83,7 +83,9 @@ struct V3PreProcImp : public V3PreProc {
// For getRawToken/ `line insertion // For getRawToken/ `line insertion
string m_lineCmt; // Line comment(s) to be returned string m_lineCmt; // Line comment(s) to be returned
int m_lineAdd; // Empty lines to return to maintain line count bool m_lineCmtNl; ///< Newline needed before inserting lineCmt
int m_lineAdd; ///< Empty lines to return to maintain line count
bool m_rawAtBol; ///< Last rawToken left us at beginning of line
// For defines // For defines
string m_defName; // Define last name being defined string m_defName; // Define last name being defined
@@ -134,6 +136,7 @@ public:
virtual bool isEof() const { return (m_lexp==NULL); } virtual bool isEof() const { return (m_lexp==NULL); }
virtual string getline(); virtual string getline();
virtual void insertUnreadback(const string& text) { m_lineCmt += text; } virtual void insertUnreadback(const string& text) { m_lineCmt += text; }
void insertUnreadbackAtBol(const string& text);
// METHODS, callbacks // METHODS, callbacks
virtual void comment(const string& cmt); // Comment detected (if keepComments==2) virtual void comment(const string& cmt); // Comment detected (if keepComments==2)
@@ -151,6 +154,8 @@ public:
m_lineChars = ""; m_lineChars = "";
m_lastSym = ""; m_lastSym = "";
m_lineAdd = 0; m_lineAdd = 0;
m_lineCmtNl = false;
m_rawAtBol = true;
m_defDepth = 0; m_defDepth = 0;
} }
}; };
@@ -328,6 +333,7 @@ const char* V3PreProcImp::tokenName(int tok) {
case VP_DEFINE : return("DEFINE"); case VP_DEFINE : return("DEFINE");
case VP_ELSE : return("ELSE"); case VP_ELSE : return("ELSE");
case VP_ELSIF : return("ELSIF"); case VP_ELSIF : return("ELSIF");
case VP_LINE : return("LINE");
case VP_SYMBOL : return("SYMBOL"); case VP_SYMBOL : return("SYMBOL");
case VP_STRING : return("STRING"); case VP_STRING : return("STRING");
case VP_DEFVALUE : return("DEFVALUE"); case VP_DEFVALUE : return("DEFVALUE");
@@ -485,14 +491,24 @@ void V3PreProcImp::openFile(FileLine* fl, const string& filename) {
yy_switch_to_buffer(m_lexp->m_yyState); yy_switch_to_buffer(m_lexp->m_yyState);
} }
void V3PreProcImp::insertUnreadbackAtBol(const string& text) {
// Insert insuring we're at the beginning of line, for `line
// We don't always add a leading newline, as it may result in extra unreadback(newlines).
if (m_lineCmt == "") { m_lineCmtNl = true; }
else if (m_lineCmt[m_lineCmt.length()-1]!='\n') {
insertUnreadback("\n");
}
insertUnreadback(text);
}
void V3PreProcImp::addLineComment(int enter_exit_level) { void V3PreProcImp::addLineComment(int enter_exit_level) {
if (lineDirectives()) { if (lineDirectives()) {
char numbuf[20]; sprintf(numbuf, "%d", m_lexp->m_curFilelinep->lineno()); char numbuf[20]; sprintf(numbuf, "%d", m_lexp->m_curFilelinep->lineno());
char levelbuf[20]; sprintf(levelbuf, "%d", enter_exit_level); char levelbuf[20]; sprintf(levelbuf, "%d", enter_exit_level);
string cmt = ((string)"\n`line "+numbuf string cmt = ((string)"`line "+numbuf
+" \""+m_lexp->m_curFilelinep->filename()+"\" " +" \""+m_lexp->m_curFilelinep->filename()+"\" "
+levelbuf+"\n"); +levelbuf+"\n");
insertUnreadback(cmt); insertUnreadbackAtBol(cmt);
} }
} }
@@ -516,6 +532,7 @@ int V3PreProcImp::getRawToken() {
next_tok: next_tok:
if (m_lineAdd) { if (m_lineAdd) {
m_lineAdd--; m_lineAdd--;
m_rawAtBol = true;
yytext="\n"; yyleng=1; yytext="\n"; yyleng=1;
return (VP_TEXT); return (VP_TEXT);
} }
@@ -523,8 +540,13 @@ int V3PreProcImp::getRawToken() {
// We have some `line directive to return to the user. Do it. // We have some `line directive to return to the user. Do it.
static string rtncmt; // Keep the c string till next call static string rtncmt; // Keep the c string till next call
rtncmt = m_lineCmt; rtncmt = m_lineCmt;
if (m_lineCmtNl) {
if (!m_rawAtBol) rtncmt = "\n"+rtncmt;
m_lineCmtNl = false;
}
yytext=(char*)rtncmt.c_str(); yyleng=rtncmt.length(); yytext=(char*)rtncmt.c_str(); yyleng=rtncmt.length();
m_lineCmt = ""; m_lineCmt = "";
if (yyleng) m_rawAtBol = (yytext[yyleng-1]=='\n');
if (m_state!=ps_DEFVALUE) return (VP_TEXT); if (m_state!=ps_DEFVALUE) return (VP_TEXT);
else { else {
V3PreLex::s_currentLexp->appendDefValue(yytext,yyleng); V3PreLex::s_currentLexp->appendDefValue(yytext,yyleng);
@@ -532,6 +554,7 @@ int V3PreProcImp::getRawToken() {
} }
} }
if (isEof()) return (VP_EOF); if (isEof()) return (VP_EOF);
// Snarf next token from the file // Snarf next token from the file
m_fileline = m_lexp->m_curFilelinep; // Remember token start location m_fileline = m_lexp->m_curFilelinep; // Remember token start location
V3PreLex::s_currentLexp = m_lexp; // Tell parser where to get/put data V3PreLex::s_currentLexp = m_lexp; // Tell parser where to get/put data
@@ -552,6 +575,7 @@ int V3PreProcImp::getRawToken() {
goto next_tok; // Parse parent, or find the EOF. goto next_tok; // Parse parent, or find the EOF.
} }
if (yyleng) m_rawAtBol = (yytext[yyleng-1]=='\n');
return tok; return tok;
} }
} }
@@ -583,6 +607,10 @@ int V3PreProcImp::getToken() {
for (int len=0; len<yyleng; len++) { if (yytext[len]=='\n') m_lineAdd++; } for (int len=0; len<yyleng; len++) { if (yytext[len]=='\n') m_lineAdd++; }
goto next_tok; goto next_tok;
} }
if (tok==VP_LINE) {
addLineComment(0);
goto next_tok;
}
// Deal with some special parser states // Deal with some special parser states
switch (m_state) { switch (m_state) {
case ps_TOP: { case ps_TOP: {
@@ -867,7 +895,8 @@ string V3PreProcImp::getline() {
// Get a single line from the parse stream. Buffer unreturned text until the newline. // Get a single line from the parse stream. Buffer unreturned text until the newline.
if (isEof()) return ""; if (isEof()) return "";
char* rtnp; char* rtnp;
while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n'))) { bool gotEof = false;
while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')) && !gotEof) {
int tok = getToken(); int tok = getToken();
if (debug()>4) { if (debug()>4) {
string buf = string (yytext, yyleng); string buf = string (yytext, yyleng);
@@ -878,8 +907,12 @@ string V3PreProcImp::getline() {
fileline()->lineno(), tokenName(tok), buf.c_str()); fileline()->lineno(), tokenName(tok), buf.c_str());
} }
if (tok==VP_EOF) { if (tok==VP_EOF) {
// Add a final newline, in case the user forgot the final \n. // Add a final newline, if the user forgot the final \n.
m_lineChars.append("\n"); // Note tok==VP_EOF isn't always seen by us, as isEof() may be set earlier
if (m_lineChars != "" && m_lineChars[m_lineChars.length()-1] != '\n') {
m_lineChars.append("\n");
}
gotEof = true;
} }
else if (tok==VP_PSL) { else if (tok==VP_PSL) {
m_lineChars.append(" psl "); m_lineChars.append(" psl ");
-6
View File
@@ -61,12 +61,6 @@ protected:
s_preprocp->define(prefl,"verilator3", "1"); s_preprocp->define(prefl,"verilator3", "1");
s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/"); s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/");
s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/");
// Standards - We ignore
s_preprocp->define(prefl,"endcelldefine", "");
s_preprocp->define(prefl,"celldefine", "");
s_preprocp->define(prefl,"resetall", "");
s_preprocp->define(prefl,"portcoerce", "");
s_preprocp->define(prefl,"inline", "");
} }
} }
+5 -1
View File
@@ -38,7 +38,8 @@ class V3Read {
V3Lexer* m_lexerp; // Current FlexLexer V3Lexer* m_lexerp; // Current FlexLexer
static V3Read* s_readp; // Current THIS, bison() isn't class based static V3Read* s_readp; // Current THIS, bison() isn't class based
FileLine* m_fileline; // Filename/linenumber currently active FileLine* m_fileline; // Filename/linenumber currently active
bool m_inLibrary; // Currently reading a library vs. regular file bool m_inCellDefine; // Inside a `celldefine
bool m_inLibrary; // Currently reading a library vs. regular file
int m_inBeginKwd; // Inside a `begin_keywords int m_inBeginKwd; // Inside a `begin_keywords
int m_lastVerilogState; // Last LEX state in `begin_keywords int m_lastVerilogState; // Last LEX state in `begin_keywords
deque<string*> m_stringps; // Created strings for later cleanup deque<string*> m_stringps; // Created strings for later cleanup
@@ -92,6 +93,8 @@ public: // But for internal use only
static FileLine* fileline() { return s_readp->m_fileline; } static FileLine* fileline() { return s_readp->m_fileline; }
static AstNetlist* rootp() { return s_readp->m_rootp; } static AstNetlist* rootp() { return s_readp->m_rootp; }
static FileLine* copyOrSameFileLine() { return s_readp->fileline()->copyOrSameFileLine(); } static FileLine* copyOrSameFileLine() { return s_readp->fileline()->copyOrSameFileLine(); }
static bool inCellDefine() { return s_readp->m_inCellDefine; }
static void inCellDefine(bool flag) { s_readp->m_inCellDefine = flag; }
static bool inLibrary() { return s_readp->m_inLibrary; } static bool inLibrary() { return s_readp->m_inLibrary; }
static void stateExitPsl(); // Parser -> lexer communication static void stateExitPsl(); // Parser -> lexer communication
static void statePushVlg(); // Parser -> lexer communication static void statePushVlg(); // Parser -> lexer communication
@@ -102,6 +105,7 @@ public:
// CREATORS // CREATORS
V3Read(AstNetlist* rootp) { V3Read(AstNetlist* rootp) {
m_rootp = rootp; m_lexerp = NULL; m_rootp = rootp; m_lexerp = NULL;
m_inCellDefine = false;
m_inLibrary = false; m_inLibrary = false;
m_inBeginKwd = 0; m_inBeginKwd = 0;
m_lastVerilogState = stateVerilogRecent(); m_lastVerilogState = stateVerilogRecent();
+10 -12
View File
@@ -198,19 +198,17 @@ private:
nodep->taskp(NULL); nodep->taskp(NULL);
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
virtual void visit(AstDisplay* nodep, AstNUser*) { virtual void visit(AstScopeName* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name() // If there's a %m in the display text, we add a special node that will contain the name()
if (nodep->name().find("%m") != string::npos) { string prefix = (string)(".")+m_scopep->prettyName();
string prefix = (string)(".")+m_scopep->prettyName(); // TOP and above will be the user's name().
// TOP and above will be the user's name(). // Note 'TOP.'is stripped by prettyName, but not 'TOP'.
// Note 'TOP.'is stripped by prettyName, but not 'TOP'. if (prefix != ".TOP") {
if (prefix != ".TOP") { // To keep correct visual order, must add before other Text's
// To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp();
AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext();
if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeAttrp(afterp);
if (afterp) nodep->scopeAttrp(afterp);
}
} }
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
+2
View File
@@ -98,8 +98,10 @@ private:
// ... (Though they should match. We don't check.) // ... (Though they should match. We don't check.)
virtual void visit(AstEq* nodep, AstNUser*) { signed_Ou_Ix(nodep); } virtual void visit(AstEq* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstEqCase* nodep, AstNUser*) { signed_Ou_Ix(nodep); } virtual void visit(AstEqCase* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstEqWild* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstNeq* nodep, AstNUser*) { signed_Ou_Ix(nodep); } virtual void visit(AstNeq* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstNeqCase* nodep, AstNUser*){ signed_Ou_Ix(nodep); } virtual void visit(AstNeqCase* nodep, AstNUser*){ signed_Ou_Ix(nodep); }
virtual void visit(AstNeqWild* nodep, AstNUser*){ signed_Ou_Ix(nodep); }
//======= //=======
// Signed: Output signed iff LHS signed; unary operator // Signed: Output signed iff LHS signed; unary operator
+42
View File
@@ -106,6 +106,42 @@ private:
newp->iterateChildren(*this); newp->iterateChildren(*this);
} }
} }
void visitEqNeqWild(AstNodeBiop* nodep) {
UINFO(4," N/EQWILD->EQ "<<nodep<<endl);
V3Const::constifyTree(nodep->lhsp());
V3Const::constifyTree(nodep->rhsp());
if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
// Both sides are constant, node can be constant
V3Const::constifyTree(nodep); nodep=NULL;
return;
} else {
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* newp;
if (!rhsp->castConst()) {
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
// Replace with anything that won't cause more errors
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
} else {
// X or Z's become mask, ala case statements.
V3Number nummask (rhsp->fileline(), rhsp->width());
nummask.opBitsNonX(rhsp->castConst()->num());
V3Number numval (rhsp->fileline(), rhsp->width());
numval.opBitsOne (rhsp->castConst()->num());
AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
new AstConst(nodep->fileline(), nummask));
AstNode* and2p = new AstConst(nodep->fileline(), numval);
if (nodep->castEqWild())
newp = new AstEq (nodep->fileline(), and1p, and2p);
else newp = new AstNeq (nodep->fileline(), and1p, and2p);
rhsp->deleteTree(); rhsp=NULL;
}
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
// Iterate tree now that we may have gotten rid of the compare
newp->iterateChildren(*this);
}
}
virtual void visit(AstEqCase* nodep, AstNUser*) { virtual void visit(AstEqCase* nodep, AstNUser*) {
visitEqNeqCase(nodep); visitEqNeqCase(nodep);
@@ -113,6 +149,12 @@ private:
virtual void visit(AstNeqCase* nodep, AstNUser*) { virtual void visit(AstNeqCase* nodep, AstNUser*) {
visitEqNeqCase(nodep); visitEqNeqCase(nodep);
} }
virtual void visit(AstEqWild* nodep, AstNUser*) {
visitEqNeqWild(nodep);
}
virtual void visit(AstNeqWild* nodep, AstNUser*) {
visitEqNeqWild(nodep);
}
virtual void visit(AstIsUnknown* nodep, AstNUser*) { virtual void visit(AstIsUnknown* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
// Ahh, we're two state, so this is easy // Ahh, we're two state, so this is easy
+5
View File
@@ -117,6 +117,7 @@ private:
void width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup); void width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup);
virtual void visit(AstEq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstEq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstEqCase* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstEqCase* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstEqWild* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstGt* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstGt* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstGtS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstGtS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstGte* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstGte* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
@@ -127,6 +128,7 @@ private:
virtual void visit(AstLteS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstLteS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstNeq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstNeq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstNeqCase* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstNeqCase* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstNeqWild* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); }
// Widths: out width = lhs width = rhs width // Widths: out width = lhs width = rhs width
void width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup); void width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup);
@@ -385,6 +387,9 @@ private:
virtual void visit(AstText* nodep, AstNUser* vup) { virtual void visit(AstText* nodep, AstNUser* vup) {
// Only used in CStmts which don't care.... // Only used in CStmts which don't care....
} }
virtual void visit(AstScopeName* nodep, AstNUser* vup) {
// Only used in Displays which don't care....
}
virtual void visit(AstVar* nodep, AstNUser* vup) { virtual void visit(AstVar* nodep, AstNUser* vup) {
//if (debug()) nodep->dumpTree(cout," InitPre: "); //if (debug()) nodep->dumpTree(cout," InitPre: ");
// Must have deterministic constant width // Must have deterministic constant width
+1 -1
View File
@@ -538,7 +538,7 @@ int main(int argc, char** argv, char** env) {
// Final steps // Final steps
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",99)); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",99));
V3Error::abortIfErrors(); V3Error::abortIfWarnings();
if (!v3Global.opt.lintOnly() && v3Global.opt.makeDepend()) { if (!v3Global.opt.lintOnly() && v3Global.opt.makeDepend()) {
V3File::writeDepend(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__ver.d"); V3File::writeDepend(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__ver.d");
+2 -2
View File
@@ -4,7 +4,7 @@
// //
// This file is part of Verilator. // This file is part of Verilator.
// //
// Author: Wilson Snyder <[email protected]> or <[email protected]> // Author: Wilson Snyder <[email protected]>
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.com/verilator
// //
@@ -24,7 +24,7 @@
//********************************************************************** //**********************************************************************
//**** Version and host name //**** Version and host name
#define DTVERSION "Verilator 3.650 4/20/2007" #define DTVERSION "Verilator 3.653 8/1/2007"
//********************************************************************** //**********************************************************************
//**** Functions //**** Functions
+5 -1
View File
@@ -19,7 +19,7 @@
# #
###################################################################### ######################################################################
# DESCRIPTION: Edits flex output to get around Redhat 8.0 broken flex. # DESCRIPTION: Edits flex output to get around various broken flex issues.
foreach my $line (<STDIN>) { foreach my $line (<STDIN>) {
# Fix flex 2.5.4 namespace omission # Fix flex 2.5.4 namespace omission
@@ -28,5 +28,9 @@ foreach my $line (<STDIN>) {
$line =~ s!(\#define\s+yyFlexLexer\s+yyFlexLexer)!//flexfix: $1!g; $line =~ s!(\#define\s+yyFlexLexer\s+yyFlexLexer)!//flexfix: $1!g;
# Fix flex 2.5.1 yytext_ptr undef # Fix flex 2.5.1 yytext_ptr undef
$line =~ s!(\#undef\s+yytext_ptr)!//flexfix: $1!g; $line =~ s!(\#undef\s+yytext_ptr)!//flexfix: $1!g;
# Fix flex 2.5.4 and GCC 4.1.0 warn_unused_result
$line =~ s!\(void\) *fwrite\((.*)\)!if (fwrite($1)) {}!g;
# Fix flex 2.5.33 and GCC 4.1.2 "warning: comparison between signed and unsigned integer expressions" in YY_INPUT
$line =~ s!for \( n = 0; n < max_size && !for ( n = 0; ((size_t)n < (size_t)max_size) && !g;
print "$line"; print "$line";
} }
+131 -106
View File
@@ -104,11 +104,12 @@ void yyerrorf(const char* format, ...) {
%o 25000 %o 25000
%s V95 V01 V05 S05 %s V95 V01 V05 S05
%s PSL STRING %s PSL STRING ATTRMODE
%s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR %s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR
%s IGNORE %s IGNORE
ws [ \t\f\r]+ ws [ \t\f\r]+
wsnr [ \t\f]+
/* identifier */ /* identifier */
id [a-zA-Z_][a-zA-Z0-9_$]* id [a-zA-Z_][a-zA-Z0-9_$]*
/* escaped identifier */ /* escaped identifier */
@@ -130,38 +131,39 @@ escid \\[^ \t\f\r\n]+
"$fdisplay" {yylval.fileline = CRELINE(); return yD_FDISPLAY;} "$fdisplay" {yylval.fileline = CRELINE(); return yD_FDISPLAY;}
"$finish" {yylval.fileline = CRELINE(); return yD_FINISH;} "$finish" {yylval.fileline = CRELINE(); return yD_FINISH;}
"$fopen" {yylval.fileline = CRELINE(); return yD_FOPEN;} "$fopen" {yylval.fileline = CRELINE(); return yD_FOPEN;}
"$fullskew" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$fullskew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$fwrite" {yylval.fileline = CRELINE(); return yD_FWRITE;} "$fwrite" {yylval.fileline = CRELINE(); return yD_FWRITE;}
"$hold" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$hold" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$nochange" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$nochange" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$period" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$period" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$readmemb" {yylval.fileline = CRELINE(); return yD_READMEMB;} "$readmemb" {yylval.fileline = CRELINE(); return yD_READMEMB;}
"$readmemh" {yylval.fileline = CRELINE(); return yD_READMEMH;} "$readmemh" {yylval.fileline = CRELINE(); return yD_READMEMH;}
"$realtime" {yylval.fileline = CRELINE(); return yD_TIME;} "$realtime" {yylval.fileline = CRELINE(); return yD_TIME;}
"$recovery" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$recovery" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$recrem" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$recrem" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$removal" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$removal" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$setup" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$setup" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$setuphold" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$setuphold" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$skew" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$skew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$stop" {yylval.fileline = CRELINE(); return yD_STOP;} "$stop" {yylval.fileline = CRELINE(); return yD_STOP;}
"$time" {yylval.fileline = CRELINE(); return yD_TIME;} "$time" {yylval.fileline = CRELINE(); return yD_TIME;}
"$timeskew" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$timeskew" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$width" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "$width" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"$write" {yylval.fileline = CRELINE(); return yD_WRITE;} "$write" {yylval.fileline = CRELINE(); return yD_WRITE;}
/* Keywords */ /* Keywords */
"always" {yylval.fileline = CRELINE(); return yALWAYS;} "always" {yylval.fileline = CRELINE(); return yALWAYS;}
"and" {yylval.fileline = CRELINE(); return yAND;} "and" {yylval.fileline = CRELINE(); return yAND;}
"assign" {yylval.fileline = CRELINE(); return yASSIGN;} "assign" {yylval.fileline = CRELINE(); return yASSIGN;}
"begin" {yylval.fileline = CRELINE(); return yBBEGIN;} "begin" {yylval.fileline = CRELINE(); return yBEGIN;}
"buf" {yylval.fileline = CRELINE(); return yBUF;} "buf" {yylval.fileline = CRELINE(); return yBUF;}
"case" {yylval.fileline = CRELINE(); return yCASE;} "case" {yylval.fileline = CRELINE(); return yCASE;}
"casex" {yylval.fileline = CRELINE(); return yCASEX;} "casex" {yylval.fileline = CRELINE(); return yCASEX;}
"casez" {yylval.fileline = CRELINE(); return yCASEZ;} "casez" {yylval.fileline = CRELINE(); return yCASEZ;}
"default" {yylval.fileline = CRELINE(); return yDEFAULT;} "default" {yylval.fileline = CRELINE(); return yDEFAULT;}
"defparam" {yylval.fileline = CRELINE(); return yDEFPARAM;} "defparam" {yylval.fileline = CRELINE(); return yDEFPARAM;}
"edge" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"else" {yylval.fileline = CRELINE(); return yELSE;} "else" {yylval.fileline = CRELINE(); return yELSE;}
"end" {yylval.fileline = CRELINE(); return yBEND;} "end" {yylval.fileline = CRELINE(); return yEND;}
"endcase" {yylval.fileline = CRELINE(); return yENDCASE;} "endcase" {yylval.fileline = CRELINE(); return yENDCASE;}
"endfunction" {yylval.fileline = CRELINE(); return yENDFUNCTION;} "endfunction" {yylval.fileline = CRELINE(); return yENDFUNCTION;}
"endmodule" {yylval.fileline = CRELINE(); return yENDMODULE;} "endmodule" {yylval.fileline = CRELINE(); return yENDMODULE;}
@@ -182,12 +184,12 @@ escid \\[^ \t\f\r\n]+
"not" {yylval.fileline = CRELINE(); return yNOT;} "not" {yylval.fileline = CRELINE(); return yNOT;}
"or" {yylval.fileline = CRELINE(); return yOR;} "or" {yylval.fileline = CRELINE(); return yOR;}
"output" {yylval.fileline = CRELINE(); return yOUTPUT;} "output" {yylval.fileline = CRELINE(); return yOUTPUT;}
"parameter" {yylval.fileline = CRELINE(); return yPARAM;} "parameter" {yylval.fileline = CRELINE(); return yPARAMETER;}
"posedge" {yylval.fileline = CRELINE(); return yPOSEDGE;} "posedge" {yylval.fileline = CRELINE(); return yPOSEDGE;}
"reg" {yylval.fileline = CRELINE(); return yREG;} "reg" {yylval.fileline = CRELINE(); return yREG;}
"scalared" {yylval.fileline = CRELINE(); return ySCALARED;} "scalared" {yylval.fileline = CRELINE(); return ySCALARED;}
"specify" {yylval.fileline = CRELINE(); return ySPECIFY;} "specify" {yylval.fileline = CRELINE(); return ySPECIFY;}
"specparam" {yylval.fileline = CRELINE(); return yTIMINGSPEC;} "specparam" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"supply0" {yylval.fileline = CRELINE(); return ySUPPLY0;} "supply0" {yylval.fileline = CRELINE(); return ySUPPLY0;}
"supply1" {yylval.fileline = CRELINE(); return ySUPPLY1;} "supply1" {yylval.fileline = CRELINE(); return ySUPPLY1;}
"task" {yylval.fileline = CRELINE(); return yTASK;} "task" {yylval.fileline = CRELINE(); return yTASK;}
@@ -216,7 +218,6 @@ escid \\[^ \t\f\r\n]+
"cmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "cmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
"deassign" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "deassign" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
"disable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "disable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
"edge" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
"endprimitive" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "endprimitive" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
"endtable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "endtable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
"event" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "event" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
@@ -273,30 +274,30 @@ escid \\[^ \t\f\r\n]+
"$signed" {yylval.fileline = CRELINE(); return yD_SIGNED;} "$signed" {yylval.fileline = CRELINE(); return yD_SIGNED;}
"$unsigned" {yylval.fileline = CRELINE(); return yD_UNSIGNED;} "$unsigned" {yylval.fileline = CRELINE(); return yD_UNSIGNED;}
/* Keywords */ /* Keywords */
"automatic" {yylval.fileline = CRELINE(); return yAUTOMATIC;}
"endgenerate" {yylval.fileline = CRELINE(); return yENDGENERATE;} "endgenerate" {yylval.fileline = CRELINE(); return yENDGENERATE;}
"generate" {yylval.fileline = CRELINE(); return yGENERATE;} "generate" {yylval.fileline = CRELINE(); return yGENERATE;}
"genvar" {yylval.fileline = CRELINE(); return yGENVAR;} "genvar" {yylval.fileline = CRELINE(); return yGENVAR;}
"ifnone" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"localparam" {yylval.fileline = CRELINE(); return yLOCALPARAM;} "localparam" {yylval.fileline = CRELINE(); return yLOCALPARAM;}
"noshowcancelled" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"pulsestyle_ondetect" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"pulsestyle_onevent" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"showcancelled" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
"signed" {yylval.fileline = CRELINE(); return ySIGNED;} "signed" {yylval.fileline = CRELINE(); return ySIGNED;}
"unsigned" {yylval.fileline = CRELINE(); return yUNSIGNED;}
/* Special errors */ /* Special errors */
"include" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented; probably you want `include instead: %s",yytext);} "include" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented; probably you want `include instead: %s",yytext);}
/* Generic unsupported warnings */ /* Generic unsupported warnings */
"automatic" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "cell" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"cell" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "config" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"config" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "design" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"design" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "endconfig" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"endconfig" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "incdir" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"ifnone" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "instance" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"incdir" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "liblist" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"instance" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "library" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"liblist" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);} "use" {yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext);}
"library" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
"noshowcancelled" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
"pulsestyle_ondetect" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
"pulsestyle_onevent" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
"showcancelled" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
"unsigned" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
"use" {yyerrorf("Unsupported: Verilog 2001 reserved word not implemented: %s",yytext);}
} }
/* Verilog 2005 */ /* Verilog 2005 */
@@ -552,45 +553,51 @@ escid \\[^ \t\f\r\n]+
/* Verilog 1995 Operators */ /* Verilog 1995 Operators */
<V95,V01,V05,S05,PSL>{ <V95,V01,V05,S05,PSL>{
"&&" {yylval.fileline = CRELINE(); return yANDAND;} "&&" {yylval.fileline = CRELINE(); return yP_ANDAND;}
"||" {yylval.fileline = CRELINE(); return yOROR;} "||" {yylval.fileline = CRELINE(); return yP_OROR;}
"<=" {yylval.fileline = CRELINE(); return yLTE;} "<=" {yylval.fileline = CRELINE(); return yP_LTE;}
">=" {yylval.fileline = CRELINE(); return yGTE;} ">=" {yylval.fileline = CRELINE(); return yP_GTE;}
"<<" {yylval.fileline = CRELINE(); return ySLEFT;} "<<" {yylval.fileline = CRELINE(); return yP_SLEFT;}
">>" {yylval.fileline = CRELINE(); return ySRIGHT;} ">>" {yylval.fileline = CRELINE(); return yP_SRIGHT;}
"==" {yylval.fileline = CRELINE(); return yEQUAL;} "==" {yylval.fileline = CRELINE(); return yP_EQUAL;}
"!=" {yylval.fileline = CRELINE(); return yNOTEQUAL;} "!=" {yylval.fileline = CRELINE(); return yP_NOTEQUAL;}
"===" {yylval.fileline = CRELINE(); return yCASEEQUAL;} "===" {yylval.fileline = CRELINE(); return yP_CASEEQUAL;}
"!==" {yylval.fileline = CRELINE(); return yCASENOTEQUAL;} "!==" {yylval.fileline = CRELINE(); return yP_CASENOTEQUAL;}
"^~" {yylval.fileline = CRELINE(); return yOP_XNOR;} "^~" {yylval.fileline = CRELINE(); return yP_XNOR;}
"~^" {yylval.fileline = CRELINE(); return yOP_XNOR;} "~^" {yylval.fileline = CRELINE(); return yP_XNOR;}
"~&" {yylval.fileline = CRELINE(); return yOP_NAND;} "~&" {yylval.fileline = CRELINE(); return yP_NAND;}
"~|" {yylval.fileline = CRELINE(); return yOP_NOR;} "~|" {yylval.fileline = CRELINE(); return yP_NOR;}
"->" {yylval.fileline = CRELINE(); return yP_MINUSGT;}
} }
/* Verilog 2001 Operators */ /* Verilog 2001 Operators */
<V01,V05,S05,PSL>{ <V01,V05,S05,PSL>{
"<<<" {yylval.fileline = CRELINE(); return ySLEFT;} "<<<" {yylval.fileline = CRELINE(); return yP_SLEFT;}
">>>" {yylval.fileline = CRELINE(); return ySSRIGHT;} ">>>" {yylval.fileline = CRELINE(); return yP_SSRIGHT;}
"**" {yylval.fileline = CRELINE(); return yPOW;} "**" {yylval.fileline = CRELINE(); return yP_POW;}
"+:" {yylval.fileline = CRELINE(); return yPLUSCOLON;} "+:" {yylval.fileline = CRELINE(); return yP_PLUSCOLON;}
"-:" {yylval.fileline = CRELINE(); return yMINUSCOLON;} "-:" {yylval.fileline = CRELINE(); return yP_MINUSCOLON;}
}
/* SystemVerilog Operators */
<S05>{
"==?" {yylval.fileline = CRELINE(); return yP_WILDEQUAL;}
"!=?" {yylval.fileline = CRELINE(); return yP_WILDNOTEQUAL;}
} }
/* PSL Operators */ /* PSL Operators */
<PSL>{ <PSL>{
"{" {yylval.fileline = CRELINE(); return yPSL_BRA;} // Avoid parser hitting concatenate. "{" {yylval.fileline = CRELINE(); return yPSL_BRA;} // Avoid parser hitting concatenate.
"}" {yylval.fileline = CRELINE(); return yPSL_KET;} // Avoid parser hitting concatenate. "}" {yylval.fileline = CRELINE(); return yPSL_KET;} // Avoid parser hitting concatenate.
"->" {yylval.fileline = CRELINE(); return yOP_LOGIF;}
"<->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} //Unsup in other tools "<->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} //Unsup in other tools
"[*" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yBRA_STAR "[*" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_STAR
"[*]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yBRA_STAR_KET "[*]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_STAR_KET
"[+]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yBRA_PLUS_KET "[+]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_PLUS_KET
"[->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yBRA_MINUS_GT "[->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_MINUS_GT
"[->]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yBRA_MINUS_GT_KET "[->]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_MINUS_GT_KET
"[=" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yBRA_EQ "[=" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_EQ
"|->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yOR_MINUS_GT "|->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_OR_MINUS_GT
"|=>" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yOR_EQ_GT "|=>" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_OR_EQ_GT
} }
/* Identifiers and numbers */ /* Identifiers and numbers */
@@ -604,45 +611,42 @@ escid \\[^ \t\f\r\n]+
} else { } else {
yylval.strp = V3Read::newString(yytext); // Need _ as "6..." isn't legal ID yylval.strp = V3Read::newString(yytext); // Need _ as "6..." isn't legal ID
} }
return yID; return yaID;
} }
{id} { yylval.strp = V3Read::newString(yytext); {id} { yylval.strp = V3Read::newString(yytext);
return yID; return yaID;
} }
\"[^\"\\]*\" { yylval.strp = V3Read::newString(yytext+1,yyleng-2); \"[^\"\\]*\" { yylval.strp = V3Read::newString(yytext+1,yyleng-2);
return ySTRING; return yaSTRING;
} }
\" { yy_push_state(STRING); yymore(); } \" { yy_push_state(STRING); yymore(); }
[0-9]*?['']s?[bcodhBCODH][ \t]*[A-Fa-f0-9xXzZ_?]* { [0-9]*?['']s?[bcodhBCODH][ \t]*[A-Fa-f0-9xXzZ_?]* {
yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
return yINTNUM; return yaINTNUM;
} }
[0-9]*?['']s?[01xXzZ] { /* SystemVerilog */ [0-9]*?['']s?[01xXzZ] { /* SystemVerilog */
yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
return yINTNUM; return yaINTNUM;
} }
[0-9]+[_0-9]*[ \t]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]* { [0-9][_0-9]*[ \t]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]* {
yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
return yINTNUM; return yaINTNUM;
} }
[0-9]* { yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); [0-9][_0-9]* { yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
return yINTNUM; return yaINTNUM;
} }
[-+]?[0-9]+(\.[0-9]+)([eE][-+]?[0-9]+)? { [0-9][_0-9]*(\.[_0-9]+)([eE][-+]?[_0-9]+)? {
yylval.cdouble = 0; /* Only for delays, not used yet */ yylval.cdouble = 0; /* Only for delays, not used yet */
return yFLOATNUM; return yaFLOATNUM;
} }
[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+) { [0-9][_0-9]*(\.[_0-9]+)?([eE][-+]?[_0-9]+) {
yylval.cdouble = 0; /* Only for delays, not used yet */ yylval.cdouble = 0; /* Only for delays, not used yet */
return yFLOATNUM; return yaFLOATNUM;
} }
"`timescale"{ws}+[^\n]* {}
"`line"{ws}+[^\n]*\n {V3Read::ppline(yytext);}
} }
/************************************************************************/ /************************************************************************/
@@ -653,42 +657,65 @@ escid \\[^ \t\f\r\n]+
<STRING>\\. { yymore(); } <STRING>\\. { yymore(); }
<STRING>\" { yy_pop_state(); <STRING>\" { yy_pop_state();
yylval.strp = V3Read::newString(yytext+1,yyleng-2); yylval.strp = V3Read::newString(yytext+1,yyleng-2);
return ySTRING; } return yaSTRING; }
/************************************************************************/ /************************************************************************/
/* Attributes */
<ATTRMODE>\n { yymore(); NEXTLINE(); }
<ATTRMODE>"*)" { yy_pop_state(); }
<ATTRMODE>. { yymore(); }
<ATTRMODE><<EOF>> { yyerror("EOF in (*");
yyleng = 0; yy_pop_state(); }
/************************************************************************/
/* Attributes */
<V95,V01,V05,S05>{
"(*" { yymore(); yy_push_state(ATTRMODE); }
}
/************************************************************************/
/* Preprocessor*/
/* Common for all SYSC header states */ /* Common for all SYSC header states */
/* OPTIMIZE: we return one per line, make it one for the entire block */ /* OPTIMIZE: we return one per line, make it one for the entire block */
<V95,V01,V05,S05,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{ <V95,V01,V05,S05,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
[ \t]*"`verilog" { BEGIN V3Read::lastVerilogState(); } "`celldefine" { V3Read::inCellDefine(true); }
[ \t]*"`psl" { if (V3Read::optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } } "`endcelldefine" { V3Read::inCellDefine(false); }
[ \t]*"`systemc_header" { BEGIN SYSCHDR; } "`endprotect" { }
[ \t]*"`systemc_ctor" { BEGIN SYSCCTOR; } "`inline" { }
[ \t]*"`systemc_dtor" { BEGIN SYSCDTOR; } "`line"{ws}+[^\n]*\n { V3Read::ppline(yytext); }
[ \t]*"`systemc_interface" { BEGIN SYSCINT; } "`portcoerce" { }
[ \t]*"`systemc_implementation" { BEGIN SYSCIMP; } "`protect" { }
[ \t]*"`systemc_imp_header" { BEGIN SYSCIMPH; } "`psl" { if (V3Read::optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } }
"`resetall" { }
"`systemc_ctor" { BEGIN SYSCCTOR; }
"`systemc_dtor" { BEGIN SYSCDTOR; }
"`systemc_header" { BEGIN SYSCHDR; }
"`systemc_imp_header" { BEGIN SYSCIMPH; }
"`systemc_implementation" { BEGIN SYSCIMP; }
"`systemc_interface" { BEGIN SYSCINT; }
"`timescale"{ws}+[^\n]* {}
"`verilog" { BEGIN V3Read::lastVerilogState(); }
[ \t]*"`begin_keywords"[ \t]*\"1364-1995\" { yy_push_state(V95); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1364-1995\" { yy_push_state(V95); V3Read::pushBeginKeywords(YY_START);}
[ \t]*"`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START);}
[ \t]*"`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START);}
[ \t]*"`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); V3Read::pushBeginKeywords(YY_START);}
[ \t]*"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); V3Read::pushBeginKeywords(YY_START);}
[ \t]*"`end_keywords" { yy_pop_state(); if (!V3Read::popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); } "`end_keywords" { yy_pop_state(); if (!V3Read::popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
"`line"[ \t][^\n]*\n {V3Read::ppline(yytext);}
} }
<SYSCHDR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCHDR;} <SYSCHDR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCHDR;}
<SYSCINT>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCINT;} <SYSCINT>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCINT;}
<SYSCIMP>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCIMP;} <SYSCIMP>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCIMP;}
<SYSCIMPH>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCIMPH;} <SYSCIMPH>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCIMPH;}
<SYSCCTOR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCCTOR;} <SYSCCTOR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCCTOR;}
<SYSCDTOR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return ySCDTOR;} <SYSCDTOR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCDTOR;}
<IGNORE>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); } <IGNORE>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); }
/* Pick up text-type data */ /* Pick up text-type data */
<SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{ <SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
[ \t]*\n { NEXTLINE(); yymore();} {wsnr}* { yymore();}
\n { NEXTLINE(); yymore();}
\r ; \r ;
} }
@@ -697,9 +724,7 @@ escid \\[^ \t\f\r\n]+
<V95,V01,V05,S05,PSL>{ <V95,V01,V05,S05,PSL>{
"`"[a-zA-Z_0-9]+ { yyerrorf("Define or directive not defined: %s",yytext); } "`"[a-zA-Z_0-9]+ { yyerrorf("Define or directive not defined: %s",yytext); }
"//"[^\n]* { } /* throw away single line comments */
"//"[^\n]+ { } /* throw away single line comments */
. {yylval.fileline = CRELINE(); return yytext[0];} /* return single char ops. */ . {yylval.fileline = CRELINE(); return yytext[0];} /* return single char ops. */
} }
+453 -322
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -32,8 +32,8 @@ use vars qw ($Debug %Vars $Driver $Fork);
$::Driver = 1; $::Driver = 1;
eval "use Parallel::Forker; \$Fork=Parallel::Forker->new();"; eval "use Parallel::Forker; \$Fork=Parallel::Forker->new(use_sig_child=>1);";
$Fork = Forker->new() if !$Fork; $Fork = Forker->new(use_sig_child=>1) if !$Fork;
$SIG{CHLD} = sub { $Fork->sig_child() if $Fork; }; $SIG{CHLD} = sub { $Fork->sig_child() if $Fork; };
$SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; }; $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; };
@@ -549,6 +549,7 @@ sub _make_main {
print $fh " double sim_time = 1000;\n"; print $fh " double sim_time = 1000;\n";
} }
print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n"; print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n";
print $fh " Verilated::randReset(".$self->{verilated_randReset}.");\n" if defined $self->{verilated_randReset};
print $fh " topp = new $VM_PREFIX (\"TOP\");\n"; print $fh " topp = new $VM_PREFIX (\"TOP\");\n";
my $set; my $set;
if ($self->sp) { if ($self->sp) {
+3
View File
@@ -60,6 +60,9 @@ module sub (/*AUTOARG*/
output reg [4:0] out2; output reg [4:0] out2;
always @* begin always @* begin
// Test empty cases
casez (in[0])
endcase
casez (in) casez (in)
24'b0000_0000_0000_0000_0000_0000 : {out1,out2} = {1'b0,5'h00}; 24'b0000_0000_0000_0000_0000_0000 : {out1,out2} = {1'b0,5'h00};
24'b????_????_????_????_????_???1 : {out1,out2} = {1'b1,5'h00}; 24'b????_????_????_????_????_???1 : {out1,out2} = {1'b1,5'h00};
+2
View File
@@ -24,6 +24,8 @@ execute (
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %s=! %s= what! %s= hmmm!1234 [0] %s=! %s= what! %s= hmmm!1234
[0] hello, from a very long string. Percent %s are literally substituted in.
*-* All Finished *-*
'), '),
); );
+3
View File
@@ -33,6 +33,9 @@ module t;
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time, $display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
str2[7:0], str2, str3); str2[7:0], str2, str3);
$display("[%0t] %s%s%s", $time,
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");
// Str check // Str check
`ifndef nc // NC-Verilog 5.3 chokes on this test `ifndef nc // NC-Verilog 5.3 chokes on this test
if (str !== 32'h00_bf_11_0a) $stop; if (str !== 32'h00_bf_11_0a) $stop;
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
top_filename("t/t_display.v");
compile (
v_flags2 => [$Last_Self->{v3}?"-O0":""],
);
execute (
check_finished=>1,
expect=>quotemeta(
'[0] In TOP.v: Hi
[0] In TOP.v.sub
[0] In TOP.v.sub.subblock
[0] In TOP.v.sub2
[0] In TOP.v.sub2.subblock2
[0] %X=0c %D=12 %0X=c %0O=14 %B=001100
[0] %x=0c %d=12 %0x=c %0o=14 %b=001100
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %s=! %s= what! %s= hmmm!1234
[0] hello, from a very long string. Percent %s are literally substituted in.
*-* All Finished *-*
'),
);
ok(1);
1;
+6 -6
View File
@@ -13,12 +13,12 @@ compile (
execute ( execute (
check_finished=>1, check_finished=>1,
expect=> quotemeta( expect=> quotemeta(
'[0] %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228 '[0] lp %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228
[0] %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348 [0] ln %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348
[0] %x=000bbbbcccc %x=000bbbbcccc %o=00027356746314 %b=00000000010111011101110111100110011001100 %0d=3149647052 %d= 3149647052 [0] qp %x=001bbbbcccc %x=001bbbbcccc %o=00067356746314 %b=00000000110111011101110111100110011001100 %0d=7444614348 %d= 7444614348
[0] %x=100bbbbcccc %x=100bbbbcccc %o=20027356746314 %b=10000000010111011101110111100110011001100 %0d=-1096361980724 %d=-1096361980724 [0] qn %x=101bbbbcccc %x=101bbbbcccc %o=20067356746314 %b=10000000110111011101110111100110011001100 %0d=-1092067013428 %d=-1092067013428
[0] %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000 [0] wp %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000
[0] %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000 [0] wn %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000
'), '),
); );
+8 -8
View File
@@ -7,24 +7,24 @@
module t; module t;
reg signed [20:0] longp; initial longp = 21'shbbccc; reg signed [20:0] longp; initial longp = 21'shbbccc;
reg signed [20:0] longn; initial longn = 21'shbbccc; initial longn[20]=1'b1; reg signed [20:0] longn; initial longn = 21'shbbccc; initial longn[20]=1'b1;
reg signed [40:0] quadp; initial quadp = 41'shbbbb_cccc; reg signed [40:0] quadp; initial quadp = 41'sh1_bbbb_cccc;
reg signed [40:0] quadn; initial quadn = 41'shbbbb_cccc; initial quadn[40]=1'b1; reg signed [40:0] quadn; initial quadn = 41'sh1_bbbb_cccc; initial quadn[40]=1'b1;
reg signed [80:0] widep; initial widep = 81'shbc_1234_5678_1234_5678; reg signed [80:0] widep; initial widep = 81'shbc_1234_5678_1234_5678;
reg signed [80:0] widen; initial widen = 81'shbc_1234_5678_1234_5678; initial widen[40]=1'b1; reg signed [80:0] widen; initial widen = 81'shbc_1234_5678_1234_5678; initial widen[40]=1'b1;
initial begin initial begin
// Display formatting // Display formatting
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, $display("[%0t] lp %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
longp, longp, longp, longp, longp, longp); longp, longp, longp, longp, longp, longp);
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, $display("[%0t] ln %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
longn, longn, longn, longn, longn, longn); longn, longn, longn, longn, longn, longn);
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, $display("[%0t] qp %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
quadp, quadp, quadp, quadp, quadp, quadp); quadp, quadp, quadp, quadp, quadp, quadp);
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, $display("[%0t] qn %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
quadn, quadn, quadn, quadn, quadn, quadn); quadn, quadn, quadn, quadn, quadn, quadn);
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b", $time, $display("[%0t] wp %%x=%x %%x=%x %%o=%o %%b=%b", $time,
widep, widep, widep, widep); widep, widep, widep, widep);
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b", $time, $display("[%0t] wn %%x=%x %%x=%x %%o=%o %%b=%b", $time,
widen, widen, widen, widen); widen, widen, widen, widen);
$display; $display;
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
top_filename("t/t_display_signed.v");
compile (
v_flags2 => [$Last_Self->{v3}?"-O0":""],
);
execute (
check_finished=>1,
expect=> quotemeta(
'[0] lp %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228
[0] ln %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348
[0] qp %x=001bbbbcccc %x=001bbbbcccc %o=00067356746314 %b=00000000110111011101110111100110011001100 %0d=7444614348 %d= 7444614348
[0] qn %x=101bbbbcccc %x=101bbbbcccc %o=20067356746314 %b=10000000110111011101110111100110011001100 %0d=-1092067013428 %d=-1092067013428
[0] wp %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000
[0] wn %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000
'),
);
ok(1);
1;
+12 -5
View File
@@ -16,6 +16,7 @@ module t;
if (add(add(3'd1)) != 3'd3) $stop; if (add(add(3'd1)) != 3'd3) $stop;
if (global != 4) $stop; if (global != 4) $stop;
if (munge4(4'b0010) != 4'b1011) $stop; if (munge4(4'b0010) != 4'b1011) $stop;
if (toint(2) != 3) $stop;
if (global != 5) $stop; if (global != 5) $stop;
setit; setit;
incr(global,global,32'h10); incr(global,global,32'h10);
@@ -43,7 +44,7 @@ module t;
reg [31:0] flocal; reg [31:0] flocal;
flocal = 1; flocal = 1;
global = global + flocal; global = global + flocal;
end end : named // SystemVerilog end labels
end end
endfunction endfunction
@@ -66,10 +67,11 @@ module t;
end end
endtask endtask
task incr; task incr (
output [31:0] z; // Check a V2K style input/output list
input [31:0] a; output [31:0] z,
input [31:0] inc; input [31:0] a, inc
);
z = a + inc; z = a + inc;
endtask endtask
@@ -104,4 +106,9 @@ module t;
nil_func = fa + fb; nil_func = fa + fb;
endfunction endfunction
function integer toint;
input integer fa;
toint = fa + 32'h1;
endfunction
endmodule endmodule
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
$Last_Self->{verilated_randReset} = 1;
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+75
View File
@@ -0,0 +1,75 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
// verilator lint_off WIDTH
// verilator lint_off VARHIDDEN
module t (
clk
);
input clk;
integer cyc=0;
reg [63:0] crc; initial crc = 64'h1;
chk chk (.clk (clk),
.rst_l (1'b1),
.expr (|crc),
);
always @ (posedge clk) begin
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
if (cyc==0) begin
crc <= 64'h5aef0c8d_d70a4497;
end
else if (cyc<90) begin
end
else if (cyc==99) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module chk (input clk, input rst_l, input expr);
integer errors; initial errors = 0;
task printerr;
input [8*64:1] msg;
begin
errors = errors + 1;
$write("%%Error: %0s\n", msg);
$stop;
end
endtask
always @(posedge clk) begin
if (rst_l) begin
if (expr == 1'b0) begin
printerr("expr not asserted");
end
end
end
wire noxs = ((expr ^ expr) == 1'b0);
reg hasx;
always @ (noxs) begin
if (noxs) begin
hasx = 1'b0;
end
else begin
hasx = 1'b1;
end
end
always @(posedge clk) begin
if (rst_l) begin
if (hasx) begin
printerr("expr has unknowns");
end
end
end
endmodule
+2 -2
View File
@@ -56,7 +56,7 @@ endmodule
module ftest( module ftest(
input [ 7:0 ] a, input [ 7:0 ] a,
input [ 7:0 ] b, b, // Test legal syntax
input clk, input clk,
output [ 7:0 ] z output [ 7:0 ] z
); );
@@ -85,7 +85,7 @@ endmodule // ftest
module mytop ( module mytop (
input [ 7:0 ] a, input [ 7:0 ] a,
input [ 7:0 ] b, b,
input clk, input clk,
output [ 7:0 ] z output [ 7:0 ] z
); );
+7 -1
View File
@@ -1,4 +1,4 @@
// $Id:$ // $Id$
// DESCRIPTION: Verilator: Verilog Test module // DESCRIPTION: Verilator: Verilog Test module
// //
// This file ONLY is placed into the Public Domain, for any use, // This file ONLY is placed into the Public Domain, for any use,
@@ -24,6 +24,8 @@ module t (/*AUTOARG*/
wire [7:0] osizedreg; // From sub of t_inst_v2k_sub.v wire [7:0] osizedreg; // From sub of t_inst_v2k_sub.v
hello hsub;
t_inst_v2k_sub sub t_inst_v2k_sub sub
( (
// Outputs // Outputs
@@ -55,6 +57,10 @@ module t (/*AUTOARG*/
endmodule endmodule
module hello;
initial $write ("Hello\n");
endmodule
// Local Variables: // Local Variables:
// compile-command: "./vlint __FILE__" // compile-command: "./vlint __FILE__"
// End: // End:
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+81
View File
@@ -0,0 +1,81 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2007 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
// Take CRC data and apply to testblock inputs
wire [31:0] in = crc[31:0];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [3:0] out; // From test of Test.v
// End of automatics
Test test (/*AUTOINST*/
// Outputs
.out (out[3:0]),
// Inputs
.clk (clk),
.in (in[31:0]));
// Aggregate outputs into a single result vector
wire [63:0] result = {60'h0, out};
// What checksum will we end up with
`define EXPECTED_SUM 64'h1a0d07009b6a30d2
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
end
else if (cyc<10) begin
sum <= 64'h0;
end
else if (cyc<90) begin
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test (/*AUTOARG*/
// Outputs
out,
// Inputs
clk, in
);
input clk;
input [31:0] in;
output [3:0] out;
assign out[0] = in[3:0] ==? 4'b1001;
assign out[1] = in[3:0] !=? 4'b1001;
assign out[2] = in[3:0] ==? 4'bx01x;
assign out[3] = in[3:0] !=? 4'bx01x;
endmodule
+2 -8
View File
@@ -1,4 +1,3 @@
`line 1 "t/t_preproc.v" 1 `line 1 "t/t_preproc.v" 1
@@ -10,7 +9,6 @@
`line 9 "t/t_preproc.v" 0 `line 9 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc2.v" 1 `line 1 "t/t_preproc_inc2.v" 1
@@ -19,8 +17,8 @@ At file t/t_preproc_inc2.v line 4
`line 6 "t/t_preproc_inc2.v" 0 `line 6 "t/t_preproc_inc2.v" 0
`line 1 "t/t_preproc_inc3.v" 1 `line 1 "t/t_preproc_inc3.v" 1
`line 2 "inc3_a_filename_from_line_directive" 0
@@ -41,14 +39,10 @@ At file t/t_preproc_inc2.v line 4
`line 17 "inc3_a_filename_from_line_directive" 0 `line 17 "inc3_a_filename_from_line_directive" 0
`line 18 "inc3_a_filename_from_line_directive" 2 `line 18 "inc3_a_filename_from_line_directive" 2
`line 6 "t/t_preproc_inc2.v" 0 `line 6 "t/t_preproc_inc2.v" 0
`line 7 "t/t_preproc_inc2.v" 2 `line 7 "t/t_preproc_inc2.v" 2
`line 9 "t/t_preproc.v" 0 `line 9 "t/t_preproc.v" 0
@@ -148,4 +142,4 @@ $display( "left side: \" right side\"" )
`line 95 "t/t_preproc.v" 0 `line 95 "t/t_preproc.v" 0
Line_Preproc_Check 96 Line_Preproc_Check 96
`line 97 "t/t_preproc.v" 2
+1 -2
View File
@@ -1,4 +1,3 @@
`line 1 "t/t_preproc_psl.v" 1 `line 1 "t/t_preproc_psl.v" 1
@@ -74,4 +73,4 @@ psl assert always sig!=90;
72 72
`line 73 "t/t_preproc_psl.v" 2
+1 -2
View File
@@ -1,4 +1,3 @@
`line 1 "t/t_preproc_psl.v" 1 `line 1 "t/t_preproc_psl.v" 1
@@ -74,4 +73,4 @@ psl assert always sig!=90;
72 72
`line 73 "t/t_preproc_psl.v" 2