mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 17:43:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4b1bc2506 | ||
|
|
551393d443 | ||
|
|
79d305f3e8 | ||
|
|
822956e769 | ||
|
|
a681a6a6d5 | ||
|
|
5f6d69affd | ||
|
|
4a9bea6980 | ||
|
|
bfddd80f43 | ||
|
|
84a778719a | ||
|
|
829d80d5b5 | ||
|
|
d6a5c97f3a | ||
|
|
4ba00bd256 | ||
|
|
c18f9da400 | ||
|
|
5b620a8dc5 | ||
|
|
9c968c590c | ||
|
|
dff5d5c4e4 | ||
|
|
1265e8cce8 | ||
|
|
2b5d7eeb50 | ||
|
|
bb9ae89049 | ||
|
|
72832a2810 | ||
|
|
18cb210eac | ||
|
|
2c5a183368 | ||
|
|
386f0a75df | ||
|
|
ea26482154 | ||
|
|
3aee7f918a | ||
|
|
b3dd18b215 | ||
|
|
a77e331e89 | ||
|
|
6f414ee9e2 | ||
|
|
8d56b498d1 |
@@ -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
@@ -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
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
+107
-11
@@ -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
|
||||||
@@ -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.
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
"<>" => \¶meter,
|
"<>" => \¶meter,
|
||||||
)) {
|
)) {
|
||||||
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";
|
||||||
|
|||||||
Executable
+211
@@ -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,
|
||||||
|
"<>" => \¶meter,
|
||||||
|
)) {
|
||||||
|
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
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Executable
+67
@@ -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:
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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); }
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|||||||
+38
-5
@@ -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,9 +907,13 @@ 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.
|
||||||
|
// 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");
|
m_lineChars.append("\n");
|
||||||
}
|
}
|
||||||
|
gotEof = true;
|
||||||
|
}
|
||||||
else if (tok==VP_PSL) {
|
else if (tok==VP_PSL) {
|
||||||
m_lineChars.append(" psl ");
|
m_lineChars.append(" psl ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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", "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ 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_inCellDefine; // Inside a `celldefine
|
||||||
bool m_inLibrary; // Currently reading a library vs. regular file
|
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
|
||||||
@@ -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();
|
||||||
|
|||||||
+1
-3
@@ -198,9 +198,8 @@ 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'.
|
||||||
@@ -211,7 +210,6 @@ private:
|
|||||||
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);
|
||||||
}
|
}
|
||||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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");
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+443
-312
File diff suppressed because it is too large
Load Diff
@@ -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) {
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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 *-*
|
||||||
'),
|
'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Executable
+36
@@ -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;
|
||||||
@@ -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
|
||||||
'),
|
'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Executable
+29
@@ -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
@@ -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
|
||||||
|
|||||||
Executable
+20
@@ -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;
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Executable
+18
@@ -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;
|
||||||
@@ -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
|
||||||
@@ -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,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,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
|
||||||
|
|||||||
Reference in New Issue
Block a user