mirror of
https://github.com/verilator/verilator.git
synced 2025-01-06 06:37:45 +00:00
Add bisonpre for simplifing grammar and cleaning output
This commit is contained in:
parent
1d091e49e1
commit
a76ae67a81
@ -110,7 +110,7 @@ DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
|
||||
include/*.in \
|
||||
include/.*ignore \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/*fix \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
|
||||
src/*.pl \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \
|
||||
|
@ -31,7 +31,6 @@ LEX = @LEX@
|
||||
LFLAGS = -d
|
||||
PERL = @PERL@
|
||||
YACC = @YACC@
|
||||
YFLAGS = -y -d -v
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
@ -98,6 +97,7 @@ endif
|
||||
HEADERS = $(wildcard V*.h v*.h)
|
||||
|
||||
ASTGEN = $(srcdir)/astgen
|
||||
BISONPRE = $(srcdir)/bisonpre
|
||||
|
||||
######################################################################
|
||||
#### Top level
|
||||
@ -254,11 +254,9 @@ V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
|
||||
y.tab.h: y.tab.c
|
||||
|
||||
# Have only one output file in this rule to prevent parallel make issues
|
||||
y.tab.c: verilog.y $(HEADERS)
|
||||
y.tab.c: verilog.y $(HEADERS) bisonpre
|
||||
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
|
||||
${YACC} ${YFLAGS} $<
|
||||
mv y.tab.c y_pregen.tab.c && $(PERL) $(srcdir)/bisonfix < y_pregen.tab.c > y.tab.c
|
||||
mv y.tab.h y_pregen.tab.h && $(PERL) $(srcdir)/bisonfix < y_pregen.tab.h > y.tab.h
|
||||
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o y.tab.c $<
|
||||
|
||||
V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS)
|
||||
${LEX} ${LFLAGS} -o$@ $<
|
||||
|
27
src/bisonfix
27
src/bisonfix
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2008-2008 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: Edits bison output to get around various issues.
|
||||
|
||||
foreach my $line (<STDIN>) {
|
||||
# Fix bison 2.3 and GCC 4.2.1
|
||||
$line =~ s!\(YY_\("!(YY_((char*)"!g;
|
||||
print "$line";
|
||||
}
|
382
src/bisonpre
Executable file
382
src/bisonpre
Executable file
@ -0,0 +1,382 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw ($Debug $VERSION);
|
||||
|
||||
$VERSION = '3.035';
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
our $Opt_Debug;
|
||||
our $Opt_Definitions;
|
||||
our $Opt_File_Prefix;
|
||||
our $Opt_Name_Prefix;
|
||||
our $Opt_Output;
|
||||
our $Opt_Token_Table;
|
||||
our $Opt_Verbose;
|
||||
our $Opt_Yacc = "bison";
|
||||
our $Opt_Input;
|
||||
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config ("no_auto_abbrev");
|
||||
if (! GetOptions (
|
||||
# Local options
|
||||
"help" => \&usage,
|
||||
"version" => sub { print "Version $VERSION\n"; },
|
||||
"yacc=s" => \$Opt_Yacc,
|
||||
# Passed to Bison
|
||||
"t|debug" => sub { $Opt_Debug = 1; },
|
||||
"b|file-prefix=s" => \$Opt_File_Prefix,
|
||||
"d" => \$Opt_Definitions,
|
||||
"k|token-table" => \$Opt_Token_Table,
|
||||
"o=s" => \$Opt_Output,
|
||||
"p|name-prefix=s" => \$Opt_Name_Prefix,
|
||||
"v|verbose" => \$Opt_Verbose,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'bisonpre --help'\n";
|
||||
}
|
||||
|
||||
$Opt_Input or die "bisonpp: %Error: input file not specified\n";
|
||||
$Opt_Output or die "bisonpp: %Error: --o option is required\n";
|
||||
|
||||
process();
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print "Version $VERSION\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_Input) {
|
||||
$Opt_Input = $param;
|
||||
} else {
|
||||
die "bisonpp: %Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub process {
|
||||
remove_outputs();
|
||||
|
||||
clean_input($Opt_Input, tmp_prefix().".y");
|
||||
|
||||
# Run bison
|
||||
my $command = ($Opt_Yacc
|
||||
.($Opt_Debug?" -t":"")
|
||||
.($Opt_Definitions?" -d":"")
|
||||
.($Opt_Token_Table?" -k":"")
|
||||
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
|
||||
.($Opt_Verbose?" -v":"")
|
||||
." -b ".tmp_prefix()
|
||||
." -o ".tmp_prefix().".c"
|
||||
." ".tmp_prefix().".y" );
|
||||
|
||||
print " $command\n";
|
||||
system $command;
|
||||
my $status = $?;
|
||||
if ($status != 0) {
|
||||
remove_outputs();
|
||||
my $v = bison_version_check();
|
||||
die "bisonpp: %Error: $Opt_Yacc version $v run failed due to errors\n";
|
||||
}
|
||||
|
||||
clean_output(tmp_prefix().".output",output_prefix().".output");
|
||||
warning_check(output_prefix().".output");
|
||||
|
||||
clean_output(tmp_prefix().".c", output_prefix().".c");
|
||||
clean_output(tmp_prefix().".h", output_prefix().".h");
|
||||
remove_tmp();
|
||||
}
|
||||
|
||||
sub tmp_prefix {
|
||||
return output_prefix().".pre";
|
||||
}
|
||||
|
||||
sub output_prefix {
|
||||
my $o;
|
||||
if ($Opt_Output) {
|
||||
(my $o = $Opt_Output) =~ s!\.[^.]*$!!;
|
||||
return $o;
|
||||
} else {
|
||||
return $Opt_File_Prefix.".tab";
|
||||
}
|
||||
}
|
||||
|
||||
sub remove_tmp {
|
||||
unlink(tmp_prefix().".c"); # Ok if errors
|
||||
unlink(tmp_prefix().".h"); # Ok if errors
|
||||
unlink(tmp_prefix().".output"); # Ok if errors
|
||||
}
|
||||
|
||||
sub remove_outputs {
|
||||
remove_tmp();
|
||||
unlink(output_prefix().".c"); # Ok if errors
|
||||
unlink(output_prefix().".h"); # Ok if errors
|
||||
# We don't remove .output file, as it's useful for debugging errors
|
||||
}
|
||||
|
||||
sub bison_version_check {
|
||||
my $v = `$Opt_Yacc --version`;
|
||||
if ($v && $v =~ /([0-9]+\.[0-9]+)/) {
|
||||
my $v = $1;
|
||||
($v >= 1.875) or die "bisonpp: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n";
|
||||
return $v;
|
||||
} else {
|
||||
die "bisonpp: %Error: '$Opt_Yacc' is not installed, or not working\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub clean_output {
|
||||
my $filename = shift;
|
||||
my $outname = shift || $filename;
|
||||
print " edit $filename $outname\n";
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
my @lines = $fh->getlines;
|
||||
$fh->close;
|
||||
|
||||
(my $basename = tmp_prefix().".y") =~ s!.*/!!;
|
||||
$basename = quotemeta($basename);
|
||||
(my $newbase = output_prefix().".y") =~ s!.*/!!;
|
||||
|
||||
$fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
|
||||
foreach my $line (@lines) {
|
||||
# Fix bison 2.3 and GCC 4.2.1
|
||||
$line =~ s!\(YY_\("!(YY_((char*)"!g;
|
||||
# Fix filename refs
|
||||
$line =~ s!$basename!$newbase!g;
|
||||
$fh->write($line);
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
|
||||
sub warning_check {
|
||||
my $filename = shift;
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
if ($line =~ /conflicts/) {
|
||||
clean_output();
|
||||
die "%Error: $filename:$.: $line\n";
|
||||
}
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub clean_input {
|
||||
my $filename = shift;
|
||||
my $outname = shift || $filename; # Can == filename if desired
|
||||
print " edit $filename $outname\n";
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
my @lines = $fh->getlines;
|
||||
$fh->close;
|
||||
|
||||
# Find "rule<type>:"
|
||||
my %types;
|
||||
{
|
||||
my @linesin = @lines; @lines=(); my $l=0;
|
||||
foreach my $line (@linesin) {
|
||||
if ($line =~ s/^(\S+)<(\S+)>:/$1:/) {
|
||||
$types{$2}{$1} = 1;
|
||||
}
|
||||
push @lines, $line;
|
||||
}
|
||||
}
|
||||
|
||||
# Find "BISONPRE_TYPES"
|
||||
{
|
||||
my @linesin = @lines; @lines=(); my $l=0;
|
||||
my $needmore = 0;
|
||||
foreach my $line (@linesin) {
|
||||
$l++;
|
||||
if ($line =~ m!//BISONPRE_TYPES!) {
|
||||
push @lines, $line;
|
||||
foreach my $type (sort keys %types) {
|
||||
my $line = "%type<$type>\t";
|
||||
foreach my $rule (sort keys %{$types{$type}}) {
|
||||
$line.=" ".$rule;
|
||||
}
|
||||
$line .= "\n";
|
||||
push @lines, $line;
|
||||
$needmore++
|
||||
}
|
||||
} elsif ($needmore) {
|
||||
# Bison doesn't have a #line directive, so we need somewhere to insert into
|
||||
$line =~ s!^\s*//.*$!!;
|
||||
($line =~ m/^\s*$/) or die "%Error: $filename:$l: Need $needmore more blank lines to insure line numbers are constant\n";
|
||||
$needmore--;
|
||||
} else {
|
||||
push @lines, $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
|
||||
foreach my $line (@lines) {
|
||||
$fh->write($line);
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
bisonpre - Bison wrapper with pre and post processing
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
bisonpre --yacc bison --debug --verbose --defines X.h -k $< -pX -o X.c
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Bisonpre is a wrapper for the Bison YACC replacement. Input to Bison is
|
||||
preprocessed with substitution as described below under EXTENSIONS. Output
|
||||
from Bison is checked for additional errors, and corrected to work around
|
||||
various compile warnings.
|
||||
|
||||
=head1 EXTENSIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item //BISONPRE_TYPES
|
||||
|
||||
This is expanded into %type declarations.
|
||||
|
||||
=item rule_label<type>:
|
||||
|
||||
This allows the label declaring a rule to also specify the type of the
|
||||
rule. The type will be inserted where /*BISONPP_TYPES*/ is encountered.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item -b file-prefix
|
||||
=item --file-prefix=file-prefix
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Specify a prefix to use for all bison output file names. The names are
|
||||
chosen as if the input file were named file-prefix.c.
|
||||
|
||||
=item -d
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Write an extra output file containing macro definitions for the token type
|
||||
names defined in the grammar and the semantic value type YYSTYPE, as well
|
||||
as a few extern variable declarations. If the parser output file is named
|
||||
name.c then this file is named name.h. This output file is essential if
|
||||
you wish to put the definition of yylex in a separate source file, because
|
||||
yylex needs to be able to refer to token type codes and the variable
|
||||
yylval.
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item -k
|
||||
=item --token-table
|
||||
|
||||
Passed to bison.
|
||||
|
||||
This switch causes the name.tab.c output to include a list of token names
|
||||
in order by their token numbers; this is defined in the array yytname.
|
||||
Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES.
|
||||
|
||||
=item -p prefix
|
||||
=item --name-prefix=prefix
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Rename the external symbols used in the parser so that they start with
|
||||
prefix instead of yy. The precise list of symbols renamed is yyparse,
|
||||
yylex, yyerror, yylval, yychar, and yydebug. For example, if you use -p c,
|
||||
the names become cparse, clex, and so on.
|
||||
|
||||
==item -t
|
||||
==item --debug
|
||||
|
||||
Passed to bison.
|
||||
|
||||
In the parser file, define the macro YYDEBUG to 1 if it is not already
|
||||
defined, so that the debugging facilities are compiled.
|
||||
|
||||
==item -v
|
||||
==item --verbose
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Write an extra output file containing verbose descriptions of the parser
|
||||
states and what is done for each type of look-ahead token in that state.
|
||||
This file also describes all the conflicts, both those resolved by operator
|
||||
precedence and the unresolved ones. The file's name is made by removing
|
||||
.tab.c or .c from the parser output file name, and adding .output instead.
|
||||
Therefore, if the input file is foo.y, then the parser file is called
|
||||
foo.tab.c by default. As a consequence, the verbose output file is called
|
||||
foo.output.
|
||||
|
||||
=item --version
|
||||
|
||||
Print the version number and exit.
|
||||
|
||||
=item --yacc
|
||||
|
||||
Specify the name of the bison executable, defaults to "bison."
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
This is part of the L<http://www.veripool.org/> free Verilog EDA software
|
||||
tool suite. The latest version is available from CPAN and from
|
||||
L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2008-2008 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.
|
||||
|
||||
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.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <wsnyder@wsnyder.org>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
C<bison>
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./bisonpre "
|
||||
### End:
|
466
src/verilog.y
466
src/verilog.y
@ -116,7 +116,6 @@ class AstSenTree;
|
||||
AstCell* cellp;
|
||||
AstConst* constp;
|
||||
AstFunc* funcp;
|
||||
AstFuncRef* funcrefp;
|
||||
AstModule* modulep;
|
||||
AstNodeVarRef* varnodep;
|
||||
AstParseRef* parserefp;
|
||||
@ -124,7 +123,6 @@ class AstSenTree;
|
||||
AstRange* rangep;
|
||||
AstSenItem* senitemp;
|
||||
AstSenTree* sentreep;
|
||||
AstTaskRef* taskrefp;
|
||||
AstVar* varp;
|
||||
AstVarRef* varrefp;
|
||||
}
|
||||
@ -382,61 +380,25 @@ class AstSenTree;
|
||||
// Types are in same order as declarations.
|
||||
// Naming:
|
||||
// Trailing E indicates this type may have empty match
|
||||
%type<modulep> modHdr
|
||||
%type<nodep> modPortsE portList port
|
||||
%type<nodep> portV2kArgs portV2kList portV2kSecond portV2kInit portV2kSig
|
||||
%type<nodep> portV2kDecl portDecl varDecl
|
||||
%type<nodep> modParArgs modParSecond modParDecl modParList modParE
|
||||
%type<nodep> modItem modItemList modItemListE modOrGenItem
|
||||
%type<nodep> generateRegion
|
||||
%type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList
|
||||
%type<nodep> dlyTerm minTypMax
|
||||
%type<fileline> delay
|
||||
%type<varp> sigAndAttr sigId sigIdRange regsig regsigList regSigId
|
||||
%type<varp> netSig netSigList
|
||||
%type<rangep> rangeListE regrangeE anyrange rangeList delayrange portRangeE
|
||||
%type<varp> param paramList
|
||||
%type<nodep> instDecl
|
||||
%type<nodep> instnameList
|
||||
%type<cellp> instnameParen
|
||||
%type<pinp> cellpinList cellpinItList cellpinItemE instparamListE
|
||||
%type<nodep> defpList defpOne
|
||||
%type<sentreep> eventControl
|
||||
%type<sentreep> eventControlE
|
||||
%type<senitemp> senList senitem senitemEdge senitemVar
|
||||
%type<nodep> stmtBlock stmtList stmt labeledStmt stateCaseForIf
|
||||
%type<nodep> assertStmt
|
||||
%type<beginp> beginNamed
|
||||
%type<casep> caseStmt
|
||||
%type<caseitemp> caseList caseListE
|
||||
%type<nodep> caseCondList assignList assignOne
|
||||
%type<nodep> constExpr exprNoStr expr exprPsl exprStrText
|
||||
%type<nodep> exprList cateList cStrList
|
||||
%type<varrefp> varRefBase
|
||||
%type<parserefp> varRefMem
|
||||
%type<parserefp> varRefDotBit
|
||||
%type<taskrefp> taskRef
|
||||
%type<funcrefp> funcRef
|
||||
%type<nodep> idArrayed
|
||||
%type<nodep> idDotted
|
||||
%type<nodep> strAsInt strAsText concIdList
|
||||
%type<nodep> taskDecl
|
||||
%type<nodep> varDeclList
|
||||
%type<funcp> funcDecl
|
||||
%type<nodep> funcBody funcGuts funcVarList funcVar
|
||||
%type<rangep> funcTypeE
|
||||
%type<rangep> instRangeE
|
||||
%type<nodep> gateDecl
|
||||
%type<nodep> gateBufList gateNotList gateAndList gateNandList
|
||||
%type<nodep> gateOrList gateNorList gateXorList gateXnorList
|
||||
%type<assignwp> gateBuf gateNot gateAnd gateNand gateOr gateNor gateXor gateXnor
|
||||
%type<nodep> gateAndPinList gateOrPinList gateXorPinList
|
||||
%type<nodep> commaEListE
|
||||
%type<nodep> commaVRDListE vrdList
|
||||
|
||||
%type<nodep> pslStmt pslDir pslDirOne pslProp
|
||||
%type<nodep> pslDecl
|
||||
%type<nodep> pslSequence pslSere pslExpr
|
||||
//BISONPRE_TYPES
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
|
||||
%start fileE
|
||||
|
||||
@ -475,90 +437,109 @@ moduleDecl: modHdr modParE modPortsE ';' modItemListE yENDMODULE endLabelE
|
||||
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); }
|
||||
;
|
||||
|
||||
modHdr: yMODULE { V3Parse::s_trace=v3Global.opt.trace();}
|
||||
modHdr<modulep>:
|
||||
yMODULE { V3Parse::s_trace=v3Global.opt.trace();}
|
||||
yaID { $$ = new AstModule($1,*$3); $$->inLibrary(V3Read::inLibrary()||V3Read::inCellDefine());
|
||||
$$->modTrace(v3Global.opt.trace());
|
||||
V3Read::rootp()->addModulep($$); }
|
||||
;
|
||||
|
||||
modParE: /* empty */ { $$ = NULL; }
|
||||
modParE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '#' '(' ')' { $$ = NULL; }
|
||||
| '#' '(' modParArgs ')' { $$ = $3; }
|
||||
;
|
||||
|
||||
modParArgs: modParDecl { $$ = $1; }
|
||||
modParArgs<nodep>:
|
||||
modParDecl { $$ = $1; }
|
||||
| modParDecl ',' modParList { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
modParList: modParSecond { $$ = $1; }
|
||||
modParList<nodep>:
|
||||
modParSecond { $$ = $1; }
|
||||
| modParList ',' modParSecond { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
// Called only after a comma in a v2k list, to allow parsing "parameter a,b, parameter x"
|
||||
modParSecond: modParDecl { $$ = $1; }
|
||||
modParSecond<nodep>:
|
||||
modParDecl { $$ = $1; }
|
||||
| param { $$ = $1; }
|
||||
;
|
||||
|
||||
modPortsE: /* empty */ { $$ = NULL; }
|
||||
modPortsE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '(' ')' { $$ = NULL; }
|
||||
| '(' {V3Parse::s_pinNum=1;} portList ')' { $$ = $3; }
|
||||
| '(' {V3Parse::s_pinNum=1;} portV2kArgs ')' { $$ = $3; }
|
||||
;
|
||||
|
||||
portList: port { $$ = $1; }
|
||||
portList<nodep>:
|
||||
port { $$ = $1; }
|
||||
| portList ',' port { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
port: yaID portRangeE { $$ = new AstPort(CRELINE(),V3Parse::s_pinNum++,*$1); }
|
||||
port<nodep>:
|
||||
yaID portRangeE { $$ = new AstPort(CRELINE(),V3Parse::s_pinNum++,*$1); }
|
||||
;
|
||||
|
||||
portV2kArgs: portV2kDecl { $$ = $1; }
|
||||
portV2kArgs<nodep>:
|
||||
portV2kDecl { $$ = $1; }
|
||||
| portV2kDecl ',' portV2kList { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
portV2kList: portV2kSecond { $$ = $1; }
|
||||
portV2kList<nodep>:
|
||||
portV2kSecond { $$ = $1; }
|
||||
| portV2kList ',' portV2kSecond { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
// Called only after a comma in a v2k list, to allow parsing "input a,b"
|
||||
portV2kSecond: portV2kDecl { $$ = $1; }
|
||||
portV2kSecond<nodep>:
|
||||
portV2kDecl { $$ = $1; }
|
||||
| portV2kInit { $$ = $1; }
|
||||
;
|
||||
|
||||
portV2kInit: portV2kSig { $$=$1; }
|
||||
portV2kInit<nodep>:
|
||||
portV2kSig { $$=$1; }
|
||||
| portV2kSig '=' expr
|
||||
{ $$=$1; $$->addNext(new AstInitial($2,new AstAssign($2, new AstVarRef($2,V3Parse::s_varAttrp->name(),true), $3))); }
|
||||
;
|
||||
|
||||
portV2kSig: sigAndAttr { $$=$1; $$->addNext(new AstPort(CRELINE(),V3Parse::s_pinNum++, V3Parse::s_varAttrp->name())); }
|
||||
portV2kSig<nodep>:
|
||||
sigAndAttr { $$=$1; $$->addNext(new AstPort(CRELINE(),V3Parse::s_pinNum++, V3Parse::s_varAttrp->name())); }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Variable Declarations
|
||||
|
||||
varDeclList: varDecl { $$ = $1; }
|
||||
varDeclList<nodep>:
|
||||
varDecl { $$ = $1; }
|
||||
| varDecl varDeclList { $$ = $1->addNext($2); }
|
||||
;
|
||||
|
||||
regsigList: regsig { $$ = $1; }
|
||||
regsigList<varp>:
|
||||
regsig { $$ = $1; }
|
||||
| regsigList ',' regsig { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
|
||||
portV2kDecl: varRESET portDirection v2kVarDeclE signingE regrangeE portV2kInit { $$ = $6; }
|
||||
portV2kDecl<nodep>:
|
||||
varRESET portDirection v2kVarDeclE signingE regrangeE portV2kInit { $$ = $6; }
|
||||
;
|
||||
|
||||
// IEEE: port_declaration - plus ';'
|
||||
portDecl: varRESET portDirection v2kVarDeclE signingE regrangeE regsigList ';' { $$ = $6; }
|
||||
portDecl<nodep>:
|
||||
varRESET portDirection v2kVarDeclE signingE regrangeE regsigList ';' { $$ = $6; }
|
||||
;
|
||||
|
||||
varDecl: varRESET varReg signingE regrangeE regsigList ';' { $$ = $5; }
|
||||
varDecl<nodep>:
|
||||
varRESET varReg signingE regrangeE regsigList ';' { $$ = $5; }
|
||||
| varRESET varGParam signingE regrangeE paramList ';' { $$ = $5; }
|
||||
| varRESET varLParam signingE regrangeE paramList ';' { $$ = $5; }
|
||||
| varRESET varNet signingE delayrange netSigList ';' { $$ = $5; }
|
||||
| varRESET varGenVar signingE regsigList ';' { $$ = $4; }
|
||||
;
|
||||
|
||||
modParDecl: varRESET varGParam signingE regrangeE param { $$ = $5; }
|
||||
modParDecl<nodep>:
|
||||
varRESET varGParam signingE regrangeE param { $$ = $5; }
|
||||
;
|
||||
|
||||
varRESET: /* empty */ { VARRESET(); }
|
||||
@ -600,15 +581,18 @@ v2kVarDeclE: /*empty*/ { }
|
||||
//************************************************
|
||||
// Module Items
|
||||
|
||||
modItemListE: /* empty */ { $$ = NULL; }
|
||||
modItemListE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| modItemList { $$ = $1; }
|
||||
;
|
||||
|
||||
modItemList: modItem { $$ = $1; }
|
||||
modItemList<nodep>:
|
||||
modItem { $$ = $1; }
|
||||
| modItemList modItem { $$ = $1->addNextNull($2); }
|
||||
;
|
||||
|
||||
modItem: modOrGenItem { $$ = $1; }
|
||||
modItem<nodep>:
|
||||
modOrGenItem { $$ = $1; }
|
||||
| generateRegion { $$ = $1; }
|
||||
| yaSCHDR { $$ = new AstScHdr(CRELINE(),*$1); }
|
||||
| yaSCINT { $$ = new AstScInt(CRELINE(),*$1); }
|
||||
@ -626,10 +610,12 @@ modItem: modOrGenItem { $$ = $1; }
|
||||
;
|
||||
|
||||
// IEEE: generate_region
|
||||
generateRegion: yGENERATE genTopBlock yENDGENERATE { $$ = new AstGenerate($1, $2); }
|
||||
generateRegion<nodep>:
|
||||
yGENERATE genTopBlock yENDGENERATE { $$ = new AstGenerate($1, $2); }
|
||||
;
|
||||
|
||||
modOrGenItem: yALWAYS eventControlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
|
||||
modOrGenItem<nodep>:
|
||||
yALWAYS eventControlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
|
||||
| yFINAL stmtBlock { $$ = new AstFinal($1,$2); }
|
||||
| yINITIAL stmtBlock { $$ = new AstInitial($1,$2); }
|
||||
| yASSIGN delayE assignList ';' { $$ = $3; }
|
||||
@ -648,25 +634,30 @@ modOrGenItem: yALWAYS eventControlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
|
||||
// Generates
|
||||
|
||||
// Because genItemList includes variable declarations, we don't need beginNamed
|
||||
genItemBlock: genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); }
|
||||
genItemBlock<nodep>:
|
||||
genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); }
|
||||
| genItemBegin { $$ = $1; }
|
||||
;
|
||||
|
||||
genTopBlock: genItemList { $$ = $1; }
|
||||
genTopBlock<nodep>:
|
||||
genItemList { $$ = $1; }
|
||||
| genItemBegin { $$ = $1; }
|
||||
;
|
||||
|
||||
genItemBegin: yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); }
|
||||
genItemBegin<nodep>:
|
||||
yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); }
|
||||
| yBEGIN yEND { $$ = NULL; }
|
||||
| yBEGIN ':' yaID genItemList yEND endLabelE { $$ = new AstBegin($2,*$3,$4); }
|
||||
| yBEGIN ':' yaID yEND endLabelE { $$ = NULL; }
|
||||
;
|
||||
|
||||
genItemList: genItem { $$ = $1; }
|
||||
genItemList<nodep>:
|
||||
genItem { $$ = $1; }
|
||||
| genItemList genItem { $$ = $1->addNextNull($2); }
|
||||
;
|
||||
|
||||
genItem: modOrGenItem { $$ = $1; }
|
||||
genItem<nodep>:
|
||||
modOrGenItem { $$ = $1; }
|
||||
| yCASE '(' expr ')' genCaseListE yENDCASE { $$ = new AstGenCase($1,$3,$5); }
|
||||
| yIF '(' expr ')' genItemBlock %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$3,$5,NULL); }
|
||||
| yIF '(' expr ')' genItemBlock yELSE genItemBlock { $$ = new AstGenIf($1,$3,$5,$7); }
|
||||
@ -676,11 +667,13 @@ genItem: modOrGenItem { $$ = $1; }
|
||||
,$13);}
|
||||
;
|
||||
|
||||
genCaseListE: /* empty */ { $$ = NULL; }
|
||||
genCaseListE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| genCaseList { $$ = $1; }
|
||||
;
|
||||
|
||||
genCaseList: caseCondList ':' genItemBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
genCaseList<nodep>:
|
||||
caseCondList ':' genItemBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
| yDEFAULT ':' genItemBlock { $$ = new AstCaseItem($2,NULL,$3); }
|
||||
| yDEFAULT genItemBlock { $$ = new AstCaseItem($1,NULL,$2); }
|
||||
| genCaseList caseCondList ':' genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
|
||||
@ -691,11 +684,13 @@ genCaseList: caseCondList ':' genItemBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
//************************************************
|
||||
// Assignments and register declarations
|
||||
|
||||
assignList: assignOne { $$ = $1; }
|
||||
assignList<nodep>:
|
||||
assignOne { $$ = $1; }
|
||||
| assignList ',' assignOne { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
assignOne: varRefDotBit '=' expr { $$ = new AstAssignW($2,$1,$3); }
|
||||
assignOne<nodep>:
|
||||
varRefDotBit '=' expr { $$ = new AstAssignW($2,$1,$3); }
|
||||
| '{' concIdList '}' '=' expr { $$ = new AstAssignW($1,$2,$5); }
|
||||
;
|
||||
|
||||
@ -703,46 +698,54 @@ delayE: /* empty */ { }
|
||||
| delay { } /* ignored */
|
||||
;
|
||||
|
||||
delay: '#' dlyTerm { $$ = $1; } /* ignored */
|
||||
delay<fileline>:
|
||||
'#' dlyTerm { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
;
|
||||
|
||||
dlyTerm: yaID { $$ = NULL; }
|
||||
dlyTerm<nodep>:
|
||||
yaID { $$ = NULL; }
|
||||
| yaINTNUM { $$ = NULL; }
|
||||
| yaFLOATNUM { $$ = NULL; }
|
||||
;
|
||||
|
||||
// IEEE: mintypmax_expression and constant_mintypmax_expression
|
||||
minTypMax: dlyTerm { $$ = $1; } /* ignored */
|
||||
minTypMax<nodep>:
|
||||
dlyTerm { $$ = $1; } /* ignored */
|
||||
| dlyTerm ':' dlyTerm ':' dlyTerm { $$ = $1; } /* ignored */
|
||||
;
|
||||
|
||||
sigAndAttr: sigId sigAttrListE { $$ = $1; }
|
||||
sigAndAttr<varp>:
|
||||
sigId sigAttrListE { $$ = $1; }
|
||||
;
|
||||
|
||||
netSigList: netSig { $$ = $1; }
|
||||
netSigList<varp>:
|
||||
netSig { $$ = $1; }
|
||||
| netSigList ',' netSig { $$ = $1; $1->addNext($3); }
|
||||
;
|
||||
|
||||
netSig: sigId sigAttrListE { $$ = $1; }
|
||||
netSig<varp>:
|
||||
sigId sigAttrListE { $$ = $1; }
|
||||
| sigId sigAttrListE '=' expr { $$ = $1; $1->addNext(new AstAssignW($3,new AstVarRef($3,$1->name(),true),$4)); }
|
||||
| sigIdRange sigAttrListE { $$ = $1; }
|
||||
;
|
||||
|
||||
sigIdRange: yaID rangeList { $$ = V3Parse::createVariable(CRELINE(), *$1, $2); }
|
||||
sigIdRange<varp>:
|
||||
yaID rangeList { $$ = V3Parse::createVariable(CRELINE(), *$1, $2); }
|
||||
;
|
||||
|
||||
regSigId: yaID rangeListE { $$ = V3Parse::createVariable(CRELINE(), *$1, $2); }
|
||||
regSigId<varp>:
|
||||
yaID rangeListE { $$ = V3Parse::createVariable(CRELINE(), *$1, $2); }
|
||||
| yaID rangeListE '=' constExpr { $$ = V3Parse::createVariable(CRELINE(), *$1, $2);
|
||||
$$->addNext(new AstInitial($3,new AstAssign($3, new AstVarRef($3, $$, true), $4))); }
|
||||
;
|
||||
|
||||
sigId: yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); }
|
||||
sigId<varp>: yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); }
|
||||
;
|
||||
|
||||
regsig: regSigId sigAttrListE {}
|
||||
regsig<varp>: regSigId sigAttrListE {}
|
||||
;
|
||||
|
||||
sigAttrListE: /* empty */ {}
|
||||
@ -760,27 +763,33 @@ sigAttr: yVL_CLOCK { V3Parse::s_varAttrp->attrScClocked(true); }
|
||||
| yVL_ISOLATE_ASSIGNMENTS { V3Parse::s_varAttrp->attrIsolateAssign(true); }
|
||||
;
|
||||
|
||||
rangeListE: /* empty */ { $$ = NULL; }
|
||||
rangeListE<rangep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| rangeList { $$ = $1; }
|
||||
;
|
||||
|
||||
rangeList: anyrange { $$ = $1; }
|
||||
rangeList<rangep>:
|
||||
anyrange { $$ = $1; }
|
||||
| rangeList anyrange { $$ = $1; $1->addNext($2); }
|
||||
;
|
||||
|
||||
regrangeE: /* empty */ { $$ = NULL; VARRANGE($$); }
|
||||
regrangeE<rangep>:
|
||||
/* empty */ { $$ = NULL; VARRANGE($$); }
|
||||
| anyrange { $$ = $1; VARRANGE($$); }
|
||||
;
|
||||
|
||||
anyrange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
|
||||
anyrange<rangep>:
|
||||
'[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
|
||||
;
|
||||
|
||||
delayrange: regrangeE delayE { $$ = $1; }
|
||||
delayrange<rangep>:
|
||||
regrangeE delayE { $$ = $1; }
|
||||
| ySCALARED regrangeE delayE { $$ = $2; }
|
||||
| yVECTORED regrangeE delayE { $$ = $2; }
|
||||
;
|
||||
|
||||
portRangeE: /* empty */ { $$ = NULL; }
|
||||
portRangeE<rangep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '[' constExpr ']' { $$ = NULL; $1->v3error("Ranges ignored on port-list.\n"); }
|
||||
| '[' constExpr ':' constExpr ']' { $$ = NULL; $1->v3error("Ranges ignored on port-list.\n"); }
|
||||
;
|
||||
@ -788,50 +797,62 @@ portRangeE: /* empty */ { $$ = NULL; }
|
||||
//************************************************
|
||||
// Parameters
|
||||
|
||||
param: sigId sigAttrListE '=' expr { $$ = $1; $$->initp($4); }
|
||||
param<varp>:
|
||||
sigId sigAttrListE '=' expr { $$ = $1; $$->initp($4); }
|
||||
;
|
||||
|
||||
paramList: param { $$ = $1; }
|
||||
paramList<varp>:
|
||||
param { $$ = $1; }
|
||||
| paramList ',' param { $$ = $1; $1->addNext($3); }
|
||||
;
|
||||
|
||||
// IEEE: list_of_defparam_assignments
|
||||
defpList: defpOne { $$ = $1; }
|
||||
defpList<nodep>:
|
||||
defpOne { $$ = $1; }
|
||||
| defpList ',' defpOne { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
defpOne: yaID '.' yaID '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); }
|
||||
defpOne<nodep>:
|
||||
yaID '.' yaID '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Instances
|
||||
|
||||
instDecl: yaID instparamListE {INSTPREP(*$1,$2);} instnameList ';' { $$ = $4; V3Parse::s_impliedDecl=false;}
|
||||
instDecl<nodep>:
|
||||
yaID instparamListE {INSTPREP(*$1,$2);} instnameList ';' { $$ = $4; V3Parse::s_impliedDecl=false;}
|
||||
|
||||
instparamListE: /* empty */ { $$ = NULL; }
|
||||
instparamListE<pinp>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '#' '(' cellpinList ')' { $$ = $3; }
|
||||
;
|
||||
|
||||
instnameList: instnameParen { $$ = $1; }
|
||||
instnameList<nodep>:
|
||||
instnameParen { $$ = $1; }
|
||||
| instnameList ',' instnameParen { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
instnameParen: yaID instRangeE '(' cellpinList ')' { $$ = new AstCell($3, *$1,V3Parse::s_instModule,$4, V3Parse::s_instParamp,$2); $$->pinStar(V3Parse::s_pinStar); }
|
||||
instnameParen<cellp>:
|
||||
yaID instRangeE '(' cellpinList ')' { $$ = new AstCell($3, *$1,V3Parse::s_instModule,$4, V3Parse::s_instParamp,$2); $$->pinStar(V3Parse::s_pinStar); }
|
||||
| yaID instRangeE { $$ = new AstCell(CRELINE(),*$1,V3Parse::s_instModule,NULL,V3Parse::s_instParamp,$2); $$->pinStar(V3Parse::s_pinStar); }
|
||||
;
|
||||
|
||||
instRangeE: /* empty */ { $$ = NULL; }
|
||||
instRangeE<rangep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
|
||||
;
|
||||
|
||||
cellpinList: {V3Parse::s_pinNum=1; V3Parse::s_pinStar=false; } cellpinItList { $$ = $2; }
|
||||
cellpinList<pinp>:
|
||||
{V3Parse::s_pinNum=1; V3Parse::s_pinStar=false; } cellpinItList { $$ = $2; }
|
||||
;
|
||||
|
||||
cellpinItList: cellpinItemE { $$ = $1; }
|
||||
cellpinItList<pinp>:
|
||||
cellpinItemE { $$ = $1; }
|
||||
| cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); }
|
||||
;
|
||||
|
||||
cellpinItemE: /* empty: ',,' is legal */ { $$ = NULL; V3Parse::s_pinNum++; }
|
||||
cellpinItemE<pinp>:
|
||||
/* empty: ',,' is legal */ { $$ = NULL; V3Parse::s_pinNum++; }
|
||||
| yP_DOTSTAR { $$ = NULL; if (V3Parse::s_pinStar) $1->v3error("Duplicate .* in a cell"); V3Parse::s_pinStar=true; }
|
||||
| '.' yaID { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
|
||||
| '.' yaID '(' ')' { $$ = NULL; V3Parse::s_pinNum++; }
|
||||
@ -842,31 +863,37 @@ cellpinItemE: /* empty: ',,' is legal */ { $$ = NULL; V3Parse::s_pinNum++; }
|
||||
//************************************************
|
||||
// EventControl lists
|
||||
|
||||
eventControlE: /* empty */ { $$ = NULL; }
|
||||
eventControlE<sentreep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| eventControl { $$ = $1; }
|
||||
|
||||
// IEEE: event_control
|
||||
eventControl: '@' '(' senList ')' { $$ = new AstSenTree($1,$3); }
|
||||
eventControl<sentreep>:
|
||||
'@' '(' senList ')' { $$ = new AstSenTree($1,$3); }
|
||||
| '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */
|
||||
| '@' '(' '*' ')' { $$ = NULL; } /* Verilog 2001 */
|
||||
| '@' '*' { $$ = NULL; } /* Verilog 2001 */
|
||||
;
|
||||
|
||||
// IEEE: event_expression - split over several
|
||||
senList: senitem { $$ = $1; }
|
||||
senList<senitemp>:
|
||||
senitem { $$ = $1; }
|
||||
| senList yOR senitem { $$ = $1;$1->addNext($3); }
|
||||
| senList ',' senitem { $$ = $1;$1->addNext($3); } /* Verilog 2001 */
|
||||
;
|
||||
|
||||
senitem: senitemEdge { $$ = $1; }
|
||||
senitem<senitemp>:
|
||||
senitemEdge { $$ = $1; }
|
||||
| senitemVar { $$ = $1; }
|
||||
| '(' senitemVar ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
senitemVar: varRefDotBit { $$ = new AstSenItem(CRELINE(),AstEdgeType::ANYEDGE,$1); }
|
||||
senitemVar<senitemp>:
|
||||
varRefDotBit { $$ = new AstSenItem(CRELINE(),AstEdgeType::ANYEDGE,$1); }
|
||||
;
|
||||
|
||||
senitemEdge: yPOSEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::POSEDGE,$2); }
|
||||
senitemEdge<senitemp>:
|
||||
yPOSEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::POSEDGE,$2); }
|
||||
| yNEGEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::NEGEDGE,$2); }
|
||||
| yPOSEDGE '(' varRefDotBit ')' { $$ = new AstSenItem($1,AstEdgeType::POSEDGE,$3); }
|
||||
| yNEGEDGE '(' varRefDotBit ')' { $$ = new AstSenItem($1,AstEdgeType::NEGEDGE,$3); }
|
||||
@ -875,22 +902,26 @@ senitemEdge: yPOSEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::POSED
|
||||
//************************************************
|
||||
// Statements
|
||||
|
||||
stmtBlock: stmt { $$ = $1; }
|
||||
stmtBlock<nodep>:
|
||||
stmt { $$ = $1; }
|
||||
| yBEGIN stmtList yEND { $$ = $2; }
|
||||
| yBEGIN yEND { $$ = NULL; }
|
||||
| beginNamed stmtList yEND endLabelE { $$ = $1; $1->addStmtp($2); }
|
||||
| beginNamed yEND endLabelE { $$ = $1; }
|
||||
;
|
||||
|
||||
beginNamed: yBEGIN ':' yaID varDeclList { $$ = new AstBegin($2,*$3,$4); }
|
||||
beginNamed<beginp>:
|
||||
yBEGIN ':' yaID varDeclList { $$ = new AstBegin($2,*$3,$4); }
|
||||
| yBEGIN ':' yaID { $$ = new AstBegin($2,*$3,NULL); }
|
||||
;
|
||||
|
||||
stmtList: stmtBlock { $$ = $1; }
|
||||
stmtList<nodep>:
|
||||
stmtBlock { $$ = $1; }
|
||||
| stmtList stmtBlock { $$ = ($2==NULL)?($1):($1->addNext($2)); }
|
||||
;
|
||||
|
||||
stmt: ';' { $$ = NULL; }
|
||||
stmt<nodep>:
|
||||
';' { $$ = NULL; }
|
||||
| labeledStmt { $$ = $1; }
|
||||
| yaID ':' labeledStmt { $$ = new AstBegin($2, *$1, $3); } /*S05 block creation rule*/
|
||||
|
||||
@ -941,7 +972,8 @@ stmt: ';' { $$ = NULL; }
|
||||
//************************************************
|
||||
// Case/If
|
||||
|
||||
stateCaseForIf: caseStmt caseAttrE caseListE yENDCASE { $$ = $1; if ($3) $1->addItemsp($3); }
|
||||
stateCaseForIf<nodep>:
|
||||
caseStmt caseAttrE caseListE yENDCASE { $$ = $1; if ($3) $1->addItemsp($3); }
|
||||
| yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstIf($1,$3,$5,NULL); }
|
||||
| yIF '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstIf($1,$3,$5,$7); }
|
||||
| yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' stmtBlock
|
||||
@ -952,7 +984,8 @@ stateCaseForIf: caseStmt caseAttrE caseListE yENDCASE { $$ = $1; if ($3) $1->add
|
||||
| yDO stmtBlock yWHILE '(' expr ')' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));}
|
||||
;
|
||||
|
||||
caseStmt: yCASE '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASE,$3,NULL); }
|
||||
caseStmt<casep>:
|
||||
yCASE '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASE,$3,NULL); }
|
||||
| yCASEX '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEX,$3,NULL); $1->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)\n"); }
|
||||
| yCASEZ '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEZ,$3,NULL); }
|
||||
;
|
||||
@ -962,11 +995,13 @@ caseAttrE: /*empty*/ { }
|
||||
| caseAttrE yVL_PARALLEL_CASE { V3Parse::s_caseAttrp->parallelPragma(true); }
|
||||
;
|
||||
|
||||
caseListE: /* empty */ { $$ = NULL; }
|
||||
caseListE<caseitemp>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| caseList { $$ = $1; }
|
||||
;
|
||||
|
||||
caseList: caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
caseList<caseitemp>:
|
||||
caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
| yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); }
|
||||
| yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); }
|
||||
| caseList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
|
||||
@ -974,25 +1009,30 @@ caseList: caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
| caseList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); }
|
||||
;
|
||||
|
||||
caseCondList: expr { $$ = $1; }
|
||||
caseCondList<nodep>:
|
||||
expr { $$ = $1; }
|
||||
| caseCondList ',' expr { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Functions/tasks
|
||||
|
||||
taskRef: idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),NULL);}
|
||||
taskRef<nodep>:
|
||||
idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),NULL);}
|
||||
| idDotted '(' exprList ')' { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),$3);}
|
||||
;
|
||||
|
||||
funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
|
||||
funcRef<nodep>:
|
||||
idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
|
||||
;
|
||||
|
||||
taskDecl: yTASK lifetimeE yaID funcGuts yENDTASK endLabelE
|
||||
taskDecl<nodep>:
|
||||
yTASK lifetimeE yaID funcGuts yENDTASK endLabelE
|
||||
{ $$ = new AstTask ($1,*$3,$4);}
|
||||
;
|
||||
|
||||
funcDecl: yFUNCTION lifetimeE funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); }
|
||||
funcDecl<funcp>:
|
||||
yFUNCTION lifetimeE funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); }
|
||||
| yFUNCTION lifetimeE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); }
|
||||
| yFUNCTION lifetimeE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);}
|
||||
| yFUNCTION lifetimeE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
|
||||
@ -1004,24 +1044,29 @@ lifetimeE: /* empty */ { }
|
||||
| yAUTOMATIC { }
|
||||
;
|
||||
|
||||
funcGuts: '(' {V3Parse::s_pinNum=1;} portV2kArgs ')' ';' funcBody { $$ = $3->addNextNull($6); }
|
||||
funcGuts<nodep>:
|
||||
'(' {V3Parse::s_pinNum=1;} portV2kArgs ')' ';' funcBody { $$ = $3->addNextNull($6); }
|
||||
| ';' funcBody { $$ = $2; }
|
||||
;
|
||||
|
||||
funcBody: funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); }
|
||||
funcBody<nodep>:
|
||||
funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); }
|
||||
| stmtBlock { $$ = $1; }
|
||||
;
|
||||
|
||||
funcTypeE: /* empty */ { $$ = NULL; }
|
||||
funcTypeE<rangep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| yINTEGER { $$ = new AstRange($1,31,0); }
|
||||
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
|
||||
;
|
||||
|
||||
funcVarList: funcVar { $$ = $1; }
|
||||
funcVarList<nodep>:
|
||||
funcVar { $$ = $1; }
|
||||
| funcVarList funcVar { $$ = $1;$1->addNext($2); }
|
||||
;
|
||||
|
||||
funcVar: portDecl { $$ = $1; }
|
||||
funcVar<nodep>:
|
||||
portDecl { $$ = $1; }
|
||||
| varDecl { $$ = $1; }
|
||||
| yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); }
|
||||
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
|
||||
@ -1034,10 +1079,12 @@ parenE: /* empty */ { }
|
||||
//************************************************
|
||||
// Expressions
|
||||
|
||||
constExpr: expr { $$ = $1; }
|
||||
constExpr<nodep>:
|
||||
expr { $$ = $1; }
|
||||
;
|
||||
|
||||
exprNoStr: expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); }
|
||||
exprNoStr<nodep>:
|
||||
expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); }
|
||||
| expr yP_ANDAND expr { $$ = new AstLogAnd ($2,$1,$3); }
|
||||
| expr '&' expr { $$ = new AstAnd ($2,$1,$3); }
|
||||
| expr '|' expr { $$ = new AstOr ($2,$1,$3); }
|
||||
@ -1112,49 +1159,59 @@ exprNoStr: expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); }
|
||||
;
|
||||
|
||||
// Generic expressions
|
||||
expr: exprNoStr { $$ = $1; }
|
||||
expr<nodep>:
|
||||
exprNoStr { $$ = $1; }
|
||||
| strAsInt { $$ = $1; }
|
||||
;
|
||||
|
||||
// Psl excludes {}'s by lexer converting to different token
|
||||
exprPsl: exprNoStr { $$ = $1; }
|
||||
exprPsl<nodep>:
|
||||
exprNoStr { $$ = $1; }
|
||||
| strAsInt { $$ = $1; }
|
||||
;
|
||||
|
||||
// PLI calls exclude "" as integers, they're strings
|
||||
// For $c("foo","bar") we want "bar" as a string, not a Verilog integer.
|
||||
exprStrText: exprNoStr { $$ = $1; }
|
||||
exprStrText<nodep>:
|
||||
exprNoStr { $$ = $1; }
|
||||
| strAsText { $$ = $1; }
|
||||
;
|
||||
|
||||
cStrList: exprStrText { $$ = $1; }
|
||||
cStrList<nodep>:
|
||||
exprStrText { $$ = $1; }
|
||||
| exprStrText ',' cStrList { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
|
||||
cateList: expr { $$ = $1; }
|
||||
cateList<nodep>:
|
||||
expr { $$ = $1; }
|
||||
| cateList ',' expr { $$ = new AstConcat($2,$1,$3); }
|
||||
;
|
||||
|
||||
exprList: expr { $$ = $1; }
|
||||
exprList<nodep>:
|
||||
expr { $$ = $1; }
|
||||
| exprList ',' expr { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
|
||||
commaEListE: /* empty */ { $$ = NULL; }
|
||||
commaEListE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| ',' exprList { $$ = $2; }
|
||||
;
|
||||
|
||||
vrdList: varRefDotBit { $$ = $1; }
|
||||
vrdList<nodep>:
|
||||
varRefDotBit { $$ = $1; }
|
||||
| vrdList ',' varRefDotBit { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
|
||||
commaVRDListE: /* empty */ { $$ = NULL; }
|
||||
commaVRDListE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| ',' vrdList { $$ = $2; }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Gate declarations
|
||||
|
||||
gateDecl: yBUF delayE gateBufList ';' { $$ = $3; }
|
||||
gateDecl<nodep>:
|
||||
yBUF delayE gateBufList ';' { $$ = $3; }
|
||||
| yNOT delayE gateNotList ';' { $$ = $3; }
|
||||
| yAND delayE gateAndList ';' { $$ = $3; }
|
||||
| yNAND delayE gateNandList ';' { $$ = $3; }
|
||||
@ -1164,59 +1221,70 @@ gateDecl: yBUF delayE gateBufList ';' { $$ = $3; }
|
||||
| yXNOR delayE gateXnorList ';' { $$ = $3; }
|
||||
;
|
||||
|
||||
gateBufList: gateBuf { $$ = $1; }
|
||||
gateBufList<nodep>:
|
||||
gateBuf { $$ = $1; }
|
||||
| gateBufList ',' gateBuf { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateNotList: gateNot { $$ = $1; }
|
||||
gateNotList<nodep>:
|
||||
gateNot { $$ = $1; }
|
||||
| gateNotList ',' gateNot { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateAndList: gateAnd { $$ = $1; }
|
||||
gateAndList<nodep>:
|
||||
gateAnd { $$ = $1; }
|
||||
| gateAndList ',' gateAnd { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateNandList: gateNand { $$ = $1; }
|
||||
gateNandList<nodep>:
|
||||
gateNand { $$ = $1; }
|
||||
| gateNandList ',' gateNand { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateOrList: gateOr { $$ = $1; }
|
||||
gateOrList<nodep>:
|
||||
gateOr { $$ = $1; }
|
||||
| gateOrList ',' gateOr { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateNorList: gateNor { $$ = $1; }
|
||||
gateNorList<nodep>:
|
||||
gateNor { $$ = $1; }
|
||||
| gateNorList ',' gateNor { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateXorList: gateXor { $$ = $1; }
|
||||
gateXorList<nodep>:
|
||||
gateXor { $$ = $1; }
|
||||
| gateXorList ',' gateXor { $$ = $1->addNext($3); }
|
||||
;
|
||||
gateXnorList: gateXnor { $$ = $1; }
|
||||
gateXnorList<nodep>:
|
||||
gateXnor { $$ = $1; }
|
||||
| gateXnorList ',' gateXnor { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
gateBuf: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
gateBuf<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
;
|
||||
gateNot: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
gateNot<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
;
|
||||
gateAnd: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
gateAnd<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
;
|
||||
gateNand: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
gateNand<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
;
|
||||
gateOr: gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
gateOr<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
;
|
||||
gateNor: gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
gateNor<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
;
|
||||
gateXor: gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
gateXor<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
|
||||
;
|
||||
gateXnor: gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
gateXnor<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
|
||||
;
|
||||
|
||||
gateIdE: /*empty*/ {}
|
||||
| yaID {}
|
||||
;
|
||||
|
||||
gateAndPinList: expr { $$ = $1; }
|
||||
gateAndPinList<nodep>:
|
||||
expr { $$ = $1; }
|
||||
| gateAndPinList ',' expr { $$ = new AstAnd($2,$1,$3); }
|
||||
;
|
||||
gateOrPinList: expr { $$ = $1; }
|
||||
gateOrPinList<nodep>:
|
||||
expr { $$ = $1; }
|
||||
| gateOrPinList ',' expr { $$ = new AstOr($2,$1,$3); }
|
||||
;
|
||||
gateXorPinList: expr { $$ = $1; }
|
||||
gateXorPinList<nodep>:
|
||||
expr { $$ = $1; }
|
||||
| gateXorPinList ',' expr { $$ = new AstXor($2,$1,$3); }
|
||||
;
|
||||
|
||||
@ -1299,21 +1367,25 @@ specifyJunk: dlyTerm {} /* ignored */
|
||||
// IDs
|
||||
|
||||
// VarRef to a Memory
|
||||
varRefMem: idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VAR_MEM, $1); }
|
||||
varRefMem<parserefp>:
|
||||
idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VAR_MEM, $1); }
|
||||
;
|
||||
|
||||
// VarRef to dotted, and/or arrayed, and/or bit-ranged variable
|
||||
varRefDotBit: idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VAR_ANY, $1); }
|
||||
varRefDotBit<parserefp>:
|
||||
idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VAR_ANY, $1); }
|
||||
;
|
||||
|
||||
idDotted: idArrayed { $$ = $1; }
|
||||
idDotted<nodep>:
|
||||
idArrayed { $$ = $1; }
|
||||
| idDotted '.' idArrayed { $$ = new AstDot($2,$1,$3); }
|
||||
;
|
||||
|
||||
// Single component of dotted path, maybe [#].
|
||||
// Due to lookahead constraints, we can't know if [:] or [+:] are valid (last dotted part),
|
||||
// we'll assume so and cleanup later.
|
||||
idArrayed: yaID { $$ = new AstText(CRELINE(),*$1); }
|
||||
idArrayed<nodep>:
|
||||
yaID { $$ = new AstText(CRELINE(),*$1); }
|
||||
| idArrayed '[' expr ']' { $$ = new AstSelBit($2,$1,$3); } // Or AstArraySel, don't know yet.
|
||||
| idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2,$1,$3,$5); }
|
||||
| idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus($2,$1,$3,$5); }
|
||||
@ -1321,16 +1393,20 @@ idArrayed: yaID { $$ = new AstText(CRELINE(),*$1); }
|
||||
;
|
||||
|
||||
// VarRef without any dots or vectorizaion
|
||||
varRefBase: yaID { $$ = new AstVarRef(CRELINE(),*$1,false);}
|
||||
varRefBase<varrefp>:
|
||||
yaID { $$ = new AstVarRef(CRELINE(),*$1,false);}
|
||||
;
|
||||
|
||||
strAsInt: yaSTRING { $$ = new AstConst(CRELINE(),V3Number(V3Number::VerilogString(),CRELINE(),V3Parse::deQuote(CRELINE(),*$1)));}
|
||||
strAsInt<nodep>:
|
||||
yaSTRING { $$ = new AstConst(CRELINE(),V3Number(V3Number::VerilogString(),CRELINE(),V3Parse::deQuote(CRELINE(),*$1)));}
|
||||
;
|
||||
|
||||
strAsText: yaSTRING { $$ = V3Parse::createTextQuoted(CRELINE(),*$1);}
|
||||
strAsText<nodep>:
|
||||
yaSTRING { $$ = V3Parse::createTextQuoted(CRELINE(),*$1);}
|
||||
;
|
||||
|
||||
concIdList: varRefDotBit { $$ = $1; }
|
||||
concIdList<nodep>:
|
||||
varRefDotBit { $$ = $1; }
|
||||
| concIdList ',' varRefDotBit { $$ = new AstConcat($2,$1,$3); }
|
||||
;
|
||||
|
||||
@ -1341,10 +1417,12 @@ endLabelE: /* empty */ { }
|
||||
//************************************************
|
||||
// Asserts
|
||||
|
||||
labeledStmt: assertStmt { $$ = $1; }
|
||||
labeledStmt<nodep>:
|
||||
assertStmt { $$ = $1; }
|
||||
;
|
||||
|
||||
assertStmt: yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, V3Parse::createDisplayError($1)); }
|
||||
assertStmt<nodep>:
|
||||
yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, V3Parse::createDisplayError($1)); }
|
||||
| yASSERT '(' expr ')' yELSE stmtBlock { $$ = new AstVAssert($1,$3,NULL,$6); }
|
||||
| yASSERT '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstVAssert($1,$3,$5,$7); }
|
||||
;
|
||||
@ -1352,22 +1430,26 @@ assertStmt: yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new As
|
||||
//************************************************
|
||||
// PSL Statements
|
||||
|
||||
pslStmt: yPSL pslDir stateExitPsl { $$ = $2; }
|
||||
pslStmt<nodep>:
|
||||
yPSL pslDir stateExitPsl { $$ = $2; }
|
||||
| yPSL pslDecl stateExitPsl { $$ = $2; }
|
||||
;
|
||||
|
||||
pslDir: yaID ':' pslDirOne { $$ = $3; } // ADD: Create label on $1
|
||||
pslDir<nodep>:
|
||||
yaID ':' pslDirOne { $$ = $3; } // ADD: Create label on $1
|
||||
| pslDirOne { $$ = $1; }
|
||||
;
|
||||
|
||||
//ADD: | yRESTRICT pslSequence ';' { $$ = PSLUNSUP(new AstPslRestrict($1,$2)); }
|
||||
pslDirOne: yPSL_ASSERT pslProp ';' { $$ = new AstPslAssert($1,$2); }
|
||||
pslDirOne<nodep>:
|
||||
yPSL_ASSERT pslProp ';' { $$ = new AstPslAssert($1,$2); }
|
||||
| yPSL_ASSERT pslProp yREPORT yaSTRING ';' { $$ = new AstPslAssert($1,$2,*$4); }
|
||||
| yCOVER pslProp ';' { $$ = new AstPslCover($1,$2); }
|
||||
| yCOVER pslProp yREPORT yaSTRING ';' { $$ = new AstPslCover($1,$2,*$4); }
|
||||
;
|
||||
|
||||
pslDecl: yDEFAULT yCLOCK '=' senitemEdge ';' { $$ = new AstPslDefClock($3, $4); }
|
||||
pslDecl<nodep>:
|
||||
yDEFAULT yCLOCK '=' senitemEdge ';' { $$ = new AstPslDefClock($3, $4); }
|
||||
| yDEFAULT yCLOCK '=' '(' senitemEdge ')' ';' { $$ = new AstPslDefClock($3, $5); }
|
||||
;
|
||||
|
||||
@ -1375,19 +1457,22 @@ pslDecl: yDEFAULT yCLOCK '=' senitemEdge ';' { $$ = new AstPslDefClock($3, $4);
|
||||
// PSL Properties, Sequences and SEREs
|
||||
// Don't use '{' or '}'; in PSL they're yPSL_BRA and yPSL_KET to avoid expr concatenates
|
||||
|
||||
pslProp: pslSequence { $$ = $1; }
|
||||
pslProp<nodep>:
|
||||
pslSequence { $$ = $1; }
|
||||
| pslSequence '@' %prec prPSLCLK '(' senitemEdge ')' { $$ = new AstPslClocked($2, $4, $1); } // or pslSequence @ ...?
|
||||
;
|
||||
|
||||
//ADD: | pslCallSeq { $$ = PSLUNSUP($1); }
|
||||
//ADD: | pslRepeat { $$ = PSLUNSUP($1); }
|
||||
pslSequence: yPSL_BRA pslSere yPSL_KET { $$ = $2; }
|
||||
pslSequence<nodep>:
|
||||
yPSL_BRA pslSere yPSL_KET { $$ = $2; }
|
||||
;
|
||||
|
||||
//ADD: | pslSere ';' pslSere %prec prPSLCONC { $$ = PSLUNSUP(new AstPslSeqConcat($2, $1, $3)); }
|
||||
//ADD: | pslSere ':' pslSere %prec prPSLFUS { $$ = PSLUNSUP(new AstPslSeqFusion($2, $1, $3)); }
|
||||
//ADD: | pslSereCpnd { $$ = $1; }
|
||||
pslSere: pslExpr { $$ = $1; }
|
||||
pslSere<nodep>:
|
||||
pslExpr { $$ = $1; }
|
||||
| pslSequence { $$ = $1; } // Sequence containing sequence
|
||||
;
|
||||
|
||||
@ -1395,7 +1480,8 @@ pslSere: pslExpr { $$ = $1; }
|
||||
// This can be bypassed with the _(...) embedding of any arbitrary expression.
|
||||
//ADD: | pslFunc { $$ = UNSUP($1); }
|
||||
//ADD: | pslExpr yUNION pslExpr { $$ = UNSUP(new AstPslUnion($2, $1, $3)); }
|
||||
pslExpr: exprPsl { $$ = new AstPslBool($1->fileline(), $1); }
|
||||
pslExpr<nodep>:
|
||||
exprPsl { $$ = new AstPslBool($1->fileline(), $1); }
|
||||
| yTRUE { $$ = new AstPslBool($1, new AstConst($1, V3Number($1,1,1))); }
|
||||
;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user