2012-04-13 01:08:20 +00:00
// -*- mode: C++; c-file-style: "cc-mode" -*-
2006-08-26 11:35:28 +00:00
//*************************************************************************
// DESCRIPTION: Verilator: Bison grammer file
//
2008-04-25 12:14:27 +00:00
// Code available from: http://www.veripool.org/verilator
2006-08-26 11:35:28 +00:00
//
//*************************************************************************
//
2014-01-07 00:28:57 +00:00
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
2006-08-26 11:35:28 +00:00
// redistribute it and/or modify it under the terms of either the GNU
2009-05-04 21:07:57 +00:00
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
2006-08-26 11:35:28 +00:00
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
// Original code here by Paul Wasson and Duane Galbi
//*************************************************************************
%{
2008-06-30 17:11:25 +00:00
#include <cstdio>
2008-05-28 19:58:18 +00:00
#include <cstdlib>
2006-08-26 11:35:28 +00:00
#include <cstdarg>
2008-05-28 19:58:18 +00:00
#include <cstring>
2006-08-26 11:35:28 +00:00
#include "V3Ast.h"
#include "V3Global.h"
2010-01-21 11:11:30 +00:00
#include "V3Config.h"
2009-10-31 14:08:38 +00:00
#include "V3ParseImp.h" // Defines YYTYPE; before including bison header
2006-08-26 11:35:28 +00:00
2007-05-16 12:55:25 +00:00
#define YYERROR_VERBOSE 1
2008-09-17 15:11:09 +00:00
#define YYINITDEPTH 10000 // Older bisons ignore YYMAXDEPTH
2008-08-20 19:59:10 +00:00
#define YYMAXDEPTH 10000
2006-08-26 11:35:28 +00:00
// Pick up new lexer
2009-10-31 14:08:38 +00:00
#define yylex PARSEP->lexToBison
2010-01-08 03:08:48 +00:00
#define GATEUNSUP(fl,tok) { if (!v3Global.opt.bboxUnsup()) { (fl)->v3error("Unsupported: Verilog 1995 gate primitive: "<<(tok)); } }
2006-08-26 11:35:28 +00:00
2009-05-07 22:28:05 +00:00
extern void yyerror(const char* errmsg);
2006-08-26 11:35:28 +00:00
extern void yyerrorf(const char* format, ...);
//======================================================================
// Statics (for here only)
2009-11-08 02:05:02 +00:00
#define PARSEP V3ParseImp::parsep()
#define SYMP PARSEP->symp()
#define GRAMMARP V3ParseGrammar::singletonp()
2009-10-31 14:08:38 +00:00
class V3ParseGrammar {
2006-08-26 11:35:28 +00:00
public:
2009-10-31 14:08:38 +00:00
bool m_impliedDecl; // Allow implied wire declarations
AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc)
AstVarType m_varIO; // Type for next signal declaration (input/output/etc)
AstVar* m_varAttrp; // Current variable for attribute adding
AstCase* m_caseAttrp; // Current case statement for attribute adding
2009-11-02 13:06:04 +00:00
AstNodeDType* m_varDTypep; // Pointer to data type for next signal declaration
2012-07-29 14:16:20 +00:00
AstNodeDType* m_memDTypep; // Pointer to data type for next member declaration
2009-10-31 14:08:38 +00:00
int m_pinNum; // Pin number currently parsing
string m_instModule; // Name of module referenced for instantiations
AstPin* m_instParamp; // Parameters for instantiations
2010-01-07 00:04:20 +00:00
AstNodeModule* m_modp; // Module
int m_modTypeImpNum; // Implicit type number, incremented each module
2009-10-31 14:08:38 +00:00
// CONSTRUCTORS
V3ParseGrammar() {
m_impliedDecl = false;
m_varDecl = AstVarType::UNKNOWN;
m_varIO = AstVarType::UNKNOWN;
2009-11-02 13:06:04 +00:00
m_varDTypep = NULL;
2012-07-29 14:16:20 +00:00
m_memDTypep = NULL;
2009-10-31 14:08:38 +00:00
m_pinNum = -1;
2011-08-23 01:02:09 +00:00
m_instModule = "";
2009-10-31 14:08:38 +00:00
m_instParamp = NULL;
2010-01-07 00:04:20 +00:00
m_modp = NULL;
m_modTypeImpNum = 0;
2009-10-31 14:08:38 +00:00
m_varAttrp = NULL;
m_caseAttrp = NULL;
}
static V3ParseGrammar* singletonp() {
static V3ParseGrammar singleton;
return &singleton;
}
// METHODS
2013-08-18 00:34:49 +00:00
void argWrapList(AstNodeFTaskRef* nodep);
2010-04-10 00:40:41 +00:00
AstNodeDType* createArray(AstNodeDType* basep, AstRange* rangep, bool isPacked);
2009-10-31 14:08:38 +00:00
AstVar* createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp);
AstNode* createSupplyExpr(FileLine* fileline, string name, int value);
AstText* createTextQuoted(FileLine* fileline, string text) {
string newtext = deQuote(fileline, text);
return new AstText(fileline, newtext);
}
AstDisplay* createDisplayError(FileLine* fileline) {
2010-02-02 01:15:48 +00:00
AstDisplay* nodep = new AstDisplay(fileline,AstDisplayType::DT_ERROR, "", NULL,NULL);
2007-05-12 16:29:25 +00:00
nodep->addNext(new AstStop(fileline));
2007-03-06 21:43:38 +00:00
return nodep;
}
2012-03-08 01:14:18 +00:00
void endLabel(FileLine* fl, AstNode* nodep, string* endnamep) { endLabel(fl, nodep->prettyName(), endnamep); }
void endLabel(FileLine* fl, string name, string* endnamep) {
if (fl && endnamep && *endnamep != "" && name != *endnamep) {
fl->v3warn(ENDLABEL,"End label '"<<*endnamep<<"' does not match begin label '"<<name<<"'");
}
}
2009-11-02 13:06:04 +00:00
void setDType(AstNodeDType* dtypep) {
if (m_varDTypep) { m_varDTypep->deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe.
m_varDTypep = dtypep;
2009-10-31 14:08:38 +00:00
}
2012-03-20 20:01:53 +00:00
AstPackage* unitPackage(FileLine* fl) {
2009-11-08 02:05:02 +00:00
// Find one made earlier?
2012-06-20 10:13:28 +00:00
AstPackage* pkgp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName())->nodep()->castPackage();
2009-11-08 02:05:02 +00:00
if (!pkgp) {
2013-01-17 23:36:20 +00:00
pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
2010-01-07 00:04:20 +00:00
GRAMMARP->m_modp = pkgp; GRAMMARP->m_modTypeImpNum = 0;
2009-11-08 02:05:02 +00:00
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
}
return pkgp;
}
2010-04-10 00:40:41 +00:00
AstNodeDType* addRange(AstBasicDType* dtypep, AstRange* rangesp, bool isPacked) {
2010-01-26 13:06:39 +00:00
// If dtypep isn't basic, don't use this, call createArray() instead
2009-11-05 14:57:23 +00:00
if (!rangesp) {
return dtypep;
} else {
2010-01-26 13:06:39 +00:00
// If rangesp is "wire [3:3][2:2][1:1] foo [5:5][4:4]"
// then [1:1] becomes the basicdtype range; everything else is arraying
// the final [5:5][4:4] will be passed in another call to createArray
2009-11-05 14:57:23 +00:00
AstRange* rangearraysp = NULL;
2012-02-20 16:48:31 +00:00
if (dtypep->isRanged()) {
2009-11-05 14:57:23 +00:00
rangearraysp = rangesp; // Already a range; everything is an array
} else {
2010-01-26 13:06:39 +00:00
AstRange* finalp = rangesp;
while (finalp->nextp()) finalp=finalp->nextp()->castRange();
if (finalp != rangesp) {
finalp->unlinkFrBack();
rangearraysp = rangesp;
2009-11-05 14:57:23 +00:00
}
2012-04-29 14:14:13 +00:00
if (dtypep->implicit()) {
// It's no longer implicit but a real logic type
AstBasicDType* newp = new AstBasicDType(dtypep->fileline(), AstBasicDTypeKwd::LOGIC,
dtypep->numeric(), dtypep->width(), dtypep->widthMin());
dtypep->deleteTree(); dtypep=NULL;
dtypep = newp;
}
2010-01-26 13:06:39 +00:00
dtypep->rangep(finalp);
2009-11-05 14:57:23 +00:00
}
2010-04-10 00:40:41 +00:00
return createArray(dtypep, rangearraysp, isPacked);
2009-11-05 14:57:23 +00:00
}
}
2009-10-31 14:08:38 +00:00
string deQuote(FileLine* fileline, string text);
2009-12-03 11:55:29 +00:00
void checkDpiVer(FileLine* fileline, const string& str) {
2009-12-04 12:05:44 +00:00
if (str != "DPI-C" && !v3Global.opt.bboxSys()) {
fileline->v3error("Unsupported DPI type '"<<str<<"': Use 'DPI-C'");
}
2009-12-03 11:55:29 +00:00
}
2009-10-31 14:08:38 +00:00
};
2009-11-02 13:06:04 +00:00
const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
2009-11-03 03:14:11 +00:00
const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
2009-11-02 13:06:04 +00:00
2009-05-07 22:28:05 +00:00
//======================================================================
// Macro functions
2011-01-19 02:12:31 +00:00
#define CRELINE() (PARSEP->copyOrSameFileLine()) // Only use in empty rules, so lines point at beginnings
2007-05-16 12:55:25 +00:00
2009-10-31 14:08:38 +00:00
#define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist
#define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist
2009-11-02 13:06:04 +00:00
#define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARDTYPE(NULL); }
2009-10-31 14:08:38 +00:00
#define VARDECL(type) { GRAMMARP->m_varDecl = AstVarType::type; }
#define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; }
2009-11-02 13:06:04 +00:00
#define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); }
2009-05-07 22:28:05 +00:00
2011-01-19 02:12:31 +00:00
#define VARDONEA(fl,name,array,attrs) GRAMMARP->createVariable((fl),(name),(array),(attrs))
2009-10-31 14:08:38 +00:00
#define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs))
#define PINNUMINC() (GRAMMARP->m_pinNum++)
2007-05-16 12:55:25 +00:00
2009-10-31 14:08:38 +00:00
#define INSTPREP(modname,paramsp) { GRAMMARP->m_impliedDecl = true; GRAMMARP->m_instModule = modname; GRAMMARP->m_instParamp = paramsp; }
2006-08-26 11:35:28 +00:00
2012-05-31 03:17:55 +00:00
#define DEL(nodep) { if (nodep) nodep->deleteTree(); }
2009-09-07 19:54:12 +00:00
static void ERRSVKWD(FileLine* fileline, const string& tokname) {
static int toldonce = 0;
fileline->v3error((string)"Unexpected \""+tokname+"\": \""+tokname+"\" is a SystemVerilog keyword misused as an identifier.");
if (!toldonce++) fileline->v3error("Modify the Verilog-2001 code to avoid SV keywords, or use `begin_keywords or --language.");
}
2006-08-26 11:35:28 +00:00
//======================================================================
class AstSenTree;
%}
2009-01-28 20:27:41 +00:00
// When writing Bison patterns we use yTOKEN instead of "token",
// so Bison will error out on unknown "token"s.
2007-05-12 16:29:25 +00:00
// Generic lexer tokens, for example a number
2007-10-26 14:58:26 +00:00
// IEEE: real_number
2007-05-12 16:29:25 +00:00
%token<cdouble> yaFLOATNUM "FLOATING-POINT NUMBER"
2009-01-28 20:27:41 +00:00
2007-10-26 14:58:26 +00:00
// IEEE: identifier, class_identifier, class_variable_identifier,
// covergroup_variable_identifier, dynamic_array_variable_identifier,
// enum_identifier, interface_identifier, interface_instance_identifier,
// package_identifier, type_identifier, variable_identifier,
2009-05-07 22:28:05 +00:00
%token<strp> yaID__ETC "IDENTIFIER"
2009-10-31 03:17:56 +00:00
%token<strp> yaID__LEX "IDENTIFIER-in-lex"
2009-11-08 02:05:02 +00:00
%token<strp> yaID__aPACKAGE "PACKAGE-IDENTIFIER"
2009-11-07 04:16:06 +00:00
%token<strp> yaID__aTYPE "TYPE-IDENTIFIER"
2012-10-09 01:20:13 +00:00
// Can't predecode aFUNCTION, can declare after use
// Can't predecode aINTERFACE, can declare after use
// Can't predecode aTASK, can declare after use
2007-10-26 14:58:26 +00:00
// IEEE: integral_number
%token<nump> yaINTNUM "INTEGER NUMBER"
2008-10-14 18:49:54 +00:00
// IEEE: time_literal + time_unit
%token<cdouble> yaTIMENUM "TIME NUMBER"
2007-10-26 14:58:26 +00:00
// IEEE: string_literal
2007-05-12 16:29:25 +00:00
%token<strp> yaSTRING "STRING"
2009-05-07 22:28:05 +00:00
%token<strp> yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed
2009-10-31 14:08:38 +00:00
%token<fl> yaTIMINGSPEC "TIMING SPEC ELEMENT"
2007-05-12 16:29:25 +00:00
2009-11-21 00:53:40 +00:00
%token<strp> yaTABLELINE "TABLE LINE"
2007-05-12 16:29:25 +00:00
%token<strp> yaSCHDR "`systemc_header BLOCK"
%token<strp> yaSCINT "`systemc_ctor BLOCK"
%token<strp> yaSCIMP "`systemc_dtor BLOCK"
%token<strp> yaSCIMPH "`systemc_interface BLOCK"
%token<strp> yaSCCTOR "`systemc_implementation BLOCK"
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
2010-01-21 11:11:30 +00:00
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
%token<fl> yVLT_LINT_OFF "lint_off"
%token<fl> yVLT_TRACING_OFF "tracing_off"
%token<fl> yVLT_D_FILE "--file"
%token<fl> yVLT_D_LINES "--lines"
%token<fl> yVLT_D_MSG "--msg"
2009-12-04 12:05:44 +00:00
%token<strp> yaD_IGNORE "${ignored-bbox-sys}"
%token<strp> yaD_DPI "${dpi-sys}"
2009-10-31 14:08:38 +00:00
// <fl> is the fileline, abbreviated to shorten "$<fl>1" references
%token<fl> '!'
%token<fl> '#'
%token<fl> '%'
%token<fl> '&'
%token<fl> '('
%token<fl> ')'
%token<fl> '*'
%token<fl> '+'
%token<fl> ','
%token<fl> '-'
%token<fl> '.'
%token<fl> '/'
%token<fl> ':'
%token<fl> ';'
%token<fl> '<'
%token<fl> '='
%token<fl> '>'
%token<fl> '?'
%token<fl> '@'
%token<fl> '['
%token<fl> ']'
%token<fl> '^'
%token<fl> '{'
%token<fl> '|'
%token<fl> '}'
%token<fl> '~'
2009-01-28 20:27:41 +00:00
2007-05-12 16:29:25 +00:00
// Specific keywords
// yKEYWORD means match "keyword"
// Other cases are yXX_KEYWORD where XX makes it unique,
// for example yP_ for punctuation based operators.
2009-05-07 22:28:05 +00:00
// Double underscores "yX__Y" means token X followed by Y,
// and "yX__ETC" means X folled by everything but Y(s).
2009-10-31 14:08:38 +00:00
%token<fl> yALWAYS "always"
2013-05-01 02:55:28 +00:00
%token<fl> yALWAYS_FF "always_ff"
%token<fl> yALWAYS_COMB "always_comb"
%token<fl> yALWAYS_LATCH "always_latch"
2009-10-31 14:08:38 +00:00
%token<fl> yAND "and"
%token<fl> yASSERT "assert"
%token<fl> yASSIGN "assign"
%token<fl> yAUTOMATIC "automatic"
%token<fl> yBEGIN "begin"
2013-01-15 04:19:44 +00:00
%token<fl> yBIND "bind"
2009-10-31 19:12:28 +00:00
%token<fl> yBIT "bit"
2010-02-14 15:01:21 +00:00
%token<fl> yBREAK "break"
2009-10-31 14:08:38 +00:00
%token<fl> yBUF "buf"
%token<fl> yBUFIF0 "bufif0"
%token<fl> yBUFIF1 "bufif1"
2009-11-03 03:14:11 +00:00
%token<fl> yBYTE "byte"
2009-10-31 14:08:38 +00:00
%token<fl> yCASE "case"
%token<fl> yCASEX "casex"
%token<fl> yCASEZ "casez"
2009-11-24 14:11:25 +00:00
%token<fl> yCHANDLE "chandle"
2009-10-31 14:08:38 +00:00
%token<fl> yCLOCKING "clocking"
2011-07-02 16:45:26 +00:00
%token<fl> yCONST__ETC "const"
%token<fl> yCONST__LEX "const-in-lex"
2010-01-08 03:08:48 +00:00
%token<fl> yCMOS "cmos"
2009-12-03 11:55:29 +00:00
%token<fl> yCONTEXT "context"
2010-02-14 15:01:21 +00:00
%token<fl> yCONTINUE "continue"
2009-10-31 14:08:38 +00:00
%token<fl> yCOVER "cover"
%token<fl> yDEFAULT "default"
%token<fl> yDEFPARAM "defparam"
%token<fl> yDISABLE "disable"
%token<fl> yDO "do"
2009-12-29 00:49:40 +00:00
%token<fl> yEDGE "edge"
2009-10-31 14:08:38 +00:00
%token<fl> yELSE "else"
%token<fl> yEND "end"
%token<fl> yENDCASE "endcase"
%token<fl> yENDCLOCKING "endclocking"
%token<fl> yENDFUNCTION "endfunction"
%token<fl> yENDGENERATE "endgenerate"
2013-05-28 01:39:19 +00:00
%token<fl> yENDINTERFACE "endinterface"
2009-10-31 14:08:38 +00:00
%token<fl> yENDMODULE "endmodule"
2009-11-08 02:05:02 +00:00
%token<fl> yENDPACKAGE "endpackage"
2009-11-20 13:41:28 +00:00
%token<fl> yENDPRIMITIVE "endprimitive"
2009-11-06 00:09:45 +00:00
%token<fl> yENDPROGRAM "endprogram"
2009-10-31 14:08:38 +00:00
%token<fl> yENDPROPERTY "endproperty"
%token<fl> yENDSPECIFY "endspecify"
2009-11-21 00:53:40 +00:00
%token<fl> yENDTABLE "endtable"
2009-10-31 14:08:38 +00:00
%token<fl> yENDTASK "endtask"
2009-12-27 13:29:55 +00:00
%token<fl> yENUM "enum"
2009-12-03 11:55:29 +00:00
%token<fl> yEXPORT "export"
2009-10-31 14:08:38 +00:00
%token<fl> yFINAL "final"
%token<fl> yFOR "for"
%token<fl> yFOREVER "forever"
%token<fl> yFUNCTION "function"
%token<fl> yGENERATE "generate"
%token<fl> yGENVAR "genvar"
2010-01-23 00:08:20 +00:00
%token<fl> yGLOBAL__CLOCKING "global-then-clocking"
%token<fl> yGLOBAL__LEX "global-in-lex"
2009-10-31 14:08:38 +00:00
%token<fl> yIF "if"
%token<fl> yIFF "iff"
2009-11-10 00:07:59 +00:00
%token<fl> yIMPORT "import"
2009-10-31 14:08:38 +00:00
%token<fl> yINITIAL "initial"
%token<fl> yINOUT "inout"
%token<fl> yINPUT "input"
2013-02-02 17:55:28 +00:00
%token<fl> yINSIDE "inside"
2009-11-03 03:14:11 +00:00
%token<fl> yINT "int"
2009-10-31 14:08:38 +00:00
%token<fl> yINTEGER "integer"
2013-05-28 01:39:19 +00:00
%token<fl> yINTERFACE "interface"
2009-10-31 14:08:38 +00:00
%token<fl> yLOCALPARAM "localparam"
2009-11-03 03:14:11 +00:00
%token<fl> yLOGIC "logic"
%token<fl> yLONGINT "longint"
2013-05-28 01:39:19 +00:00
%token<fl> yMODPORT "modport"
2009-10-31 14:08:38 +00:00
%token<fl> yMODULE "module"
%token<fl> yNAND "nand"
%token<fl> yNEGEDGE "negedge"
2010-01-08 03:08:48 +00:00
%token<fl> yNMOS "nmos"
2009-10-31 14:08:38 +00:00
%token<fl> yNOR "nor"
%token<fl> yNOT "not"
%token<fl> yNOTIF0 "notif0"
%token<fl> yNOTIF1 "notif1"
%token<fl> yOR "or"
%token<fl> yOUTPUT "output"
2009-11-08 02:05:02 +00:00
%token<fl> yPACKAGE "package"
2012-07-29 14:16:20 +00:00
%token<fl> yPACKED "packed"
2009-10-31 14:08:38 +00:00
%token<fl> yPARAMETER "parameter"
2010-01-08 03:08:48 +00:00
%token<fl> yPMOS "pmos"
2009-10-31 14:08:38 +00:00
%token<fl> yPOSEDGE "posedge"
2009-11-20 13:41:28 +00:00
%token<fl> yPRIMITIVE "primitive"
2009-10-31 14:08:38 +00:00
%token<fl> yPRIORITY "priority"
2009-11-06 00:09:45 +00:00
%token<fl> yPROGRAM "program"
2009-10-31 14:08:38 +00:00
%token<fl> yPROPERTY "property"
%token<fl> yPULLDOWN "pulldown"
%token<fl> yPULLUP "pullup"
2009-12-03 11:55:29 +00:00
%token<fl> yPURE "pure"
2012-07-29 14:16:20 +00:00
%token<fl> yRAND "rand"
%token<fl> yRANDC "randc"
2010-01-08 03:08:48 +00:00
%token<fl> yRCMOS "rcmos"
2011-07-24 19:01:51 +00:00
%token<fl> yREAL "real"
%token<fl> yREALTIME "realtime"
2009-10-31 14:08:38 +00:00
%token<fl> yREG "reg"
%token<fl> yREPEAT "repeat"
2010-02-14 15:01:21 +00:00
%token<fl> yRETURN "return"
2010-01-08 03:08:48 +00:00
%token<fl> yRNMOS "rnmos"
%token<fl> yRPMOS "rpmos"
%token<fl> yRTRAN "rtran"
%token<fl> yRTRANIF0 "rtranif0"
%token<fl> yRTRANIF1 "rtranif1"
2009-10-31 14:08:38 +00:00
%token<fl> ySCALARED "scalared"
2009-11-03 03:14:11 +00:00
%token<fl> ySHORTINT "shortint"
2009-10-31 14:08:38 +00:00
%token<fl> ySIGNED "signed"
%token<fl> ySPECIFY "specify"
%token<fl> ySPECPARAM "specparam"
%token<fl> ySTATIC "static"
2009-12-04 12:05:44 +00:00
%token<fl> ySTRING "string"
2012-07-29 14:16:20 +00:00
%token<fl> ySTRUCT "struct"
2009-10-31 14:08:38 +00:00
%token<fl> ySUPPLY0 "supply0"
%token<fl> ySUPPLY1 "supply1"
2009-11-21 00:53:40 +00:00
%token<fl> yTABLE "table"
2009-10-31 14:08:38 +00:00
%token<fl> yTASK "task"
2009-11-19 15:45:59 +00:00
%token<fl> yTIME "time"
2009-10-31 14:08:38 +00:00
%token<fl> yTIMEPRECISION "timeprecision"
%token<fl> yTIMEUNIT "timeunit"
2010-01-08 03:08:48 +00:00
%token<fl> yTRAN "tran"
%token<fl> yTRANIF0 "tranif0"
%token<fl> yTRANIF1 "tranif1"
2009-10-31 14:08:38 +00:00
%token<fl> yTRI "tri"
2012-04-22 01:45:28 +00:00
%token<fl> yTRI0 "tri0"
%token<fl> yTRI1 "tri1"
2009-10-31 14:08:38 +00:00
%token<fl> yTRUE "true"
2009-11-07 04:16:06 +00:00
%token<fl> yTYPEDEF "typedef"
2012-07-29 14:16:20 +00:00
%token<fl> yUNION "union"
2009-10-31 14:08:38 +00:00
%token<fl> yUNIQUE "unique"
2010-12-26 02:58:28 +00:00
%token<fl> yUNIQUE0 "unique0"
2009-10-31 14:08:38 +00:00
%token<fl> yUNSIGNED "unsigned"
2009-11-06 00:57:31 +00:00
%token<fl> yVAR "var"
2009-10-31 14:08:38 +00:00
%token<fl> yVECTORED "vectored"
2009-11-03 03:50:31 +00:00
%token<fl> yVOID "void"
2009-10-31 14:08:38 +00:00
%token<fl> yWHILE "while"
%token<fl> yWIRE "wire"
2011-11-27 15:31:06 +00:00
%token<fl> yWREAL "wreal"
2009-10-31 14:08:38 +00:00
%token<fl> yXNOR "xnor"
%token<fl> yXOR "xor"
%token<fl> yD_BITS "$bits"
2011-07-24 19:01:51 +00:00
%token<fl> yD_BITSTOREAL "$bitstoreal"
2009-10-31 14:08:38 +00:00
%token<fl> yD_C "$c"
2011-09-29 01:35:16 +00:00
%token<fl> yD_CEIL "$ceil"
2009-10-31 14:08:38 +00:00
%token<fl> yD_CLOG2 "$clog2"
%token<fl> yD_COUNTONES "$countones"
2013-01-20 17:19:22 +00:00
%token<fl> yD_DIMENSIONS "$dimensions"
2009-10-31 14:08:38 +00:00
%token<fl> yD_DISPLAY "$display"
%token<fl> yD_ERROR "$error"
2011-09-29 01:35:16 +00:00
%token<fl> yD_EXP "$exp"
2009-10-31 14:08:38 +00:00
%token<fl> yD_FATAL "$fatal"
%token<fl> yD_FCLOSE "$fclose"
%token<fl> yD_FDISPLAY "$fdisplay"
%token<fl> yD_FEOF "$feof"
%token<fl> yD_FFLUSH "$fflush"
%token<fl> yD_FGETC "$fgetc"
%token<fl> yD_FGETS "$fgets"
%token<fl> yD_FINISH "$finish"
2011-09-29 01:35:16 +00:00
%token<fl> yD_FLOOR "$floor"
2009-10-31 14:08:38 +00:00
%token<fl> yD_FOPEN "$fopen"
%token<fl> yD_FSCANF "$fscanf"
%token<fl> yD_FWRITE "$fwrite"
2013-01-20 17:19:22 +00:00
%token<fl> yD_HIGH "$high"
%token<fl> yD_INCREMENT "$increment"
2009-10-31 14:08:38 +00:00
%token<fl> yD_INFO "$info"
%token<fl> yD_ISUNKNOWN "$isunknown"
2011-07-24 19:01:51 +00:00
%token<fl> yD_ITOR "$itor"
2013-01-20 17:19:22 +00:00
%token<fl> yD_LEFT "$left"
2011-09-29 01:35:16 +00:00
%token<fl> yD_LN "$ln"
%token<fl> yD_LOG10 "$log10"
2013-01-20 17:19:22 +00:00
%token<fl> yD_LOW "$low"
2009-10-31 14:08:38 +00:00
%token<fl> yD_ONEHOT "$onehot"
%token<fl> yD_ONEHOT0 "$onehot0"
2011-09-29 01:35:16 +00:00
%token<fl> yD_POW "$pow"
2009-10-31 14:08:38 +00:00
%token<fl> yD_RANDOM "$random"
%token<fl> yD_READMEMB "$readmemb"
%token<fl> yD_READMEMH "$readmemh"
2011-07-24 19:01:51 +00:00
%token<fl> yD_REALTIME "$realtime"
%token<fl> yD_REALTOBITS "$realtobits"
2013-01-20 17:19:22 +00:00
%token<fl> yD_RIGHT "$right"
2011-07-24 19:01:51 +00:00
%token<fl> yD_RTOI "$rtoi"
2009-11-24 02:24:55 +00:00
%token<fl> yD_SFORMAT "$sformat"
2009-10-31 14:08:38 +00:00
%token<fl> yD_SIGNED "$signed"
2013-01-20 17:19:22 +00:00
%token<fl> yD_SIZE "$size"
2011-09-29 01:35:16 +00:00
%token<fl> yD_SQRT "$sqrt"
2009-10-31 14:08:38 +00:00
%token<fl> yD_SSCANF "$sscanf"
%token<fl> yD_STIME "$stime"
%token<fl> yD_STOP "$stop"
2009-11-24 02:24:55 +00:00
%token<fl> yD_SWRITE "$swrite"
2011-11-20 07:01:48 +00:00
%token<fl> yD_SYSTEM "$system"
2009-11-19 22:04:21 +00:00
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
2009-10-31 14:08:38 +00:00
%token<fl> yD_TIME "$time"
2009-11-08 02:05:02 +00:00
%token<fl> yD_UNIT "$unit"
2013-01-20 17:19:22 +00:00
%token<fl> yD_UNPACKED_DIMENSIONS "$unpacked_dimensions"
2009-10-31 14:08:38 +00:00
%token<fl> yD_UNSIGNED "$unsigned"
2009-11-19 22:04:21 +00:00
%token<fl> yD_VALUEPLUSARGS "$value$plusargs"
2009-10-31 14:08:38 +00:00
%token<fl> yD_WARNING "$warning"
%token<fl> yD_WRITE "$write"
%token<fl> yPSL "psl"
%token<fl> yPSL_ASSERT "PSL assert"
%token<fl> yPSL_CLOCK "PSL clock"
%token<fl> yPSL_COVER "PSL cover"
%token<fl> yPSL_REPORT "PSL report"
%token<fl> yVL_CLOCK "/*verilator sc_clock*/"
%token<fl> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
%token<fl> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
%token<fl> yVL_FULL_CASE "/*verilator full_case*/"
%token<fl> yVL_INLINE_MODULE "/*verilator inline_module*/"
%token<fl> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
%token<fl> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
%token<fl> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
2011-10-26 12:57:27 +00:00
%token<fl> yVL_SC_BV "/*verilator sc_bv*/"
2010-01-18 00:13:44 +00:00
%token<fl> yVL_SFORMAT "/*verilator sformat*/"
2009-10-31 14:08:38 +00:00
%token<fl> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
%token<fl> yVL_PUBLIC "/*verilator public*/"
%token<fl> yVL_PUBLIC_FLAT "/*verilator public_flat*/"
2010-04-06 00:01:17 +00:00
%token<fl> yVL_PUBLIC_FLAT_RD "/*verilator public_flat_rd*/"
%token<fl> yVL_PUBLIC_FLAT_RW "/*verilator public_flat_rw*/"
2009-10-31 14:08:38 +00:00
%token<fl> yVL_PUBLIC_MODULE "/*verilator public_module*/"
%token<fl> yP_TICK "'"
%token<fl> yP_TICKBRA "'{"
%token<fl> yP_OROR "||"
%token<fl> yP_ANDAND "&&"
%token<fl> yP_NOR "~|"
%token<fl> yP_XNOR "^~"
%token<fl> yP_NAND "~&"
%token<fl> yP_EQUAL "=="
%token<fl> yP_NOTEQUAL "!="
%token<fl> yP_CASEEQUAL "==="
%token<fl> yP_CASENOTEQUAL "!=="
%token<fl> yP_WILDEQUAL "==?"
%token<fl> yP_WILDNOTEQUAL "!=?"
%token<fl> yP_GTE ">="
%token<fl> yP_LTE "<="
2012-12-31 22:05:13 +00:00
%token<fl> yP_LTE__IGNORE "<=-ignored" // Used when expr:<= means assignment
2009-10-31 14:08:38 +00:00
%token<fl> yP_SLEFT "<<"
%token<fl> yP_SRIGHT ">>"
%token<fl> yP_SSRIGHT ">>>"
%token<fl> yP_POW "**"
%token<fl> yP_PLUSCOLON "+:"
%token<fl> yP_MINUSCOLON "-:"
%token<fl> yP_MINUSGT "->"
%token<fl> yP_MINUSGTGT "->>"
%token<fl> yP_EQGT "=>"
%token<fl> yP_ASTGT "*>"
%token<fl> yP_ANDANDAND "&&&"
%token<fl> yP_POUNDPOUND "##"
%token<fl> yP_DOTSTAR ".*"
%token<fl> yP_ATAT "@@"
%token<fl> yP_COLONCOLON "::"
%token<fl> yP_COLONEQ ":="
%token<fl> yP_COLONDIV ":/"
%token<fl> yP_ORMINUSGT "|->"
%token<fl> yP_OREQGT "|=>"
%token<fl> yP_BRASTAR "[*"
%token<fl> yP_BRAEQ "[="
%token<fl> yP_BRAMINUSGT "[->"
%token<fl> yP_PLUSPLUS "++"
%token<fl> yP_MINUSMINUS "--"
%token<fl> yP_PLUSEQ "+="
%token<fl> yP_MINUSEQ "-="
%token<fl> yP_TIMESEQ "*="
%token<fl> yP_DIVEQ "/="
%token<fl> yP_MODEQ "%="
%token<fl> yP_ANDEQ "&="
%token<fl> yP_OREQ "|="
%token<fl> yP_XOREQ "^="
%token<fl> yP_SLEFTEQ "<<="
%token<fl> yP_SRIGHTEQ ">>="
%token<fl> yP_SSRIGHTEQ ">>>="
%token<fl> yPSL_BRA "{"
%token<fl> yPSL_KET "}"
%token<fl> yP_LOGIFF
2007-11-05 21:38:20 +00:00
2007-10-23 20:54:29 +00:00
// [* is not a operator, as "[ * ]" is legal
// [= and [-> could be repitition operators, but to match [* we don't add them.
// '( is not a operator, as "' (" is legal
2006-08-26 11:35:28 +00:00
//********************
// PSL op precedence
2007-11-05 21:38:20 +00:00
%right yP_MINUSGT yP_LOGIFF
%right yP_ORMINUSGT yP_OREQGT
2013-02-02 17:55:28 +00:00
%left<fl> prPSLCLK
2006-08-26 11:35:28 +00:00
// Verilog op precedence
2009-02-08 01:54:09 +00:00
%right '?' ':'
2007-11-05 21:38:20 +00:00
%left yP_OROR
%left yP_ANDAND
%left '|' yP_NOR
2009-02-08 01:54:09 +00:00
%left '^' yP_XNOR
2007-11-05 21:38:20 +00:00
%left '&' yP_NAND
%left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
2013-02-02 17:55:28 +00:00
%left '>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE
2007-11-05 21:38:20 +00:00
%left yP_SLEFT yP_SRIGHT yP_SSRIGHT
%left '+' '-'
%left '*' '/' '%'
%left yP_POW
2009-05-07 22:28:05 +00:00
%left prUNARYARITH yP_MINUSMINUS yP_PLUSPLUS prREDUCTION prNEGATION
%left '.'
// Not in IEEE, but need to avoid conflicts; TICK should bind tightly just lower than COLONCOLON
%left yP_TICK
//%left '(' ')' '[' ']' yP_COLONCOLON '.'
2006-08-26 11:35:28 +00:00
2007-05-12 16:29:25 +00:00
%nonassoc prLOWER_THAN_ELSE
2006-08-26 11:35:28 +00:00
%nonassoc yELSE
2008-08-06 16:35:34 +00:00
//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
2009-05-07 22:28:05 +00:00
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
2009-11-08 02:05:02 +00:00
// 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
2012-12-31 18:43:54 +00:00
// 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
2006-08-26 11:35:28 +00:00
2009-01-25 02:36:14 +00:00
%start source_text
2006-08-26 11:35:28 +00:00
%%
//**********************************************************************
// Feedback to the Lexer
2009-01-25 02:36:14 +00:00
// Note we read a parenthesis ahead, so this may not change the lexer at the right point.
2006-08-26 11:35:28 +00:00
2009-02-25 22:16:51 +00:00
stateExitPsl: // For PSL lexing, return from PSL state
2009-10-31 14:08:38 +00:00
/* empty */ { PARSEP->stateExitPsl(); }
2006-08-26 11:35:28 +00:00
;
2009-02-25 22:16:51 +00:00
statePushVlg: // For PSL lexing, escape current state into Verilog state
2009-10-31 14:08:38 +00:00
/* empty */ { PARSEP->statePushVlg(); }
2006-08-26 11:35:28 +00:00
;
2009-02-25 22:16:51 +00:00
statePop: // Return to previous lexing state
2009-10-31 14:08:38 +00:00
/* empty */ { PARSEP->statePop(); }
2006-08-26 11:35:28 +00:00
;
//**********************************************************************
2007-05-14 20:59:58 +00:00
// Files
2006-08-26 11:35:28 +00:00
2009-01-25 02:36:14 +00:00
source_text: // ==IEEE: source_text
/* empty */ { }
2009-05-07 22:28:05 +00:00
// // timeunits_declaration moved into description:package_item
| descriptionList { }
2008-03-25 13:42:48 +00:00
;
2009-01-25 02:36:14 +00:00
descriptionList: // IEEE: part of source_text
description { }
| descriptionList description { }
2007-10-31 20:11:59 +00:00
;
2009-01-15 18:58:43 +00:00
description: // ==IEEE: description
module_declaration { }
2012-10-09 00:45:39 +00:00
// // udp_declaration moved into module_declaration
2013-05-28 01:39:19 +00:00
| interface_declaration { }
2009-11-06 00:09:45 +00:00
| program_declaration { }
2009-11-08 02:05:02 +00:00
| package_declaration { }
| package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
2013-02-14 11:55:09 +00:00
| bind_directive { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
2009-01-28 20:27:41 +00:00
// unsupported // IEEE: config_declaration
2012-12-31 18:43:54 +00:00
// // Verilator only
2010-01-21 11:11:30 +00:00
| vltItem { }
2009-01-25 02:36:14 +00:00
| error { }
2006-08-26 11:35:28 +00:00
;
2009-11-07 04:16:06 +00:00
timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
yTIMEUNIT yaTIMENUM ';' { $$ = NULL; }
2012-10-09 00:45:39 +00:00
| yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';' { $$ = NULL; }
2009-11-07 04:16:06 +00:00
| yTIMEPRECISION yaTIMENUM ';' { $$ = NULL; }
2008-10-14 18:49:54 +00:00
;
2007-05-14 20:59:58 +00:00
//**********************************************************************
2009-05-07 22:28:05 +00:00
// Packages
2009-11-08 02:05:02 +00:00
package_declaration: // ==IEEE: package_declaration
packageFront package_itemListE yENDPACKAGE endLabelE
{ $1->modTrace(v3Global.opt.trace() && $1->fileline()->tracingOn()); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2);
2012-03-08 01:14:18 +00:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>4,$1,$4); }
2009-11-08 02:05:02 +00:00
;
packageFront<modulep>:
yPACKAGE idAny ';'
{ $$ = new AstPackage($1,*$2);
$$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
$$->modTrace(v3Global.opt.trace());
2010-01-07 00:04:20 +00:00
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
2009-11-08 02:05:02 +00:00
PARSEP->rootp()->addModulep($$);
SYMP->pushNew($$); }
;
package_itemListE<nodep>: // IEEE: [{ package_item }]
/* empty */ { $$ = NULL; }
| package_itemList { $$ = $1; }
;
package_itemList<nodep>: // IEEE: { package_item }
package_item { $$ = $1; }
| package_itemList package_item { $$ = $1->addNextNull($2); }
;
package_item<nodep>: // ==IEEE: package_item
package_or_generate_item_declaration { $$ = $1; }
//UNSUP anonymous_program { $$ = $1; }
2012-10-09 00:45:39 +00:00
//UNSUP package_export_declaration { $$ = $1; }
2009-11-08 02:05:02 +00:00
| timeunits_declaration { $$ = $1; }
;
2009-05-07 22:28:05 +00:00
package_or_generate_item_declaration<nodep>: // ==IEEE: package_or_generate_item_declaration
net_declaration { $$ = $1; }
| data_declaration { $$ = $1; }
| task_declaration { $$ = $1; }
| function_declaration { $$ = $1; }
2012-10-09 00:45:39 +00:00
//UNSUP checker_declaration { $$ = $1; }
2009-12-03 11:55:29 +00:00
| dpi_import_export { $$ = $1; }
2009-05-07 22:28:05 +00:00
//UNSUP extern_constraint_declaration { $$ = $1; }
//UNSUP class_declaration { $$ = $1; }
// // class_constructor_declaration is part of function_declaration
2012-10-09 01:20:13 +00:00
| local_parameter_declaration ';' { $$ = $1; }
2012-10-09 00:45:39 +00:00
| parameter_declaration ';' { $$ = $1; }
2009-05-07 22:28:05 +00:00
//UNSUP covergroup_declaration { $$ = $1; }
//UNSUP overload_declaration { $$ = $1; }
2012-10-09 00:45:39 +00:00
//UNSUP assertion_item_declaration { $$ = $1; }
2009-05-07 22:28:05 +00:00
| ';' { $$ = NULL; }
2008-10-14 18:49:54 +00:00
;
2009-11-10 00:07:59 +00:00
package_import_declaration<nodep>: // ==IEEE: package_import_declaration
yIMPORT package_import_itemList ';' { $$ = $2; }
;
package_import_itemList<nodep>:
package_import_item { $$ = $1; }
| package_import_itemList ',' package_import_item { $$ = $1->addNextNull($3); }
;
package_import_item<nodep>: // ==IEEE: package_import_item
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
{ $$ = new AstPackageImport($<fl>1, $<scp>1->castPackage(), *$3);
SYMP->import($<scp>1,*$3); }
;
package_import_itemObj<strp>: // IEEE: part of package_import_item
idAny { $<fl>$=$<fl>1; $$=$1; }
| '*' { $<fl>$=$<fl>1; static string star="*"; $$=☆ }
;
2009-05-07 22:28:05 +00:00
//**********************************************************************
// Module headers
module_declaration: // ==IEEE: module_declaration
// // timeunits_declaration instead in module_item
// // IEEE: module_nonansi_header + module_ansi_header
modFront parameter_port_listE portsStarE ';'
module_itemListE yENDMODULE endLabelE
2008-12-11 21:01:41 +00:00
{ $1->modTrace(v3Global.opt.trace() && $1->fileline()->tracingOn()); // Stash for implicit wires, etc
2009-05-07 22:28:05 +00:00
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3);
2009-10-31 14:08:38 +00:00
if ($5) $1->addStmtp($5);
2012-03-08 01:14:18 +00:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); }
2009-11-20 13:41:28 +00:00
| udpFront parameter_port_listE portsStarE ';'
module_itemListE yENDPRIMITIVE endLabelE
{ $1->modTrace(false); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3);
if ($5) $1->addStmtp($5);
2012-03-08 01:14:18 +00:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); }
2009-05-07 22:28:05 +00:00
//
//UNSUP yEXTERN modFront parameter_port_listE portsStarE ';'
//UNSUP { UNSUP }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
modFront<modulep>:
2009-10-31 14:08:38 +00:00
// // General note: all *Front functions must call symPushNew before
// // any formal arguments, as the arguments must land in the new scope.
2009-05-07 22:28:05 +00:00
yMODULE lifetimeE idAny
2009-10-31 14:08:38 +00:00
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
2009-01-25 02:36:14 +00:00
$$->modTrace(v3Global.opt.trace());
2010-01-07 00:04:20 +00:00
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
2009-10-31 14:08:38 +00:00
PARSEP->rootp()->addModulep($$);
2009-10-31 14:14:04 +00:00
SYMP->pushNew($$); }
2006-08-26 11:35:28 +00:00
;
2009-11-20 13:41:28 +00:00
udpFront<modulep>:
yPRIMITIVE lifetimeE idAny
2010-01-08 03:44:30 +00:00
{ $$ = new AstPrimitive($1,*$3); $$->inLibrary(true);
2009-11-20 13:41:28 +00:00
$$->modTrace(false);
$$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
PARSEP->fileline()->tracingOn(false);
2010-01-07 00:04:20 +00:00
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
2009-11-20 13:41:28 +00:00
PARSEP->rootp()->addModulep($$);
SYMP->pushNew($$); }
;
2009-05-07 22:28:05 +00:00
parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2009-05-07 22:28:05 +00:00
| '#' '(' cellpinList ')' { $$ = $3; }
2009-11-10 21:29:58 +00:00
// // Parentheses are optional around a single parameter
| '#' yaINTNUM { $$ = new AstPin($1,1,"",new AstConst($1,*$2)); }
2010-01-08 03:44:30 +00:00
| '#' yaFLOATNUM { $$ = new AstPin($1,1,"",new AstConst($1,AstConst::Unsized32(),(int)(($2<0)?($2-0.5):($2+0.5)))); }
2009-11-10 21:29:58 +00:00
| '#' idClassSel { $$ = new AstPin($1,1,"",$2); }
2009-05-07 22:28:05 +00:00
// // Not needed in Verilator:
// // Side effect of combining *_instantiations
// // '#' delay_value { UNSUP }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
parameter_port_listE<nodep>: // IEEE: parameter_port_list + empty == parameter_value_assignment
/* empty */ { $$ = NULL; }
| '#' '(' ')' { $$ = NULL; }
// // IEEE: '#' '(' list_of_param_assignments { ',' parameter_port_declaration } ')'
// // IEEE: '#' '(' parameter_port_declaration { ',' parameter_port_declaration } ')'
// // Can't just do that as "," conflicts with between vars and between stmts, so
// // split into pre-comma and post-comma parts
| '#' '(' {VARRESET_LIST(GPARAM);} paramPortDeclOrArgList ')' { $$ = $4; VARRESET_NONLIST(UNKNOWN); }
// // Note legal to start with "a=b" with no parameter statement
2007-09-11 13:35:02 +00:00
;
2009-05-07 22:28:05 +00:00
paramPortDeclOrArgList<nodep>: // IEEE: list_of_param_assignments + { parameter_port_declaration }
paramPortDeclOrArg { $$ = $1; }
| paramPortDeclOrArgList ',' paramPortDeclOrArg { $$ = $1->addNext($3); }
2007-09-11 13:35:02 +00:00
;
2009-05-07 22:28:05 +00:00
paramPortDeclOrArg<nodep>: // IEEE: param_assignment + parameter_port_declaration
// // We combine the two as we can't tell which follows a comma
param_assignment { $$ = $1; }
| parameter_port_declarationFront param_assignment { $$ = $2; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
portsStarE<nodep>: // IEEE: .* + list_of_ports + list_of_port_declarations + empty
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2006-08-26 11:35:28 +00:00
| '(' ')' { $$ = NULL; }
2009-05-07 22:28:05 +00:00
// // .* expanded from module_declaration
//UNSUP '(' yP_DOTSTAR ')' { UNSUP }
| '(' {VARRESET_LIST(PORT);} list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
list_of_ports<nodep>: // IEEE: list_of_ports + list_of_port_declarations
port { $$ = $1; }
| list_of_ports ',' port { $$ = $1->addNextNull($3); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
port<nodep>: // ==IEEE: port
// // Though not type for interfaces, we factor out the port direction and type
// // so we can simply handle it in one place
//
// // IEEE: interface_port_header port_identifier { unpacked_dimension }
// // Expanded interface_port_header
// // We use instantCb here because the non-port form looks just like a module instantiation
2013-06-13 23:38:18 +00:00
portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE
{ $$ = $3; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN);
VARDTYPE(new AstIfaceRefDType($<fl>2,"",*$2));
$$->addNextNull(VARDONEP($$,$4,$5)); }
| portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig rangeListE sigAttrListE
{ $$ = $5; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN);
VARDTYPE(new AstIfaceRefDType($<fl>2,"",*$2,*$4));
$$->addNextNull(VARDONEP($$,$6,$7)); }
| portDirNetE yINTERFACE portSig rangeListE sigAttrListE
{ $<fl>2->v3error("Unsupported: virtual interfaces"); $$=NULL; }
| portDirNetE yINTERFACE '.' idAny/*modport*/ portSig rangeListE sigAttrListE
{ $<fl>2->v3error("Unsupported: virtual interfaces"); $$=NULL; }
2009-05-07 22:28:05 +00:00
//
// // IEEE: ansi_port_declaration, with [port_direction] removed
2012-10-09 00:45:39 +00:00
// // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ]
2009-05-07 22:28:05 +00:00
// // IEEE: [ net_port_header | variable_port_header ] '.' port_identifier '(' [ expression ] ')'
// // IEEE: [ variable_port_header ] port_identifier { variable_dimension } [ '=' constant_expression ]
// // Substitute net_port_header = [ port_direction ] net_port_type
// // Substitute variable_port_header = [ port_direction ] variable_port_type
// // Substitute net_port_type = [ net_type ] data_type_or_implicit
// // Substitute variable_port_type = var_data_type
// // Substitute var_data_type = data_type | yVAR data_type_or_implicit
// // [ [ port_direction ] net_port_type | interface_port_header ] port_identifier { unpacked_dimension }
// // [ [ port_direction ] var_data_type ] port_identifier variable_dimensionListE [ '=' constant_expression ]
// // [ [ port_direction ] net_port_type | [ port_direction ] var_data_type ] '.' port_identifier '(' [ expression ] ')'
//
// // Remove optional '[...] id' is in portAssignment
// // Remove optional '[port_direction]' is in port
// // net_port_type | interface_port_header port_identifier { unpacked_dimension }
// // net_port_type | interface_port_header port_identifier { unpacked_dimension }
// // var_data_type port_identifier variable_dimensionListE [ '=' constExpr ]
// // net_port_type | [ port_direction ] var_data_type '.' port_identifier '(' [ expr ] ')'
// // Expand implicit_type
//
2009-11-13 01:33:50 +00:00
// // variable_dimensionListE instead of rangeListE to avoid conflicts
2009-05-07 22:28:05 +00:00
//
// // Note implicit rules looks just line declaring additional followon port
// // No VARDECL("port") for implicit, as we don't want to declare variables for them
2012-10-09 01:20:13 +00:00
//UNSUP portDirNetE data_type '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE yVAR data_type '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE yVAR implicit_type '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE signingE rangeList '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
2009-05-07 22:28:05 +00:00
//
2013-06-13 23:38:18 +00:00
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE
2009-11-06 00:57:31 +00:00
{ $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
2009-12-18 01:58:14 +00:00
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE
2009-11-06 00:57:31 +00:00
{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
2009-12-18 01:58:14 +00:00
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
2009-11-06 00:57:31 +00:00
{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
2009-12-18 01:58:14 +00:00
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE
2013-01-14 03:18:57 +00:00
{ $$=$4; VARDTYPE(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2), $3,true)); $$->addNextNull(VARDONEP($$,$5,$6)); }
2009-12-18 01:58:14 +00:00
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE
2009-11-06 00:57:31 +00:00
{ $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
2009-05-07 22:28:05 +00:00
//
2009-12-18 01:58:14 +00:00
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
2010-01-22 01:08:45 +00:00
{ $$=$3; VARDTYPE($2); AstVar* vp=VARDONEP($$,$4,$5); $$->addNextNull(vp); vp->valuep($7); }
2009-12-18 01:58:14 +00:00
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
2010-10-04 11:48:09 +00:00
{ $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
2009-12-18 01:58:14 +00:00
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
2010-10-04 11:48:09 +00:00
{ $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
2009-12-18 01:58:14 +00:00
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
2010-10-04 11:48:09 +00:00
{ $$=$2; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); }
2009-05-07 22:28:05 +00:00
;
2011-05-10 03:58:38 +00:00
2009-05-07 22:28:05 +00:00
portDirNetE: // IEEE: part of port, optional net type and/or direction
/* empty */ { }
// // Per spec, if direction given default the nettype.
2009-11-02 13:06:04 +00:00
// // The higher level rule may override this VARDTYPE with one later in the parse.
2012-04-27 23:41:13 +00:00
| port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); }
| port_direction { VARDECL(PORT); } net_type { VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET
| net_type { } // net_type calls VARNET
2009-05-07 22:28:05 +00:00
;
2011-05-10 03:58:38 +00:00
2009-05-07 22:28:05 +00:00
port_declNetE: // IEEE: part of port_declaration, optional net type
/* empty */ { }
| net_type { } // net_type calls VARNET
;
2011-05-10 03:58:38 +00:00
2009-10-31 03:17:56 +00:00
portSig<nodep>:
2011-01-19 02:12:31 +00:00
id/*port*/ { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
| idSVKwd { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
2009-05-07 22:28:05 +00:00
;
2006-08-26 11:35:28 +00:00
2009-05-07 22:28:05 +00:00
//**********************************************************************
// Interface headers
2007-06-12 13:58:56 +00:00
2013-05-28 01:39:19 +00:00
interface_declaration: // IEEE: interface_declaration + interface_nonansi_header + interface_ansi_header:
// // timeunits_delcarationE is instead in interface_item
intFront parameter_port_listE portsStarE ';'
interface_itemListE yENDINTERFACE endLabelE
{ if ($2) $1->addStmtp($2);
if ($3) $1->addStmtp($3);
if ($5) $1->addStmtp($5);
SYMP->popScope($1); }
//UNSUP yEXTERN intFront parameter_port_listE portsStarE ';' { }
;
intFront<modulep>:
yINTERFACE lifetimeE idAny/*new_interface*/
{ $$ = new AstIface($1,*$3);
$$->inLibrary(true);
PARSEP->rootp()->addModulep($$);
SYMP->pushNew($$); }
;
interface_itemListE<nodep>:
/* empty */ { $$ = NULL; }
| interface_itemList { $$ = $1; }
;
interface_itemList<nodep>:
interface_item { $$ = $1; }
| interface_itemList interface_item { $$ = $1->addNextNull($2); }
;
interface_item<nodep>: // IEEE: interface_item + non_port_interface_item
port_declaration ';' { $$ = $1; }
// // IEEE: non_port_interface_item
//UNSUP generate_region { $$ = $1; }
| interface_or_generate_item { $$ = $1; }
//UNSUP program_declaration { $$ = $1; }
//UNSUP interface_declaration { $$ = $1; }
| timeunits_declaration { $$ = $1; }
// // See note in interface_or_generate item
| module_common_item { $$ = $1; }
;
interface_or_generate_item<nodep>: // ==IEEE: interface_or_generate_item
// // module_common_item in interface_item, as otherwise duplicated
// // with module_or_generate_item's module_common_item
modport_declaration { $$ = $1; }
//UNSUP extern_tf_declaration { $$ = $1; }
;
2009-05-07 22:28:05 +00:00
//**********************************************************************
// Program headers
2009-11-06 00:09:45 +00:00
program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header:
// // timeunits_delcarationE is instead in program_item
pgmFront parameter_port_listE portsStarE ';'
program_itemListE yENDPROGRAM endLabelE
{ $1->modTrace(v3Global.opt.trace() && $1->fileline()->tracingOn()); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3);
if ($5) $1->addStmtp($5);
2012-03-08 01:14:18 +00:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); }
2009-11-06 00:09:45 +00:00
//UNSUP yEXTERN pgmFront parameter_port_listE portsStarE ';'
//UNSUP { PARSEP->symPopScope(VAstType::PROGRAM); }
;
pgmFront<modulep>:
yPROGRAM lifetimeE idAny/*new_program*/
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
$$->modTrace(v3Global.opt.trace());
2010-01-07 00:04:20 +00:00
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
2009-11-06 00:09:45 +00:00
PARSEP->rootp()->addModulep($$);
SYMP->pushNew($$); }
;
program_itemListE<nodep>: // ==IEEE: [{ program_item }]
/* empty */ { $$ = NULL; }
| program_itemList { $$ = $1; }
;
program_itemList<nodep>: // ==IEEE: { program_item }
program_item { $$ = $1; }
| program_itemList program_item { $$ = $1->addNextNull($2); }
;
program_item<nodep>: // ==IEEE: program_item
port_declaration ';' { $$ = $1; }
| non_port_program_item { $$ = $1; }
;
non_port_program_item<nodep>: // ==IEEE: non_port_program_item
continuous_assign { $$ = $1; }
| module_or_generate_item_declaration { $$ = $1; }
| initial_construct { $$ = $1; }
| final_construct { $$ = $1; }
| concurrent_assertion_item { $$ = $1; }
2009-11-07 04:16:06 +00:00
| timeunits_declaration { $$ = $1; }
2009-11-06 00:09:45 +00:00
| program_generate_item { $$ = $1; }
;
program_generate_item<nodep>: // ==IEEE: program_generate_item
loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
| generate_region { $$ = $1; }
2012-10-09 00:45:39 +00:00
//UNSUP elaboration_system_task { $$ = $1; }
2009-11-06 00:09:45 +00:00
;
2013-05-28 01:39:19 +00:00
modport_declaration<nodep>: // ==IEEE: modport_declaration
yMODPORT modport_itemList ';' { $$ = $2; }
;
modport_itemList<nodep>: // IEEE: part of modport_declaration
modport_item { $$ = $1; }
| modport_itemList ',' modport_item { $$ = $1->addNextNull($3); }
;
modport_item<nodep>: // ==IEEE: modport_item
id/*new-modport*/ '(' modportPortsDeclList ')' { $$ = new AstModport($2,*$1,$3); }
;
2013-12-21 11:51:15 +00:00
modportPortsDeclList<nodep>:
2013-05-28 01:39:19 +00:00
modportPortsDecl { $$ = $1; }
2013-12-21 11:51:15 +00:00
| modportPortsDeclList ',' modportPortsDecl { $$ = $1->addNextNull($3); }
2013-05-28 01:39:19 +00:00
;
// IEEE: modport_ports_declaration + modport_simple_ports_declaration
// + (modport_tf_ports_declaration+import_export) + modport_clocking_declaration
// We've expanded the lists each take to instead just have standalone ID ports.
// We track the type as with the V2k series of defines, then create as each ID is seen.
2013-12-21 11:51:15 +00:00
modportPortsDecl<nodep>:
2013-05-28 01:39:19 +00:00
// // IEEE: modport_simple_ports_declaration
port_direction modportSimplePort { $$ = new AstModportVarRef($<fl>1,*$2,GRAMMARP->m_varIO); }
// // IEEE: modport_clocking_declaration
2013-12-21 11:51:15 +00:00
| yCLOCKING idAny/*clocking_identifier*/ { $1->v3error("Unsupported: Modport clocking"); }
// // IEEE: yIMPORT modport_tf_port
// // IEEE: yEXPORT modport_tf_port
// // modport_tf_port expanded here
| yIMPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef($<fl>1,*$2,false); }
| yEXPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef($<fl>1,*$2,true); }
| yIMPORT method_prototype { $1->v3error("Unsupported: Modport import with prototype"); }
| yEXPORT method_prototype { $1->v3error("Unsupported: Modport export with prototype"); }
2013-05-28 01:39:19 +00:00
// Continuations of above after a comma.
// // IEEE: modport_simple_ports_declaration
| modportSimplePort { $$ = new AstModportVarRef($<fl>1,*$1,AstVarType::INOUT); }
;
modportSimplePort<strp>: // IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
id { $$ = $1; }
//UNSUP '.' idAny '(' ')' { }
//UNSUP '.' idAny '(' expr ')' { }
;
2009-05-07 22:28:05 +00:00
//************************************************
// Variable Declarations
2007-06-12 13:58:56 +00:00
2009-05-07 22:28:05 +00:00
genvar_declaration<nodep>: // ==IEEE: genvar_declaration
yGENVAR list_of_genvar_identifiers ';' { $$ = $2; }
2008-04-14 21:10:34 +00:00
;
2009-05-07 22:28:05 +00:00
list_of_genvar_identifiers<nodep>: // IEEE: list_of_genvar_identifiers (for declaration)
genvar_identifierDecl { $$ = $1; }
| list_of_genvar_identifiers ',' genvar_identifierDecl { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2011-11-29 23:23:18 +00:00
genvar_identifierDecl<varp>: // IEEE: genvar_identifier (for declaration)
2009-11-02 13:06:04 +00:00
id/*new-genvar_identifier*/ sigAttrListE
{ VARRESET_NONLIST(GENVAR); VARDTYPE(new AstBasicDType($<fl>1,AstBasicDTypeKwd::INTEGER));
2011-01-19 02:12:31 +00:00
$$ = VARDONEA($<fl>1, *$1, NULL, $2); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration
// // See notes in parameter_declaration
2012-10-09 01:20:13 +00:00
local_parameter_declarationFront list_of_param_assignments { $$ = $2; }
2009-05-07 22:28:05 +00:00
;
2007-05-14 20:59:58 +00:00
2009-05-07 22:28:05 +00:00
parameter_declaration<nodep>: // IEEE: parameter_declaration
// // IEEE: yPARAMETER yTYPE list_of_type_assignments ';'
// // Instead of list_of_type_assignments
// // we use list_of_param_assignments because for port handling
// // it already must accept types, so simpler to have code only one place
parameter_declarationFront list_of_param_assignments { $$ = $2; }
2007-05-14 20:59:58 +00:00
;
2009-05-07 22:28:05 +00:00
local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
2009-12-18 01:58:14 +00:00
varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
2009-11-03 03:14:11 +00:00
| varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
2009-11-02 13:06:04 +00:00
//UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
2007-05-14 20:59:58 +00:00
;
2009-05-07 22:28:05 +00:00
parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
2009-12-18 01:58:14 +00:00
varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
2009-11-03 03:14:11 +00:00
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
2009-11-02 13:06:04 +00:00
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
2007-05-14 20:59:58 +00:00
;
2009-05-07 22:28:05 +00:00
parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment
// // IEEE: parameter_declaration (minus assignment)
parameter_declarationFront { }
//
2009-11-02 13:06:04 +00:00
//UNSUP data_type { VARDTYPE($1); }
//UNSUP yTYPE { VARDTYPE($1); }
2007-05-14 20:59:58 +00:00
;
2009-05-07 22:28:05 +00:00
net_declaration<nodep>: // IEEE: net_declaration - excluding implict
net_declarationFront netSigList ';' { $$ = $2; }
2007-05-14 20:59:58 +00:00
;
2009-05-07 22:28:05 +00:00
net_declarationFront: // IEEE: beginning of net_declaration
2013-02-02 14:33:04 +00:00
net_declRESET net_type strengthSpecE net_scalaredE net_dataType { VARDTYPE($5); }
2007-05-14 20:59:58 +00:00
;
2006-08-26 11:35:28 +00:00
2009-05-07 22:28:05 +00:00
net_declRESET:
/* empty */ { VARRESET_NONLIST(UNKNOWN); }
2006-08-26 11:35:28 +00:00
;
2013-02-02 14:33:04 +00:00
net_scalaredE:
/* empty */ { }
//UNSUP: ySCALARED/yVECTORED ignored
| ySCALARED { }
| yVECTORED { }
;
net_dataType<dtypep>:
// // If there's a SV data type there shouldn't be a delay on this wire
// // Otherwise #(...) can't be determined to be a delay or parameters
// // Submit this as a footnote to the committee
var_data_type { $$ = $1; }
| signingE rangeList delayE { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC, $1),$2,true); } // not implicit
| signing { $$ = new AstBasicDType($<fl>1, LOGIC, $1); } // not implicit
| /*implicit*/ delayE { $$ = new AstBasicDType(CRELINE(), LOGIC); } // not implicit
;
2009-01-25 02:36:14 +00:00
net_type: // ==IEEE: net_type
2009-01-15 18:58:43 +00:00
ySUPPLY0 { VARDECL(SUPPLY0); }
2006-08-26 11:35:28 +00:00
| ySUPPLY1 { VARDECL(SUPPLY1); }
| yTRI { VARDECL(TRIWIRE); }
2012-04-22 01:45:28 +00:00
| yTRI0 { VARDECL(TRI0); }
| yTRI1 { VARDECL(TRI1); }
2009-05-07 22:28:05 +00:00
//UNSUP yTRIAND { VARDECL(TRIAND); }
//UNSUP yTRIOR { VARDECL(TRIOR); }
//UNSUP yTRIREG { VARDECL(TRIREG); }
//UNSUP yWAND { VARDECL(WAND); }
| yWIRE { VARDECL(WIRE); }
//UNSUP yWOR { VARDECL(WOR); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
varGParamReset:
yPARAMETER { VARRESET_NONLIST(GPARAM); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
varLParamReset:
yLOCALPARAM { VARRESET_NONLIST(LPARAM); }
2006-08-26 11:35:28 +00:00
;
2008-04-14 21:10:34 +00:00
2009-05-07 22:28:05 +00:00
port_direction: // ==IEEE: port_direction + tf_port_direction
// // IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here
2009-01-15 18:58:43 +00:00
yINPUT { VARIO(INPUT); }
2008-04-14 21:10:34 +00:00
| yOUTPUT { VARIO(OUTPUT); }
| yINOUT { VARIO(INOUT); }
2009-05-07 22:28:05 +00:00
//UNSUP yREF { VARIO(REF); }
//UNSUP yCONST__REF yREF { VARIO(CONSTREF); }
;
port_directionReset: // IEEE: port_direction that starts a port_declaraiton
// // Used only for declarations outside the port list
yINPUT { VARRESET_NONLIST(UNKNOWN); VARIO(INPUT); }
| yOUTPUT { VARRESET_NONLIST(UNKNOWN); VARIO(OUTPUT); }
| yINOUT { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
//UNSUP yREF { VARRESET_NONLIST(UNKNOWN); VARIO(REF); }
//UNSUP yCONST__REF yREF { VARRESET_NONLIST(UNKNOWN); VARIO(CONSTREF); }
;
port_declaration<nodep>: // ==IEEE: port_declaration
// // Used inside block; followed by ';'
// // SIMILAR to tf_port_declaration
//
// // IEEE: inout_declaration
// // IEEE: input_declaration
// // IEEE: output_declaration
// // IEEE: ref_declaration
2009-11-02 13:06:04 +00:00
port_directionReset port_declNetE data_type { VARDTYPE($3); }
list_of_variable_decl_assignments { $$ = $5; }
2009-11-06 00:57:31 +00:00
| port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); }
list_of_variable_decl_assignments { $$ = $6; }
2009-12-18 01:58:14 +00:00
| port_directionReset port_declNetE yVAR implicit_typeE { VARDTYPE($4); }
2009-11-06 00:57:31 +00:00
list_of_variable_decl_assignments { $$ = $6; }
2013-01-14 03:18:57 +00:00
| port_directionReset port_declNetE signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($4->fileline(), LOGIC_IMPLICIT, $3),$4,true)); }
2009-11-02 13:06:04 +00:00
list_of_variable_decl_assignments { $$ = $6; }
2009-11-05 14:57:23 +00:00
| port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $3)); }
2009-11-02 13:06:04 +00:00
list_of_variable_decl_assignments { $$ = $5; }
| port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/}
list_of_variable_decl_assignments { $$ = $4; }
2009-05-07 22:28:05 +00:00
;
tf_port_declaration<nodep>: // ==IEEE: tf_port_declaration
// // Used inside function; followed by ';'
// // SIMILAR to port_declaration
//
2009-12-18 01:58:14 +00:00
port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
| port_directionReset implicit_typeE { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
| port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; }
| port_directionReset yVAR implicit_typeE { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; }
2006-08-26 11:35:28 +00:00
;
2009-11-02 13:06:04 +00:00
integer_atom_type<bdtypep>: // ==IEEE: integer_atom_type
2009-11-03 03:14:11 +00:00
yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); }
| ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); }
| yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); }
| yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); }
| yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); }
2009-11-19 15:45:59 +00:00
| yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); }
2009-10-31 19:12:28 +00:00
;
2009-11-02 13:06:04 +00:00
integer_vector_type<bdtypep>: // ==IEEE: integer_atom_type
yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); }
| yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); }
2009-11-03 03:14:11 +00:00
| yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } // logic==reg
2009-10-31 19:12:28 +00:00
;
2012-03-20 20:01:53 +00:00
non_integer_type<bdtypep>: // ==IEEE: non_integer_type
2011-07-24 19:01:51 +00:00
yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
| yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
//UNSUP ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::FLOAT); }
2011-11-27 15:31:06 +00:00
// // VAMS - somewhat hackish
| yWREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); VARDECL(WIRE); }
2011-07-24 19:01:51 +00:00
;
2009-11-02 13:06:04 +00:00
signingE<signstate>: // IEEE: signing - plus empty
2012-04-29 12:30:02 +00:00
/*empty*/ { $$ = signedst_NOSIGN; }
2009-11-02 13:06:04 +00:00
| signing { $$ = $1; }
2009-05-07 22:28:05 +00:00
;
2009-11-02 13:06:04 +00:00
signing<signstate>: // ==IEEE: signing
ySIGNED { $<fl>$ = $<fl>1; $$ = signedst_SIGNED; }
| yUNSIGNED { $<fl>$ = $<fl>1; $$ = signedst_UNSIGNED; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
//************************************************
// Data Types
2011-03-18 02:25:49 +00:00
casting_type<dtypep>: // IEEE: casting_type
simple_type { $$ = $1; }
// // IEEE: constant_primary
// // In expr:cast this is expanded to just "expr"
//
// // IEEE: signing
//See where casting_type used
//^^ ySIGNED { $$ = new AstSigned($1,$3); }
//^^ yUNSIGNED { $$ = new AstUnsigned($1,$3); }
//UNSUP ySTRING { $$ = $1; }
//UNSUP yCONST__ETC/*then `*/ { $$ = $1; }
;
simple_type<dtypep>: // ==IEEE: simple_type
// // IEEE: integer_type
integer_atom_type { $$ = $1; }
| integer_vector_type { $$ = $1; }
2011-07-24 19:01:51 +00:00
| non_integer_type { $$ = $1; }
2011-03-18 02:25:49 +00:00
// // IEEE: ps_type_identifier
// // IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE)
| ps_type { $$ = $1; }
// // { generate_block_identifer ... } '.'
// // Need to determine if generate_block_identifier can be lex-detected
;
2009-11-05 14:57:23 +00:00
data_type<dtypep>: // ==IEEE: data_type
2009-05-07 22:28:05 +00:00
// // This expansion also replicated elsewhere, IE data_type__AndID
data_typeNoRef { $$ = $1; }
// // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
2010-04-10 00:40:41 +00:00
| ps_type packed_dimensionListE { $$ = GRAMMARP->createArray($1,$2,true); }
2009-11-13 01:33:50 +00:00
//UNSUP class_scope_type packed_dimensionListE { UNSUP }
2009-05-07 22:28:05 +00:00
// // IEEE: class_type
//UNSUP class_typeWithoutId { $$ = $1; }
// // IEEE: ps_covergroup_identifier
2012-02-24 03:09:51 +00:00
// // we put covergroups under ps_type, so can ignore this
2009-05-07 22:28:05 +00:00
;
2009-11-05 14:57:23 +00:00
data_typeBasic<dtypep>: // IEEE: part of data_type
2010-04-10 00:40:41 +00:00
integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); }
2009-11-05 14:57:23 +00:00
| integer_atom_type signingE { $1->setSignedState($2); $$ = $1; }
2011-07-24 19:01:51 +00:00
| non_integer_type { $$ = $1; }
2009-11-02 13:06:04 +00:00
;
2009-11-05 14:57:23 +00:00
data_typeNoRef<dtypep>: // ==IEEE: data_type, excluding class_type etc references
2009-11-02 13:06:04 +00:00
data_typeBasic { $$ = $1; }
2012-07-29 14:16:20 +00:00
| struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->m_modTypeImpNum++),
2013-01-14 03:18:57 +00:00
GRAMMARP->m_modp,VFlagChildDType(),$1),$2,true); }
2012-03-03 17:10:29 +00:00
| enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++),
2012-03-31 15:22:19 +00:00
GRAMMARP->m_modp,VFlagChildDType(),$1); }
2009-12-04 12:05:44 +00:00
| ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
2009-11-24 14:11:25 +00:00
| yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
2009-05-07 22:28:05 +00:00
//UNSUP yEVENT { UNSUP }
2009-05-19 11:49:19 +00:00
//UNSUP yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { UNSUP }
//UNSUP yVIRTUAL__anyID id/*interface*/ { UNSUP }
2009-05-07 22:28:05 +00:00
//UNSUP type_reference { UNSUP }
// // IEEE: class_scope: see data_type above
// // IEEE: class_type: see data_type above
// // IEEE: ps_covergroup: see data_type above
;
2013-02-02 14:33:04 +00:00
data_type_or_void<dtypep>: // ==IEEE: data_type_or_void
data_type { $$ = $1; }
2012-07-29 14:16:20 +00:00
//UNSUP yVOID { UNSUP } // No yTAGGED structures
;
2013-02-02 14:33:04 +00:00
var_data_type<dtypep>: // ==IEEE: var_data_type
data_type { $$ = $1; }
| yVAR data_type { $$ = $2; }
| yVAR implicit_typeE { $$ = $2; }
;
2012-07-29 14:16:20 +00:00
struct_unionDecl<classp>: // IEEE: part of data_type
// // packedSigningE is NOP for unpacked
ySTRUCT packedSigningE '{' { $<classp>$ = new AstStructDType($1, $2); SYMP->pushNew($<classp>$); }
/*cont*/ struct_union_memberList '}'
{ $$=$<classp>4; $$->addMembersp($5); SYMP->popScope($$); }
| yUNION taggedE packedSigningE '{' { $<classp>$ = new AstUnionDType($1, $3); SYMP->pushNew($<classp>$); }
/*cont*/ struct_union_memberList '}'
{ $$=$<classp>5; $$->addMembersp($6); SYMP->popScope($$); }
;
struct_union_memberList<nodep>: // IEEE: { struct_union_member }
struct_union_member { $$ = $1; }
| struct_union_memberList struct_union_member { $$ = $1->addNextNull($2); }
;
struct_union_member<nodep>: // ==IEEE: struct_union_member
random_qualifierE data_type_or_void
{ GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member.
/*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; }
;
list_of_member_decl_assignments<nodep>: // Derived from IEEE: list_of_variable_decl_assignments
member_decl_assignment { $$ = $1; }
| list_of_member_decl_assignments ',' member_decl_assignment { $$ = $1->addNextNull($3); }
;
member_decl_assignment<memberp>: // Derived from IEEE: variable_decl_assignment
// // At present we allow only packed structures/unions. So this is different from variable_decl_assignment
id variable_dimensionListE
{ if ($2) $2->v3error("Unsupported: Unpacked array in packed struct/union");
$$ = new AstMemberDType($<fl>1, *$1, VFlagChildDType(), GRAMMARP->m_memDTypep->cloneTree(true)); }
| id variable_dimensionListE '=' variable_declExpr
{ $4->v3error("Unsupported: Initial values in struct/union members."); }
| idSVKwd { $$ = NULL; }
//
// // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
// // Matches above with variable_dimensionE = "[]"
// // IEEE: "class_variable_identifier [ '=' class_new ]"
// // variable_dimensionE must be empty
// // Pushed into variable_declExpr:dynamic_array_new
//
// // IEEE: "[ covergroup_variable_identifier ] '=' class_new
// // Pushed into variable_declExpr:class_new
//UNSUP '=' class_new { UNSUP }
;
2009-05-07 22:28:05 +00:00
list_of_variable_decl_assignments<nodep>: // ==IEEE: list_of_variable_decl_assignments
variable_decl_assignment { $$ = $1; }
| list_of_variable_decl_assignments ',' variable_decl_assignment { $$ = $1->addNextNull($3); }
;
variable_decl_assignment<varp>: // ==IEEE: variable_decl_assignment
id variable_dimensionListE sigAttrListE
2011-01-19 02:12:31 +00:00
{ $$ = VARDONEA($<fl>1,*$1,$2,$3); }
2009-05-07 22:28:05 +00:00
| id variable_dimensionListE sigAttrListE '=' variable_declExpr
2011-01-19 02:12:31 +00:00
{ $$ = VARDONEA($<fl>1,*$1,$2,$3); $$->valuep($5); }
2009-09-07 19:54:12 +00:00
| idSVKwd { $$ = NULL; }
2009-05-07 22:28:05 +00:00
//
// // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
// // Matches above with variable_dimensionE = "[]"
// // IEEE: "class_variable_identifier [ '=' class_new ]"
// // variable_dimensionE must be empty
// // Pushed into variable_declExpr:dynamic_array_new
//
// // IEEE: "[ covergroup_variable_identifier ] '=' class_new
// // Pushed into variable_declExpr:class_new
//UNSUP '=' class_new { UNSUP }
;
list_of_tf_variable_identifiers<nodep>: // ==IEEE: list_of_tf_variable_identifiers
tf_variable_identifier { $$ = $1; }
| list_of_tf_variable_identifiers ',' tf_variable_identifier { $$ = $1->addNext($3); }
;
tf_variable_identifier<varp>: // IEEE: part of list_of_tf_variable_identifiers
2009-05-19 11:49:19 +00:00
id variable_dimensionListE sigAttrListE
2011-01-19 02:12:31 +00:00
{ $$ = VARDONEA($<fl>1,*$1, $2, $3); }
2009-05-19 11:49:19 +00:00
| id variable_dimensionListE sigAttrListE '=' expr
2011-01-19 02:12:31 +00:00
{ $$ = VARDONEA($<fl>1,*$1, $2, $3);
2009-05-07 22:28:05 +00:00
$$->addNext(new AstAssign($4, new AstVarRef($4, *$1, true), $5)); }
;
variable_declExpr<nodep>: // IEEE: part of variable_decl_assignment - rhs of expr
expr { $$ = $1; }
//UNSUP dynamic_array_new { $$ = $1; }
//UNSUP class_new { $$ = $1; }
;
variable_dimensionListE<rangep>: // IEEE: variable_dimension + empty
/*empty*/ { $$ = NULL; }
| variable_dimensionList { $$ = $1; }
;
variable_dimensionList<rangep>: // IEEE: variable_dimension + empty
variable_dimension { $$ = $1; }
| variable_dimensionList variable_dimension { $$ = $1->addNext($2)->castRange(); }
;
variable_dimension<rangep>: // ==IEEE: variable_dimension
// // IEEE: unsized_dimension
//UNSUP '[' ']' { UNSUP }
// // IEEE: unpacked_dimension
anyrange { $$ = $1; }
2009-11-06 00:26:44 +00:00
| '[' constExpr ']' { $$ = new AstRange($1,new AstSub($1,$2, new AstConst($1,1)), new AstConst($1,0)); }
2009-05-07 22:28:05 +00:00
// // IEEE: associative_dimension
//UNSUP '[' data_type ']' { UNSUP }
//UNSUP yP_BRASTAR ']' { UNSUP }
//UNSUP '[' '*' ']' { UNSUP }
// // IEEE: queue_dimension
// // '[' '$' ']' -- $ is part of expr
// // '[' '$' ':' expr ']' -- anyrange:expr:$
;
2012-07-29 14:16:20 +00:00
random_qualifierE: // IEEE: random_qualifier + empty
/*empty*/ { }
| random_qualifier { }
;
random_qualifier: // ==IEEE: random_qualifier
yRAND { } // Ignored until we support randomize()
| yRANDC { } // Ignored until we support randomize()
;
taggedE:
/*empty*/ { }
//UNSUP yTAGGED { UNSUP }
;
packedSigningE<signstate>:
// // AstNumeric::NOSIGN overloaded to indicate not packed
/*empty*/ { $$ = signedst_NOSIGN; }
| yPACKED signingE { $$ = $2; if ($$ == signedst_NOSIGN) $$ = signedst_UNSIGNED; }
;
2009-12-27 13:29:55 +00:00
//************************************************
// enum
// IEEE: part of data_type
enumDecl<dtypep>:
2012-03-31 15:22:19 +00:00
yENUM enum_base_typeE '{' enum_nameList '}' { $$ = new AstEnumDType($1,VFlagChildDType(),$2,$4); }
2009-12-27 13:29:55 +00:00
;
enum_base_typeE<dtypep>: // IEEE: enum_base_type
/* empty */ { $$ = new AstBasicDType(CRELINE(),AstBasicDTypeKwd::INT); }
// // Not in spec, but obviously "enum [1:0]" should work
// // implicit_type expanded, without empty
2013-01-14 03:18:57 +00:00
// // Note enum base types are always packed data types
| signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); }
2009-12-27 13:29:55 +00:00
| signing { $$ = new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $1); }
//
| integer_atom_type signingE { $1->setSignedState($2); $$ = $1; }
2013-01-14 03:18:57 +00:00
| integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); }
2012-02-24 03:09:51 +00:00
// // below can be idAny or yaID__aTYPE
// // IEEE requires a type, though no shift conflict if idAny
2013-01-14 03:18:57 +00:00
| idAny rangeListE { $$ = GRAMMARP->createArray(new AstRefDType($<fl>1, *$1), $2, true); }
2009-12-27 13:29:55 +00:00
;
enum_nameList<nodep>:
enum_name_declaration { $$ = $1; }
| enum_nameList ',' enum_name_declaration { $$ = $1->addNextNull($3); }
;
enum_name_declaration<nodep>: // ==IEEE: enum_name_declaration
idAny/*enum_identifier*/ enumNameRangeE enumNameStartE { $$ = new AstEnumItem($<fl>1, *$1, $2, $3); }
;
enumNameRangeE<nodep>: // IEEE: second part of enum_name_declaration
/* empty */ { $$ = NULL; }
| '[' intnumAsConst ']' { $$ = new AstRange($1,new AstConst($1,0), $2); }
| '[' intnumAsConst ':' intnumAsConst ']' { $$ = new AstRange($1,$2,$4); }
;
enumNameStartE<nodep>: // IEEE: third part of enum_name_declaration
/* empty */ { $$ = NULL; }
| '=' constExpr { $$ = $2; }
;
intnumAsConst<nodep>:
yaINTNUM { $$ = new AstConst($<fl>1,*$1); }
;
2009-05-07 22:28:05 +00:00
//************************************************
// Typedef
data_declaration<nodep>: // ==IEEE: data_declaration
2009-05-19 11:49:19 +00:00
// // VARRESET can't be called here - conflicts
2009-05-07 22:28:05 +00:00
data_declarationVar { $$ = $1; }
2009-11-07 04:16:06 +00:00
| type_declaration { $$ = $1; }
2009-11-10 00:07:59 +00:00
| package_import_declaration { $$ = $1; }
2009-05-07 22:28:05 +00:00
// // IEEE: virtual_interface_declaration
// // "yVIRTUAL yID yID" looks just like a data_declaration
// // Therefore the virtual_interface_declaration term isn't used
;
2009-05-19 11:49:19 +00:00
data_declarationVar<nodep>: // IEEE: part of data_declaration
2009-05-07 22:28:05 +00:00
// // The first declaration has complications between assuming what's the type vs ID declaring
2012-12-31 18:43:54 +00:00
data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; }
2009-05-07 22:28:05 +00:00
;
data_declarationVarFront: // IEEE: part of data_declaration
2011-07-02 16:45:26 +00:00
// // Expanded: "constE yVAR lifetimeE data_type"
2009-05-07 22:28:05 +00:00
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
2012-12-31 18:43:54 +00:00
/**/ yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE($3); }
| /**/ yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT)); }
2013-01-14 03:18:57 +00:00
| /**/ yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true)); }
2011-07-02 16:45:26 +00:00
//
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
2012-12-31 18:43:54 +00:00
| yCONST__ETC yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), $4)); }
| yCONST__ETC yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), new AstBasicDType($<fl>2, LOGIC_IMPLICIT))); }
2013-01-14 03:18:57 +00:00
| yCONST__ETC yVAR lifetimeE signingE rangeList { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), GRAMMARP->addRange(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $4), $5,true))); }
2009-05-07 22:28:05 +00:00
//
// // Expanded: "constE lifetimeE data_type"
2012-12-31 18:43:54 +00:00
| /**/ data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
| /**/ lifetime data_type { VARRESET_NONLIST(VAR); VARDTYPE($2); }
| yCONST__ETC lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), $3)); }
2009-05-07 22:28:05 +00:00
// // = class_new is in variable_decl_assignment
;
2009-12-18 01:58:14 +00:00
implicit_typeE<dtypep>: // IEEE: part of *data_type_or_implicit
2009-05-07 22:28:05 +00:00
// // Also expanded in data_declaration
/* empty */ { $$ = NULL; }
2013-01-14 03:18:57 +00:00
| signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); }
2009-11-05 14:57:23 +00:00
| signing { $$ = new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $1); }
2006-08-26 11:35:28 +00:00
;
2009-11-07 04:16:06 +00:00
type_declaration<nodep>: // ==IEEE: type_declaration
// // Use idAny, as we can redeclare a typedef on an existing typedef
2012-03-31 15:22:19 +00:00
yTYPEDEF data_type idAny variable_dimensionListE ';' { $$ = new AstTypedef($<fl>1, *$3, VFlagChildDType(), GRAMMARP->createArray($2,$4,false));
SYMP->reinsert($$); }
2009-11-07 04:16:06 +00:00
//UNSUP yTYPEDEF id/*interface*/ '.' idAny/*type*/ idAny/*type*/ ';' { $$ = NULL; $1->v3error("Unsupported: SystemVerilog 2005 typedef in this context"); } //UNSUP
// // Combines into above "data_type id" rule
// // Verilator: Not important what it is in the AST, just need to make sure the yaID__aTYPE gets returned
| yTYPEDEF id ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$2); SYMP->reinsert($$); }
2009-12-27 13:29:55 +00:00
| yTYPEDEF yENUM idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$3); SYMP->reinsert($$); }
2012-07-29 14:16:20 +00:00
| yTYPEDEF ySTRUCT idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$3); SYMP->reinsert($$); }
| yTYPEDEF yUNION idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$3); SYMP->reinsert($$); }
2009-12-18 01:58:14 +00:00
//UNSUP yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>1, *$3); SYMP->reinsert($$); }
2009-11-07 04:16:06 +00:00
;
2006-08-26 11:35:28 +00:00
//************************************************
2007-05-14 20:59:58 +00:00
// Module Items
2006-08-26 11:35:28 +00:00
2009-01-25 02:36:14 +00:00
module_itemListE<nodep>: // IEEE: Part of module_declaration
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2009-01-25 02:36:14 +00:00
| module_itemList { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
module_itemList<nodep>: // IEEE: Part of module_declaration
module_item { $$ = $1; }
| module_itemList module_item { $$ = $1->addNextNull($2); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
module_item<nodep>: // ==IEEE: module_item
2009-05-07 22:28:05 +00:00
port_declaration ';' { $$ = $1; }
| non_port_module_item { $$ = $1; }
;
non_port_module_item<nodep>: // ==IEEE: non_port_module_item
2009-01-25 02:36:14 +00:00
generate_region { $$ = $1; }
2009-01-28 20:27:41 +00:00
| module_or_generate_item { $$ = $1; }
| specify_block { $$ = $1; }
2009-05-07 22:28:05 +00:00
| specparam_declaration { $$ = $1; }
//UNSUP program_declaration { $$ = $1; }
//UNSUP module_declaration { $$ = $1; }
//UNSUP interface_declaration { $$ = $1; }
2009-11-07 04:16:06 +00:00
| timeunits_declaration { $$ = $1; }
2009-01-25 02:36:14 +00:00
// // Verilator specific
2009-10-31 14:08:38 +00:00
| yaSCHDR { $$ = new AstScHdr($<fl>1,*$1); }
| yaSCINT { $$ = new AstScInt($<fl>1,*$1); }
| yaSCIMP { $$ = new AstScImp($<fl>1,*$1); }
| yaSCIMPH { $$ = new AstScImpHdr($<fl>1,*$1); }
| yaSCCTOR { $$ = new AstScCtor($<fl>1,*$1); }
| yaSCDTOR { $$ = new AstScDtor($<fl>1,*$1); }
2006-08-26 11:35:28 +00:00
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
2012-10-30 07:02:35 +00:00
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); v3Global.dpi(true); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
module_or_generate_item<nodep>: // ==IEEE: module_or_generate_item
// // IEEE: parameter_override
yDEFPARAM list_of_defparam_assignments ';' { $$ = $2; }
// // IEEE: gate_instantiation + udp_instantiation + module_instantiation
// // not here, see etcInst in module_common_item
// // We joined udp & module definitions, so this goes here
2012-10-09 01:20:13 +00:00
| combinational_body { $$ = $1; }
// // This module_common_item shared with interface_or_generate_item:module_common_item
2009-05-07 22:28:05 +00:00
| module_common_item { $$ = $1; }
;
module_common_item<nodep>: // ==IEEE: module_common_item
module_or_generate_item_declaration { $$ = $1; }
// // IEEE: interface_instantiation
// // + IEEE: program_instantiation
// // + module_instantiation from module_or_generate_item
| etcInst { $$ = $1; }
| concurrent_assertion_item { $$ = $1; }
2013-01-15 04:19:44 +00:00
| bind_directive { $$ = $1; }
2009-01-28 20:27:41 +00:00
| continuous_assign { $$ = $1; }
2009-05-07 22:28:05 +00:00
// // IEEE: net_alias
//UNSUP yALIAS variable_lvalue aliasEqList ';' { UNSUP }
2009-01-28 20:27:41 +00:00
| initial_construct { $$ = $1; }
| final_construct { $$ = $1; }
2009-05-07 22:28:05 +00:00
// // IEEE: always_construct
// // Verilator only - event_control attached to always
2013-05-01 02:55:28 +00:00
| yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS, $2,$3); }
| yALWAYS_FF event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_FF, $2,$3); }
| yALWAYS_COMB event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_COMB, $2,$3); }
| yALWAYS_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); }
2009-05-07 22:28:05 +00:00
| loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
// // Verilator only
2006-08-26 11:35:28 +00:00
| pslStmt { $$ = $1; }
2009-05-07 22:28:05 +00:00
//
| error ';' { $$ = NULL; }
2009-01-28 20:27:41 +00:00
;
2009-01-25 02:36:14 +00:00
2009-01-28 20:27:41 +00:00
continuous_assign<nodep>: // IEEE: continuous_assign
yASSIGN delayE assignList ';' { $$ = $3; }
2009-05-07 22:28:05 +00:00
//UNSUP: strengthSpecE not in above assign
2009-01-28 20:27:41 +00:00
;
initial_construct<nodep>: // IEEE: initial_construct
yINITIAL stmtBlock { $$ = new AstInitial($1,$2); }
;
final_construct<nodep>: // IEEE: final_construct
yFINAL stmtBlock { $$ = new AstFinal($1,$2); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
module_or_generate_item_declaration<nodep>: // ==IEEE: module_or_generate_item_declaration
package_or_generate_item_declaration { $$ = $1; }
| genvar_declaration { $$ = $1; }
| clocking_declaration { $$ = $1; }
2009-05-19 11:49:19 +00:00
//UNSUP yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';' { $$ = $1; }
2009-05-07 22:28:05 +00:00
;
2013-01-15 04:19:44 +00:00
bind_directive<nodep>: // ==IEEE: bind_directive + bind_target_scope
// // ';' - Note IEEE grammar is wrong, includes extra ';' - it's already in module_instantiation
// // We merged the rules - id may be a bind_target_instance or module_identifier or interface_identifier
yBIND bind_target_instance bind_instantiation { $$ = new AstBind($<fl>1,*$2,$3); }
| yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation { $$=NULL; $1->v3error("Unsupported: Bind with instance list"); }
;
bind_target_instance_list: // ==IEEE: bind_target_instance_list
bind_target_instance { }
| bind_target_instance_list ',' bind_target_instance { }
;
bind_target_instance<strp>: // ==IEEE: bind_target_instance
//UNSUP hierarchical_identifierBit { }
idAny { $$ = $1; }
;
bind_instantiation<nodep>: // ==IEEE: bind_instantiation
// // IEEE: program_instantiation
// // IEEE: + module_instantiation
// // IEEE: + interface_instantiation
// // Need to get an AstBind instead of AstCell, so have special rules
instDecl { $$ = $1; }
;
2006-08-26 11:35:28 +00:00
//************************************************
2007-05-14 20:59:58 +00:00
// Generates
2012-10-09 01:20:13 +00:00
//
// Way down in generate_item is speced a difference between module,
// interface and checker generates. modules and interfaces are almost
// identical (minus DEFPARAMs) so we overlap them. Checkers are too
// different, so we copy all rules for checkers.
2006-08-26 11:35:28 +00:00
2012-03-23 12:49:47 +00:00
generate_region<nodep>: // ==IEEE: generate_region
yGENERATE genItemList yENDGENERATE { $$ = new AstGenerate($1, $2); }
| yGENERATE yENDGENERATE { $$ = NULL; }
;
2009-01-28 20:27:41 +00:00
generate_block_or_null<nodep>: // IEEE: generate_block_or_null
2009-05-07 22:28:05 +00:00
// ';' // is included in
// // IEEE: generate_block
2012-07-21 21:12:42 +00:00
// // Must always return a BEGIN node, or NULL - see GenFor construction
2012-07-20 01:18:39 +00:00
generate_item { $$ = $1 ? (new AstBegin($1->fileline(),"genblk",$1,true)) : NULL; }
2006-08-26 11:35:28 +00:00
| genItemBegin { $$ = $1; }
;
2009-01-25 02:36:14 +00:00
genItemBegin<nodep>: // IEEE: part of generate_block
2012-07-20 01:18:39 +00:00
yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2,true); }
2007-05-12 16:29:25 +00:00
| yBEGIN yEND { $$ = NULL; }
2012-07-20 01:18:39 +00:00
| id ':' yBEGIN genItemList yEND endLabelE { $$ = new AstBegin($2,*$1,$4,true); GRAMMARP->endLabel($<fl>6,*$1,$6); }
2012-03-08 01:14:18 +00:00
| id ':' yBEGIN yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$1,$5); }
2012-07-20 01:18:39 +00:00
| yBEGIN ':' idAny genItemList yEND endLabelE { $$ = new AstBegin($2,*$3,$4,true); GRAMMARP->endLabel($<fl>6,*$3,$6); }
2012-03-08 01:14:18 +00:00
| yBEGIN ':' idAny yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$3,$5); }
2006-08-26 11:35:28 +00:00
;
2012-03-23 12:49:47 +00:00
genItemOrBegin<nodep>: // Not in IEEE, but our begin isn't under generate_item
2012-10-09 01:20:13 +00:00
~c~generate_item { $$ = $1; }
| ~c~genItemBegin { $$ = $1; }
2012-03-23 12:49:47 +00:00
;
2008-08-06 16:35:34 +00:00
genItemList<nodep>:
2012-10-09 01:20:13 +00:00
~c~genItemOrBegin { $$ = $1; }
| ~c~genItemList ~c~genItemOrBegin { $$ = $1->addNextNull($2); }
2006-08-26 11:35:28 +00:00
;
2012-03-23 12:49:47 +00:00
generate_item<nodep>: // IEEE: module_or_interface_or_generate_item
// // Only legal when in a generate under a module (or interface under a module)
2009-01-28 20:27:41 +00:00
module_or_generate_item { $$ = $1; }
2012-03-23 12:49:47 +00:00
// // Only legal when in a generate under an interface
2009-05-07 22:28:05 +00:00
//UNSUP interface_or_generate_item { $$ = $1; }
2012-10-09 00:45:39 +00:00
// // IEEE: checker_or_generate_item
// // Only legal when in a generate under a checker
// // so below in c_generate_item
2009-01-28 20:27:41 +00:00
;
conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
2012-10-09 01:20:13 +00:00
yCASE '(' expr ')' ~c~case_generate_itemListE yENDCASE { $$ = new AstGenCase($1,$3,$5); }
2009-01-28 20:27:41 +00:00
| yIF '(' expr ')' generate_block_or_null %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$3,$5,NULL); }
| yIF '(' expr ')' generate_block_or_null yELSE generate_block_or_null { $$ = new AstGenIf($1,$3,$5,$7); }
;
loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
2012-10-09 01:20:13 +00:00
yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null
2012-07-21 21:12:42 +00:00
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
AstBegin* lowerBegp = $9->castBegin();
if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin");
if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body
AstNode* lowerNoBegp = lowerBegp->stmtsp();
if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext();
//
AstBegin* blkp = new AstBegin($1,lowerBegp->name(),NULL,true);
// V3LinkDot detects BEGIN(GENFOR(...)) as a special case
2011-11-29 23:23:18 +00:00
AstNode* initp = $3; AstNode* varp = $3;
if (varp->castVar()) { // Genvar
initp = varp->nextp();
initp->unlinkFrBackWithNext(); // Detach 2nd from varp, make 1st init
blkp->addStmtsp(varp);
}
2012-07-21 21:12:42 +00:00
// Statements are under 'genforp' as cells under this
2011-11-29 23:23:18 +00:00
// for loop won't get an extra layer of hierarchy tacked on
2012-07-21 21:12:42 +00:00
blkp->addGenforp(new AstGenFor($1,initp,$5,$7,lowerNoBegp));
$$ = blkp;
lowerBegp->deleteTree(); lowerBegp=NULL;
}
2009-05-07 22:28:05 +00:00
;
genvar_initialization<nodep>: // ==IEEE: genvar_initalization
varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); }
2011-11-29 23:23:18 +00:00
| yGENVAR genvar_identifierDecl '=' constExpr { $$ = $2; $2->addNext(new AstAssign($3,new AstVarRef($3,$2,true), $4)); }
2009-05-07 22:28:05 +00:00
;
genvar_iteration<nodep>: // ==IEEE: genvar_iteration
2009-09-16 14:32:14 +00:00
varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); }
| varRefBase yP_PLUSEQ expr { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_MINUSEQ expr { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_TIMESEQ expr { $$ = new AstAssign($2,$1,new AstMul ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_DIVEQ expr { $$ = new AstAssign($2,$1,new AstDiv ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_MODEQ expr { $$ = new AstAssign($2,$1,new AstModDiv ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_ANDEQ expr { $$ = new AstAssign($2,$1,new AstAnd ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_OREQ expr { $$ = new AstAssign($2,$1,new AstOr ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_XOREQ expr { $$ = new AstAssign($2,$1,new AstXor ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_SLEFTEQ expr { $$ = new AstAssign($2,$1,new AstShiftL ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_SRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftR ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); }
2009-05-07 22:28:05 +00:00
// // inc_or_dec_operator
2010-02-14 15:01:21 +00:00
// When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstMathStmt?
2009-09-16 14:32:14 +00:00
| yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
2006-08-26 11:35:28 +00:00
;
2009-01-28 20:27:41 +00:00
case_generate_itemListE<nodep>: // IEEE: [{ case_generate_itemList }]
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2009-01-28 20:27:41 +00:00
| case_generate_itemList { $$ = $1; }
2007-05-18 14:03:50 +00:00
;
2009-01-28 20:27:41 +00:00
case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
2012-10-09 01:20:13 +00:00
~c~case_generate_item { $$=$1; }
| ~c~case_generate_itemList ~c~case_generate_item { $$=$1; $1->addNext($2); }
2009-01-28 20:27:41 +00:00
;
case_generate_item<nodep>: // ==IEEE: case_generate_item
caseCondList ':' generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); }
| yDEFAULT ':' generate_block_or_null { $$ = new AstCaseItem($2,NULL,$3); }
| yDEFAULT generate_block_or_null { $$ = new AstCaseItem($1,NULL,$2); }
2006-08-26 11:35:28 +00:00
;
//************************************************
2007-05-14 20:59:58 +00:00
// Assignments and register declarations
2006-08-26 11:35:28 +00:00
2008-08-06 16:35:34 +00:00
assignList<nodep>:
assignOne { $$ = $1; }
2006-08-26 11:35:28 +00:00
| assignList ',' assignOne { $$ = $1->addNext($3); }
;
2008-08-06 16:35:34 +00:00
assignOne<nodep>:
2009-05-07 22:28:05 +00:00
variable_lvalue '=' expr { $$ = new AstAssignW($2,$1,$3); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
delayE:
/* empty */ { }
2011-10-21 11:13:38 +00:00
| delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); } /* ignored */
2007-05-16 18:19:23 +00:00
;
2009-10-31 14:08:38 +00:00
delay_control<fl>: //== IEEE: delay_control
2009-05-07 22:28:05 +00:00
'#' delay_value { $$ = $1; } /* ignored */
2008-03-31 21:03:56 +00:00
| '#' '(' minTypMax ')' { $$ = $1; } /* ignored */
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
delay_value: // ==IEEE:delay_value
// // IEEE: ps_identifier
ps_id_etc { }
| yaINTNUM { }
| yaFLOATNUM { }
| yaTIMENUM { }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
delayExpr:
2012-05-31 03:17:55 +00:00
expr { DEL($1); }
2011-07-24 19:01:51 +00:00
// // Verilator doesn't support yaTIMENUM, so not in expr
2009-05-07 22:28:05 +00:00
| yaTIMENUM { }
2007-05-16 18:19:23 +00:00
;
2009-05-07 22:28:05 +00:00
minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression
delayExpr { }
| delayExpr ':' delayExpr ':' delayExpr { }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
netSigList<varp>: // IEEE: list_of_port_identifiers
2008-08-06 16:35:34 +00:00
netSig { $$ = $1; }
2007-05-14 20:59:58 +00:00
| netSigList ',' netSig { $$ = $1; $1->addNext($3); }
;
2009-05-07 22:28:05 +00:00
netSig<varp>: // IEEE: net_decl_assignment - one element from list_of_port_identifiers
2011-01-19 02:12:31 +00:00
netId sigAttrListE { $$ = VARDONEA($<fl>1,*$1, NULL, $2); }
| netId sigAttrListE '=' expr { $$ = VARDONEA($<fl>1,*$1, NULL, $2); $$->addNext(new AstAssignW($3,new AstVarRef($3,$$->name(),true),$4)); }
2013-12-15 00:50:55 +00:00
| netId variable_dimensionList sigAttrListE { $$ = VARDONEA($<fl>1,*$1, $2, $3); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
netId<strp>:
2011-01-19 02:12:31 +00:00
id/*new-net*/ { $$ = $1; $<fl>$=$<fl>1; }
| idSVKwd { $$ = $1; $<fl>$=$<fl>1; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
sigAttrListE<nodep>:
/* empty */ { $$ = NULL; }
| sigAttrList { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
sigAttrList<nodep>:
sigAttr { $$ = $1; }
| sigAttrList sigAttr { $$ = $1->addNextNull($2); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
sigAttr<nodep>:
yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); }
| yVL_CLOCK_ENABLE { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK_ENABLE); }
2012-10-30 07:02:35 +00:00
| yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT_RD { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RD); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT_RW { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true);
2010-04-06 00:01:17 +00:00
$$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); }
2009-05-07 22:28:05 +00:00
| yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); }
2011-10-26 12:57:27 +00:00
| yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); }
2010-01-18 00:13:44 +00:00
| yVL_SFORMAT { $$ = new AstAttrOf($1,AstAttrType::VAR_SFORMAT); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
rangeListE<rangep>: // IEEE: [{packed_dimension}]
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2006-08-26 11:35:28 +00:00
| rangeList { $$ = $1; }
;
2009-05-07 22:28:05 +00:00
rangeList<rangep>: // IEEE: {packed_dimension}
2008-08-06 16:35:34 +00:00
anyrange { $$ = $1; }
2006-08-26 11:35:28 +00:00
| rangeList anyrange { $$ = $1; $1->addNext($2); }
;
2009-05-07 22:28:05 +00:00
// IEEE: select
// Merged into more general idArray
2008-08-06 16:35:34 +00:00
anyrange<rangep>:
'[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
2006-08-26 11:35:28 +00:00
;
2009-11-13 01:33:50 +00:00
packed_dimensionListE<rangep>: // IEEE: [{ packed_dimension }]
2009-11-07 04:16:06 +00:00
/* empty */ { $$ = NULL; }
2009-11-13 01:33:50 +00:00
| packed_dimensionList { $$ = $1; }
;
packed_dimensionList<rangep>: // IEEE: { packed_dimension }
packed_dimension { $$ = $1; }
| packed_dimensionList packed_dimension { $$ = $1->addNext($2)->castRange(); }
2009-11-07 04:16:06 +00:00
;
packed_dimension<rangep>: // ==IEEE: packed_dimension
anyrange { $$ = $1; }
//UNSUP '[' ']' { UNSUP }
;
2007-05-14 20:59:58 +00:00
//************************************************
2006-08-26 11:35:28 +00:00
// Parameters
2007-05-14 20:59:58 +00:00
2009-05-07 22:28:05 +00:00
param_assignment<varp>: // ==IEEE: param_assignment
// // IEEE: constant_param_expression
// // constant_param_expression: '$' is in expr
2014-04-02 03:16:16 +00:00
id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr
/**/ { $$ = VARDONEA($<fl>1,*$1, $2, $3); $$->valuep($5); }
2009-05-07 22:28:05 +00:00
//UNSUP: exprOrDataType instead of expr
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
list_of_param_assignments<varp>: // ==IEEE: list_of_param_assignments
param_assignment { $$ = $1; }
| list_of_param_assignments ',' param_assignment { $$ = $1; $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
list_of_defparam_assignments<nodep>: //== IEEE: list_of_defparam_assignments
2009-01-15 18:58:43 +00:00
defparam_assignment { $$ = $1; }
| list_of_defparam_assignments ',' defparam_assignment { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
defparam_assignment<nodep>: // ==IEEE: defparam_assignment
2009-05-07 22:28:05 +00:00
id '.' id '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); }
//UNSUP More general dotted identifiers
2006-08-26 11:35:28 +00:00
;
2007-05-14 20:59:58 +00:00
//************************************************
2006-08-26 11:35:28 +00:00
// Instances
2009-05-07 22:28:05 +00:00
// We don't know identifier types, so this matches all module,udp,etc instantiation
// module_id [#(params)] name (pins) [, name ...] ; // module_instantiation
// gate (strong0) [#(delay)] [name] (pins) [, (pins)...] ; // gate_instantiation
// program_id [#(params}] name ; // program_instantiation
// interface_id [#(params}] name ; // interface_instantiation
2012-10-09 00:45:39 +00:00
// checker_id name (pins) ; // checker_instantiation
2009-05-07 22:28:05 +00:00
etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_instantiation
instDecl { $$ = $1; }
| gateDecl { $$ = $1; }
2009-01-15 18:58:43 +00:00
;
2007-05-16 12:55:25 +00:00
2009-05-07 22:28:05 +00:00
instDecl<nodep>:
id parameter_value_assignmentE {INSTPREP(*$1,$2);} instnameList ';'
2009-10-31 14:08:38 +00:00
{ $$ = $4; GRAMMARP->m_impliedDecl=false;}
2009-05-07 22:28:05 +00:00
//UNSUP: strengthSpecE for udp_instantiations
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
instnameList<nodep>:
instnameParen { $$ = $1; }
2007-05-16 12:55:25 +00:00
| instnameList ',' instnameParen { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
instnameParen<nodep>:
2011-01-19 02:12:31 +00:00
id instRangeE '(' cellpinList ')' { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); }
| id instRangeE { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); }
2009-05-07 22:28:05 +00:00
//UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP
2012-04-25 00:43:15 +00:00
// // Adding above and switching to the Verilog-Perl syntax
// // causes a shift conflict due to use of idClassSel inside exprScope.
// // It also breaks allowing "id foo;" instantiation syntax.
2007-05-16 18:19:23 +00:00
;
2008-08-06 16:35:34 +00:00
instRangeE<rangep>:
/* empty */ { $$ = NULL; }
2009-05-07 22:28:05 +00:00
| '[' constExpr ']' { $$ = new AstRange($1,$2,$2->cloneTree(true)); }
2007-05-16 18:19:23 +00:00
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
cellpinList<pinp>:
2009-05-07 22:28:05 +00:00
{VARRESET_LIST(UNKNOWN);} cellpinItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
cellpinItList<pinp>: // IEEE: list_of_port_connections + list_of_parameter_assignmente
2008-08-06 16:35:34 +00:00
cellpinItemE { $$ = $1; }
2007-05-16 12:55:25 +00:00
| cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
cellpinItemE<pinp>: // IEEE: named_port_connection + named_parameter_assignment + empty
2011-01-29 23:00:48 +00:00
// Note empty can match either () or (,); V3LinkCells cleans up ()
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),PINNUMINC(),"",NULL); }
2009-05-07 22:28:05 +00:00
| yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); }
2011-01-29 23:00:48 +00:00
| '.' idSVKwd { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
2009-05-12 00:32:52 +00:00
| '.' idAny { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
2011-01-29 23:00:48 +00:00
| '.' idAny '(' ')' { $$ = new AstPin($1,PINNUMINC(),*$2,NULL); }
2010-04-06 22:55:54 +00:00
// // mintypmax is expanded here, as it might be a UDP or gate primitive
2009-05-12 00:32:52 +00:00
| '.' idAny '(' expr ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); }
2010-04-06 22:55:54 +00:00
//UNSUP '.' idAny '(' expr ':' expr ')' { }
//UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { }
2009-05-07 22:28:05 +00:00
// // For parameters
2009-05-12 00:32:52 +00:00
//UNSUP '.' idAny '(' data_type ')' { PINDONE($1,$2,$4); GRAMMARP->pinNumInc(); }
2009-05-07 22:28:05 +00:00
// // For parameters
//UNSUP data_type { PINDONE($1->fileline(),"",$1); GRAMMARP->pinNumInc(); }
//
| expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
2010-04-06 22:55:54 +00:00
//UNSUP expr ':' expr { }
//UNSUP expr ':' expr ':' expr { }
2006-08-26 11:35:28 +00:00
;
2007-05-14 20:59:58 +00:00
//************************************************
2007-10-26 14:58:26 +00:00
// EventControl lists
2007-05-14 20:59:58 +00:00
2010-04-06 00:01:17 +00:00
attr_event_control<sentreep>: // ==IEEE: event_control
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
| '@' '(' '*' ')' { $$ = NULL; }
| '@' '*' { $$ = NULL; }
;
2009-01-15 18:58:43 +00:00
event_controlE<sentreep>:
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2009-01-15 18:58:43 +00:00
| event_control { $$ = $1; }
2009-01-25 02:36:14 +00:00
;
2007-05-16 19:27:29 +00:00
2009-01-15 18:58:43 +00:00
event_control<sentreep>: // ==IEEE: event_control
2009-05-07 22:28:05 +00:00
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
2009-01-28 20:27:41 +00:00
| '@' '(' '*' ')' { $$ = NULL; }
2009-05-07 22:28:05 +00:00
| '@' '*' { $$ = NULL; }
// // IEEE: hierarchical_event_identifier
| '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */
// // IEEE: sequence_instance
// // sequence_instance without parens matches idClassSel above.
// // Ambiguity: "'@' sequence (-for-sequence" versus expr:delay_or_event_controlE "'@' id (-for-expr
// // For now we avoid this, as it's very unlikely someone would mix
// // 1995 delay with a sequence with parameters.
// // Alternatively split this out of event_control, and delay_or_event_controlE
// // and anywhere delay_or_event_controlE is called allow two expressions
//| '@' idClassSel '(' list_of_argumentsE ')' { }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
event_expression<senitemp>: // IEEE: event_expression - split over several
2008-08-06 16:35:34 +00:00
senitem { $$ = $1; }
2012-05-31 03:15:25 +00:00
| event_expression yOR senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); }
| event_expression ',' senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); } /* Verilog 2001 */
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
2008-08-06 16:35:34 +00:00
senitemEdge { $$ = $1; }
2007-05-18 18:48:22 +00:00
| senitemVar { $$ = $1; }
2008-04-14 21:47:39 +00:00
| '(' senitemVar ')' { $$ = $2; }
2009-05-07 22:28:05 +00:00
//UNSUP expr { UNSUP }
//UNSUP expr yIFF expr { UNSUP }
2011-11-02 22:34:17 +00:00
// Since expr is unsupported we allow and ignore constants (removed in V3Const)
| yaINTNUM { $$ = NULL; }
| yaFLOATNUM { $$ = NULL; }
| '(' yaINTNUM ')' { $$ = NULL; }
| '(' yaFLOATNUM ')' { $$ = NULL; }
2007-05-18 18:48:22 +00:00
;
2008-08-06 16:35:34 +00:00
senitemVar<senitemp>:
2011-01-19 02:12:31 +00:00
idClassSel { $$ = new AstSenItem($1->fileline(),AstEdgeType::ET_ANYEDGE,$1); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
senitemEdge<senitemp>: // IEEE: part of event_expression
2010-02-02 01:15:48 +00:00
yPOSEDGE idClassSel { $$ = new AstSenItem($1,AstEdgeType::ET_POSEDGE,$2); }
| yNEGEDGE idClassSel { $$ = new AstSenItem($1,AstEdgeType::ET_NEGEDGE,$2); }
| yEDGE idClassSel { $$ = new AstSenItem($1,AstEdgeType::ET_BOTHEDGE,$2); }
| yPOSEDGE '(' idClassSel ')' { $$ = new AstSenItem($1,AstEdgeType::ET_POSEDGE,$3); }
| yNEGEDGE '(' idClassSel ')' { $$ = new AstSenItem($1,AstEdgeType::ET_NEGEDGE,$3); }
| yEDGE '(' idClassSel ')' { $$ = new AstSenItem($1,AstEdgeType::ET_BOTHEDGE,$3); }
2009-05-07 22:28:05 +00:00
//UNSUP yIFF...
2006-08-26 11:35:28 +00:00
;
2007-05-14 20:59:58 +00:00
//************************************************
// Statements
2009-01-25 02:36:14 +00:00
stmtBlock<nodep>: // IEEE: statement + seq_block + par_block
2008-08-06 16:35:34 +00:00
stmt { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
seq_block<nodep>: // ==IEEE: seq_block
// // IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
2012-10-09 01:20:13 +00:00
// // So need AstBegin's even if unnamed to scope variables down
2012-03-08 01:14:18 +00:00
seq_blockFront blockDeclStmtList yEND endLabelE { $$=$1; $1->addStmtsp($2); SYMP->popScope($1); GRAMMARP->endLabel($<fl>4,$1,$4); }
| seq_blockFront /**/ yEND endLabelE { $$=$1; SYMP->popScope($1); GRAMMARP->endLabel($<fl>3,$1,$3); }
2009-05-07 22:28:05 +00:00
;
2009-10-31 14:08:38 +00:00
seq_blockFront<beginp>: // IEEE: part of par_block
2009-10-31 14:14:04 +00:00
yBEGIN { $$ = new AstBegin($1,"",NULL); SYMP->pushNew($$); }
| yBEGIN ':' idAny/*new-block_identifier*/ { $$ = new AstBegin($1,*$3,NULL); SYMP->pushNew($$); }
2009-05-07 22:28:05 +00:00
;
blockDeclStmtList<nodep>: // IEEE: { block_item_declaration } { statement or null }
// // The spec seems to suggest a empty declaration isn't ok, but most simulators take it
block_item_declarationList { $$ = $1; }
| block_item_declarationList stmtList { $$ = $1->addNextNull($2); }
| stmtList { $$ = $1; }
;
block_item_declarationList<nodep>: // IEEE: [ block_item_declaration ]
block_item_declaration { $$ = $1; }
| block_item_declarationList block_item_declaration { $$ = $1->addNextNull($2); }
;
block_item_declaration<nodep>: // ==IEEE: block_item_declaration
data_declaration { $$ = $1; }
2012-10-09 01:20:13 +00:00
| local_parameter_declaration ';' { $$ = $1; }
2009-05-07 22:28:05 +00:00
| parameter_declaration ';' { $$ = $1; }
//UNSUP overload_declaration { $$ = $1; }
2012-10-09 00:45:39 +00:00
//UNSUP let_declaration { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
stmtList<nodep>:
stmtBlock { $$ = $1; }
2006-08-26 11:35:28 +00:00
| stmtList stmtBlock { $$ = ($2==NULL)?($1):($1->addNext($2)); }
;
2009-05-07 22:28:05 +00:00
stmt<nodep>: // IEEE: statement_or_null == function_statement_or_null
statement_item { }
//UNSUP: Labeling any statement
2007-03-06 21:43:38 +00:00
| labeledStmt { $$ = $1; }
2009-05-07 22:28:05 +00:00
| id ':' labeledStmt { $$ = new AstBegin($2, *$1, $3); } /*S05 block creation rule*/
// // from _or_null
| ';' { $$ = NULL; }
;
statement_item<nodep>: // IEEE: statement_item
2009-01-28 20:27:41 +00:00
// // IEEE: operator_assignment
2009-05-07 22:28:05 +00:00
foperator_assignment ';' { $$ = $1; }
//
// // IEEE: blocking_assignment
2012-10-09 00:45:39 +00:00
// // 1800-2009 restricts LHS of assignment to new to not have a range
// // This is ignored to avoid conflicts
2009-05-07 22:28:05 +00:00
//UNSUP fexprLvalue '=' class_new ';' { UNSUP }
//UNSUP fexprLvalue '=' dynamic_array_new ';' { UNSUP }
2009-02-25 22:16:51 +00:00
//
2009-01-28 20:27:41 +00:00
// // IEEE: nonblocking_assignment
2012-12-31 22:05:13 +00:00
| fexprLvalue yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); }
2009-05-07 22:28:05 +00:00
//UNSUP fexprLvalue yP_LTE delay_or_event_controlE expr ';' { UNSUP }
2009-02-25 22:16:51 +00:00
//
2009-01-28 20:27:41 +00:00
// // IEEE: procedural_continuous_assignment
2009-05-07 22:28:05 +00:00
| yASSIGN idClassSel '=' delayE expr ';' { $$ = new AstAssign($1,$2,$5); }
//UNSUP: delay_or_event_controlE above
//UNSUP yDEASSIGN variable_lvalue ';' { UNSUP }
//UNSUP yFORCE expr '=' expr ';' { UNSUP }
//UNSUP yRELEASE variable_lvalue ';' { UNSUP }
2009-02-25 22:16:51 +00:00
//
2009-01-28 20:27:41 +00:00
// // IEEE: case_statement
| unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
2010-12-26 02:58:28 +00:00
if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
2009-05-07 22:28:05 +00:00
//UNSUP caseStart caseAttrE yMATCHES case_patternListE yENDCASE { }
2014-01-21 02:59:53 +00:00
| unique_priorityE caseStart caseAttrE yINSIDE case_insideListE yENDCASE { $$ = $2; if ($5) $2->addItemsp($5);
if (!$2->caseSimple()) $2->v3error("Illegal to have inside on a casex/casez");
$2->caseInsideSet();
if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
2009-02-25 22:16:51 +00:00
//
2009-01-28 20:27:41 +00:00
// // IEEE: conditional_statement
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
2010-12-26 02:58:28 +00:00
{ $$ = new AstIf($2,$4,$6,NULL);
if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); }
2009-01-28 20:27:41 +00:00
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
2010-12-26 02:58:28 +00:00
{ $$ = new AstIf($2,$4,$6,$8);
if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); }
2009-02-25 22:16:51 +00:00
//
2010-12-08 01:18:47 +00:00
| finc_or_dec_expression ';' { $$ = $1; }
2009-05-07 22:28:05 +00:00
// // IEEE: inc_or_dec_expression
// // Below under expr
//
// // IEEE: subroutine_call_statement
//UNSUP yVOID yP_TICK '(' function_subroutine_callNoMethod ')' ';' { }
2009-05-19 11:49:19 +00:00
//UNSUP yVOID yP_TICK '(' expr '.' function_subroutine_callNoMethod ')' ';' { }
2009-05-07 22:28:05 +00:00
// // Expr included here to resolve our not knowing what is a method call
// // Expr here must result in a subroutine_call
| task_subroutine_callNoMethod ';' { $$ = $1; }
//UNSUP fexpr '.' array_methodNoRoot ';' { UNSUP }
2012-12-31 22:05:13 +00:00
| fexpr '.' task_subroutine_callNoMethod ';' { $$ = new AstDot($<fl>2,$1,$3); }
2009-05-07 22:28:05 +00:00
//UNSUP fexprScope ';' { UNSUP }
2009-05-19 11:49:19 +00:00
// // Not here in IEEE; from class_constructor_declaration
// // Because we've joined class_constructor_declaration into generic functions
// // Way over-permissive;
// // IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ]
//UNSUP fexpr '.' class_new ';' { }
2009-05-07 22:28:05 +00:00
//
| statementVerilatorPragmas { $$ = $1; }
//
// // IEEE: disable_statement
2011-06-29 01:26:49 +00:00
| yDISABLE idAny/*hierarchical_identifier-task_or_block*/ ';' { $$ = new AstDisable($1,*$2); }
2009-05-07 22:28:05 +00:00
//UNSUP yDISABLE yFORK ';' { UNSUP }
// // IEEE: event_trigger
//UNSUP yP_MINUSGT hierarchical_identifier/*event*/ ';' { UNSUP }
//UNSUP yP_MINUSGTGT delay_or_event_controlE hierarchical_identifier/*event*/ ';' { UNSUP }
// // IEEE: loop_statement
2009-11-23 00:57:41 +00:00
| yFOREVER stmtBlock { $$ = new AstWhile($1,new AstConst($1,AstConst::LogicTrue()),$2); }
2009-02-26 03:06:59 +00:00
| yREPEAT '(' expr ')' stmtBlock { $$ = new AstRepeat($1,$3,$5);}
2009-01-28 20:27:41 +00:00
| yWHILE '(' expr ')' stmtBlock { $$ = new AstWhile($1,$3,$5);}
2009-05-07 22:28:05 +00:00
// // for's first ';' is in for_initalization
| yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
2010-02-14 15:01:21 +00:00
{ $$ = new AstBegin($1,"",$3); $3->addNext(new AstWhile($1, $4,$8,$6)); }
2010-07-07 23:15:51 +00:00
| yDO stmtBlock yWHILE '(' expr ')' ';' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));}
2012-10-09 00:45:39 +00:00
// // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
2009-05-19 11:49:19 +00:00
//UNSUP yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' stmt { UNSUP }
2009-05-07 22:28:05 +00:00
//
// // IEEE: jump_statement
2010-02-14 15:01:21 +00:00
| yRETURN ';' { $$ = new AstReturn($1); }
| yRETURN expr ';' { $$ = new AstReturn($1,$2); }
| yBREAK ';' { $$ = new AstBreak($1); }
| yCONTINUE ';' { $$ = new AstContinue($1); }
2009-05-07 22:28:05 +00:00
//
//UNSUP par_block { $$ = $1; }
// // IEEE: procedural_timing_control_statement + procedural_timing_control
2011-10-21 11:13:38 +00:00
| delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Unsupported: Ignoring delay on this delayed statement."); }
2009-05-07 22:28:05 +00:00
//UNSUP event_control stmtBlock { UNSUP }
//UNSUP cycle_delay stmtBlock { UNSUP }
//
| seq_block { $$ = $1; }
//
// // IEEE: wait_statement
//UNSUP yWAIT '(' expr ')' stmtBlock { UNSUP }
//UNSUP yWAIT yFORK ';' { UNSUP }
//UNSUP yWAIT_ORDER '(' hierarchical_identifierList ')' action_block { UNSUP }
//
// // IEEE: procedural_assertion_statement
// // Verilator: Label included instead
| concurrent_assertion_item { $$ = $1; }
// // concurrent_assertion_statement { $$ = $1; }
// // Verilator: Part of labeledStmt instead
// // immediate_assert_statement { UNSUP }
//
// // IEEE: clocking_drive ';'
// // Pattern w/o cycle_delay handled by nonblocking_assign above
// // clockvar_expression made to fexprLvalue to prevent reduce conflict
// // Note LTE in this context is highest precedence, so first on left wins
//UNSUP cycle_delay fexprLvalue yP_LTE ';' { UNSUP }
//UNSUP fexprLvalue yP_LTE cycle_delay expr ';' { UNSUP }
//
//UNSUP randsequence_statement { $$ = $1; }
//
// // IEEE: randcase_statement
//UNSUP yRANDCASE case_itemList yENDCASE { UNSUP }
//
//UNSUP expect_property_statement { $$ = $1; }
//
| error ';' { $$ = NULL; }
;
statementVerilatorPragmas<nodep>:
yVL_COVERAGE_BLOCK_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
;
foperator_assignment<nodep>: // IEEE: operator_assignment (for first part of expression)
2012-12-31 22:05:13 +00:00
fexprLvalue '=' delayE expr { $$ = new AstAssign($2,$1,$4); }
2013-02-22 22:14:27 +00:00
| fexprLvalue '=' yD_FOPEN '(' expr ')' { $$ = NULL; $3->v3error("Unsupported: $fopen with multichannel descriptor. Add ,\"w\" as second argument to open a file descriptor."); }
2012-12-31 22:05:13 +00:00
| fexprLvalue '=' yD_FOPEN '(' expr ',' expr ')' { $$ = new AstFOpen($3,$1,$5,$7); }
2009-05-07 22:28:05 +00:00
//
//UNSUP ~f~exprLvalue '=' delay_or_event_controlE expr { UNSUP }
2010-12-08 01:18:47 +00:00
//UNSUP ~f~exprLvalue yP_PLUS(etc) expr { UNSUP }
2012-12-31 22:05:13 +00:00
| fexprLvalue yP_PLUSEQ expr { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_MINUSEQ expr { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_TIMESEQ expr { $$ = new AstAssign($2,$1,new AstMul ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_DIVEQ expr { $$ = new AstAssign($2,$1,new AstDiv ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_MODEQ expr { $$ = new AstAssign($2,$1,new AstModDiv ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_ANDEQ expr { $$ = new AstAssign($2,$1,new AstAnd ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_OREQ expr { $$ = new AstAssign($2,$1,new AstOr ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_XOREQ expr { $$ = new AstAssign($2,$1,new AstXor ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_SLEFTEQ expr { $$ = new AstAssign($2,$1,new AstShiftL ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_SRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftR ($2,$1->cloneTree(true),$3)); }
| fexprLvalue yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); }
2010-12-08 01:18:47 +00:00
;
finc_or_dec_expression<nodep>: // ==IEEE: inc_or_dec_expression
//UNSUP: Generic scopes in incrementes
2013-05-06 12:02:16 +00:00
fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
2007-03-06 21:43:38 +00:00
;
2007-05-14 20:59:58 +00:00
//************************************************
// Case/If
2006-08-26 11:35:28 +00:00
2009-01-25 02:36:14 +00:00
unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
2008-10-10 23:02:27 +00:00
/*empty*/ { $$ = uniq_NONE; }
| yPRIORITY { $$ = uniq_PRIORITY; }
| yUNIQUE { $$ = uniq_UNIQUE; }
2010-12-26 02:58:28 +00:00
| yUNIQUE0 { $$ = uniq_UNIQUE0; }
2008-10-10 23:02:27 +00:00
;
2009-01-28 20:27:41 +00:00
caseStart<casep>: // IEEE: part of case_statement
2014-01-21 02:59:53 +00:00
yCASE '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,VCaseType::CT_CASE,$3,NULL); }
| yCASEX '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,VCaseType::CT_CASEX,$3,NULL); }
| yCASEZ '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,VCaseType::CT_CASEZ,$3,NULL); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
caseAttrE:
/*empty*/ { }
2009-10-31 14:08:38 +00:00
| caseAttrE yVL_FULL_CASE { GRAMMARP->m_caseAttrp->fullPragma(true); }
| caseAttrE yVL_PARALLEL_CASE { GRAMMARP->m_caseAttrp->parallelPragma(true); }
2006-08-26 11:35:28 +00:00
;
2009-01-25 02:36:14 +00:00
case_itemListE<caseitemp>: // IEEE: [ { case_item } ]
2008-08-06 16:35:34 +00:00
/* empty */ { $$ = NULL; }
2009-01-25 02:36:14 +00:00
| case_itemList { $$ = $1; }
2007-05-18 14:03:50 +00:00
;
2014-01-21 02:59:53 +00:00
case_insideListE<caseitemp>: // IEEE: [ { case_inside_item } ]
/* empty */ { $$ = NULL; }
| case_inside_itemList { $$ = $1; }
;
2009-01-25 02:36:14 +00:00
case_itemList<caseitemp>: // IEEE: { case_item + ... }
2008-08-06 16:35:34 +00:00
caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
2006-08-26 11:35:28 +00:00
| yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); }
| yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); }
2009-01-25 02:36:14 +00:00
| case_itemList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
| case_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); }
| case_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); }
2006-08-26 11:35:28 +00:00
;
2014-01-21 02:59:53 +00:00
case_inside_itemList<caseitemp>: // IEEE: { case_inside_item + open_range_list ... }
open_range_list ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
| yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); }
| yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); }
| case_inside_itemList open_range_list ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
| case_inside_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); }
| case_inside_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); }
;
2013-02-02 17:55:28 +00:00
open_range_list<nodep>: // ==IEEE: open_range_list + open_value_range
open_value_range { $$ = $1; }
| open_range_list ',' open_value_range { $$ = $1;$1->addNext($3); }
;
open_value_range<nodep>: // ==IEEE: open_value_range
value_range { $$ = $1; }
;
value_range<nodep>: // ==IEEE: value_range
expr { $$ = $1; }
| '[' expr ':' expr ']' { $$ = new AstInsideRange($3,$2,$4); }
;
2009-01-25 02:36:14 +00:00
caseCondList<nodep>: // IEEE: part of case_item
2008-08-06 16:35:34 +00:00
expr { $$ = $1; }
2007-05-14 20:59:58 +00:00
| caseCondList ',' expr { $$ = $1;$1->addNext($3); }
;
2012-08-12 19:15:21 +00:00
patternNoExpr<nodep>: // IEEE: pattern **Excluding Expr*
'.' id/*variable*/ { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; }
| yP_DOTSTAR { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; }
// // IEEE: "expr" excluded; expand in callers
// // "yTAGGED id [expr]" Already part of expr
//UNSUP yTAGGED id/*member_identifier*/ patternNoExpr { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; }
// // "yP_TICKBRA patternList '}'" part of expr under assignment_pattern
;
patternList<nodep>: // IEEE: part of pattern
patternOne { $$ = $1; }
| patternList ',' patternOne { $$ = $1->addNextNull($3); }
;
patternOne<nodep>: // IEEE: part of pattern
expr { $$ = new AstPatMember($1->fileline(),$1,NULL,NULL); }
| expr '{' argsExprList '}' { $$ = new AstPatMember($2,$3,NULL,$1); }
| patternNoExpr { $$ = $1; }
;
patternMemberList<nodep>: // IEEE: part of pattern and assignment_pattern
patternMemberOne { $$ = $1; }
| patternMemberList ',' patternMemberOne { $$ = $1->addNextNull($3); }
;
patternMemberOne<patmemberp>: // IEEE: part of pattern and assignment_pattern
patternKey ':' expr { $$ = new AstPatMember($2,$3,$1,NULL); }
| patternKey ':' patternNoExpr { $2->v3error("Unsupported: '{} .* patterns"); $$=NULL; }
// // From assignment_pattern_key
| yDEFAULT ':' expr { $$ = new AstPatMember($2,$3,NULL,NULL); $$->isDefault(true); }
| yDEFAULT ':' patternNoExpr { $2->v3error("Unsupported: '{} .* patterns"); $$=NULL; }
;
patternKey<nodep>: // IEEE: merge structure_pattern_key, array_pattern_key, assignment_pattern_key
// // IEEE: structure_pattern_key
// // id/*member*/ is part of constExpr below
//UNSUP constExpr { $$ = $1; }
// // IEEE: assignment_pattern_key
//UNSUP simple_type { $1->v3error("Unsupported: '{} with data type as key"); $$=$1; }
// // simple_type reference looks like constExpr
// // Verilator:
// // The above expressions cause problems because "foo" may be a constant identifier
// // (if array) or a reference to the "foo"member (if structure)
// // So for now we only allow a true constant number, or a identifier which we treat as a structure member name
yaINTNUM { $$ = new AstConst($<fl>1,*$1); }
| yaFLOATNUM { $$ = new AstConst($<fl>1,AstConst::RealDouble(),$1); }
| yaID__ETC { $$ = new AstText($<fl>1,*$1); }
;
2013-02-14 01:52:38 +00:00
assignment_pattern<patternp>: // ==IEEE: assignment_pattern
2012-08-12 19:15:21 +00:00
// This doesn't match the text of the spec. I think a : is missing, or example code needed
// yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; }
// // "'{ const_expression }" is same as patternList with one entry
// // From patternNoExpr
// // also IEEE: "''{' expression { ',' expression } '}'"
// // matches since patternList includes expr
yP_TICKBRA patternList '}' { $$ = new AstPattern($1,$2); }
// // From patternNoExpr
// // also IEEE "''{' structure_pattern_key ':' ...
// // also IEEE "''{' array_pattern_key ':' ...
| yP_TICKBRA patternMemberList '}' { $$ = new AstPattern($1,$2); }
// // IEEE: Not in grammar, but in VMM
| yP_TICKBRA '}' { $1->v3error("Unsupported: Empty '{}"); $$=NULL; }
;
2009-05-07 22:28:05 +00:00
// "datatype id = x {, id = x }" | "yaId = x {, id=x}" is legal
for_initialization<nodep>: // ==IEEE: for_initialization + for_variable_declaration + extra terminating ";"
// // IEEE: for_variable_declaration
2012-12-31 18:43:54 +00:00
data_type idAny/*new*/ '=' expr ';'
{ VARRESET_NONLIST(VAR); VARDTYPE($1);
$$ = VARDONEA($<fl>2,*$2,NULL,NULL);
$$->addNext(new AstAssign($3,new AstVarRef($3,*$2,true),$4));}
2009-11-10 00:09:27 +00:00
| varRefBase '=' expr ';' { $$ = new AstAssign($2,$1,$3); }
2009-05-07 22:28:05 +00:00
//UNSUP: List of initializations
;
for_stepE<nodep>: // IEEE: for_step + empty
/* empty */ { $$ = NULL; }
| for_step { $$ = $1; }
;
for_step<nodep>: // IEEE: for_step
2012-03-23 01:02:38 +00:00
//UNSUP: List of steps, instead we keep it simple
genvar_iteration { $$ = $1; }
2009-05-07 22:28:05 +00:00
;
2007-05-14 20:59:58 +00:00
//************************************************
// Functions/tasks
2012-12-31 22:05:13 +00:00
taskRef<nodep>: // IEEE: part of tf_call
id { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
| id '(' list_of_argumentsE ')' { $$ = new AstTaskRef($<fl>1,*$1,$3); }
| package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($<fl>2, $1, new AstTaskRef($<fl>2,*$2,$4)); }
2007-05-14 20:59:58 +00:00
;
2012-12-31 22:05:13 +00:00
funcRef<nodep>: // IEEE: part of tf_call
2012-10-09 01:20:13 +00:00
// // package_scope/hierarchical_... is part of expr, so just need ID
// // making-a id-is-a
// // ----------------- ------------------
// // tf_call tf_identifier expr (list_of_arguments)
// // method_call(post .) function_identifier expr (list_of_arguments)
// // property_instance property_identifier property_actual_arg
// // sequence_instance sequence_identifier sequence_actual_arg
// // let_expression let_identifier let_actual_arg
2013-08-18 00:34:49 +00:00
//
2012-12-31 22:05:13 +00:00
id '(' list_of_argumentsE ')' { $$ = new AstFuncRef($2, *$1, $3); }
| package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($<fl>2, $1, new AstFuncRef($<fl>2,*$2,$4)); }
2009-05-07 22:28:05 +00:00
//UNSUP: idDotted is really just id to allow dotted method calls
;
task_subroutine_callNoMethod<nodep>: // function_subroutine_callNoMethod (as task)
// // IEEE: tf_call
taskRef { $$ = $1; }
| system_t_call { $$ = $1; }
// // IEEE: method_call requires a "." so is in expr
//UNSUP randomize_call { $$ = $1; }
;
function_subroutine_callNoMethod<nodep>: // IEEE: function_subroutine_call (as function)
// // IEEE: tf_call
funcRef { $$ = $1; }
| system_f_call { $$ = $1; }
// // IEEE: method_call requires a "." so is in expr
//UNSUP randomize_call { $$ = $1; }
;
system_t_call<nodep>: // IEEE: system_tf_call (as task)
//
2010-12-30 12:55:31 +00:00
yaD_IGNORE parenE { $$ = new AstSysIgnore($<fl>1,NULL); }
| yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($<fl>1,$3); }
2009-12-04 12:05:44 +00:00
//
2010-01-06 19:21:34 +00:00
| yaD_DPI parenE { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
2013-08-18 00:34:49 +00:00
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList($$->castTaskRef()); }
2009-09-16 13:28:09 +00:00
//
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
2009-05-07 22:28:05 +00:00
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
2010-01-16 01:07:16 +00:00
| yD_FFLUSH parenE { $1->v3error("Unsupported: $fflush of all handles does not map to C++."); }
2011-10-10 22:13:17 +00:00
| yD_FFLUSH '(' idClassSel ')' { $$ = new AstFFlush($1, $3); }
2009-05-07 22:28:05 +00:00
| yD_FINISH parenE { $$ = new AstFinish($1); }
2012-05-31 03:17:55 +00:00
| yD_FINISH '(' expr ')' { $$ = new AstFinish($1); DEL($3); }
2009-05-07 22:28:05 +00:00
| yD_STOP parenE { $$ = new AstStop($1); }
2012-05-31 03:17:55 +00:00
| yD_STOP '(' expr ')' { $$ = new AstStop($1); DEL($3); }
2009-05-07 22:28:05 +00:00
//
2010-01-14 23:34:49 +00:00
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
2011-11-20 07:01:48 +00:00
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); }
2009-11-24 02:24:55 +00:00
//
2010-02-02 01:15:48 +00:00
| yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); }
| yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); }
2010-01-06 19:13:11 +00:00
| yD_WRITE parenE { $$ = NULL; } // NOP
2010-02-02 01:15:48 +00:00
| yD_WRITE '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$3,NULL,$4); }
| yD_FDISPLAY '(' idClassSel ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"",$3,NULL); }
| yD_FDISPLAY '(' idClassSel ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$5,$3,$6); }
| yD_FWRITE '(' idClassSel ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$5,$3,$6); }
| yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, "", NULL,NULL); }
| yD_INFO '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, *$3,NULL,$4); }
| yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,"", NULL,NULL); }
| yD_WARNING '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,*$3,NULL,$4); }
2009-10-31 14:08:38 +00:00
| yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); }
2010-02-02 01:15:48 +00:00
| yD_ERROR '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); }
| yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
2012-05-31 03:17:55 +00:00
| yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); DEL($3); }
| yD_FATAL '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); DEL($3); }
2009-05-07 22:28:05 +00:00
//
2012-12-31 18:47:34 +00:00
| yD_READMEMB '(' expr ',' idClassSel ')' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); }
| yD_READMEMB '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); }
| yD_READMEMB '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem($1,false,$3,$5,$7,$9); }
| yD_READMEMH '(' expr ',' idClassSel ')' { $$ = new AstReadMem($1,true, $3,$5,NULL,NULL); }
| yD_READMEMH '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem($1,true, $3,$5,$7,NULL); }
| yD_READMEMH '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem($1,true, $3,$5,$7,$9); }
2009-05-07 22:28:05 +00:00
;
system_f_call<nodep>: // IEEE: system_tf_call (as func)
2010-01-06 19:13:11 +00:00
yaD_IGNORE parenE { $$ = new AstConst($<fl>1,V3Number($<fl>1,"'b0")); } // Unsized 0
2009-12-04 12:05:44 +00:00
| yaD_IGNORE '(' exprList ')' { $$ = new AstConst($2,V3Number($2,"'b0")); } // Unsized 0
//
2010-01-06 19:13:11 +00:00
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
2013-08-18 00:34:49 +00:00
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList($$->castFuncRef()); }
2009-09-16 13:28:09 +00:00
//
2013-01-20 17:19:22 +00:00
| yD_BITS '(' data_type ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); }
| yD_BITS '(' data_type ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); }
| yD_BITS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); }
| yD_BITS '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); }
2011-07-24 19:01:51 +00:00
| yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); }
2009-05-07 22:28:05 +00:00
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
2013-01-20 17:19:22 +00:00
| yD_CEIL '(' expr ')' { $$ = new AstCeilD($1,$3); }
2009-05-07 22:28:05 +00:00
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
| yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); }
2013-01-20 17:19:22 +00:00
| yD_DIMENSIONS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_DIMENSIONS,$3); }
| yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); }
2009-05-07 22:28:05 +00:00
| yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); }
| yD_FGETC '(' expr ')' { $$ = new AstFGetC($1,$3); }
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
2013-01-20 17:19:22 +00:00
| yD_FLOOR '(' expr ')' { $$ = new AstFloorD($1,$3); }
2009-10-23 01:16:52 +00:00
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); }
2013-01-20 17:19:22 +00:00
| yD_HIGH '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,NULL); }
| yD_HIGH '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,$5); }
| yD_INCREMENT '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,NULL); }
| yD_INCREMENT '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,$5); }
2009-05-07 22:28:05 +00:00
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); }
2011-07-24 19:01:51 +00:00
| yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); }
2013-01-20 17:19:22 +00:00
| yD_LEFT '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,NULL); }
| yD_LEFT '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,$5); }
| yD_LN '(' expr ')' { $$ = new AstLogD($1,$3); }
| yD_LOG10 '(' expr ')' { $$ = new AstLog10D($1,$3); }
| yD_LOW '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,NULL); }
| yD_LOW '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,$5); }
2009-05-07 22:28:05 +00:00
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
2013-01-20 17:19:22 +00:00
| yD_POW '(' expr ',' expr ')' { $$ = new AstPowD($1,$3,$5); }
2010-01-16 01:07:16 +00:00
| yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
2010-01-06 19:13:11 +00:00
| yD_RANDOM parenE { $$ = new AstRand($1); }
2011-07-24 19:01:51 +00:00
| yD_REALTIME parenE { $$ = new AstTimeD($1); }
| yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits($1,$3); }
2013-01-20 17:19:22 +00:00
| yD_RIGHT '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,NULL); }
| yD_RIGHT '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,$5); }
2011-07-24 19:01:51 +00:00
| yD_RTOI '(' expr ')' { $$ = new AstRToIS($1,$3); }
2010-01-18 01:06:08 +00:00
//| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,false,$4); } // Have AST, just need testing and debug
2009-05-07 22:28:05 +00:00
| yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); }
2013-01-20 17:19:22 +00:00
| yD_SIZE '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,NULL); }
| yD_SIZE '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,$5); }
| yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); }
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
2010-01-06 19:13:11 +00:00
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
2013-01-20 17:19:22 +00:00
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
2009-11-19 22:04:21 +00:00
| yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); }
2013-01-20 17:19:22 +00:00
| yD_TIME parenE { $$ = new AstTime($1); }
| yD_UNPACKED_DIMENSIONS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_UNPK_DIMENSIONS,$3); }
2009-05-07 22:28:05 +00:00
| yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); }
2009-11-19 22:04:21 +00:00
| yD_VALUEPLUSARGS '(' str ',' expr ')' { $$ = new AstValuePlusArgs($1,*$3,$5); }
2009-05-07 22:28:05 +00:00
;
list_of_argumentsE<nodep>: // IEEE: [list_of_arguments]
2013-08-18 00:34:49 +00:00
argsDottedList { $$ = $1; }
| argsExprListE { if ($1->castArg() && $1->castArg()->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()'
/*cont*/ else $$ = $1; }
| argsExprListE ',' argsDottedList { $$ = $1->addNextNull($3); }
2006-08-26 11:35:28 +00:00
;
2009-11-03 03:50:31 +00:00
task_declaration<ftaskp>: // ==IEEE: task_declaration
2009-05-07 22:28:05 +00:00
yTASK lifetimeE taskId tfGuts yENDTASK endLabelE
2012-03-08 01:14:18 +00:00
{ $$ = $3; $$->addStmtsp($4); SYMP->popScope($$);
GRAMMARP->endLabel($<fl>6,$$,$6); }
2007-05-16 19:27:29 +00:00
;
2009-12-03 11:55:29 +00:00
task_prototype<ftaskp>: // ==IEEE: task_prototype
yTASK taskId '(' tf_port_listE ')' { $$=$2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); }
;
2009-11-03 03:50:31 +00:00
function_declaration<ftaskp>: // IEEE: function_declaration + function_body_declaration
2009-11-03 03:14:11 +00:00
yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE
2009-11-03 03:50:31 +00:00
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
2012-03-08 01:14:18 +00:00
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7,$$,$7); }
2006-08-26 11:35:28 +00:00
;
2009-12-03 11:55:29 +00:00
function_prototype<ftaskp>: // IEEE: function_prototype
yFUNCTION funcId '(' tf_port_listE ')' { $$=$2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); }
;
2009-11-03 03:14:11 +00:00
funcIsolateE<cint>:
/* empty */ { $$ = 0; }
| yVL_ISOLATE_ASSIGNMENTS { $$ = 1; }
;
2013-12-21 11:51:15 +00:00
method_prototype:
task_prototype { }
| function_prototype { }
;
2009-05-07 22:28:05 +00:00
lifetimeE: // IEEE: [lifetime]
2009-01-15 18:58:43 +00:00
/* empty */ { }
2009-05-07 22:28:05 +00:00
| lifetime { }
;
lifetime: // ==IEEE: lifetime
2009-05-19 11:49:19 +00:00
// // Note lifetime used by members is instead under memberQual
2010-01-16 01:07:16 +00:00
ySTATIC { $1->v3error("Unsupported: Static in this context"); }
2007-05-16 19:27:29 +00:00
| yAUTOMATIC { }
2007-01-30 15:51:16 +00:00
;
2009-12-02 02:55:56 +00:00
taskId<ftaskp>:
2009-10-31 14:14:04 +00:00
tfIdScoped
{ $$ = new AstTask($<fl>1, *$<strp>1, NULL);
SYMP->pushNewUnder($$, NULL); }
2009-05-07 22:28:05 +00:00
;
2009-11-03 03:50:31 +00:00
funcId<ftaskp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
2009-10-31 14:08:38 +00:00
// // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
// // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
2009-11-03 03:14:11 +00:00
/**/ tfIdScoped
2009-11-03 03:50:31 +00:00
{ $$ = new AstFunc ($<fl>1,*$<strp>1,NULL,
2009-11-05 14:57:23 +00:00
new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
2009-11-03 03:14:11 +00:00
SYMP->pushNewUnder($$, NULL); }
| signingE rangeList tfIdScoped
2009-11-03 03:50:31 +00:00
{ $$ = new AstFunc ($<fl>3,*$<strp>3,NULL,
2013-01-14 03:18:57 +00:00
GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
2009-11-03 03:14:11 +00:00
SYMP->pushNewUnder($$, NULL); }
| signing tfIdScoped
2009-11-03 03:50:31 +00:00
{ $$ = new AstFunc ($<fl>2,*$<strp>2,NULL,
2009-11-05 14:57:23 +00:00
new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
2009-11-03 03:14:11 +00:00
SYMP->pushNewUnder($$, NULL); }
| data_type tfIdScoped
2009-11-03 03:50:31 +00:00
{ $$ = new AstFunc ($<fl>2,*$<strp>2,NULL,$1);
SYMP->pushNewUnder($$, NULL); }
// // To verilator tasks are the same as void functions (we separately detect time passing)
| yVOID tfIdScoped
{ $$ = new AstTask ($<fl>2,*$<strp>2,NULL);
2009-10-31 14:14:04 +00:00
SYMP->pushNewUnder($$, NULL); }
;
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
// // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
id { $<fl>$=$<fl>1; $<strp>$ = $1; }
2009-05-07 22:28:05 +00:00
//UNSUP id/*interface_identifier*/ '.' id { UNSUP }
//UNSUP class_scope_id { UNSUP }
;
2009-01-28 20:27:41 +00:00
tfGuts<nodep>:
2009-05-07 22:28:05 +00:00
'(' tf_port_listE ')' ';' tfBodyE { $$ = $2->addNextNull($5); }
| ';' tfBodyE { $$ = $2; }
2007-06-19 23:43:14 +00:00
;
2009-05-07 22:28:05 +00:00
tfBodyE<nodep>: // IEEE: part of function_body_declaration/task_body_declaration
/* empty */ { $$ = NULL; }
| tf_item_declarationList { $$ = $1; }
| tf_item_declarationList stmtList { $$ = $1->addNextNull($2); }
| stmtList { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
tf_item_declarationList<nodep>:
tf_item_declaration { $$ = $1; }
| tf_item_declarationList tf_item_declaration { $$ = $1->addNextNull($2); }
;
tf_item_declaration<nodep>: // ==IEEE: tf_item_declaration
block_item_declaration { $$ = $1; }
| tf_port_declaration { $$ = $1; }
| tf_item_declarationVerilator { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
tf_item_declarationVerilator<nodep>: // Verilator extensions
2012-10-30 07:02:35 +00:00
yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); v3Global.dpi(true); }
2006-10-11 15:41:42 +00:00
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
tf_port_listE<nodep>: // IEEE: tf_port_list + empty
// // Empty covered by tf_port_item
2009-11-25 03:16:28 +00:00
{VARRESET_LIST(UNKNOWN); VARIO(INPUT); }
2010-01-22 01:08:45 +00:00
tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
2009-05-07 22:28:05 +00:00
;
tf_port_listList<nodep>: // IEEE: part of tf_port_list
tf_port_item { $$ = $1; }
| tf_port_listList ',' tf_port_item { $$ = $1->addNextNull($3); }
;
tf_port_item<nodep>: // ==IEEE: tf_port_item
// // We split tf_port_item into the type and assignment as don't know what follows a comma
/* empty */ { $$ = NULL; PINNUMINC(); } // For example a ",," port
| tf_port_itemFront tf_port_itemAssignment { $$ = $2; }
| tf_port_itemAssignment { $$ = $1; }
;
tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type
2009-11-02 13:06:04 +00:00
data_type { VARDTYPE($1); }
2013-01-14 03:18:57 +00:00
| signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1), $2, true)); }
2009-11-05 14:57:23 +00:00
| signing { VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $1)); }
2009-11-06 00:57:31 +00:00
| yVAR data_type { VARDTYPE($2); }
2009-12-18 01:58:14 +00:00
| yVAR implicit_typeE { VARDTYPE($2); }
2009-05-07 22:28:05 +00:00
//
2009-11-02 13:06:04 +00:00
| tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ }
| tf_port_itemDir data_type { VARDTYPE($2); }
2013-01-14 03:18:57 +00:00
| tf_port_itemDir signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2),$3,true)); }
2009-11-05 14:57:23 +00:00
| tf_port_itemDir signing { VARDTYPE(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $2)); }
2009-11-06 00:57:31 +00:00
| tf_port_itemDir yVAR data_type { VARDTYPE($3); }
2009-12-18 01:58:14 +00:00
| tf_port_itemDir yVAR implicit_typeE { VARDTYPE($3); }
2009-05-07 22:28:05 +00:00
;
tf_port_itemDir: // IEEE: part of tf_port_item, direction
port_direction { } // port_direction sets VARIO
;
tf_port_itemAssignment<varp>: // IEEE: part of tf_port_item, which has assignment
2009-05-19 11:49:19 +00:00
id variable_dimensionListE sigAttrListE
2011-01-19 02:12:31 +00:00
{ $$ = VARDONEA($<fl>1, *$1, $2, $3); }
2009-05-19 11:49:19 +00:00
| id variable_dimensionListE sigAttrListE '=' expr
2011-01-19 02:12:31 +00:00
{ $$ = VARDONEA($<fl>1, *$1, $2, $3); $$->valuep($5); }
2009-05-07 22:28:05 +00:00
;
2009-01-25 02:36:14 +00:00
parenE:
/* empty */ { }
2007-09-17 17:54:02 +00:00
| '(' ')' { }
;
2009-05-07 22:28:05 +00:00
// method_call: // ==IEEE: method_call + method_call_body
// // IEEE: method_call_root '.' method_identifier [ '(' list_of_arguments ')' ]
// // "method_call_root '.' method_identifier" looks just like "expr '.' id"
// // "method_call_root '.' method_identifier (...)" looks just like "expr '.' tf_call"
// // IEEE: built_in_method_call
// // method_call_root not needed, part of expr resolution
// // What's left is below array_methodNoRoot
2009-12-03 11:55:29 +00:00
dpi_import_export<nodep>: // ==IEEE: dpi_import_export
yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';'
{ $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE);
2009-12-04 12:05:44 +00:00
$5->dpiImport(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true);
if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding
SYMP->reinsert($$); }
2009-12-03 11:55:29 +00:00
| yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';'
{ $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE);
2009-12-04 12:05:44 +00:00
$5->dpiImport(true); $5->dpiTask(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true);
if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding
SYMP->reinsert($$); }
2009-12-03 11:55:29 +00:00
| yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';' { $$ = new AstDpiExport($1,*$5,*$3);
GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); }
| yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';' { $$ = new AstDpiExport($1,*$5,*$3);
GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); }
;
dpi_importLabelE<strp>: // IEEE: part of dpi_import_export
/* empty */ { static string s = ""; $$ = &s; }
| idAny/*c_identifier*/ '=' { $$ = $1; $<fl>$=$<fl>1; }
;
dpi_tf_import_propertyE<iprop>: // IEEE: [ dpi_function_import_property + dpi_task_import_property ]
/* empty */ { $$ = iprop_NONE; }
| yCONTEXT { $$ = iprop_CONTEXT; }
| yPURE { $$ = iprop_PURE; }
;
2007-05-14 20:59:58 +00:00
//************************************************
// Expressions
2009-05-07 22:28:05 +00:00
//
// ~l~ means this is the (l)eft hand side of any operator
// it will get replaced by "", "f" or "s"equence
// ~r~ means this is a (r)ight hand later expansion in the same statement,
// not under parenthesis for <= disambiguation
// it will get replaced by "", or "f"
// ~p~ means this is a (p)arenthetized expression
// it will get replaced by "", or "s"equence
2007-05-14 20:59:58 +00:00
2008-08-06 16:35:34 +00:00
constExpr<nodep>:
expr { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
expr<nodep>: // IEEE: part of expression/constant_expression/primary
// *SEE BELOW* // IEEE: primary/constant_primary
//
// // IEEE: unary_operator primary
'+' ~r~expr %prec prUNARYARITH { $$ = $2; }
2011-07-08 10:03:07 +00:00
| '-' ~r~expr %prec prUNARYARITH { $$ = new AstNegate ($1,$2); }
2009-05-07 22:28:05 +00:00
| '!' ~r~expr %prec prNEGATION { $$ = new AstLogNot ($1,$2); }
| '&' ~r~expr %prec prREDUCTION { $$ = new AstRedAnd ($1,$2); }
| '~' ~r~expr %prec prNEGATION { $$ = new AstNot ($1,$2); }
| '|' ~r~expr %prec prREDUCTION { $$ = new AstRedOr ($1,$2); }
| '^' ~r~expr %prec prREDUCTION { $$ = new AstRedXor ($1,$2); }
| yP_NAND ~r~expr %prec prREDUCTION { $$ = new AstNot($1,new AstRedAnd($1,$2)); }
| yP_NOR ~r~expr %prec prREDUCTION { $$ = new AstNot($1,new AstRedOr ($1,$2)); }
| yP_XNOR ~r~expr %prec prREDUCTION { $$ = new AstRedXnor ($1,$2); }
//
// // IEEE: inc_or_dec_expression
//UNSUP ~l~inc_or_dec_expression { UNSUP }
//
// // IEEE: '(' operator_assignment ')'
// // Need exprScope of variable_lvalue to prevent conflict
//UNSUP '(' ~p~exprScope '=' expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_PLUSEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_MINUSEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_TIMESEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_DIVEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_MODEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_ANDEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_OREQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_XOREQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_SLEFTEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_SRIGHTEQ expr ')' { UNSUP }
//UNSUP '(' ~p~exprScope yP_SSRIGHTEQ expr ')' { UNSUP }
//
// // IEEE: expression binary_operator expression
| ~l~expr '+' ~r~expr { $$ = new AstAdd ($2,$1,$3); }
| ~l~expr '-' ~r~expr { $$ = new AstSub ($2,$1,$3); }
| ~l~expr '*' ~r~expr { $$ = new AstMul ($2,$1,$3); }
| ~l~expr '/' ~r~expr { $$ = new AstDiv ($2,$1,$3); }
| ~l~expr '%' ~r~expr { $$ = new AstModDiv ($2,$1,$3); }
| ~l~expr yP_EQUAL ~r~expr { $$ = new AstEq ($2,$1,$3); }
| ~l~expr yP_NOTEQUAL ~r~expr { $$ = new AstNeq ($2,$1,$3); }
| ~l~expr yP_CASEEQUAL ~r~expr { $$ = new AstEqCase ($2,$1,$3); }
| ~l~expr yP_CASENOTEQUAL ~r~expr { $$ = new AstNeqCase ($2,$1,$3); }
| ~l~expr yP_WILDEQUAL ~r~expr { $$ = new AstEqWild ($2,$1,$3); }
| ~l~expr yP_WILDNOTEQUAL ~r~expr { $$ = new AstNeqWild ($2,$1,$3); }
| ~l~expr yP_ANDAND ~r~expr { $$ = new AstLogAnd ($2,$1,$3); }
| ~l~expr yP_OROR ~r~expr { $$ = new AstLogOr ($2,$1,$3); }
| ~l~expr yP_POW ~r~expr { $$ = new AstPow ($2,$1,$3); }
| ~l~expr '<' ~r~expr { $$ = new AstLt ($2,$1,$3); }
| ~l~expr '>' ~r~expr { $$ = new AstGt ($2,$1,$3); }
| ~l~expr yP_GTE ~r~expr { $$ = new AstGte ($2,$1,$3); }
| ~l~expr '&' ~r~expr { $$ = new AstAnd ($2,$1,$3); }
| ~l~expr '|' ~r~expr { $$ = new AstOr ($2,$1,$3); }
| ~l~expr '^' ~r~expr { $$ = new AstXor ($2,$1,$3); }
| ~l~expr yP_XNOR ~r~expr { $$ = new AstXnor ($2,$1,$3); }
| ~l~expr yP_NOR ~r~expr { $$ = new AstNot($2,new AstOr ($2,$1,$3)); }
| ~l~expr yP_NAND ~r~expr { $$ = new AstNot($2,new AstAnd ($2,$1,$3)); }
| ~l~expr yP_SLEFT ~r~expr { $$ = new AstShiftL ($2,$1,$3); }
| ~l~expr yP_SRIGHT ~r~expr { $$ = new AstShiftR ($2,$1,$3); }
| ~l~expr yP_SSRIGHT ~r~expr { $$ = new AstShiftRS ($2,$1,$3); }
// // <= is special, as we need to disambiguate it with <= assignment
// // We copy all of expr to fexpr and rename this token to a fake one.
| ~l~expr yP_LTE~f__IGNORE~ ~r~expr { $$ = new AstLte ($2,$1,$3); }
//
// // IEEE: conditional_expression
| ~l~expr '?' ~r~expr ':' ~r~expr { $$ = new AstCond($2,$1,$3,$5); }
//
// // IEEE: inside_expression
2013-02-02 17:55:28 +00:00
| ~l~expr yINSIDE '{' open_range_list '}' { $$ = new AstInside($2,$1,$4); }
2009-05-07 22:28:05 +00:00
//
// // IEEE: tagged_union_expression
//UNSUP yTAGGED id/*member*/ %prec prTAGGED { UNSUP }
//UNSUP yTAGGED id/*member*/ %prec prTAGGED expr { UNSUP }
//
//======================// PSL expressions
//
| ~l~expr yP_MINUSGT ~r~expr { $$ = new AstLogIf ($2,$1,$3); }
| ~l~expr yP_LOGIFF ~r~expr { $$ = new AstLogIff ($2,$1,$3); }
//
//======================// IEEE: primary/constant_primary
//
// // IEEE: primary_literal (minus string, which is handled specially)
2009-10-31 14:08:38 +00:00
| yaINTNUM { $$ = new AstConst($<fl>1,*$1); }
2011-07-24 19:01:51 +00:00
| yaFLOATNUM { $$ = new AstConst($<fl>1,AstConst::RealDouble(),$1); }
2009-05-07 22:28:05 +00:00
//UNSUP yaTIMENUM { UNSUP }
| strAsInt~noStr__IGNORE~ { $$ = $1; }
//
// // IEEE: "... hierarchical_identifier select" see below
//
// // IEEE: empty_queue
//UNSUP '{' '}'
2009-02-25 22:16:51 +00:00
//
2009-01-28 20:27:41 +00:00
// // IEEE: concatenation/constant_concatenation
2009-05-07 22:28:05 +00:00
// // Part of exprOkLvalue below
//
// // IEEE: multiple_concatenation/constant_multiple_concatenation
2006-08-26 11:35:28 +00:00
| '{' constExpr '{' cateList '}' '}' { $$ = new AstReplicate($1,$4,$2); }
2009-02-25 22:16:51 +00:00
//
2009-05-07 22:28:05 +00:00
| function_subroutine_callNoMethod { $$ = $1; }
// // method_call
2012-12-31 22:05:13 +00:00
| ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2,$1,$3); }
2009-05-07 22:28:05 +00:00
// // method_call:array_method requires a '.'
//UNSUP ~l~expr '.' array_methodNoRoot { UNSUP }
2009-02-25 22:16:51 +00:00
//
2012-10-09 00:45:39 +00:00
// // IEEE: let_expression
// // see funcRef
//
2009-05-07 22:28:05 +00:00
// // IEEE: '(' mintypmax_expression ')'
| ~noPar__IGNORE~'(' expr ')' { $$ = $2; }
//UNSUP ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $$ = $4; }
// // PSL rule
| '_' '(' statePushVlg expr statePop ')' { $$ = $4; } // Arbitrary Verilog inside PSL
2009-02-25 22:16:51 +00:00
//
2009-05-07 22:28:05 +00:00
// // IEEE: cast/constant_cast
2011-03-18 02:25:49 +00:00
| casting_type yP_TICK '(' expr ')' { $$ = new AstCast($2,$4,$1); }
// // expanded from casting_type
| ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1,$4); }
| yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1,$4); }
2009-05-07 22:28:05 +00:00
// // Spec only allows primary with addition of a type reference
// // We'll be more general, and later assert LHS was a type.
//UNSUP ~l~expr yP_TICK '(' expr ')' { UNSUP }
2013-03-06 03:13:22 +00:00
| yaINTNUM yP_TICK '(' expr ')' { $$ = new AstCastSize($2,$4,new AstConst($1->fileline(),*$1)); }
2009-02-25 22:16:51 +00:00
//
2009-05-07 22:28:05 +00:00
// // IEEE: assignment_pattern_expression
// // IEEE: streaming_concatenation
// // See exprOkLvalue
2009-02-25 22:16:51 +00:00
//
2009-05-07 22:28:05 +00:00
// // IEEE: sequence_method_call
// // Indistinguishable from function_subroutine_call:method_call
//
//UNSUP '$' { UNSUP }
//UNSUP yNULL { UNSUP }
// // IEEE: yTHIS
// // See exprScope
//
//----------------------
//
2012-12-31 22:05:13 +00:00
// // Part of expr that may also be used as lvalue
2009-05-07 22:28:05 +00:00
| ~l~exprOkLvalue { $$ = $1; }
//
//----------------------
//
// // IEEE: cond_predicate - here to avoid reduce problems
// // Note expr includes cond_pattern
//UNSUP ~l~expr yP_ANDANDAND ~r~expr { UNSUP }
//
// // IEEE: cond_pattern - here to avoid reduce problems
// // "expr yMATCHES pattern"
// // IEEE: pattern - expanded here to avoid conflicts
//UNSUP ~l~expr yMATCHES patternNoExpr { UNSUP }
//UNSUP ~l~expr yMATCHES ~r~expr { UNSUP }
//
// // IEEE: expression_or_dist - here to avoid reduce problems
// // "expr yDIST '{' dist_list '}'"
//UNSUP ~l~expr yDIST '{' dist_list '}' { UNSUP }
2006-08-26 11:35:28 +00:00
;
2012-12-31 22:05:13 +00:00
fexpr<nodep>: // For use as first part of statement (disambiguates <=)
BISONPRE_COPY(expr,{s/~l~/f/g; s/~r~/f/g; s/~f__IGNORE~/__IGNORE/g;}) // {copied}
;
2009-05-07 22:28:05 +00:00
exprNoStr<nodep>: // expression with string removed
BISONPRE_COPY(expr,{s/~noStr__IGNORE~/Ignore/g;}) // {copied}
;
exprOkLvalue<nodep>: // expression that's also OK to use as a variable_lvalue
~l~exprScope { $$ = $1; }
// // IEEE: concatenation/constant_concatenation
| '{' cateList '}' { $$ = $2; }
// // IEEE: assignment_pattern_expression
2012-10-09 00:45:39 +00:00
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
2009-05-07 22:28:05 +00:00
// // We allow more here than the spec requires
//UNSUP ~l~exprScope assignment_pattern { UNSUP }
2013-02-14 01:52:38 +00:00
| data_type assignment_pattern { $$ = $2; $2->childDTypep($1); }
2012-08-12 19:15:21 +00:00
| assignment_pattern { $$ = $1; }
2009-05-07 22:28:05 +00:00
//
//UNSUP streaming_concatenation { UNSUP }
;
2012-12-31 22:05:13 +00:00
fexprOkLvalue<nodep>: // exprOkLValue, For use as first part of statement (disambiguates <=)
BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g}) // {copied}
;
fexprLvalue<nodep>: // For use as first part of statement (disambiguates <=)
fexprOkLvalue { $<fl>$=$<fl>1; $$ = $1; }
;
2009-05-07 22:28:05 +00:00
exprScope<nodep>: // scope and variable for use to inside an expression
// // Here we've split method_call_root | implicit_class_handle | class_scope | package_scope
// // from the object being called and let expr's "." deal with resolving it.
2012-10-09 00:45:39 +00:00
// // (note method_call_root was simplified to require a primary in 1800-2009)
2009-05-07 22:28:05 +00:00
//
// // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
// // Or method_call_body without parenthesis
// // See also varRefClassBit, which is the non-expr version of most of this
//UNSUP yTHIS { UNSUP }
2012-12-31 22:05:13 +00:00
idArrayed { $$ = $1; }
| package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
2009-05-19 11:49:19 +00:00
//UNSUP class_scopeIdFollows idArrayed { UNSUP }
2012-12-31 22:05:13 +00:00
| ~l~expr '.' idArrayed { $$ = new AstDot($<fl>2,$1,$3); }
2009-05-07 22:28:05 +00:00
// // expr below must be a "yTHIS"
//UNSUP ~l~expr '.' ySUPER { UNSUP }
// // Part of implicit_class_handle
//UNSUP ySUPER { UNSUP }
2006-08-26 11:35:28 +00:00
;
2012-12-31 22:05:13 +00:00
fexprScope<nodep>: // exprScope, For use as first part of statement (disambiguates <=)
BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied}
;
2006-08-26 11:35:28 +00:00
// Psl excludes {}'s by lexer converting to different token
2008-08-06 16:35:34 +00:00
exprPsl<nodep>:
2009-05-07 22:28:05 +00:00
expr { $$ = $1; }
2006-08-26 11:35:28 +00:00
;
// PLI calls exclude "" as integers, they're strings
// For $c("foo","bar") we want "bar" as a string, not a Verilog integer.
2008-08-06 16:35:34 +00:00
exprStrText<nodep>:
exprNoStr { $$ = $1; }
2006-08-26 11:35:28 +00:00
| strAsText { $$ = $1; }
;
2008-08-06 16:35:34 +00:00
cStrList<nodep>:
exprStrText { $$ = $1; }
2006-08-26 11:35:28 +00:00
| exprStrText ',' cStrList { $$ = $1;$1->addNext($3); }
;
2008-08-06 16:35:34 +00:00
cateList<nodep>:
2009-05-07 22:28:05 +00:00
// // Not just 'expr' to prevent conflict via stream_concOrExprOrType
stream_expression { $$ = $1; }
| cateList ',' stream_expression { $$ = new AstConcat($2,$1,$3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
exprList<nodep>:
expr { $$ = $1; }
2007-05-14 20:59:58 +00:00
| exprList ',' expr { $$ = $1;$1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
commaEListE<nodep>:
/* empty */ { $$ = NULL; }
2007-05-14 20:59:58 +00:00
| ',' exprList { $$ = $2; }
2007-03-06 21:43:38 +00:00
;
2008-08-06 16:35:34 +00:00
vrdList<nodep>:
2009-05-07 22:28:05 +00:00
idClassSel { $$ = $1; }
| vrdList ',' idClassSel { $$ = $1;$1->addNext($3); }
2008-07-01 18:15:10 +00:00
;
2008-08-06 16:35:34 +00:00
commaVRDListE<nodep>:
/* empty */ { $$ = NULL; }
2008-07-01 18:15:10 +00:00
| ',' vrdList { $$ = $2; }
;
2009-05-19 11:49:19 +00:00
argsExprList<nodep>: // IEEE: part of list_of_arguments (used where ,, isn't legal)
2009-05-07 22:28:05 +00:00
expr { $$ = $1; }
| argsExprList ',' expr { $$ = $1->addNext($3); }
;
2013-08-18 00:34:49 +00:00
argsExprListE<nodep>: // IEEE: part of list_of_arguments
argsExprOneE { $$ = $1; }
| argsExprListE ',' argsExprOneE { $$ = $1->addNext($3); }
;
argsExprOneE<nodep>: // IEEE: part of list_of_arguments
/*empty*/ { $$ = new AstArg(CRELINE(),"",NULL); }
| expr { $$ = new AstArg(CRELINE(),"",$1); }
;
argsDottedList<nodep>: // IEEE: part of list_of_arguments
argsDotted { $$ = $1; }
| argsDottedList ',' argsDotted { $$ = $1->addNextNull($3); }
;
argsDotted<nodep>: // IEEE: part of list_of_arguments
'.' idAny '(' ')' { $$ = new AstArg($1,*$2,NULL); }
| '.' idAny '(' expr ')' { $$ = new AstArg($1,*$2,$4); }
;
2009-05-07 22:28:05 +00:00
stream_expression<nodep>: // ==IEEE: stream_expression
// // IEEE: array_range_expression expanded below
expr { $$ = $1; }
//UNSUP expr yWITH__BRA '[' expr ']' { UNSUP }
//UNSUP expr yWITH__BRA '[' expr ':' expr ']' { UNSUP }
//UNSUP expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']' { UNSUP }
//UNSUP expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']' { UNSUP }
;
2007-05-14 20:59:58 +00:00
//************************************************
2006-08-26 11:35:28 +00:00
// Gate declarations
2007-05-14 20:59:58 +00:00
2008-08-06 16:35:34 +00:00
gateDecl<nodep>:
2009-01-06 16:57:25 +00:00
yBUF delayE gateBufList ';' { $$ = $3; }
| yBUFIF0 delayE gateBufif0List ';' { $$ = $3; }
| yBUFIF1 delayE gateBufif1List ';' { $$ = $3; }
| yNOT delayE gateNotList ';' { $$ = $3; }
| yNOTIF0 delayE gateNotif0List ';' { $$ = $3; }
| yNOTIF1 delayE gateNotif1List ';' { $$ = $3; }
2008-04-01 19:26:06 +00:00
| yAND delayE gateAndList ';' { $$ = $3; }
| yNAND delayE gateNandList ';' { $$ = $3; }
| yOR delayE gateOrList ';' { $$ = $3; }
| yNOR delayE gateNorList ';' { $$ = $3; }
| yXOR delayE gateXorList ';' { $$ = $3; }
| yXNOR delayE gateXnorList ';' { $$ = $3; }
2009-01-06 16:03:57 +00:00
| yPULLUP delayE gatePullupList ';' { $$ = $3; }
| yPULLDOWN delayE gatePulldownList ';' { $$ = $3; }
2012-04-24 00:13:07 +00:00
| yNMOS delayE gateBufif1List ';' { $$ = $3; } // ~=bufif1, as don't have strengths yet
| yPMOS delayE gateBufif0List ';' { $$ = $3; } // ~=bufif0, as don't have strengths yet
2010-01-08 03:08:48 +00:00
//
| yTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tran"); } // Unsupported
| yRCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rcmos"); } // Unsupported
| yCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"cmos"); } // Unsupported
| yRNMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rmos"); } // Unsupported
| yRPMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"pmos"); } // Unsupported
| yRTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtran"); } // Unsupported
| yRTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif0"); } // Unsupported
| yRTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif1"); } // Unsupported
| yTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif0"); } // Unsupported
| yTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif1"); } // Unsupported
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
gateBufList<nodep>:
gateBuf { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateBufList ',' gateBuf { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2009-01-06 16:57:25 +00:00
gateBufif0List<nodep>:
gateBufif0 { $$ = $1; }
| gateBufif0List ',' gateBufif0 { $$ = $1->addNext($3); }
;
gateBufif1List<nodep>:
gateBufif1 { $$ = $1; }
| gateBufif1List ',' gateBufif1 { $$ = $1->addNext($3); }
;
2008-08-06 16:35:34 +00:00
gateNotList<nodep>:
gateNot { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateNotList ',' gateNot { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2009-01-06 16:57:25 +00:00
gateNotif0List<nodep>:
gateNotif0 { $$ = $1; }
| gateNotif0List ',' gateNotif0 { $$ = $1->addNext($3); }
;
gateNotif1List<nodep>:
gateNotif1 { $$ = $1; }
| gateNotif1List ',' gateNotif1 { $$ = $1->addNext($3); }
;
2008-08-06 16:35:34 +00:00
gateAndList<nodep>:
gateAnd { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateAndList ',' gateAnd { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
gateNandList<nodep>:
gateNand { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateNandList ',' gateNand { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
gateOrList<nodep>:
gateOr { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateOrList ',' gateOr { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
gateNorList<nodep>:
gateNor { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateNorList ',' gateNor { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
gateXorList<nodep>:
gateXor { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateXorList ',' gateXor { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
gateXnorList<nodep>:
gateXnor { $$ = $1; }
2008-05-06 14:52:53 +00:00
| gateXnorList ',' gateXnor { $$ = $1->addNext($3); }
2006-08-26 11:35:28 +00:00
;
2009-01-06 16:03:57 +00:00
gatePullupList<nodep>:
gatePullup { $$ = $1; }
| gatePullupList ',' gatePullup { $$ = $1->addNext($3); }
;
gatePulldownList<nodep>:
gatePulldown { $$ = $1; }
| gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); }
;
2010-01-08 03:08:48 +00:00
gateUnsupList<nodep>:
gateUnsup { $$ = $1; }
| gateUnsupList ',' gateUnsup { $$ = $1->addNext($3); }
;
2006-08-26 11:35:28 +00:00
2009-10-31 03:17:56 +00:00
gateBuf<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' expr ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,$6); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateBufif0<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); DEL($2); }
2009-01-06 16:57:25 +00:00
;
2009-10-31 03:17:56 +00:00
gateBufif1<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); DEL($2); }
2009-01-06 16:57:25 +00:00
;
2009-10-31 03:17:56 +00:00
gateNot<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' expr ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateNotif0<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); DEL($2); }
2009-01-06 16:57:25 +00:00
;
2009-10-31 03:17:56 +00:00
gateNotif1<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); DEL($2); }
2009-01-06 16:57:25 +00:00
;
2009-10-31 03:17:56 +00:00
gateAnd<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,$6); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateNand<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateOr<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,$6); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateNor<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateXor<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,$6); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-10-31 03:17:56 +00:00
gateXnor<nodep>:
2011-02-24 02:21:59 +00:00
gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')'
2012-05-31 03:17:55 +00:00
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
gatePullup<nodep>:
2012-05-31 03:17:55 +00:00
gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); DEL($2); }
2009-01-06 16:03:57 +00:00
;
2009-05-07 22:28:05 +00:00
gatePulldown<nodep>:
2012-05-31 03:17:55 +00:00
gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); DEL($2); }
2009-01-06 16:03:57 +00:00
;
2010-01-08 03:08:48 +00:00
gateUnsup<nodep>:
2012-05-31 03:17:55 +00:00
gateIdE instRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); DEL($2); }
2010-01-08 03:08:48 +00:00
;
2009-01-25 02:36:14 +00:00
gateIdE:
/*empty*/ {}
2009-05-07 22:28:05 +00:00
| id {}
2007-05-14 20:59:58 +00:00
;
2008-08-06 16:35:34 +00:00
gateAndPinList<nodep>:
expr { $$ = $1; }
2006-08-26 11:35:28 +00:00
| gateAndPinList ',' expr { $$ = new AstAnd($2,$1,$3); }
;
2008-08-06 16:35:34 +00:00
gateOrPinList<nodep>:
expr { $$ = $1; }
2006-08-26 11:35:28 +00:00
| gateOrPinList ',' expr { $$ = new AstOr($2,$1,$3); }
;
2008-08-06 16:35:34 +00:00
gateXorPinList<nodep>:
expr { $$ = $1; }
2006-08-26 11:35:28 +00:00
| gateXorPinList ',' expr { $$ = new AstXor($2,$1,$3); }
;
2010-01-08 03:08:48 +00:00
gateUnsupPinList<nodep>:
expr { $$ = $1; }
| gateUnsupPinList ',' expr { $$ = $1->addNext($3); }
;
2006-08-26 11:35:28 +00:00
2009-05-07 22:28:05 +00:00
strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
/* empty */ { }
//UNSUP strengthSpec { }
;
2007-05-16 12:55:25 +00:00
//************************************************
// Tables
2009-11-21 00:53:40 +00:00
2012-10-09 01:20:13 +00:00
combinational_body<nodep>: // IEEE: combinational_body + sequential_body
2009-11-21 00:53:40 +00:00
yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); }
;
tableEntryList<nodep>: // IEEE: { combinational_entry | sequential_entry }
tableEntry { $$ = $1; }
| tableEntryList tableEntry { $$ = $1->addNext($2); }
;
tableEntry<nodep>: // IEEE: combinational_entry + sequential_entry
2010-01-09 20:44:06 +00:00
yaTABLELINE { $$ = new AstUdpTableLine($<fl>1,*$1); }
2009-11-21 00:53:40 +00:00
| error { $$ = NULL; }
;
2007-05-16 12:55:25 +00:00
2006-08-26 11:35:28 +00:00
//************************************************
// Specify
2007-05-14 20:59:58 +00:00
2009-01-28 20:27:41 +00:00
specify_block<nodep>: // ==IEEE: specify_block
ySPECIFY specifyJunkList yENDSPECIFY { $$ = NULL; }
| ySPECIFY yENDSPECIFY { $$ = NULL; }
;
2009-01-25 02:36:14 +00:00
specifyJunkList:
specifyJunk { } /* ignored */
| specifyJunkList specifyJunk { } /* ignored */
;
2007-05-18 18:48:22 +00:00
2009-01-25 02:36:14 +00:00
specifyJunk:
BISONPRE_NOT(ySPECIFY,yENDSPECIFY) { }
| ySPECIFY specifyJunk yENDSPECIFY { }
2007-05-18 18:48:22 +00:00
| error {}
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
specparam_declaration<nodep>: // ==IEEE: specparam_declaration
2010-02-18 13:43:16 +00:00
ySPECPARAM junkToSemiList ';' { $$ = NULL; }
2009-05-07 22:28:05 +00:00
;
2010-02-18 13:43:16 +00:00
junkToSemiList:
junkToSemi { } /* ignored */
| junkToSemiList junkToSemi { } /* ignored */
;
2011-05-10 03:58:38 +00:00
2009-05-07 22:28:05 +00:00
junkToSemi:
BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { }
| error {}
;
2006-08-26 11:35:28 +00:00
//************************************************
// IDs
2006-12-21 21:53:51 +00:00
2009-05-07 22:28:05 +00:00
id<strp>:
2009-10-31 14:08:38 +00:00
yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
2009-05-07 22:28:05 +00:00
;
idAny<strp>: // Any kind of identifier
2009-10-31 14:08:38 +00:00
//UNSUP yaID__aCLASS { $$ = $1; $<fl>$=$<fl>1; }
//UNSUP yaID__aCOVERGROUP { $$ = $1; $<fl>$=$<fl>1; }
2009-11-08 02:05:02 +00:00
yaID__aPACKAGE { $$ = $1; $<fl>$=$<fl>1; }
| yaID__aTYPE { $$ = $1; $<fl>$=$<fl>1; }
2009-11-07 04:16:06 +00:00
| yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
2009-05-07 22:28:05 +00:00
;
2009-09-07 19:54:12 +00:00
idSVKwd<strp>: // Warn about non-forward compatible Verilog 2001 code
// // yBIT, yBYTE won't work here as causes conflicts
2011-01-19 02:12:31 +00:00
yDO { static string s = "do" ; $$ = &s; ERRSVKWD($1,*$$); $<fl>$=$<fl>1; }
| yFINAL { static string s = "final"; $$ = &s; ERRSVKWD($1,*$$); $<fl>$=$<fl>1; }
2009-09-07 19:54:12 +00:00
;
2009-05-07 22:28:05 +00:00
variable_lvalue<nodep>: // IEEE: variable_lvalue or net_lvalue
// // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist
idClassSel { $$ = $1; }
| '{' variable_lvalueConcList '}' { $$ = $2; }
// // IEEE: [ assignment_pattern_expression_type ] assignment_pattern_variable_lvalue
// // We allow more assignment_pattern_expression_types then strictly required
//UNSUP data_type yP_TICKBRA variable_lvalueList '}' { UNSUP }
//UNSUP idClassSel yP_TICKBRA variable_lvalueList '}' { UNSUP }
//UNSUP /**/ yP_TICKBRA variable_lvalueList '}' { UNSUP }
//UNSUP streaming_concatenation { UNSUP }
;
variable_lvalueConcList<nodep>: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}'
variable_lvalue { $$ = $1; }
| variable_lvalueConcList ',' variable_lvalue { $$ = new AstConcat($2,$1,$3); }
;
2007-05-14 20:59:58 +00:00
// VarRef to dotted, and/or arrayed, and/or bit-ranged variable
2012-12-31 22:05:13 +00:00
idClassSel<nodep>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
idDotted { $$ = $1; }
2009-05-07 22:28:05 +00:00
// // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
//UNSUP yTHIS '.' idDotted { UNSUP }
//UNSUP ySUPER '.' idDotted { UNSUP }
//UNSUP yTHIS '.' ySUPER '.' idDotted { UNSUP }
// // Expanded: package_scope idDotted
2012-10-09 00:45:39 +00:00
//UNSUP class_scopeIdFollows idDotted { UNSUP }
2009-05-07 22:28:05 +00:00
//UNSUP package_scopeIdFollows idDotted { UNSUP }
2007-05-14 20:59:58 +00:00
;
2008-08-06 16:35:34 +00:00
idDotted<nodep>:
2009-05-07 22:28:05 +00:00
//UNSUP yD_ROOT '.' idDottedMore { UNSUP }
idDottedMore { $$ = $1; }
;
idDottedMore<nodep>:
2008-08-06 16:35:34 +00:00
idArrayed { $$ = $1; }
2012-12-02 23:03:34 +00:00
| idDottedMore '.' idArrayed { $$ = new AstDot($2,$1,$3); }
2007-05-14 20:59:58 +00:00
;
2006-12-21 21:53:51 +00:00
// 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.
2009-05-07 22:28:05 +00:00
// id below includes:
// enum_identifier
idArrayed<nodep>: // IEEE: id + select
2012-07-24 10:26:35 +00:00
id { $$ = new AstParseRef($<fl>1,AstParseRefExp::PX_TEXT,*$1,NULL,NULL); }
2009-02-25 22:16:51 +00:00
// // IEEE: id + part_select_range/constant_part_select_range
2006-12-21 21:53:51 +00:00
| idArrayed '[' expr ']' { $$ = new AstSelBit($2,$1,$3); } // Or AstArraySel, don't know yet.
| idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2,$1,$3,$5); }
2009-02-25 22:16:51 +00:00
// // IEEE: id + indexed_range/constant_indexed_range
2007-05-14 20:59:58 +00:00
| idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus($2,$1,$3,$5); }
2007-05-12 16:29:25 +00:00
| idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); }
2006-08-26 11:35:28 +00:00
;
2006-12-21 21:53:51 +00:00
// VarRef without any dots or vectorizaion
2010-01-08 03:08:48 +00:00
varRefBase<varrefp>:
2011-01-19 02:12:31 +00:00
id { $$ = new AstVarRef($<fl>1,*$1,false);}
2006-08-26 11:35:28 +00:00
;
2009-10-23 01:16:52 +00:00
// yaSTRING shouldn't be used directly, instead via an abstraction below
str<strp>: // yaSTRING but with \{escapes} need decoded
2009-10-31 14:08:38 +00:00
yaSTRING { $$ = PARSEP->newString(GRAMMARP->deQuote($<fl>1,*$1)); }
2009-10-23 01:16:52 +00:00
;
2008-08-06 16:35:34 +00:00
strAsInt<nodep>:
2009-10-31 14:08:38 +00:00
yaSTRING { $$ = new AstConst($<fl>1,V3Number(V3Number::VerilogString(),$<fl>1,GRAMMARP->deQuote($<fl>1,*$1)));}
2006-12-20 16:10:47 +00:00
;
2009-05-07 22:28:05 +00:00
strAsIntIgnore<nodep>: // strAsInt, but never matches for when expr shouldn't parse strings
yaSTRING__IGNORE { $$ = NULL; yyerror("Impossible token"); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
strAsText<nodep>:
2009-10-31 14:08:38 +00:00
yaSTRING { $$ = GRAMMARP->createTextQuoted($<fl>1,*$1);}
2006-08-26 11:35:28 +00:00
;
2012-03-08 01:14:18 +00:00
endLabelE<strp>:
/* empty */ { $$ = NULL; $<fl>$=NULL; }
| ':' idAny { $$ = $2; $<fl>$=$<fl>2; }
//UNSUP ':' yNEW__ETC { $$ = $2; $<fl>$=$<fl>2; }
2007-07-18 17:58:53 +00:00
;
2007-05-14 20:59:58 +00:00
//************************************************
2009-05-07 22:28:05 +00:00
// Clocking
2006-08-26 11:35:28 +00:00
2008-08-06 16:52:39 +00:00
clocking_declaration<nodep>: // IEEE: clocking_declaration (INCOMPLETE)
2008-08-06 21:51:36 +00:00
yDEFAULT yCLOCKING '@' '(' senitemEdge ')' ';' yENDCLOCKING
{ $$ = new AstClocking($1, $5, NULL); }
2009-05-07 22:28:05 +00:00
//UNSUP: Vastly simplified grammar
2008-08-06 16:52:39 +00:00
;
2009-05-07 22:28:05 +00:00
//************************************************
// Asserts
labeledStmt<nodep>:
immediate_assert_statement { $$ = $1; }
2008-08-06 16:52:39 +00:00
;
2009-05-07 22:28:05 +00:00
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
concurrent_assertion_statement { $$ = $1; }
| id/*block_identifier*/ ':' concurrent_assertion_statement { $$ = new AstBegin($2,*$1,$3); }
2012-10-09 01:20:13 +00:00
// // IEEE: checker_instantiation
// // identical to module_instantiation; see etcInst
2008-08-06 16:52:39 +00:00
;
2009-05-07 22:28:05 +00:00
concurrent_assertion_statement<nodep>: // ==IEEE: concurrent_assertion_statement
//UNSUP: assert/assume
// // IEEE: cover_property_statement
2008-08-06 16:52:39 +00:00
yCOVER yPROPERTY '(' property_spec ')' stmtBlock { $$ = new AstPslCover($1,$4,$6); }
;
property_spec<nodep>: // IEEE: property_spec
2009-05-07 22:28:05 +00:00
//UNSUP: This rule has been super-specialized to what is supported now
2010-04-06 22:55:54 +00:00
'@' '(' senitemEdge ')' yDISABLE yIFF '(' expr ')' expr
{ $$ = new AstPslClocked($1,$3,$8,$10); }
2009-05-07 22:28:05 +00:00
| '@' '(' senitemEdge ')' expr { $$ = new AstPslClocked($1,$3,NULL,$5); }
2010-04-06 22:55:54 +00:00
| yDISABLE yIFF '(' expr ')' expr { $$ = new AstPslClocked($4->fileline(),NULL,$4,$6); }
2009-05-07 22:28:05 +00:00
| expr { $$ = new AstPslClocked($1->fileline(),NULL,NULL,$1); }
2008-08-06 16:52:39 +00:00
;
2009-05-07 22:28:05 +00:00
immediate_assert_statement<nodep>: // ==IEEE: immediate_assert_statement
// // action_block expanded here, for compatibility with AstVAssert
2009-10-31 14:08:38 +00:00
yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, GRAMMARP->createDisplayError($1)); }
2007-05-14 20:59:58 +00:00
| yASSERT '(' expr ')' yELSE stmtBlock { $$ = new AstVAssert($1,$3,NULL,$6); }
| yASSERT '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstVAssert($1,$3,$5,$7); }
2006-08-26 11:35:28 +00:00
;
2009-05-07 22:28:05 +00:00
//************************************************
// Covergroup
//**********************************************************************
// Randsequence
//**********************************************************************
// Class
//=========
// Package scoping - to traverse the symbol table properly, the final identifer
// must be included in the rules below.
// Each of these must end with {symsPackageDone | symsClassDone}
2009-11-08 02:05:02 +00:00
ps_id_etc: // package_scope + general id
package_scopeIdFollowsE id { }
2009-11-07 04:16:06 +00:00
;
ps_type<dtypep>: // IEEE: ps_parameter_identifier | ps_type_identifier
// Even though we looked up the type and have a AstNode* to it,
// we can't fully resolve it because it may have been just a forward definition.
2009-11-08 02:05:02 +00:00
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); $$->castRefDType()->packagep($1); }
2012-10-09 00:45:39 +00:00
// // Simplify typing - from ps_covergroup_identifier
//UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $<fl>$=$<fl>1; $$=$1+$2; }
2009-05-07 22:28:05 +00:00
;
//=== Below rules assume special scoping per above
2009-11-08 02:05:02 +00:00
package_scopeIdFollowsE<packagep>: // IEEE: [package_scope]
2009-05-07 22:28:05 +00:00
// // IMPORTANT: The lexer will parse the following ID to be in the found package
2012-10-09 00:45:39 +00:00
// // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
2009-11-08 02:05:02 +00:00
/* empty */ { $$ = NULL; }
| package_scopeIdFollows { $$ = $1; }
;
package_scopeIdFollows<packagep>: // IEEE: package_scope
// // IMPORTANT: The lexer will parse the following ID to be in the found package
// //vv mid rule action needed otherwise we might not have NextId in time to parse the id token
yD_UNIT { SYMP->nextId(PARSEP->rootp()); }
/*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($<fl>1); }
| yaID__aPACKAGE { SYMP->nextId($<scp>1); }
/*cont*/ yP_COLONCOLON { $$ = $<scp>1->castPackage(); }
2012-10-09 00:45:39 +00:00
//UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
2009-05-07 22:28:05 +00:00
;
2006-08-26 11:35:28 +00:00
//************************************************
// PSL Statements
2008-08-06 16:35:34 +00:00
pslStmt<nodep>:
yPSL pslDir stateExitPsl { $$ = $2; }
2006-08-26 11:35:28 +00:00
| yPSL pslDecl stateExitPsl { $$ = $2; }
;
2008-08-06 16:35:34 +00:00
pslDir<nodep>:
2009-05-07 22:28:05 +00:00
id ':' pslDirOne { $$ = $3; }
2006-08-26 11:35:28 +00:00
| pslDirOne { $$ = $1; }
;
2008-08-06 16:35:34 +00:00
pslDirOne<nodep>:
2008-08-06 16:52:39 +00:00
yPSL_ASSERT pslProp ';' { $$ = new AstPslAssert($1,$2); }
| yPSL_ASSERT pslProp yPSL_REPORT yaSTRING ';' { $$ = new AstPslAssert($1,$2,*$4); }
| yPSL_COVER pslProp ';' { $$ = new AstPslCover($1,$2,NULL); }
| yPSL_COVER pslProp yPSL_REPORT yaSTRING ';' { $$ = new AstPslCover($1,$2,NULL,*$4); }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
pslDecl<nodep>:
2008-09-23 00:10:10 +00:00
yDEFAULT yPSL_CLOCK '=' senitemEdge ';' { $$ = new AstPslDefClock($3, $4); }
2008-08-06 16:52:39 +00:00
| yDEFAULT yPSL_CLOCK '=' '(' senitemEdge ')' ';' { $$ = new AstPslDefClock($3, $5); }
2006-08-26 11:35:28 +00:00
;
//************************************************
// PSL Properties, Sequences and SEREs
// Don't use '{' or '}'; in PSL they're yPSL_BRA and yPSL_KET to avoid expr concatenates
2008-08-06 16:35:34 +00:00
pslProp<nodep>:
pslSequence { $$ = $1; }
2008-08-06 16:52:39 +00:00
| pslSequence '@' %prec prPSLCLK '(' senitemEdge ')' { $$ = new AstPslClocked($2,$4,NULL,$1); } // or pslSequence @ ...?
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
pslSequence<nodep>:
yPSL_BRA pslSere yPSL_KET { $$ = $2; }
2006-08-26 11:35:28 +00:00
;
2008-08-06 16:35:34 +00:00
pslSere<nodep>:
pslExpr { $$ = $1; }
2006-08-26 11:35:28 +00:00
| pslSequence { $$ = $1; } // Sequence containing sequence
;
// Undocumented PSL rule is that {} is always a SERE; concatenation is not allowed.
// This can be bypassed with the _(...) embedding of any arbitrary expression.
2008-08-06 16:35:34 +00:00
pslExpr<nodep>:
exprPsl { $$ = new AstPslBool($1->fileline(), $1); }
2009-11-23 00:57:41 +00:00
| yTRUE { $$ = new AstPslBool($1, new AstConst($1, AstConst::LogicTrue())); }
2006-08-26 11:35:28 +00:00
;
2010-01-21 11:11:30 +00:00
//**********************************************************************
// VLT Files
vltItem:
vltOffFront { V3Config::addIgnore($1,"*",0,0); }
| vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,*$3,0,0); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$5->toUInt()+1); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$7->toUInt()+1); }
;
vltOffFront<errcodeen>:
yVLT_COVERAGE_OFF { $$ = V3ErrorCode::I_COVERAGE; }
| yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; }
2010-12-30 11:58:02 +00:00
| yVLT_LINT_OFF { $$ = V3ErrorCode::I_LINT; }
2010-01-21 11:11:30 +00:00
| yVLT_LINT_OFF yVLT_D_MSG yaID__ETC
{ $$ = V3ErrorCode((*$3).c_str());
2010-02-02 01:15:48 +00:00
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
2010-01-21 11:11:30 +00:00
;
2006-08-26 11:35:28 +00:00
//**********************************************************************
%%
2009-10-31 14:08:38 +00:00
int V3ParseImp::bisonParse() {
if (PARSEP->debugBison()>=9) yydebug = 1;
2011-05-10 03:58:38 +00:00
return yyparse();
2009-10-31 14:08:38 +00:00
}
const char* V3ParseImp::tokenName(int token) {
#if YYDEBUG || YYERROR_VERBOSE
if (token >= 255)
return yytname[token-255];
else {
static char ch[2]; ch[0]=token; ch[1]='\0';
return ch;
}
#else
return "";
#endif
}
void V3ParseImp::parserClear() {
2007-11-02 11:23:03 +00:00
// Clear up any dynamic memory V3Parser required
2009-11-02 13:06:04 +00:00
VARDTYPE(NULL);
2007-11-02 11:23:03 +00:00
}
2013-08-18 00:34:49 +00:00
void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) {
// Convert list of expressions to list of arguments
AstNode* outp = NULL;
while (nodep->pinsp()) {
AstNode* exprp = nodep->pinsp()->unlinkFrBack();
outp = outp->addNext(new AstArg(exprp->fileline(), "", exprp));
}
if (outp) nodep->addPinsp(outp);
}
2009-10-31 14:08:38 +00:00
AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) {
2006-08-26 11:35:28 +00:00
FileLine* newfl = new FileLine (fileline);
newfl->warnOff(V3ErrorCode::WIDTH, true);
2011-01-19 02:12:31 +00:00
AstNode* nodep = new AstConst(newfl, V3Number(newfl));
2007-11-30 22:12:53 +00:00
// Adding a NOT is less work than figuring out how wide to make it
2006-08-26 11:35:28 +00:00
if (value) nodep = new AstNot(newfl, nodep);
nodep = new AstAssignW(newfl, new AstVarRef(fileline, name, true),
nodep);
return nodep;
}
2010-04-10 00:40:41 +00:00
AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstRange* rangep, bool isPacked) {
2009-11-05 14:57:23 +00:00
// Split RANGE0-RANGE1-RANGE2 into ARRAYDTYPE0(ARRAYDTYPE1(ARRAYDTYPE2(BASICTYPE3),RANGE),RANGE)
AstNodeDType* arrayp = basep;
if (rangep) { // Maybe no range - return unmodified base type
while (rangep->nextp()) rangep = rangep->nextp()->castRange();
while (rangep) {
AstRange* prevp = rangep->backp()->castRange();
if (prevp) rangep->unlinkFrBack();
2013-01-12 21:19:25 +00:00
if (isPacked) {
arrayp = new AstPackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
} else {
arrayp = new AstUnpackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
}
2009-11-05 14:57:23 +00:00
rangep = prevp;
}
}
return arrayp;
}
2009-10-31 14:08:38 +00:00
AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp) {
2009-11-02 13:06:04 +00:00
AstNodeDType* dtypep = GRAMMARP->m_varDTypep;
UINFO(5," creVar "<<name<<" decl="<<GRAMMARP->m_varDecl<<" io="<<GRAMMARP->m_varIO<<" dt="<<(dtypep?"set":"")<<endl);
if (GRAMMARP->m_varIO == AstVarType::UNKNOWN
&& GRAMMARP->m_varDecl == AstVarType::PORT) {
// Just a port list with variable name (not v2k format); AstPort already created
if (dtypep) fileline->v3error("Unsupported: Ranges ignored in port-lists");
2009-05-07 22:28:05 +00:00
return NULL;
}
2009-11-02 13:06:04 +00:00
AstVarType type = GRAMMARP->m_varIO;
2013-06-13 23:38:18 +00:00
if (dtypep->castIfaceRefDType()) {
if (arrayp) { fileline->v3error("Unsupported: Arrayed interfaces"); arrayp=NULL; }
}
2009-11-02 13:06:04 +00:00
if (!dtypep) { // Created implicitly
2009-11-03 03:14:11 +00:00
dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
2009-11-02 13:06:04 +00:00
} else { // May make new variables with same type, so clone
dtypep = dtypep->cloneTree(false);
2006-08-26 11:35:28 +00:00
}
2009-11-02 13:06:04 +00:00
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<GRAMMARP->m_varDecl.ascii()<<" io="<<GRAMMARP->m_varIO.ascii()<<endl);
if (type == AstVarType::UNKNOWN
|| (type == AstVarType::PORT && GRAMMARP->m_varDecl != AstVarType::UNKNOWN))
type = GRAMMARP->m_varDecl;
if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared");
2006-08-26 11:35:28 +00:00
if (type == AstVarType::GENVAR) {
if (arrayp) fileline->v3error("Genvars may not be arrayed: "<<name);
}
2009-11-05 03:31:53 +00:00
// Split RANGE0-RANGE1-RANGE2 into ARRAYDTYPE0(ARRAYDTYPE1(ARRAYDTYPE2(BASICTYPE3),RANGE),RANGE)
2010-04-10 00:40:41 +00:00
AstNodeDType* arrayDTypep = createArray(dtypep,arrayp,false);
2009-11-05 03:31:53 +00:00
2012-03-31 15:22:19 +00:00
AstVar* nodep = new AstVar(fileline, type, name, VFlagChildDType(), arrayDTypep);
2009-05-07 22:28:05 +00:00
nodep->addAttrsp(attrsp);
2009-10-31 14:08:38 +00:00
if (GRAMMARP->m_varDecl != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varDecl);
if (GRAMMARP->m_varIO != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varIO);
2006-08-26 11:35:28 +00:00
2009-10-31 14:08:38 +00:00
if (GRAMMARP->m_varDecl == AstVarType::SUPPLY0) {
nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 0));
2006-08-26 11:35:28 +00:00
}
2009-10-31 14:08:38 +00:00
if (GRAMMARP->m_varDecl == AstVarType::SUPPLY1) {
nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 1));
2006-08-26 11:35:28 +00:00
}
2012-04-29 14:14:13 +00:00
// Don't set dtypep in the ranging;
2006-08-26 11:35:28 +00:00
// We need to autosize parameters and integers separately
2012-04-29 14:14:13 +00:00
//
2006-08-26 11:35:28 +00:00
// Propagate from current module tracing state
2014-03-08 20:36:04 +00:00
if (nodep->isGenVar()) nodep->trace(false);
2014-03-14 00:08:43 +00:00
else if (nodep->isParam() && !v3Global.opt.traceParams()) nodep->trace(false);
2008-12-11 21:01:41 +00:00
else nodep->trace(v3Global.opt.trace() && nodep->fileline()->tracingOn());
2006-08-26 11:35:28 +00:00
// Remember the last variable created, so we can attach attributes to it in later parsing
2009-10-31 14:08:38 +00:00
GRAMMARP->m_varAttrp = nodep;
2006-08-26 11:35:28 +00:00
return nodep;
}
2009-10-31 14:08:38 +00:00
string V3ParseGrammar::deQuote(FileLine* fileline, string text) {
2006-08-26 11:35:28 +00:00
// Fix up the quoted strings the user put in, for example "\"" becomes "
2009-10-23 01:16:52 +00:00
// Reverse is AstNode::quoteName(...)
2006-08-26 11:35:28 +00:00
bool quoted = false;
string newtext;
unsigned char octal_val = 0;
int octal_digits = 0;
for (const char* cp=text.c_str(); *cp; ++cp) {
if (quoted) {
if (isdigit(*cp)) {
octal_val = octal_val*8 + (*cp-'0');
if (++octal_digits == 3) {
octal_digits = 0;
quoted = false;
newtext += octal_val;
}
} else {
if (octal_digits) {
2008-06-27 21:52:45 +00:00
// Spec allows 1-3 digits
2006-08-26 11:35:28 +00:00
octal_digits = 0;
2008-06-27 21:52:45 +00:00
quoted = false;
newtext += octal_val;
--cp; // Backup to reprocess terminating character as non-escaped
continue;
2006-08-26 11:35:28 +00:00
}
quoted = false;
if (*cp == 'n') newtext += '\n';
else if (*cp == 'a') newtext += '\a'; // SystemVerilog 3.1
else if (*cp == 'f') newtext += '\f'; // SystemVerilog 3.1
else if (*cp == 'r') newtext += '\r';
else if (*cp == 't') newtext += '\t';
else if (*cp == 'v') newtext += '\v'; // SystemVerilog 3.1
else if (*cp == 'x' && isxdigit(cp[1]) && isxdigit(cp[2])) { // SystemVerilog 3.1
#define vl_decodexdigit(c) ((isdigit(c)?((c)-'0'):(tolower((c))-'a'+10)))
newtext += (char)(16*vl_decodexdigit(cp[1]) + vl_decodexdigit(cp[2]));
cp += 2;
}
else if (isalnum(*cp)) {
fileline->v3error("Unknown escape sequence: \\"<<*cp);
break;
}
else newtext += *cp;
}
}
else if (*cp == '\\') {
quoted = true;
octal_digits = 0;
}
else if (*cp != '"') {
newtext += *cp;
}
}
return newtext;
}
2009-05-05 17:39:25 +00:00
//YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead
// --report=lookahead
// --report=itemset
// --graph