From b3dd18b215364243b88efff0c0ee4ca6963fe340 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 14 May 2007 20:59:58 +0000 Subject: [PATCH] More bison cleanup; no functional change git-svn-id: file://localhost/svn/verilator/trunk/verilator@921 77ca24e4-aefa-0310-84f0-b9a241c72d87 --- TODO | 2 +- nodist/bisonreader | 67 +++++++++++ src/verilog.y | 293 ++++++++++++++++++++++++--------------------- 3 files changed, 226 insertions(+), 136 deletions(-) create mode 100755 nodist/bisonreader diff --git a/TODO b/TODO index f4532efc1..6bf4fa65a 100644 --- a/TODO +++ b/TODO @@ -26,11 +26,11 @@ Features: Points should be per-scope like everything else rather then per-module Expression coverage (see notes) More Verilog 2001 Support - C-style function and task arguments. [Wim Michiels] (* *) Attributes (just ignore -- preprocessor?) Real numbers (NEVER) Recursive functions (NEVER) Verilog configuration files (NEVER) + DPI to define C/C++ calls from Verilog Long-term Features Assertions diff --git a/nodist/bisonreader b/nodist/bisonreader new file mode 100755 index 000000000..fa4d172ea --- /dev/null +++ b/nodist/bisonreader @@ -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 () { + $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: diff --git a/src/verilog.y b/src/verilog.y index 0f8613b68..74ad2eebf 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -283,21 +283,21 @@ class AstSenTree; // Types are in same order as declarations. // Naming: // Trailing E indicates this type may have empty match -%type mheader -%type modportsE portList port -%type v2kPortList v2kPortSig -%type v2kPort ioDecl varDecl +%type modHdr +%type modPortsE portList port +%type portV2kList portV2kSig +%type portV2kDecl ioDecl varDecl %type modParDecl modParList modParE %type modItem modItemList modItemListE modOrGenItem %type genItem genItemList genItemBegin genItemBlock genTopBlock genCaseList -%type dterm -%type onesig sigId sigIdRange paramId sigList regsig regsigList regSigId +%type dlyTerm +%type sigAndAttr sigId sigIdRange sigList regsig regsigList regSigId %type netSig netSigList -%type rangeListE regrangeE anyrange rangeList delayrange portrangeE +%type rangeListE regrangeE anyrange rangeList delayrange portRangeE %type param paramList %type instnameList %type instname -%type cellpinList cellpinlist2 cellpinitemE instparamListE +%type cellpinList cellpinItList cellpinitemE instparamListE %type defpList defpOne %type sensitivityE %type senList senitem senitemEdge @@ -306,9 +306,9 @@ class AstSenTree; %type beginNamed %type caseStmt %type caseList -%type casecondList assignList assignOne +%type caseCondList assignList assignOne %type constExpr exprNoStr expr exprPsl exprStrText -%type eList cateList cStrList +%type exprList cateList cStrList %type varRefBase %type varRefMem %type varRefDotBit @@ -321,7 +321,7 @@ class AstSenTree; %type varDeclList %type funcDecl %type funcBody funcVarList funcVar -%type funcRange +%type funcRangeE %type gateDecl %type gateBufList gateNotList gateAndList gateNandList %type gateOrList gateNorList gateXorList gateXnorList @@ -347,18 +347,21 @@ statePop: { V3Read::statePop(); } ; //********************************************************************** -// Modules +// Files file: mod | file mod ; -mod: mheader modParE modportsE ';' modItemListE yENDMODULE +//********************************************************************** +// Module headers + +mod: modHdr modParE modPortsE ';' modItemListE yENDMODULE { $1->modTrace(V3Parse::s_trace); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); } ; -mheader: yMODULE { V3Parse::s_trace=v3Global.opt.trace();} +modHdr: yMODULE { V3Parse::s_trace=v3Global.opt.trace();} yaID { $$ = new AstModule($1,*$3); $$->inLibrary(V3Read::inLibrary()); $$->modTrace(v3Global.opt.trace()); V3Read::rootp()->addModulep($$); } @@ -374,28 +377,56 @@ modParList: modParDecl { $$ = $1; } | modParList ';' modParDecl { $$ = $1->addNext($3); } ; -modportsE: /* empty */ { $$ = NULL; } +modPortsE: /* empty */ { $$ = NULL; } | '(' ')' { $$ = NULL; } | '(' {V3Parse::s_pinNum=1;} portList ')' { $$ = $3; } - | '(' {V3Parse::s_pinNum=1;} v2kPortList ')' { $$ = $3; } + | '(' {V3Parse::s_pinNum=1;} portV2kList ')' { $$ = $3; } ; portList: port { $$ = $1; } | portList ',' port { $$ = $1->addNext($3); } ; -port: yaID portrangeE { $$ = new AstPort(CRELINE(),V3Parse::s_pinNum++,*$1); } +port: yaID portRangeE { $$ = new AstPort(CRELINE(),V3Parse::s_pinNum++,*$1); } ; -v2kPortList: v2kPort { $$ = $1; } - | v2kPortList ',' v2kPort { $$ = $1->addNext($3); } +portV2kList: portV2kDecl { $$ = $1; } + | portV2kList ',' portV2kDecl { $$ = $1->addNext($3); } ; -v2kPortSig: onesig { $$=$1; $$->addNext(new AstPort(CRELINE(),V3Parse::s_pinNum++, V3Parse::s_varAttrp->name())); } +portV2kSig: sigAndAttr { $$=$1; $$->addNext(new AstPort(CRELINE(),V3Parse::s_pinNum++, V3Parse::s_varAttrp->name())); } ; //************************************************ -// Variables +// Variable Declarations + +varDeclList: varDecl { $$ = $1; } + | varDecl varDeclList { $$ = $1->addNext($2); } + ; + +regsigList: regsig { $$ = $1; } + | regsigList ',' regsig { $$ = $1;$1->addNext($3); } + ; + +portV2kDecl: varRESET varInput varSignedE v2kNetDeclE regrangeE portV2kSig { $$ = $6; } + | varRESET varInout varSignedE v2kNetDeclE regrangeE portV2kSig { $$ = $6; } + | varRESET varOutput varSignedE v2kVarDecl regrangeE portV2kSig { $$ = $6; } + ; + +ioDecl: varRESET varInput varSignedE v2kNetDeclE regrangeE sigList ';' { $$ = $6; } + | varRESET varInout varSignedE v2kNetDeclE regrangeE sigList ';' { $$ = $6; } + | varRESET varOutput varSignedE v2kVarDecl regrangeE sigList ';' { $$ = $6; } + ; + +varDecl: varRESET varReg varSignedE regrangeE regsigList ';' { $$ = $5; } + | varRESET varGParam varSignedE regrangeE paramList ';' { $$ = $5; } + | varRESET varLParam varSignedE regrangeE paramList ';' { $$ = $5; } + | varRESET varNet varSignedE delayrange netSigList ';' { $$ = $5; } + | varRESET varGenVar varSignedE regsigList ';' { $$ = $4; } + ; + +modParDecl: varRESET varGParam varSignedE regrangeE paramList { $$ = $5; } /* No semicolon*/ + ; varRESET: /* empty */ { VARRESET(); } ; @@ -434,28 +465,8 @@ v2kVarDecl: v2kNetDeclE { } | varReg { } ; -v2kPort: varRESET varInput varSignedE v2kNetDeclE regrangeE v2kPortSig { $$ = $6; } - | varRESET varInout varSignedE v2kNetDeclE regrangeE v2kPortSig { $$ = $6; } - | varRESET varOutput varSignedE v2kVarDecl regrangeE v2kPortSig { $$ = $6; } - ; - -ioDecl: varRESET varInput varSignedE v2kNetDeclE regrangeE sigList ';' { $$ = $6; } - | varRESET varInout varSignedE v2kNetDeclE regrangeE sigList ';' { $$ = $6; } - | varRESET varOutput varSignedE v2kVarDecl regrangeE sigList ';' { $$ = $6; } - ; - -varDecl: varRESET varReg varSignedE regrangeE regsigList ';' { $$ = $5; } - | varRESET varGParam varSignedE regrangeE paramList ';' { $$ = $5; } - | varRESET varLParam varSignedE regrangeE paramList ';' { $$ = $5; } - | varRESET varNet varSignedE delayrange netSigList ';' { $$ = $5; } - | varRESET varGenVar varSignedE regsigList ';' { $$ = $4; } - ; - -modParDecl: varRESET varGParam varSignedE regrangeE paramList { $$ = $5; } /* No semicolon*/ - ; - //************************************************ -// modItemList +// Module Items modItemListE: /* empty */ { $$ = NULL; } | modItemList { $$ = $1; } @@ -497,7 +508,7 @@ modOrGenItem: yALWAYS sensitivityE stmtBlock { $$ = new AstAlways($1,$2,$3); } ; //************************************************ -// genmodItemList +// Generates // Because genItemList includes variable declarations, we don't need beginNamed genItemBlock: genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); } @@ -508,7 +519,7 @@ genTopBlock: genItemList { $$ = $1; } | genItemBegin { $$ = $1; } ; -genItemBegin: yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); } +genItemBegin: yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); } | yBEGIN yEND { $$ = NULL; } | yBEGIN ':' yaID genItemList yEND { $$ = new AstBegin($2,*$3,$4); } | yBEGIN ':' yaID yEND { $$ = NULL; } @@ -528,20 +539,16 @@ genItem: modOrGenItem { $$ = $1; } ,$13);} ; -genCaseList: casecondList ':' genItemBlock { $$ = new AstCaseItem($2,$1,$3); } +genCaseList: 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)); } + | genCaseList caseCondList ':' genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } | genCaseList yDEFAULT genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); } | genCaseList yDEFAULT ':' genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); } ; //************************************************ -// modItems - -varDeclList: varDecl { $$ = $1; } - | varDecl varDeclList { $$ = $1->addNext($2); } - ; +// Assignments and register declarations assignList: assignOne { $$ = $1; } | assignList ',' assignOne { $$ = $1->addNext($3); } @@ -552,22 +559,28 @@ assignOne: varRefDotBit '=' expr { $$ = new AstAssignW($2,$1,$3); } ; delayE: /* empty */ - | '#' dterm {} /* ignored */ - | '#' '(' dterm ')' {} /* ignored */ - | '#' '(' dterm ',' dterm ')' {} /* ignored */ - | '#' '(' dterm ',' dterm ',' dterm ')' {} /* ignored */ + | '#' dlyTerm {} /* ignored */ + | '#' '(' dlyTerm ')' {} /* ignored */ + | '#' '(' dlyTerm ',' dlyTerm ')' {} /* ignored */ + | '#' '(' dlyTerm ',' dlyTerm ',' dlyTerm ')' {} /* ignored */ ; -dterm: yaID { $$ = NULL; } +dlyTerm: yaID { $$ = NULL; } | yaINTNUM { $$ = NULL; } | yaFLOATNUM { $$ = NULL; } ; -onesig: sigId { $$=$1; } - | sigId sigAttrList { $$=$1; } +sigAndAttr: sigId { $$ = $1; } + | sigId sigAttrList { $$ = $1; } ; -sigId: yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); } +netSigList: netSig { $$ = $1; } + | netSigList ',' netSig { $$ = $1; $1->addNext($3); } + ; + +netSig: 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); } @@ -578,7 +591,15 @@ regSigId: yaID rangeListE { $$ = V3Parse::createVariable(CRELINE(), *$1, $2); $$->addNext(new AstInitial($3,new AstAssign($3, new AstVarRef($3, $$, true), $4))); } ; -paramId: yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); } +sigId: yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); } + ; + +sigList: sigAndAttr { $$ = $1; } + | sigList ',' sigAndAttr { $$ = $1; $1->addNext($3); } + ; + +regsig: regSigId {} + | regSigId sigAttrList {} ; sigAttrListE: /*empty*/ {} @@ -596,27 +617,6 @@ sigAttr: yVL_CLOCK { V3Parse::s_varAttrp->attrScClocked(true); } | yVL_ISOLATE_ASSIGNMENTS { V3Parse::s_varAttrp->attrIsolateAssign(true); } ; -sigList: onesig { $$ = $1; } - | sigList ',' onesig { $$ = $1; $1->addNext($3); } - ; - -netSig: sigId sigAttrListE { $$ = $1; } - | sigId sigAttrListE '=' expr { $$ = $1; $1->addNext(new AstAssignW($3,new AstVarRef($3,$1->name(),true),$4)); } - | sigIdRange sigAttrListE { $$ = $1; } - ; - -netSigList: netSig { $$ = $1; } - | netSigList ',' netSig { $$ = $1;$1->addNext($3); } - ; - -regsig: regSigId {} - | regSigId sigAttrList {} - ; - -regsigList: regsig { $$ = $1; } - | regsigList ',' regsig { $$ = $1;$1->addNext($3); } - ; - rangeListE: /* empty */ { $$ = NULL; } | rangeList { $$ = $1; } ; @@ -637,13 +637,15 @@ delayrange: delayE regrangeE { $$ = $2; } | yVECTORED delayE regrangeE { $$ = $3; } ; -portrangeE: /* empty */ { $$ = NULL; } +portRangeE: /* empty */ { $$ = NULL; } | '[' constExpr ']' { $$ = NULL; $1->v3error("Ranges ignored on port-list.\n"); } | '[' constExpr ':' constExpr ']' { $$ = NULL; $1->v3error("Ranges ignored on port-list.\n"); } ; +//************************************************ // Parameters -param: paramId sigAttrListE '=' expr { $$ = $1; $$->initp($4); } + +param: sigId sigAttrListE '=' expr { $$ = $1; $$->initp($4); } ; paramList: param { $$ = $1; } @@ -657,7 +659,9 @@ defpList: defpOne { $$ = $1; } defpOne: yaID '.' yaID '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); } ; +//************************************************ // Instances + instparamListE: /* empty */ { $$ = NULL; } | '#' '(' cellpinList ')' { $$ = $3; } ; @@ -666,14 +670,14 @@ instnameList: instname { $$ = $1; } | instnameList ',' instname { $$ = $1->addNext($3); } ; -instname: yaID funcRange '(' cellpinList ')' { $$ = new AstCell($3,*$1,V3Parse::s_instModule,$4,V3Parse::s_instParamp,$2); $$->pinStar(V3Parse::s_pinStar); } +instname: yaID funcRangeE '(' cellpinList ')' { $$ = new AstCell($3,*$1,V3Parse::s_instModule,$4,V3Parse::s_instParamp,$2); $$->pinStar(V3Parse::s_pinStar); } ; -cellpinList: {V3Parse::s_pinNum=1; V3Parse::s_pinStar=false; } cellpinlist2 { $$ = $2; } +cellpinList: {V3Parse::s_pinNum=1; V3Parse::s_pinStar=false; } cellpinItList { $$ = $2; } ; -cellpinlist2: cellpinitemE { $$ = $1; } - | cellpinlist2 ',' cellpinitemE { $$ = $1->addNextNull($3)->castPin(); } +cellpinItList: cellpinitemE { $$ = $1; } + | cellpinItList ',' cellpinitemE { $$ = $1->addNextNull($3)->castPin(); } ; cellpinitemE: /* empty */ { $$ = NULL; V3Parse::s_pinNum++; } @@ -684,6 +688,9 @@ cellpinitemE: /* empty */ { $$ = NULL; V3Parse::s_pinNum++; } | expr { $$ = new AstPin(CRELINE(),V3Parse::s_pinNum++,"",$1); } ; +//************************************************ +// Sensitivity lists + sensitivityE: /* empty */ { $$ = NULL; } | '@' '(' senList ')' { $$ = new AstSenTree($1,$3); } | '@' senitem { $$ = new AstSenTree($1,$2); } @@ -697,7 +704,6 @@ senList: senitem { $$ = $1; } ; senitem: senitemEdge { $$ = $1; } -//FIX need range ignoring to be stripped later, this was simple varXRef | varRefDotBit { $$ = new AstSenItem(CRELINE(),AstEdgeType::ANYEDGE,$1); } ; @@ -705,6 +711,9 @@ senitemEdge: yPOSEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::POSED | yNEGEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::NEGEDGE,$2); } ; +//************************************************ +// Statements + stmtBlock: stmt { $$ = $1; } | yBEGIN stmtList yEND { $$ = $2; } | yBEGIN yEND { $$ = NULL; } @@ -759,11 +768,10 @@ stmt: ';' { $$ = NULL; } | yD_READMEMH '(' expr ',' varRefMem ')' ';' { $$ = new AstReadMem($1,true, $3,$5,NULL,NULL); } | yD_READMEMH '(' expr ',' varRefMem ',' expr ')' ';' { $$ = new AstReadMem($1,true, $3,$5,$7,NULL); } | yD_READMEMH '(' expr ',' varRefMem ',' expr ',' expr ')' ';' { $$ = new AstReadMem($1,true, $3,$5,$7,$9); } - ; -labeledStmt: assertStmt { $$ = $1; } - ; +//************************************************ +// Case/If stateCaseForIf: caseStmt caseAttrE caseList yENDCASE { $$ = $1; $1->addItemsp($3); } | yIF expr stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstIf($1,$2,$3,NULL); } @@ -776,11 +784,6 @@ stateCaseForIf: caseStmt caseAttrE caseList yENDCASE { $$ = $1; $1->addItemsp($3 | yDO stmtBlock yWHILE '(' expr ')' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));} ; -assertStmt: 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); } - ; - caseStmt: yCASE '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,false,$3,NULL); } | yCASEX '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,true,$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,true,$3,NULL); } @@ -791,33 +794,43 @@ caseAttrE: /*empty*/ { } | caseAttrE yVL_PARALLEL_CASE { V3Parse::s_caseAttrp->parallelPragma(true); } ; -caseList: casecondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); } +caseList: 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)); } + | caseList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } | caseList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); } | caseList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); } ; -casecondList: expr { $$ = $1; } - | casecondList ',' expr { $$ = $1;$1->addNext($3); } +caseCondList: expr { $$ = $1; } + | caseCondList ',' expr { $$ = $1;$1->addNext($3); } + ; + +//************************************************ +// Functions/tasks + +taskRef: 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); } ; taskDecl: yTASK yaID ';' stmtBlock yENDTASK { $$ = new AstTask ($1,*$2,$4);} | yTASK yaID ';' funcVarList stmtBlock yENDTASK { $$ = new AstTask ($1,*$2,$4); $4->addNextNull($5); } ; -funcDecl: yFUNCTION funcRange yaID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$3,$5,$2); } - | yFUNCTION ySIGNED funcRange yaID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); $$->isSigned(true); } - | yFUNCTION funcRange yaID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$3,$6,$2); $$->attrIsolateAssign(true);} - | yFUNCTION ySIGNED funcRange yaID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$7,$3); $$->attrIsolateAssign(true); $$->isSigned(true); } +funcDecl: yFUNCTION funcRangeE yaID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$3,$5,$2); } + | yFUNCTION ySIGNED funcRangeE yaID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); $$->isSigned(true); } + | yFUNCTION funcRangeE yaID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$3,$6,$2); $$->attrIsolateAssign(true);} + | yFUNCTION ySIGNED funcRangeE yaID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$7,$3); $$->attrIsolateAssign(true); $$->isSigned(true); } ; funcBody: funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); } ; -funcRange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } - | { $$ = NULL; } +funcRangeE: /* empty */ { $$ = NULL; } + | '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; funcVarList: funcVar { $$ = $1; } @@ -830,6 +843,9 @@ funcVar: ioDecl { $$ = $1; } | yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); } ; +//************************************************ +// Expressions + constExpr: expr { $$ = $1; } ; @@ -919,15 +935,17 @@ cateList: expr { $$ = $1; } | cateList ',' expr { $$ = new AstConcat($2,$1,$3); } ; -eList: expr { $$ = $1; } - | eList ',' expr { $$ = $1;$1->addNext($3); } +exprList: expr { $$ = $1; } + | exprList ',' expr { $$ = $1;$1->addNext($3); } ; commaEListE: /* empty */ { $$ = NULL; } - | ',' eList { $$ = $2; } + | ',' exprList { $$ = $2; } ; +//************************************************ // Gate declarations + gateDecl: yBUF gateBufList ';' { $$ = $2; } | yNOT gateNotList ';' { $$ = $2; } | yAND gateAndList ';' { $$ = $2; } @@ -963,10 +981,6 @@ gateXnorList: gateXnor { $$ = $1; } | gateXnor ',' gateXnor { $$ = $1->addNext($3); } ; -gateIdE: /*empty*/ {} - | yaID {} - ; - gateBuf: gateIdE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($2,$3,$5); $$->allowImplicit(true); } ; gateNot: gateIdE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($2,$3,new AstNot($4,$5)); $$->allowImplicit(true); } @@ -984,6 +998,10 @@ gateXor: gateIdE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ( gateXnor: gateIdE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($2,$3,new AstNot($4,$5)); $$->allowImplicit(true); } ; +gateIdE: /*empty*/ {} + | yaID {} + ; + gateAndPinList: expr { $$ = $1; } | gateAndPinList ',' expr { $$ = new AstAnd($2,$1,$3); } ; @@ -996,11 +1014,12 @@ gateXorPinList: expr { $$ = $1; } //************************************************ // Specify + specifyJunkList: specifyJunk /* ignored */ | specifyJunkList specifyJunk /* ignored */ ; -specifyJunk: dterm {} /* ignored */ +specifyJunk: dlyTerm {} /* ignored */ | ';' {} | '!' {} | '&' {} @@ -1045,24 +1064,6 @@ specifyJunk: dterm {} /* ignored */ //************************************************ // IDs -// 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 '[' 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); } - | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); } - ; - -idDotted: idArrayed { $$ = $1; } - | idDotted '.' idArrayed { $$ = new AstDot($2,$1,$3); } - ; - -// VarRef without any dots or vectorizaion -varRefBase: yaID { $$ = new AstVarRef(CRELINE(),*$1,false);} - ; - // VarRef to a Memory varRefMem: idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VAR_MEM, $1); } ; @@ -1071,11 +1072,22 @@ varRefMem: idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VA varRefDotBit: idDotted { $$ = new AstParseRef($1->fileline(), AstParseRefExp::VAR_ANY, $1); } ; -taskRef: idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),NULL);} - | idDotted '(' eList ')' { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),$3);} +idDotted: idArrayed { $$ = $1; } + | idDotted '.' idArrayed { $$ = new AstDot($2,$1,$3); } ; -funcRef: idDotted '(' eList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $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 '[' 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); } + | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); } + ; + +// VarRef without any dots or vectorizaion +varRefBase: yaID { $$ = new AstVarRef(CRELINE(),*$1,false);} ; strAsInt: yaSTRING { $$ = new AstConst(CRELINE(),V3Number(V3Number::VerilogString(),CRELINE(),V3Parse::deQuote(CRELINE(),*$1)));} @@ -1088,6 +1100,17 @@ concIdList: varRefDotBit { $$ = $1; } | concIdList ',' varRefDotBit { $$ = new AstConcat($2,$1,$3); } ; +//************************************************ +// Asserts + +labeledStmt: assertStmt { $$ = $1; } + ; + +assertStmt: 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); } + ; + //************************************************ // PSL Statements