2012-04-13 03:08:20 +02:00
// -*- mode: C++; c-file-style: "cc-mode" -*-
2006-08-26 13:35:28 +02:00
//*************************************************************************
// DESCRIPTION: Verilator: Bison grammer file
//
2019-11-08 04:33:59 +01:00
// Code available from: https://verilator.org
2006-08-26 13:35:28 +02:00
//
//*************************************************************************
//
2020-03-21 16:24:24 +01:00
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
2009-05-04 23:07:57 +02:00
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
2020-03-21 16:24:24 +01:00
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
2006-08-26 13:35:28 +02:00
//
//*************************************************************************
// Original code here by Paul Wasson and Duane Galbi
//*************************************************************************
%{
#include "V3Ast.h"
#include "V3Global.h"
2010-01-21 12:11:30 +01:00
#include "V3Config.h"
2009-10-31 15:08:38 +01:00
#include "V3ParseImp.h" // Defines YYTYPE; before including bison header
2006-08-26 13:35:28 +02:00
2018-10-14 19:43:24 +02:00
#include <cstdlib>
#include <cstdarg>
2007-05-16 14:55:25 +02:00
#define YYERROR_VERBOSE 1
2008-09-17 17:11:09 +02:00
#define YYINITDEPTH 10000 // Older bisons ignore YYMAXDEPTH
2008-08-20 21:59:10 +02:00
#define YYMAXDEPTH 10000
2006-08-26 13:35:28 +02:00
// Pick up new lexer
2009-10-31 15:08:38 +01:00
#define yylex PARSEP->lexToBison
2019-06-01 03:05:50 +02:00
#define BBUNSUP(fl,msg) { if (!v3Global.opt.bboxUnsup()) { (fl)->v3error(msg); } }
#define GATEUNSUP(fl,tok) { BBUNSUP((fl), "Unsupported: Verilog 1995 gate primitive: "<<(tok)); }
2006-08-26 13:35:28 +02:00
2009-05-08 00:28:05 +02:00
extern void yyerror(const char* errmsg);
2006-08-26 13:35:28 +02:00
extern void yyerrorf(const char* format, ...);
//======================================================================
// Statics (for here only)
2009-11-08 03:05:02 +01:00
#define PARSEP V3ParseImp::parsep()
#define SYMP PARSEP->symp()
#define GRAMMARP V3ParseGrammar::singletonp()
2009-10-31 15:08:38 +01:00
class V3ParseGrammar {
2006-08-26 13:35:28 +02:00
public:
2009-10-31 15:08:38 +01:00
bool m_impliedDecl; // Allow implied wire declarations
AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc)
2019-06-22 18:43:48 +02:00
bool m_varDeclTyped; // Var got reg/wire for dedup check
2018-10-27 23:29:00 +02:00
VDirection m_varIO; // Direction for next signal declaration (reg/wire/etc)
2020-04-26 18:45:06 +02:00
VLifetime m_varLifetime; // Static/Automatic for next signal
2009-10-31 15:08:38 +01:00
AstVar* m_varAttrp; // Current variable for attribute adding
2014-05-16 02:57:09 +02:00
AstRange* m_gateRangep; // Current range for gate declarations
2009-10-31 15:08:38 +01:00
AstCase* m_caseAttrp; // Current case statement for attribute adding
2009-11-02 14:06:04 +01:00
AstNodeDType* m_varDTypep; // Pointer to data type for next signal declaration
2012-07-29 16:16:20 +02:00
AstNodeDType* m_memDTypep; // Pointer to data type for next member declaration
2020-04-16 01:39:03 +02:00
AstNodeModule* m_modp; // Last module for timeunits
2019-06-22 18:43:48 +02:00
bool m_pinAnsi; // In ANSI port list
2009-10-31 15:08:38 +01:00
int m_pinNum; // Pin number currently parsing
2019-07-14 21:06:49 +02:00
FileLine* m_instModuleFl; // Fileline of module referenced for instantiations
2009-10-31 15:08:38 +01:00
string m_instModule; // Name of module referenced for instantiations
AstPin* m_instParamp; // Parameters for instantiations
2014-11-04 13:49:03 +01:00
bool m_tracingParse; // Tracing disable for parser
2014-06-15 17:18:47 +02:00
static int s_modTypeImpNum; // Implicit type number, incremented each module
2009-10-31 15:08:38 +01:00
// CONSTRUCTORS
V3ParseGrammar() {
m_impliedDecl = false;
m_varDecl = AstVarType::UNKNOWN;
2019-06-22 18:43:48 +02:00
m_varDeclTyped = false;
2018-10-27 23:29:00 +02:00
m_varIO = VDirection::NONE;
2009-11-02 14:06:04 +01:00
m_varDTypep = NULL;
2014-05-16 02:57:09 +02:00
m_gateRangep = NULL;
2012-07-29 16:16:20 +02:00
m_memDTypep = NULL;
2020-04-16 01:39:03 +02:00
m_modp = NULL;
2019-06-22 18:43:48 +02:00
m_pinAnsi = false;
2009-10-31 15:08:38 +01:00
m_pinNum = -1;
2019-07-14 21:06:49 +02:00
m_instModuleFl = NULL;
2011-08-23 03:02:09 +02:00
m_instModule = "";
2009-10-31 15:08:38 +01:00
m_instParamp = NULL;
m_varAttrp = NULL;
m_caseAttrp = NULL;
2014-11-04 13:49:03 +01:00
m_tracingParse = true;
2009-10-31 15:08:38 +01:00
}
static V3ParseGrammar* singletonp() {
static V3ParseGrammar singleton;
return &singleton;
}
// METHODS
2013-08-18 02:34:49 +02:00
void argWrapList(AstNodeFTaskRef* nodep);
2014-11-04 13:49:03 +01:00
bool allTracingOn(FileLine* fl) {
return v3Global.opt.trace() && m_tracingParse && fl->tracingOn();
}
2017-12-17 22:28:58 +01:00
AstRange* scrubRange(AstNodeRange* rangep);
AstNodeDType* createArray(AstNodeDType* basep, AstNodeRange* rangep, bool isPacked);
2019-10-06 14:20:02 +02:00
AstVar* createVariable(FileLine* fileline, const string& name, AstNodeRange* arrayp, AstNode* attrsp);
AstNode* createSupplyExpr(FileLine* fileline, const string& name, int value);
AstText* createTextQuoted(FileLine* fileline, const string& text) {
2009-10-31 15:08:38 +01:00
string newtext = deQuote(fileline, text);
return new AstText(fileline, newtext);
}
AstDisplay* createDisplayError(FileLine* fileline) {
2019-12-17 03:43:52 +01:00
AstDisplay* nodep = new AstDisplay(fileline, AstDisplayType::DT_ERROR, "", NULL, NULL);
2019-11-17 00:25:47 +01:00
nodep->addNext(new AstStop(fileline, true));
2007-03-06 22:43:38 +01:00
return nodep;
}
2014-05-16 02:57:09 +02:00
AstNode* createGatePin(AstNode* exprp) {
AstRange* rangep = m_gateRangep;
if (!rangep) return exprp;
else return new AstGatePin(rangep->fileline(), exprp, rangep->cloneTree(true));
}
2020-02-04 05:21:56 +01:00
void endLabel(FileLine* fl, AstNode* nodep, string* endnamep) {
endLabel(fl, nodep->prettyName(), endnamep);
}
void endLabel(FileLine* fl, const string& name, string* endnamep) {
if (fl && endnamep && *endnamep != "" && name != *endnamep
&& name != AstNode::prettyName(*endnamep)) {
fl->v3warn(ENDLABEL,"End label '"<<*endnamep<<"' does not match begin label '"<<name<<"'");
}
2012-03-08 02:14:18 +01:00
}
2019-11-06 03:15:44 +01:00
void setVarDecl(AstVarType type) { m_varDecl = type; }
2009-11-02 14:06:04 +01:00
void setDType(AstNodeDType* dtypep) {
2020-01-18 16:29:49 +01:00
if (m_varDTypep) VL_DO_CLEAR(m_varDTypep->deleteTree(), m_varDTypep=NULL); // It was cloned, so this is safe.
2009-11-02 14:06:04 +01:00
m_varDTypep = dtypep;
2009-10-31 15:08:38 +01:00
}
2012-03-20 21:01:53 +01:00
AstPackage* unitPackage(FileLine* fl) {
2009-11-08 03:05:02 +01:00
// Find one made earlier?
2016-02-03 03:02:00 +01:00
VSymEnt* symp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName());
AstPackage* pkgp;
if (!symp) {
2013-01-18 00:36:20 +01:00
pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
2009-11-08 03:05:02 +01:00
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
2016-02-03 03:02:00 +01:00
} else {
2018-02-02 03:32:58 +01:00
pkgp = VN_CAST(symp->nodep(), Package);
2009-11-08 03:05:02 +01:00
}
return pkgp;
}
2017-12-17 22:28:58 +01:00
AstNodeDType* addRange(AstBasicDType* dtypep, AstNodeRange* rangesp, bool isPacked) {
2010-01-26 14:06:39 +01:00
// If dtypep isn't basic, don't use this, call createArray() instead
2009-11-05 15:57:23 +01:00
if (!rangesp) {
return dtypep;
} else {
2010-01-26 14:06:39 +01: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
2017-12-17 22:28:58 +01:00
AstNodeRange* rangearraysp = NULL;
if (dtypep->isRanged()) {
rangearraysp = rangesp; // Already a range; everything is an array
} else {
AstNodeRange* finalp = rangesp;
2018-02-02 03:32:58 +01:00
while (finalp->nextp()) finalp = VN_CAST(finalp->nextp(), Range);
2017-12-17 22:28:58 +01:00
if (finalp != rangesp) {
finalp->unlinkFrBack();
rangearraysp = rangesp;
}
2018-02-02 03:32:58 +01:00
if (AstRange* finalRangep = VN_CAST(finalp, Range)) { // not an UnsizedRange
2017-12-17 22:28:58 +01:00
if (dtypep->implicit()) {
2019-11-06 02:42:49 +01:00
// It's no longer implicit but a wire logic type
2017-12-17 22:28:58 +01:00
AstBasicDType* newp = new AstBasicDType(dtypep->fileline(), AstBasicDTypeKwd::LOGIC,
dtypep->numeric(), dtypep->width(), dtypep->widthMin());
2020-01-17 02:17:11 +01:00
VL_DO_DANGLING(dtypep->deleteTree(), dtypep);
2017-12-17 22:28:58 +01:00
dtypep = newp;
}
dtypep->rangep(finalRangep);
}
2009-11-05 15:57:23 +01:00
}
2010-04-10 02:40:41 +02:00
return createArray(dtypep, rangearraysp, isPacked);
2009-11-05 15:57:23 +01:00
}
}
2009-10-31 15:08:38 +01:00
string deQuote(FileLine* fileline, string text);
2009-12-03 12:55:29 +01:00
void checkDpiVer(FileLine* fileline, const string& str) {
2009-12-04 13:05:44 +01:00
if (str != "DPI-C" && !v3Global.opt.bboxSys()) {
fileline->v3error("Unsupported DPI type '"<<str<<"': Use 'DPI-C'");
}
2009-12-03 12:55:29 +01:00
}
2009-10-31 15:08:38 +01:00
};
2009-11-02 14:06:04 +01:00
const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
2009-11-03 04:14:11 +01:00
const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
2009-11-02 14:06:04 +01:00
2014-06-15 17:18:47 +02:00
int V3ParseGrammar::s_modTypeImpNum = 0;
2009-05-08 00:28:05 +02:00
//======================================================================
// Macro functions
2011-01-19 03:12:31 +01:00
#define CRELINE() (PARSEP->copyOrSameFileLine()) // Only use in empty rules, so lines point at beginnings
2019-10-17 02:05:29 +02:00
#define FILELINE_OR_CRE(nodep) ((nodep) ? (nodep)->fileline() : CRELINE())
2007-05-16 14:55:25 +02:00
2019-06-22 18:43:48 +02:00
#define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; GRAMMARP->m_pinAnsi=false; \
VARRESET(); VARDECL(decl); } // Start of pinlist
#define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; GRAMMARP->m_pinAnsi=false; \
VARRESET(); VARDECL(decl); } // Not in a pinlist
#define VARRESET() { VARDECL(UNKNOWN); VARIO(NONE); VARDTYPE_NDECL(NULL); \
2020-04-26 18:45:06 +02:00
GRAMMARP->m_varLifetime = VLifetime::NONE; \
2019-06-22 18:43:48 +02:00
GRAMMARP->m_varDeclTyped = false; }
#define VARDECL(type) { GRAMMARP->setVarDecl(AstVarType::type); }
2018-10-27 23:29:00 +02:00
#define VARIO(type) { GRAMMARP->m_varIO = VDirection::type; }
2020-04-26 18:45:06 +02:00
#define VARLIFE(flag) { GRAMMARP->m_varLifetime = flag; }
2019-06-22 18:43:48 +02:00
#define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); GRAMMARP->m_varDeclTyped = true; }
#define VARDTYPE_NDECL(dtypep) { GRAMMARP->setDType(dtypep); } // Port that is range or signed only (not a decl)
2009-05-08 00:28:05 +02:00
2011-01-19 03:12:31 +01:00
#define VARDONEA(fl,name,array,attrs) GRAMMARP->createVariable((fl),(name),(array),(attrs))
2009-10-31 15:08:38 +01:00
#define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs))
#define PINNUMINC() (GRAMMARP->m_pinNum++)
2007-05-16 14:55:25 +02:00
2014-05-16 02:57:09 +02:00
#define GATERANGE(rangep) { GRAMMARP->m_gateRangep = rangep; }
2019-07-14 21:06:49 +02:00
#define INSTPREP(modfl,modname,paramsp) { \
GRAMMARP->m_impliedDecl = true; \
GRAMMARP->m_instModuleFl = modfl; GRAMMARP->m_instModule = modname; \
GRAMMARP->m_instParamp = paramsp; }
2006-08-26 13:35:28 +02:00
2012-05-31 05:17:55 +02:00
#define DEL(nodep) { if (nodep) nodep->deleteTree(); }
2009-09-07 21:54:12 +02:00
static void ERRSVKWD(FileLine* fileline, const string& tokname) {
static int toldonce = 0;
2019-07-12 04:36:32 +02:00
fileline->v3error(string("Unexpected '")+tokname+"': '"+tokname
+"' is a SystemVerilog keyword misused as an identifier."
2019-05-31 02:30:59 +02:00
+(!toldonce++
? "\n"+V3Error::warnMore()
2019-06-22 22:09:10 +02:00
+"... Suggest modify the Verilog-2001 code to avoid SV keywords,"
2019-05-31 02:30:59 +02:00
+" or use `begin_keywords or --language."
: ""));
2009-09-07 21:54:12 +02:00
}
2019-11-23 15:16:06 +01:00
static void UNSUPREAL(FileLine* fileline) {
fileline->v3warn(SHORTREAL, "Unsupported: shortreal being promoted to real (suggest use real instead)");
}
2019-11-23 16:39:36 +01:00
2006-08-26 13:35:28 +02:00
//======================================================================
class AstSenTree;
%}
2009-01-28 21:27:41 +01:00
// When writing Bison patterns we use yTOKEN instead of "token",
// so Bison will error out on unknown "token"s.
2007-05-12 18:29:25 +02:00
// Generic lexer tokens, for example a number
2007-10-26 16:58:26 +02:00
// IEEE: real_number
2007-05-12 18:29:25 +02:00
%token<cdouble> yaFLOATNUM "FLOATING-POINT NUMBER"
2009-01-28 21:27:41 +01:00
2007-10-26 16:58:26 +02: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-08 00:28:05 +02:00
%token<strp> yaID__ETC "IDENTIFIER"
2009-10-31 04:17:56 +01:00
%token<strp> yaID__LEX "IDENTIFIER-in-lex"
2009-11-08 03:05:02 +01:00
%token<strp> yaID__aPACKAGE "PACKAGE-IDENTIFIER"
2009-11-07 05:16:06 +01:00
%token<strp> yaID__aTYPE "TYPE-IDENTIFIER"
2012-10-09 03:20:13 +02: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 16:58:26 +02:00
// IEEE: integral_number
%token<nump> yaINTNUM "INTEGER NUMBER"
2008-10-14 20:49:54 +02:00
// IEEE: time_literal + time_unit
%token<cdouble> yaTIMENUM "TIME NUMBER"
2007-10-26 16:58:26 +02:00
// IEEE: string_literal
2007-05-12 18:29:25 +02:00
%token<strp> yaSTRING "STRING"
2009-05-08 00:28:05 +02:00
%token<strp> yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed
2009-10-31 15:08:38 +01:00
%token<fl> yaTIMINGSPEC "TIMING SPEC ELEMENT"
2007-05-12 18:29:25 +02:00
2019-06-01 03:05:50 +02:00
%token<fl> ygenSTRENGTH "STRENGTH keyword (strong1/etc)"
2009-11-21 01:53:40 +01:00
%token<strp> yaTABLELINE "TABLE LINE"
2007-05-12 18:29:25 +02: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"
2020-01-12 10:03:17 +01:00
%token<fl> yVLT_CLOCKER "clocker"
%token<fl> yVLT_CLOCK_ENABLE "clock_enable"
%token<fl> yVLT_COVERAGE_BLOCK_OFF "coverage_block_off"
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
%token<fl> yVLT_COVERAGE_ON "coverage_on"
%token<fl> yVLT_FULL_CASE "full_case"
%token<fl> yVLT_INLINE "inline"
%token<fl> yVLT_ISOLATE_ASSIGNMENTS "isolate_assignments"
%token<fl> yVLT_LINT_OFF "lint_off"
%token<fl> yVLT_LINT_ON "lint_on"
%token<fl> yVLT_NO_CLOCKER "no_clocker"
%token<fl> yVLT_NO_INLINE "no_inline"
%token<fl> yVLT_PARALLEL_CASE "parallel_case"
%token<fl> yVLT_PUBLIC "public"
%token<fl> yVLT_PUBLIC_FLAT "public_flat"
%token<fl> yVLT_PUBLIC_FLAT_RD "public_flat_rd"
%token<fl> yVLT_PUBLIC_FLAT_RW "public_flat_rw"
%token<fl> yVLT_PUBLIC_MODULE "public_module"
%token<fl> yVLT_SC_BV "sc_bv"
%token<fl> yVLT_SFORMAT "sformat"
2020-04-03 14:08:23 +02:00
%token<fl> yVLT_SPLIT_VAR "split_var"
2020-01-12 10:03:17 +01:00
%token<fl> yVLT_TRACING_OFF "tracing_off"
%token<fl> yVLT_TRACING_ON "tracing_on"
%token<fl> yVLT_D_BLOCK "--block"
%token<fl> yVLT_D_FILE "--file"
%token<fl> yVLT_D_FUNCTION "--function"
%token<fl> yVLT_D_LINES "--lines"
%token<fl> yVLT_D_MODULE "--module"
%token<fl> yVLT_D_MATCH "--match"
%token<fl> yVLT_D_MSG "--msg"
%token<fl> yVLT_D_RULE "--rule"
%token<fl> yVLT_D_TASK "--task"
%token<fl> yVLT_D_VAR "--var"
2010-01-21 12:11:30 +01:00
2009-12-04 13:05:44 +01:00
%token<strp> yaD_IGNORE "${ignored-bbox-sys}"
%token<strp> yaD_DPI "${dpi-sys}"
2019-12-15 04:04:58 +01:00
%token<fl> yaT_RESETALL "`resetall"
2009-10-31 15:08:38 +01: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 21:27:41 +01:00
2007-05-12 18:29:25 +02: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-08 00:28:05 +02:00
// Double underscores "yX__Y" means token X followed by Y,
// and "yX__ETC" means X folled by everything but Y(s).
2019-06-01 03:05:50 +02:00
%token<fl> yALIAS "alias"
2009-10-31 15:08:38 +01:00
%token<fl> yALWAYS "always"
2013-05-01 04:55:28 +02:00
%token<fl> yALWAYS_COMB "always_comb"
2019-06-01 03:05:50 +02:00
%token<fl> yALWAYS_FF "always_ff"
2013-05-01 04:55:28 +02:00
%token<fl> yALWAYS_LATCH "always_latch"
2009-10-31 15:08:38 +01:00
%token<fl> yAND "and"
%token<fl> yASSERT "assert"
%token<fl> yASSIGN "assign"
2018-10-12 03:00:29 +02:00
%token<fl> yASSUME "assume"
2009-10-31 15:08:38 +01:00
%token<fl> yAUTOMATIC "automatic"
%token<fl> yBEGIN "begin"
2013-01-15 05:19:44 +01:00
%token<fl> yBIND "bind"
2009-10-31 20:12:28 +01:00
%token<fl> yBIT "bit"
2010-02-14 16:01:21 +01:00
%token<fl> yBREAK "break"
2009-10-31 15:08:38 +01:00
%token<fl> yBUF "buf"
%token<fl> yBUFIF0 "bufif0"
%token<fl> yBUFIF1 "bufif1"
2009-11-03 04:14:11 +01:00
%token<fl> yBYTE "byte"
2009-10-31 15:08:38 +01:00
%token<fl> yCASE "case"
%token<fl> yCASEX "casex"
%token<fl> yCASEZ "casez"
2009-11-24 15:11:25 +01:00
%token<fl> yCHANDLE "chandle"
2019-12-23 21:03:04 +01:00
%token<fl> yCLASS "class"
2009-10-31 15:08:38 +01:00
%token<fl> yCLOCKING "clocking"
2019-06-01 03:05:50 +02:00
%token<fl> yCMOS "cmos"
2011-07-02 18:45:26 +02:00
%token<fl> yCONST__ETC "const"
%token<fl> yCONST__LEX "const-in-lex"
2018-10-12 03:57:07 +02:00
%token<fl> yCONST__REF "const-then-ref"
2009-12-03 12:55:29 +01:00
%token<fl> yCONTEXT "context"
2010-02-14 16:01:21 +01:00
%token<fl> yCONTINUE "continue"
2009-10-31 15:08:38 +01:00
%token<fl> yCOVER "cover"
2016-12-21 23:43:19 +01:00
%token<fl> yDEASSIGN "deassign"
2009-10-31 15:08:38 +01:00
%token<fl> yDEFAULT "default"
%token<fl> yDEFPARAM "defparam"
%token<fl> yDISABLE "disable"
%token<fl> yDO "do"
2009-12-29 01:49:40 +01:00
%token<fl> yEDGE "edge"
2009-10-31 15:08:38 +01:00
%token<fl> yELSE "else"
%token<fl> yEND "end"
%token<fl> yENDCASE "endcase"
2019-12-23 21:03:04 +01:00
%token<fl> yENDCLASS "endclass"
2009-10-31 15:08:38 +01:00
%token<fl> yENDCLOCKING "endclocking"
%token<fl> yENDFUNCTION "endfunction"
%token<fl> yENDGENERATE "endgenerate"
2013-05-28 03:39:19 +02:00
%token<fl> yENDINTERFACE "endinterface"
2009-10-31 15:08:38 +01:00
%token<fl> yENDMODULE "endmodule"
2009-11-08 03:05:02 +01:00
%token<fl> yENDPACKAGE "endpackage"
2009-11-20 14:41:28 +01:00
%token<fl> yENDPRIMITIVE "endprimitive"
2009-11-06 01:09:45 +01:00
%token<fl> yENDPROGRAM "endprogram"
2009-10-31 15:08:38 +01:00
%token<fl> yENDPROPERTY "endproperty"
%token<fl> yENDSPECIFY "endspecify"
2009-11-21 01:53:40 +01:00
%token<fl> yENDTABLE "endtable"
2009-10-31 15:08:38 +01:00
%token<fl> yENDTASK "endtask"
2009-12-27 14:29:55 +01:00
%token<fl> yENUM "enum"
2019-06-01 03:05:50 +02:00
%token<fl> yEVENT "event"
2009-12-03 12:55:29 +01:00
%token<fl> yEXPORT "export"
2019-12-23 21:03:04 +01:00
%token<fl> yEXTENDS "extends"
2018-10-09 04:18:09 +02:00
%token<fl> yEXTERN "extern"
2009-10-31 15:08:38 +01:00
%token<fl> yFINAL "final"
%token<fl> yFOR "for"
2019-06-01 03:05:50 +02:00
%token<fl> yFORCE "force"
2016-09-20 04:00:13 +02:00
%token<fl> yFOREACH "foreach"
2009-10-31 15:08:38 +01:00
%token<fl> yFOREVER "forever"
2019-06-01 03:05:50 +02:00
%token<fl> yFORK "fork"
2018-10-09 04:18:09 +02:00
%token<fl> yFORKJOIN "forkjoin"
2009-10-31 15:08:38 +01:00
%token<fl> yFUNCTION "function"
%token<fl> yGENERATE "generate"
%token<fl> yGENVAR "genvar"
2010-01-23 01:08:20 +01:00
%token<fl> yGLOBAL__CLOCKING "global-then-clocking"
2019-11-16 17:59:21 +01:00
%token<fl> yGLOBAL__ETC "global"
2010-01-23 01:08:20 +01:00
%token<fl> yGLOBAL__LEX "global-in-lex"
2009-10-31 15:08:38 +01:00
%token<fl> yIF "if"
%token<fl> yIFF "iff"
2019-12-23 21:03:04 +01:00
%token<fl> yIMPLEMENTS "implements"
2009-11-10 01:07:59 +01:00
%token<fl> yIMPORT "import"
2009-10-31 15:08:38 +01:00
%token<fl> yINITIAL "initial"
%token<fl> yINOUT "inout"
%token<fl> yINPUT "input"
2013-02-02 18:55:28 +01:00
%token<fl> yINSIDE "inside"
2009-11-03 04:14:11 +01:00
%token<fl> yINT "int"
2009-10-31 15:08:38 +01:00
%token<fl> yINTEGER "integer"
2013-05-28 03:39:19 +02:00
%token<fl> yINTERFACE "interface"
2019-06-01 03:05:50 +02:00
%token<fl> yJOIN "join"
2019-12-23 21:19:22 +01:00
%token<fl> yJOIN_ANY "join_any"
%token<fl> yJOIN_NONE "join_none"
2009-10-31 15:08:38 +01:00
%token<fl> yLOCALPARAM "localparam"
2019-12-23 21:03:04 +01:00
%token<fl> yLOCAL__COLONCOLON "local-then-::"
%token<fl> yLOCAL__ETC "local"
%token<fl> yLOCAL__LEX "local-in-lex"
2009-11-03 04:14:11 +01:00
%token<fl> yLOGIC "logic"
%token<fl> yLONGINT "longint"
2013-05-28 03:39:19 +02:00
%token<fl> yMODPORT "modport"
2009-10-31 15:08:38 +01:00
%token<fl> yMODULE "module"
%token<fl> yNAND "nand"
%token<fl> yNEGEDGE "negedge"
2019-12-23 21:03:04 +01:00
%token<fl> yNEW__ETC "new"
%token<fl> yNEW__LEX "new-in-lex"
%token<fl> yNEW__PAREN "new-then-paren"
2010-01-08 04:08:48 +01:00
%token<fl> yNMOS "nmos"
2009-10-31 15:08:38 +01:00
%token<fl> yNOR "nor"
%token<fl> yNOT "not"
%token<fl> yNOTIF0 "notif0"
%token<fl> yNOTIF1 "notif1"
2019-06-01 03:05:50 +02:00
%token<fl> yNULL "null"
2009-10-31 15:08:38 +01:00
%token<fl> yOR "or"
%token<fl> yOUTPUT "output"
2009-11-08 03:05:02 +01:00
%token<fl> yPACKAGE "package"
2012-07-29 16:16:20 +02:00
%token<fl> yPACKED "packed"
2009-10-31 15:08:38 +01:00
%token<fl> yPARAMETER "parameter"
2010-01-08 04:08:48 +01:00
%token<fl> yPMOS "pmos"
2009-10-31 15:08:38 +01:00
%token<fl> yPOSEDGE "posedge"
2009-11-20 14:41:28 +01:00
%token<fl> yPRIMITIVE "primitive"
2009-10-31 15:08:38 +01:00
%token<fl> yPRIORITY "priority"
2009-11-06 01:09:45 +01:00
%token<fl> yPROGRAM "program"
2009-10-31 15:08:38 +01:00
%token<fl> yPROPERTY "property"
2019-12-23 21:03:04 +01:00
%token<fl> yPROTECTED "protected"
2009-10-31 15:08:38 +01:00
%token<fl> yPULLDOWN "pulldown"
%token<fl> yPULLUP "pullup"
2009-12-03 12:55:29 +01:00
%token<fl> yPURE "pure"
2012-07-29 16:16:20 +02:00
%token<fl> yRAND "rand"
%token<fl> yRANDC "randc"
2019-06-01 03:05:50 +02:00
%token<fl> yRANDCASE "randcase"
2010-01-08 04:08:48 +01:00
%token<fl> yRCMOS "rcmos"
2011-07-24 21:01:51 +02:00
%token<fl> yREAL "real"
%token<fl> yREALTIME "realtime"
2018-10-12 03:57:07 +02:00
%token<fl> yREF "ref"
2009-10-31 15:08:38 +01:00
%token<fl> yREG "reg"
2019-06-01 03:05:50 +02:00
%token<fl> yRELEASE "release"
2009-10-31 15:08:38 +01:00
%token<fl> yREPEAT "repeat"
2018-09-23 21:20:12 +02:00
%token<fl> yRESTRICT "restrict"
2010-02-14 16:01:21 +01:00
%token<fl> yRETURN "return"
2010-01-08 04:08:48 +01:00
%token<fl> yRNMOS "rnmos"
%token<fl> yRPMOS "rpmos"
%token<fl> yRTRAN "rtran"
%token<fl> yRTRANIF0 "rtranif0"
%token<fl> yRTRANIF1 "rtranif1"
2009-10-31 15:08:38 +01:00
%token<fl> ySCALARED "scalared"
2009-11-03 04:14:11 +01:00
%token<fl> ySHORTINT "shortint"
2018-10-09 04:18:09 +02:00
%token<fl> ySHORTREAL "shortreal"
2009-10-31 15:08:38 +01:00
%token<fl> ySIGNED "signed"
%token<fl> ySPECIFY "specify"
%token<fl> ySPECPARAM "specparam"
2019-11-17 15:01:41 +01:00
%token<fl> ySTATIC__ETC "static"
2009-12-04 13:05:44 +01:00
%token<fl> ySTRING "string"
2012-07-29 16:16:20 +02:00
%token<fl> ySTRUCT "struct"
2019-12-23 21:03:04 +01:00
%token<fl> ySUPER "super"
2009-10-31 15:08:38 +01:00
%token<fl> ySUPPLY0 "supply0"
%token<fl> ySUPPLY1 "supply1"
2009-11-21 01:53:40 +01:00
%token<fl> yTABLE "table"
2009-10-31 15:08:38 +01:00
%token<fl> yTASK "task"
2019-12-23 21:03:04 +01:00
%token<fl> yTHIS "this"
2009-11-19 16:45:59 +01:00
%token<fl> yTIME "time"
2009-10-31 15:08:38 +01:00
%token<fl> yTIMEPRECISION "timeprecision"
%token<fl> yTIMEUNIT "timeunit"
2010-01-08 04:08:48 +01:00
%token<fl> yTRAN "tran"
%token<fl> yTRANIF0 "tranif0"
%token<fl> yTRANIF1 "tranif1"
2009-10-31 15:08:38 +01:00
%token<fl> yTRI "tri"
2012-04-22 03:45:28 +02:00
%token<fl> yTRI0 "tri0"
%token<fl> yTRI1 "tri1"
2019-06-01 03:05:50 +02:00
%token<fl> yTRIAND "triand"
%token<fl> yTRIOR "trior"
%token<fl> yTRIREG "trireg"
2009-10-31 15:08:38 +01:00
%token<fl> yTRUE "true"
2016-03-15 02:51:31 +01:00
%token<fl> yTYPE "type"
2009-11-07 05:16:06 +01:00
%token<fl> yTYPEDEF "typedef"
2012-07-29 16:16:20 +02:00
%token<fl> yUNION "union"
2009-10-31 15:08:38 +01:00
%token<fl> yUNIQUE "unique"
2010-12-26 03:58:28 +01:00
%token<fl> yUNIQUE0 "unique0"
2009-10-31 15:08:38 +01:00
%token<fl> yUNSIGNED "unsigned"
2009-11-06 01:57:31 +01:00
%token<fl> yVAR "var"
2009-10-31 15:08:38 +01:00
%token<fl> yVECTORED "vectored"
2019-12-23 21:03:04 +01:00
%token<fl> yVIRTUAL__CLASS "virtual-then-class"
%token<fl> yVIRTUAL__ETC "virtual"
%token<fl> yVIRTUAL__INTERFACE "virtual-then-interface"
%token<fl> yVIRTUAL__LEX "virtual-in-lex"
%token<fl> yVIRTUAL__anyID "virtual-then-identifier"
2009-11-03 04:50:31 +01:00
%token<fl> yVOID "void"
2019-06-01 03:05:50 +02:00
%token<fl> yWAIT "wait"
%token<fl> yWAND "wand"
2009-10-31 15:08:38 +01:00
%token<fl> yWHILE "while"
%token<fl> yWIRE "wire"
2019-06-01 03:05:50 +02:00
%token<fl> yWOR "wor"
2011-11-27 16:31:06 +01:00
%token<fl> yWREAL "wreal"
2009-10-31 15:08:38 +01:00
%token<fl> yXNOR "xnor"
%token<fl> yXOR "xor"
2018-02-26 10:25:07 +01:00
%token<fl> yD_ACOS "$acos"
%token<fl> yD_ACOSH "$acosh"
%token<fl> yD_ASIN "$asin"
%token<fl> yD_ASINH "$asinh"
%token<fl> yD_ATAN "$atan"
%token<fl> yD_ATAN2 "$atan2"
%token<fl> yD_ATANH "$atanh"
2009-10-31 15:08:38 +01:00
%token<fl> yD_BITS "$bits"
2011-07-24 21:01:51 +02:00
%token<fl> yD_BITSTOREAL "$bitstoreal"
2019-11-23 15:16:06 +01:00
%token<fl> yD_BITSTOSHORTREAL "$bitstoshortreal"
2009-10-31 15:08:38 +01:00
%token<fl> yD_C "$c"
2011-09-29 03:35:16 +02:00
%token<fl> yD_CEIL "$ceil"
2009-10-31 15:08:38 +01:00
%token<fl> yD_CLOG2 "$clog2"
2018-02-26 10:25:07 +01:00
%token<fl> yD_COS "$cos"
%token<fl> yD_COSH "$cosh"
2020-05-10 20:27:22 +02:00
%token<fl> yD_COUNTBITS "$countbits"
2009-10-31 15:08:38 +01:00
%token<fl> yD_COUNTONES "$countones"
2013-01-20 18:19:22 +01:00
%token<fl> yD_DIMENSIONS "$dimensions"
2009-10-31 15:08:38 +01:00
%token<fl> yD_DISPLAY "$display"
2020-03-06 03:49:25 +01:00
%token<fl> yD_DISPLAYB "$displayb"
%token<fl> yD_DISPLAYH "$displayh"
%token<fl> yD_DISPLAYO "$displayo"
2020-03-02 03:39:23 +01:00
%token<fl> yD_DUMPALL "$dumpall"
%token<fl> yD_DUMPFILE "$dumpfile"
%token<fl> yD_DUMPFLUSH "$dumpflush"
%token<fl> yD_DUMPLIMIT "$dumplimit"
%token<fl> yD_DUMPOFF "$dumpoff"
%token<fl> yD_DUMPON "$dumpon"
%token<fl> yD_DUMPPORTS "$dumpports"
%token<fl> yD_DUMPVARS "$dumpvars"
2009-10-31 15:08:38 +01:00
%token<fl> yD_ERROR "$error"
2011-09-29 03:35:16 +02:00
%token<fl> yD_EXP "$exp"
2009-10-31 15:08:38 +01:00
%token<fl> yD_FATAL "$fatal"
%token<fl> yD_FCLOSE "$fclose"
%token<fl> yD_FDISPLAY "$fdisplay"
2020-03-06 03:49:25 +01:00
%token<fl> yD_FDISPLAYB "$fdisplayb"
%token<fl> yD_FDISPLAYH "$fdisplayh"
%token<fl> yD_FDISPLAYO "$fdisplayo"
2009-10-31 15:08:38 +01:00
%token<fl> yD_FEOF "$feof"
2020-04-05 17:22:05 +02:00
%token<fl> yD_FERROR "$ferror"
2009-10-31 15:08:38 +01:00
%token<fl> yD_FFLUSH "$fflush"
%token<fl> yD_FGETC "$fgetc"
%token<fl> yD_FGETS "$fgets"
%token<fl> yD_FINISH "$finish"
2011-09-29 03:35:16 +02:00
%token<fl> yD_FLOOR "$floor"
2009-10-31 15:08:38 +01:00
%token<fl> yD_FOPEN "$fopen"
2019-03-08 02:56:53 +01:00
%token<fl> yD_FREAD "$fread"
2019-09-04 03:28:15 +02:00
%token<fl> yD_FREWIND "$frewind"
2009-10-31 15:08:38 +01:00
%token<fl> yD_FSCANF "$fscanf"
2019-09-04 03:28:15 +02:00
%token<fl> yD_FSEEK "$fseek"
%token<fl> yD_FTELL "$ftell"
2009-10-31 15:08:38 +01:00
%token<fl> yD_FWRITE "$fwrite"
2020-03-06 03:49:25 +01:00
%token<fl> yD_FWRITEB "$fwriteb"
%token<fl> yD_FWRITEH "$fwriteh"
%token<fl> yD_FWRITEO "$fwriteo"
2013-01-20 18:19:22 +01:00
%token<fl> yD_HIGH "$high"
2018-02-26 10:25:07 +01:00
%token<fl> yD_HYPOT "$hypot"
2013-01-20 18:19:22 +01:00
%token<fl> yD_INCREMENT "$increment"
2009-10-31 15:08:38 +01:00
%token<fl> yD_INFO "$info"
2020-05-08 03:09:14 +02:00
%token<fl> yD_ISUNBOUNDED "$isunbounded"
2009-10-31 15:08:38 +01:00
%token<fl> yD_ISUNKNOWN "$isunknown"
2011-07-24 21:01:51 +02:00
%token<fl> yD_ITOR "$itor"
2013-01-20 18:19:22 +01:00
%token<fl> yD_LEFT "$left"
2011-09-29 03:35:16 +02:00
%token<fl> yD_LN "$ln"
%token<fl> yD_LOG10 "$log10"
2013-01-20 18:19:22 +01:00
%token<fl> yD_LOW "$low"
2009-10-31 15:08:38 +01:00
%token<fl> yD_ONEHOT "$onehot"
%token<fl> yD_ONEHOT0 "$onehot0"
2018-09-23 21:09:47 +02:00
%token<fl> yD_PAST "$past"
2011-09-29 03:35:16 +02:00
%token<fl> yD_POW "$pow"
2020-04-16 01:39:03 +02:00
%token<fl> yD_PRINTTIMESCALE "$printtimescale"
2009-10-31 15:08:38 +01:00
%token<fl> yD_RANDOM "$random"
%token<fl> yD_READMEMB "$readmemb"
%token<fl> yD_READMEMH "$readmemh"
2011-07-24 21:01:51 +02:00
%token<fl> yD_REALTIME "$realtime"
%token<fl> yD_REALTOBITS "$realtobits"
2019-11-16 18:21:35 +01:00
%token<fl> yD_REWIND "$rewind"
2013-01-20 18:19:22 +01:00
%token<fl> yD_RIGHT "$right"
2020-05-02 14:29:20 +02:00
%token<fl> yD_ROOT "$root"
2011-07-24 21:01:51 +02:00
%token<fl> yD_RTOI "$rtoi"
2020-01-26 19:38:15 +01:00
%token<fl> yD_SAMPLED "$sampled"
2009-11-24 03:24:55 +01:00
%token<fl> yD_SFORMAT "$sformat"
2015-10-03 13:12:56 +02:00
%token<fl> yD_SFORMATF "$sformatf"
2019-11-23 15:16:06 +01:00
%token<fl> yD_SHORTREALTOBITS "$shortrealtobits"
2009-10-31 15:08:38 +01:00
%token<fl> yD_SIGNED "$signed"
2018-02-26 10:25:07 +01:00
%token<fl> yD_SIN "$sin"
%token<fl> yD_SINH "$sinh"
2013-01-20 18:19:22 +01:00
%token<fl> yD_SIZE "$size"
2011-09-29 03:35:16 +02:00
%token<fl> yD_SQRT "$sqrt"
2009-10-31 15:08:38 +01:00
%token<fl> yD_SSCANF "$sscanf"
%token<fl> yD_STIME "$stime"
%token<fl> yD_STOP "$stop"
2009-11-24 03:24:55 +01:00
%token<fl> yD_SWRITE "$swrite"
2020-03-06 03:49:25 +01:00
%token<fl> yD_SWRITEB "$swriteb"
%token<fl> yD_SWRITEH "$swriteh"
%token<fl> yD_SWRITEO "$swriteo"
2011-11-20 08:01:48 +01:00
%token<fl> yD_SYSTEM "$system"
2018-02-26 10:25:07 +01:00
%token<fl> yD_TAN "$tan"
%token<fl> yD_TANH "$tanh"
2009-11-19 23:04:21 +01:00
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
2009-10-31 15:08:38 +01:00
%token<fl> yD_TIME "$time"
2020-04-16 01:39:03 +02:00
%token<fl> yD_TIMEFORMAT "$timeformat"
2020-01-26 19:21:25 +01:00
%token<fl> yD_TYPENAME "$typename"
2019-11-16 18:55:10 +01:00
%token<fl> yD_UNGETC "$ungetc"
2009-11-08 03:05:02 +01:00
%token<fl> yD_UNIT "$unit"
2013-01-20 18:19:22 +01:00
%token<fl> yD_UNPACKED_DIMENSIONS "$unpacked_dimensions"
2009-10-31 15:08:38 +01:00
%token<fl> yD_UNSIGNED "$unsigned"
2009-11-19 23:04:21 +01:00
%token<fl> yD_VALUEPLUSARGS "$value$plusargs"
2009-10-31 15:08:38 +01:00
%token<fl> yD_WARNING "$warning"
%token<fl> yD_WRITE "$write"
2020-03-06 03:49:25 +01:00
%token<fl> yD_WRITEB "$writeb"
%token<fl> yD_WRITEH "$writeh"
2018-03-12 21:44:01 +01:00
%token<fl> yD_WRITEMEMH "$writememh"
2020-03-06 03:49:25 +01:00
%token<fl> yD_WRITEO "$writeo"
2009-10-31 15:08:38 +01:00
%token<fl> yVL_CLOCK "/*verilator sc_clock*/"
2015-03-13 00:20:46 +01:00
%token<fl> yVL_CLOCKER "/*verilator clocker*/"
%token<fl> yVL_NO_CLOCKER "/*verilator no_clocker*/"
2009-10-31 15:08:38 +01:00
%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 14:57:27 +02:00
%token<fl> yVL_SC_BV "/*verilator sc_bv*/"
2010-01-18 01:13:44 +01:00
%token<fl> yVL_SFORMAT "/*verilator sformat*/"
2009-10-31 15:08:38 +01: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 02:01:17 +02:00
%token<fl> yVL_PUBLIC_FLAT_RD "/*verilator public_flat_rd*/"
%token<fl> yVL_PUBLIC_FLAT_RW "/*verilator public_flat_rw*/"
2009-10-31 15:08:38 +01:00
%token<fl> yVL_PUBLIC_MODULE "/*verilator public_module*/"
2020-02-29 01:15:08 +01:00
%token<fl> yVL_SPLIT_VAR "/*verilator split_var*/"
2009-10-31 15:08:38 +01:00
%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 23:05:13 +01:00
%token<fl> yP_LTE__IGNORE "<=-ignored" // Used when expr:<= means assignment
2009-10-31 15:08:38 +01:00
%token<fl> yP_SLEFT "<<"
%token<fl> yP_SRIGHT ">>"
%token<fl> yP_SSRIGHT ">>>"
%token<fl> yP_POW "**"
2019-06-01 03:05:50 +02:00
%token<fl> yP_PAR__STRENGTH "(-for-strength"
2019-06-02 01:40:06 +02:00
%token<fl> yP_LTMINUSGT "<->"
2009-10-31 15:08:38 +01:00
%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 ">>>="
2007-10-23 22:54:29 +02: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 13:35:28 +02:00
//********************
2019-06-01 03:05:50 +02:00
// These prevent other conflicts
%left yP_ANDANDAND
2006-08-26 13:35:28 +02:00
// PSL op precedence
2019-06-02 01:40:06 +02:00
%right yP_ORMINUSGT yP_OREQGT
2006-08-26 13:35:28 +02:00
// Verilog op precedence
2019-06-02 01:40:06 +02:00
%right yP_MINUSGT yP_LTMINUSGT
2009-02-08 02:54:09 +01:00
%right '?' ':'
2007-11-05 22:38:20 +01:00
%left yP_OROR
%left yP_ANDAND
%left '|' yP_NOR
2009-02-08 02:54:09 +01:00
%left '^' yP_XNOR
2007-11-05 22:38:20 +01:00
%left '&' yP_NAND
%left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
2013-02-02 18:55:28 +01:00
%left '>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE
2007-11-05 22:38:20 +01:00
%left yP_SLEFT yP_SRIGHT yP_SSRIGHT
%left '+' '-'
%left '*' '/' '%'
%left yP_POW
2009-05-08 00:28:05 +02: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 13:35:28 +02:00
2007-05-12 18:29:25 +02:00
%nonassoc prLOWER_THAN_ELSE
2006-08-26 13:35:28 +02:00
%nonassoc yELSE
2008-08-06 18:35:34 +02: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-08 00:28:05 +02:00
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
2009-11-08 03:05:02 +01: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 19:43:54 +01: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
2020-01-12 10:03:17 +01:00
// Blank lines for type insertion
2020-04-23 03:31:40 +02:00
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
2020-04-26 18:45:06 +02:00
// Blank lines for type insertion
// Blank lines for type insertion
2006-08-26 13:35:28 +02:00
2009-01-25 03:36:14 +01:00
%start source_text
2006-08-26 13:35:28 +02:00
%%
//**********************************************************************
2007-05-14 22:59:58 +02:00
// Files
2006-08-26 13:35:28 +02:00
2009-01-25 03:36:14 +01:00
source_text: // ==IEEE: source_text
/* empty */ { }
2009-05-08 00:28:05 +02:00
// // timeunits_declaration moved into description:package_item
| descriptionList { }
2008-03-25 14:42:48 +01:00
;
2009-01-25 03:36:14 +01:00
descriptionList: // IEEE: part of source_text
description { }
| descriptionList description { }
2007-10-31 21:11:59 +01:00
;
2009-01-15 19:58:43 +01:00
description: // ==IEEE: description
module_declaration { }
2012-10-09 02:45:39 +02:00
// // udp_declaration moved into module_declaration
2013-05-28 03:39:19 +02:00
| interface_declaration { }
2009-11-06 01:09:45 +01:00
| program_declaration { }
2009-11-08 03:05:02 +01:00
| package_declaration { }
| package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
2013-02-14 12:55:09 +01:00
| bind_directive { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
2009-01-28 21:27:41 +01:00
// unsupported // IEEE: config_declaration
2012-12-31 19:43:54 +01:00
// // Verilator only
2019-12-15 04:04:58 +01:00
| yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3
2010-01-21 12:11:30 +01:00
| vltItem { }
2009-01-25 03:36:14 +01:00
| error { }
2006-08-26 13:35:28 +02:00
;
2009-11-07 05:16:06 +01:00
timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
2020-04-16 01:39:03 +02:00
yTIMEUNIT yaTIMENUM ';'
{ PARSEP->timescaleMod($<fl>2, GRAMMARP->m_modp, true, $2, false, 0); $$ = NULL; }
| yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';'
{ PARSEP->timescaleMod($<fl>2, GRAMMARP->m_modp, true, $2, true, $4); $$ = NULL; }
| yTIMEPRECISION yaTIMENUM ';'
{ PARSEP->timescaleMod($<fl>2, GRAMMARP->m_modp, false, 0, true, $2); $$ = NULL; }
2008-10-14 20:49:54 +02:00
;
2007-05-14 22:59:58 +02:00
//**********************************************************************
2009-05-08 00:28:05 +02:00
// Packages
2009-11-08 03:05:02 +01:00
package_declaration: // ==IEEE: package_declaration
packageFront package_itemListE yENDPACKAGE endLabelE
2014-11-04 13:49:03 +01:00
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
2009-11-08 03:05:02 +01:00
if ($2) $1->addStmtp($2);
2020-04-16 01:39:03 +02:00
GRAMMARP->m_modp = NULL;
2012-03-08 02:14:18 +01:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>4,$1,$4); }
2009-11-08 03:05:02 +01:00
;
packageFront<modulep>:
2018-10-09 04:18:09 +02:00
yPACKAGE lifetimeE idAny ';'
2019-07-13 18:01:26 +02:00
{ $$ = new AstPackage($<fl>3, *$3);
2009-11-08 03:05:02 +01:00
$$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2014-11-04 13:49:03 +01:00
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
2020-04-16 01:39:03 +02:00
$$->timeunit(PARSEP->timeLastUnit());
2009-11-08 03:05:02 +01:00
PARSEP->rootp()->addModulep($$);
2020-04-16 01:39:03 +02:00
SYMP->pushNew($$);
GRAMMARP->m_modp = $$; }
2009-11-08 03:05:02 +01:00
;
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; }
2018-10-09 04:18:09 +02:00
| anonymous_program { $$ = $1; }
2017-09-21 03:04:59 +02:00
| package_export_declaration { $$ = $1; }
2009-11-08 03:05:02 +01:00
| timeunits_declaration { $$ = $1; }
;
2009-05-08 00:28:05 +02: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 02:45:39 +02:00
//UNSUP checker_declaration { $$ = $1; }
2009-12-03 12:55:29 +01:00
| dpi_import_export { $$ = $1; }
2009-05-08 00:28:05 +02:00
//UNSUP extern_constraint_declaration { $$ = $1; }
2019-12-23 21:03:04 +01:00
| class_declaration { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // class_constructor_declaration is part of function_declaration
2012-10-09 03:20:13 +02:00
| local_parameter_declaration ';' { $$ = $1; }
2012-10-09 02:45:39 +02:00
| parameter_declaration ';' { $$ = $1; }
2009-05-08 00:28:05 +02:00
//UNSUP covergroup_declaration { $$ = $1; }
2012-10-09 02:45:39 +02:00
//UNSUP assertion_item_declaration { $$ = $1; }
2009-05-08 00:28:05 +02:00
| ';' { $$ = NULL; }
2008-10-14 20:49:54 +02:00
;
2014-05-16 02:50:42 +02:00
package_import_declarationList<nodep>:
package_import_declaration { $$ = $1; }
| package_import_declarationList package_import_declaration { $$ = $1->addNextNull($2); }
;
2009-11-10 01:07:59 +01: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
2019-07-13 18:01:26 +02:00
{ $$ = new AstPackageImport($<fl>2, VN_CAST($<scp>1, Package), *$3);
2017-09-21 03:04:59 +02:00
SYMP->importItem($<scp>1,*$3); }
2009-11-10 01:07:59 +01:00
;
package_import_itemObj<strp>: // IEEE: part of package_import_item
idAny { $<fl>$=$<fl>1; $$=$1; }
| '*' { $<fl>$=$<fl>1; static string star="*"; $$=☆ }
;
2017-09-21 03:04:59 +02:00
package_export_declaration<nodep>: // IEEE: package_export_declaration
2019-07-13 18:01:26 +02:00
yEXPORT '*' yP_COLONCOLON '*' ';' { $$ = new AstPackageExportStarStar($<fl>2); SYMP->exportStarStar($<scp>1); }
2017-09-21 03:04:59 +02:00
| yEXPORT package_export_itemList ';' { $$ = $2; }
;
package_export_itemList<nodep>:
package_export_item { $$ = $1; }
| package_export_itemList ',' package_export_item { $$ = $1->addNextNull($3); }
;
package_export_item<nodep>: // ==IEEE: package_export_item
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
2019-07-13 18:01:26 +02:00
{ $$ = new AstPackageExport($<fl>3, VN_CAST($<scp>1, Package), *$3);
2017-09-21 03:04:59 +02:00
SYMP->exportItem($<scp>1,*$3); }
;
2009-05-08 00:28:05 +02:00
//**********************************************************************
// Module headers
module_declaration: // ==IEEE: module_declaration
// // timeunits_declaration instead in module_item
// // IEEE: module_nonansi_header + module_ansi_header
2014-05-16 02:50:42 +02:00
modFront importsAndParametersE portsStarE ';'
2009-05-08 00:28:05 +02:00
module_itemListE yENDMODULE endLabelE
2014-11-04 13:49:03 +01:00
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
2009-05-08 00:28:05 +02:00
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3);
2009-10-31 15:08:38 +01:00
if ($5) $1->addStmtp($5);
2020-04-16 01:39:03 +02:00
GRAMMARP->m_modp = NULL;
2012-03-08 02:14:18 +01:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); }
2009-11-20 14:41:28 +01: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);
2014-11-04 13:49:03 +01:00
GRAMMARP->m_tracingParse = true;
2020-04-16 01:39:03 +02:00
GRAMMARP->m_modp = NULL;
2012-03-08 02:14:18 +01:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); }
2009-05-08 00:28:05 +02:00
//
2018-10-09 04:18:09 +02:00
| yEXTERN modFront parameter_port_listE portsStarE ';'
2019-06-01 03:05:50 +02:00
{ BBUNSUP($<fl>1, "Unsupported: extern module"); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
modFront<modulep>:
2009-10-31 15:08:38 +01:00
// // General note: all *Front functions must call symPushNew before
// // any formal arguments, as the arguments must land in the new scope.
2009-05-08 00:28:05 +02:00
yMODULE lifetimeE idAny
2019-07-13 18:01:26 +02:00
{ $$ = new AstModule($<fl>3,*$3);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2019-07-13 18:01:26 +02:00
$$->inLibrary(PARSEP->inLibrary() || PARSEP->inCellDefine());
2014-11-04 13:49:03 +01:00
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
2020-04-16 01:39:03 +02:00
$$->timeunit(PARSEP->timeLastUnit());
2020-04-10 05:26:03 +02:00
$$->unconnectedDrive(PARSEP->unconnectedDrive());
2009-10-31 15:08:38 +01:00
PARSEP->rootp()->addModulep($$);
2020-04-16 01:39:03 +02:00
SYMP->pushNew($$);
GRAMMARP->m_modp = $$; }
2006-08-26 13:35:28 +02:00
;
2014-05-16 02:50:42 +02:00
importsAndParametersE<nodep>: // IEEE: common part of module_declaration, interface_declaration, program_declaration
// // { package_import_declaration } [ parameter_port_list ]
parameter_port_listE { $$ = $1; }
| package_import_declarationList parameter_port_listE { $$ = $1->addNextNull($2); }
;
2009-11-20 14:41:28 +01:00
udpFront<modulep>:
yPRIMITIVE lifetimeE idAny
2019-07-13 18:01:26 +02:00
{ $$ = new AstPrimitive($<fl>3, *$3); $$->inLibrary(true);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2009-11-20 14:41:28 +01:00
$$->modTrace(false);
2019-07-13 18:01:26 +02:00
$$->addStmtp(new AstPragma($<fl>3, AstPragmaType::INLINE_MODULE));
2014-11-04 13:49:03 +01:00
GRAMMARP->m_tracingParse = false;
2009-11-20 14:41:28 +01:00
PARSEP->rootp()->addModulep($$);
SYMP->pushNew($$); }
;
2009-05-08 00:28:05 +02:00
parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2016-03-13 02:54:52 +01:00
| '#' '(' cellparamList ')' { $$ = $3; }
2009-11-10 22:29:58 +01:00
// // Parentheses are optional around a single parameter
2019-07-13 18:01:26 +02:00
| '#' yaINTNUM { $$ = new AstPin($<fl>2, 1, "", new AstConst($<fl>2, *$2)); }
| '#' yaFLOATNUM { $$ = new AstPin($<fl>2, 1, "",
new AstConst($<fl>2, AstConst::Unsized32(),
(int)(($2<0)?($2-0.5):($2+0.5)))); }
2020-04-16 01:39:03 +02:00
| '#' timeNumAdjusted { $$ = new AstPin($<fl>2, 1, "", $2); }
2019-07-13 18:01:26 +02:00
| '#' idClassSel { $$ = new AstPin($<fl>2, 1, "", $2); }
2009-05-08 00:28:05 +02:00
// // Not needed in Verilator:
// // Side effect of combining *_instantiations
// // '#' delay_value { UNSUP }
2006-08-26 13:35:28 +02:00
;
2019-12-23 21:03:04 +01:00
parameter_value_assignmentClass<pinp>: // IEEE: [ parameter_value_assignment ] (for classes)
// // Like parameter_value_assignment, but for classes only, which always have #()
'#' '(' cellparamList ')' { $$ = $3; }
;
2009-05-08 00:28:05 +02: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 15:35:02 +02:00
;
2009-05-08 00:28:05 +02:00
paramPortDeclOrArgList<nodep>: // IEEE: list_of_param_assignments + { parameter_port_declaration }
paramPortDeclOrArg { $$ = $1; }
| paramPortDeclOrArgList ',' paramPortDeclOrArg { $$ = $1->addNext($3); }
2007-09-11 15:35:02 +02:00
;
2009-05-08 00:28:05 +02:00
paramPortDeclOrArg<nodep>: // IEEE: param_assignment + parameter_port_declaration
// // We combine the two as we can't tell which follows a comma
2014-08-27 13:57:20 +02:00
parameter_port_declarationFrontE param_assignment { $$ = $2; }
2020-03-21 17:13:55 +01:00
| parameter_port_declarationTypeFrontE type_assignment { $$ = $2; }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
portsStarE<nodep>: // IEEE: .* + list_of_ports + list_of_port_declarations + empty
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2006-08-26 13:35:28 +02:00
| '(' ')' { $$ = NULL; }
2009-05-08 00:28:05 +02:00
// // .* expanded from module_declaration
//UNSUP '(' yP_DOTSTAR ')' { UNSUP }
| '(' {VARRESET_LIST(PORT);} list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02: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 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
port<nodep>: // ==IEEE: port
2019-11-06 02:42:49 +01:00
// // SEE ALSO port_declaration, tf_port_declaration,
// // data_declarationVarFront
//
2009-05-08 00:28:05 +02:00
// // 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-14 01:38:18 +02:00
portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE
2019-11-06 02:42:49 +01:00
{ $$ = $3; VARDECL(IFACEREF); VARIO(NONE);
2013-06-14 01:38:18 +02:00
VARDTYPE(new AstIfaceRefDType($<fl>2,"",*$2));
$$->addNextNull(VARDONEP($$,$4,$5)); }
2017-09-15 03:15:56 +02:00
| portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE
2019-11-06 02:42:49 +01:00
{ $$ = $5; VARDECL(IFACEREF); VARIO(NONE);
2019-07-14 21:06:49 +02:00
VARDTYPE(new AstIfaceRefDType($<fl>2, $<fl>4, "", *$2, *$4));
2013-06-14 01:38:18 +02:00
$$->addNextNull(VARDONEP($$,$6,$7)); }
| portDirNetE yINTERFACE portSig rangeListE sigAttrListE
2019-06-01 03:05:50 +02:00
{ $$ = NULL; BBUNSUP($<fl>2, "Unsupported: virtual or generic interfaces"); }
2013-06-14 01:38:18 +02:00
| portDirNetE yINTERFACE '.' idAny/*modport*/ portSig rangeListE sigAttrListE
2019-06-01 03:05:50 +02:00
{ $$ = NULL; BBUNSUP($<fl>2, "Unsupported: virtual or generic interfaces"); }
2009-05-08 00:28:05 +02:00
//
// // IEEE: ansi_port_declaration, with [port_direction] removed
2012-10-09 02:45:39 +02:00
// // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ]
2009-05-08 00:28:05 +02: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 02:33:50 +01:00
// // variable_dimensionListE instead of rangeListE to avoid conflicts
2009-05-08 00:28:05 +02: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 03:20:13 +02: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-08 00:28:05 +02:00
//
2013-06-14 01:38:18 +02:00
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE
2009-11-06 01:57:31 +01:00
{ $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
2009-12-18 02:58:14 +01:00
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE
2009-11-06 01:57:31 +01:00
{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
2009-12-18 02:58:14 +01:00
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
2009-11-06 01:57:31 +01:00
{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
2018-03-30 02:10:27 +02:00
| portDirNetE signing portSig variable_dimensionListE sigAttrListE
2019-06-22 18:43:48 +02:00
{ $$=$3; VARDTYPE_NDECL(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2)); $$->addNextNull(VARDONEP($$,$4,$5)); }
2009-12-18 02:58:14 +01:00
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE
2019-06-22 18:43:48 +02:00
{ $$=$4; VARDTYPE_NDECL(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2), $3,true)); $$->addNextNull(VARDONEP($$,$5,$6)); }
2009-12-18 02:58:14 +01:00
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE
2009-11-06 01:57:31 +01:00
{ $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
2009-05-08 00:28:05 +02:00
//
2009-12-18 02:58:14 +01:00
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
2018-05-10 00:32:12 +02:00
{ $$=$3; VARDTYPE($2); if (AstVar* vp=VARDONEP($$,$4,$5)) { $$->addNextNull(vp); vp->valuep($7); } }
2009-12-18 02:58:14 +01:00
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
2018-05-10 00:32:12 +02:00
{ $$=$4; VARDTYPE($3); if (AstVar* vp=VARDONEP($$,$5,$6)) { $$->addNextNull(vp); vp->valuep($8); } }
2009-12-18 02:58:14 +01:00
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
2018-05-10 00:32:12 +02:00
{ $$=$4; VARDTYPE($3); if (AstVar* vp=VARDONEP($$,$5,$6)) { $$->addNextNull(vp); vp->valuep($8); } }
2009-12-18 02:58:14 +01:00
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
2018-05-10 00:32:12 +02:00
{ $$=$2; /*VARDTYPE-same*/ if (AstVar* vp=VARDONEP($$,$3,$4)) { $$->addNextNull(vp); vp->valuep($6); } }
2009-05-08 00:28:05 +02:00
;
2011-05-10 05:58:38 +02:00
2009-05-08 00:28:05 +02:00
portDirNetE: // IEEE: part of port, optional net type and/or direction
/* empty */ { }
// // Per spec, if direction given default the nettype.
2009-11-02 14:06:04 +01:00
// // The higher level rule may override this VARDTYPE with one later in the parse.
2019-06-22 18:43:48 +02:00
| port_direction { VARDECL(PORT); VARDTYPE_NDECL(NULL/*default_nettype*/); }
| port_direction { VARDECL(PORT); } net_type { VARDTYPE_NDECL(NULL/*default_nettype*/); } // net_type calls VARDECL
2017-03-31 00:32:37 +02:00
| net_type { } // net_type calls VARDECL
2009-05-08 00:28:05 +02:00
;
2011-05-10 05:58:38 +02:00
2009-05-08 00:28:05 +02:00
port_declNetE: // IEEE: part of port_declaration, optional net type
/* empty */ { }
2017-03-31 00:32:37 +02:00
| net_type { } // net_type calls VARDECL
2009-05-08 00:28:05 +02:00
;
2011-05-10 05:58:38 +02:00
2009-10-31 04:17:56 +01:00
portSig<nodep>:
2011-01-19 03:12:31 +01:00
id/*port*/ { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
| idSVKwd { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
2009-05-08 00:28:05 +02:00
;
2006-08-26 13:35:28 +02:00
2009-05-08 00:28:05 +02:00
//**********************************************************************
// Interface headers
2007-06-12 15:58:56 +02:00
2013-05-28 03:39:19 +02: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); }
2018-10-09 04:18:09 +02:00
| yEXTERN intFront parameter_port_listE portsStarE ';'
2019-06-01 03:05:50 +02:00
{ BBUNSUP($<fl>1, "Unsupported: extern interface"); }
2013-05-28 03:39:19 +02:00
;
intFront<modulep>:
yINTERFACE lifetimeE idAny/*new_interface*/
2019-07-13 18:01:26 +02:00
{ $$ = new AstIface($<fl>3, *$3);
2013-05-28 03:39:19 +02:00
$$->inLibrary(true);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2013-05-28 03:39:19 +02:00
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
2014-11-29 03:32:57 +01:00
// // IEEE: generate_region
| interface_generate_region { $$ = $1; }
2013-05-28 03:39:19 +02:00
| interface_or_generate_item { $$ = $1; }
2019-06-01 03:05:50 +02:00
| program_declaration { $$ = NULL; v3error("Unsupported: program decls within interface decls"); }
// // IEEE 1800-2017: modport_item
// // See instead old 2012 position in interface_or_generate_item
| interface_declaration { $$ = NULL; v3error("Unsupported: interface decls within interface decls"); }
2013-05-28 03:39:19 +02:00
| timeunits_declaration { $$ = $1; }
// // See note in interface_or_generate item
| module_common_item { $$ = $1; }
;
2014-11-29 03:32:57 +01:00
interface_generate_region<nodep>: // ==IEEE: generate_region
2020-02-26 00:57:51 +01:00
yGENERATE interface_itemList yENDGENERATE { $$ = $2; }
2014-11-29 03:32:57 +01:00
| yGENERATE yENDGENERATE { $$ = NULL; }
;
2013-05-28 03:39:19 +02:00
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; }
2018-10-09 04:18:09 +02:00
| extern_tf_declaration { $$ = $1; }
2013-05-28 03:39:19 +02:00
;
2009-05-08 00:28:05 +02:00
//**********************************************************************
// Program headers
2018-10-09 04:18:09 +02:00
anonymous_program<nodep>: // ==IEEE: anonymous_program
// // See the spec - this doesn't change the scope, items still go up "top"
yPROGRAM ';' anonymous_program_itemListE yENDPROGRAM { $<fl>1->v3error("Unsupported: Anonymous programs"); $$ = NULL; }
;
anonymous_program_itemListE<nodep>: // IEEE: { anonymous_program_item }
/* empty */ { $$ = NULL; }
| anonymous_program_itemList { $$ = $1; }
;
anonymous_program_itemList<nodep>: // IEEE: { anonymous_program_item }
anonymous_program_item { $$ = $1; }
| anonymous_program_itemList anonymous_program_item { $$ = $1->addNextNull($2); }
;
anonymous_program_item<nodep>: // ==IEEE: anonymous_program_item
task_declaration { $$ = $1; }
| function_declaration { $$ = $1; }
2019-12-23 21:03:04 +01:00
| class_declaration { $$ = $1; }
2018-10-09 04:18:09 +02:00
//UNSUP covergroup_declaration { $$ = $1; }
// // class_constructor_declaration is part of function_declaration
2019-10-16 01:06:00 +02:00
| ';' { $$ = NULL; }
2018-10-09 04:18:09 +02:00
;
2009-11-06 01:09:45 +01: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
2014-11-04 13:49:03 +01:00
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
2009-11-06 01:09:45 +01:00
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3);
if ($5) $1->addStmtp($5);
2020-04-16 01:39:03 +02:00
GRAMMARP->m_modp = NULL;
2012-03-08 02:14:18 +01:00
SYMP->popScope($1);
GRAMMARP->endLabel($<fl>7,$1,$7); }
2018-10-09 04:18:09 +02:00
| yEXTERN pgmFront parameter_port_listE portsStarE ';'
2019-06-01 03:05:50 +02:00
{ BBUNSUP($<fl>1, "Unsupported: extern program");
2018-10-09 04:18:09 +02:00
SYMP->popScope($2); }
2009-11-06 01:09:45 +01:00
;
pgmFront<modulep>:
yPROGRAM lifetimeE idAny/*new_program*/
2019-07-13 18:01:26 +02:00
{ $$ = new AstModule($<fl>3,*$3);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2019-07-13 18:01:26 +02:00
$$->inLibrary(PARSEP->inLibrary() || PARSEP->inCellDefine());
2014-11-04 13:49:03 +01:00
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
2020-04-16 01:39:03 +02:00
$$->timeunit(PARSEP->timeLastUnit());
2009-11-06 01:09:45 +01:00
PARSEP->rootp()->addModulep($$);
2020-04-16 01:39:03 +02:00
SYMP->pushNew($$);
GRAMMARP->m_modp = $$; }
2009-11-06 01:09:45 +01:00
;
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 05:16:06 +01:00
| timeunits_declaration { $$ = $1; }
2009-11-06 01:09:45 +01:00
| program_generate_item { $$ = $1; }
;
program_generate_item<nodep>: // ==IEEE: program_generate_item
loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
| generate_region { $$ = $1; }
2017-11-22 03:10:42 +01:00
| elaboration_system_task { $$ = $1; }
2009-11-06 01:09:45 +01:00
;
2018-10-09 04:18:09 +02:00
extern_tf_declaration<nodep>: // ==IEEE: extern_tf_declaration
2019-06-01 03:05:50 +02:00
yEXTERN task_prototype ';' { $$ = NULL; BBUNSUP($<fl>1, "Unsupported: extern task"); }
| yEXTERN function_prototype ';' { $$ = NULL; BBUNSUP($<fl>1, "Unsupported: extern function"); }
| yEXTERN yFORKJOIN task_prototype ';' { $$ = NULL; BBUNSUP($<fl>1, "Unsupported: extern forkjoin"); }
2018-10-09 04:18:09 +02:00
;
2013-05-28 03:39:19 +02: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
2017-11-29 01:11:41 +01:00
id/*new-modport*/ '(' { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
2019-07-13 18:01:26 +02:00
/*cont*/ modportPortsDeclList ')' { $$ = new AstModport($<fl>1, *$1, $4); }
2013-05-28 03:39:19 +02:00
;
2013-12-21 12:51:15 +01:00
modportPortsDeclList<nodep>:
2013-05-28 03:39:19 +02:00
modportPortsDecl { $$ = $1; }
2013-12-21 12:51:15 +01:00
| modportPortsDeclList ',' modportPortsDecl { $$ = $1->addNextNull($3); }
2013-05-28 03:39:19 +02: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 12:51:15 +01:00
modportPortsDecl<nodep>:
2013-05-28 03:39:19 +02:00
// // IEEE: modport_simple_ports_declaration
2019-07-13 18:01:26 +02:00
port_direction modportSimplePort { $$ = new AstModportVarRef($<fl>2, *$2, GRAMMARP->m_varIO); }
2013-05-28 03:39:19 +02:00
// // IEEE: modport_clocking_declaration
2019-06-01 03:05:50 +02:00
| yCLOCKING idAny/*clocking_identifier*/ { $$ = NULL; BBUNSUP($<fl>1, "Unsupported: Modport clocking"); }
2013-12-21 12:51:15 +01:00
// // IEEE: yIMPORT modport_tf_port
// // IEEE: yEXPORT modport_tf_port
// // modport_tf_port expanded here
2019-07-13 18:01:26 +02:00
| yIMPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef($<fl>2, *$2, false); }
| yEXPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef($<fl>2, *$2, true); }
2019-06-01 03:05:50 +02:00
| yIMPORT method_prototype { $$ = NULL; BBUNSUP($<fl>1, "Unsupported: Modport import with prototype"); }
| yEXPORT method_prototype { $$ = NULL; BBUNSUP($<fl>1, "Unsupported: Modport export with prototype"); }
2013-05-28 03:39:19 +02:00
// Continuations of above after a comma.
// // IEEE: modport_simple_ports_declaration
2017-11-29 01:11:41 +01:00
| modportSimplePort { $$ = new AstModportVarRef($<fl>1,*$1,GRAMMARP->m_varIO); }
2013-05-28 03:39:19 +02:00
;
modportSimplePort<strp>: // IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
id { $$ = $1; }
//UNSUP '.' idAny '(' ')' { }
//UNSUP '.' idAny '(' expr ')' { }
;
2009-05-08 00:28:05 +02:00
//************************************************
// Variable Declarations
2007-06-12 15:58:56 +02:00
2009-05-08 00:28:05 +02:00
genvar_declaration<nodep>: // ==IEEE: genvar_declaration
yGENVAR list_of_genvar_identifiers ';' { $$ = $2; }
2008-04-14 23:10:34 +02:00
;
2009-05-08 00:28:05 +02: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 13:35:28 +02:00
;
2011-11-30 00:23:18 +01:00
genvar_identifierDecl<varp>: // IEEE: genvar_identifier (for declaration)
2009-11-02 14:06:04 +01:00
id/*new-genvar_identifier*/ sigAttrListE
{ VARRESET_NONLIST(GENVAR); VARDTYPE(new AstBasicDType($<fl>1,AstBasicDTypeKwd::INTEGER));
2011-01-19 03:12:31 +01:00
$$ = VARDONEA($<fl>1, *$1, NULL, $2); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration
// // See notes in parameter_declaration
2016-03-13 02:54:52 +01:00
// // Front must execute first so VARDTYPE is ready before list of vars
2012-10-09 03:20:13 +02:00
local_parameter_declarationFront list_of_param_assignments { $$ = $2; }
2020-03-21 17:13:55 +01:00
| local_parameter_declarationTypeFront list_of_type_assignments { $$ = $2; }
2009-05-08 00:28:05 +02:00
;
2007-05-14 22:59:58 +02:00
2009-05-08 00:28:05 +02: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
2016-03-13 02:54:52 +01:00
// // Front must execute first so VARDTYPE is ready before list of vars
2020-03-21 17:13:55 +01:00
parameter_declarationFront list_of_param_assignments { $$ = $2; }
| parameter_declarationTypeFront list_of_type_assignments { $$ = $2; }
2007-05-14 22:59:58 +02:00
;
2009-05-08 00:28:05 +02:00
local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
2016-03-13 02:54:52 +01:00
// // Front must execute first so VARDTYPE is ready before list of vars
2009-12-18 02:58:14 +01:00
varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
2009-11-03 04:14:11 +01:00
| varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
2020-03-21 17:13:55 +01:00
;
local_parameter_declarationTypeFront: // IEEE: local_parameter_declaration w/o assignment
// // Front must execute first so VARDTYPE is ready before list of vars
varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); }
2007-05-14 22:59:58 +02:00
;
2009-05-08 00:28:05 +02:00
parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
2016-03-13 02:54:52 +01:00
// // Front must execute first so VARDTYPE is ready before list of vars
2009-12-18 02:58:14 +01:00
varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
2009-11-03 04:14:11 +01:00
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
2020-03-21 17:13:55 +01:00
;
parameter_declarationTypeFront: // IEEE: parameter_declaration w/o assignment
// // Front must execute first so VARDTYPE is ready before list of vars
varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); }
2007-05-14 22:59:58 +02:00
;
2014-08-27 13:57:20 +02:00
parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment
2009-05-08 00:28:05 +02:00
// // IEEE: parameter_declaration (minus assignment)
2017-01-27 04:41:32 +01:00
// // IEEE: local_parameter_declaration (minus assignment)
2016-03-13 02:54:52 +01:00
// // Front must execute first so VARDTYPE is ready before list of vars
2014-08-27 13:57:20 +02:00
varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
2017-01-27 04:41:32 +01:00
| varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
| varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); }
2014-08-27 13:57:20 +02:00
| implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
| data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
2020-03-21 17:13:55 +01:00
;
parameter_port_declarationTypeFrontE: // IEEE: parameter_port_declaration w/o assignment
// // IEEE: parameter_declaration (minus assignment)
// // IEEE: local_parameter_declaration (minus assignment)
// // Front must execute first so VARDTYPE is ready before list of vars
varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); }
| varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); }
2016-03-15 02:51:31 +01:00
| yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($1)); }
2007-05-14 22:59:58 +02:00
;
2009-05-08 00:28:05 +02:00
net_declaration<nodep>: // IEEE: net_declaration - excluding implict
net_declarationFront netSigList ';' { $$ = $2; }
2007-05-14 22:59:58 +02:00
;
2009-05-08 00:28:05 +02:00
net_declarationFront: // IEEE: beginning of net_declaration
2019-11-06 03:15:44 +01:00
net_declRESET net_type strengthSpecE net_scalaredE net_dataTypeE { VARDTYPE_NDECL($5); }
2018-10-09 04:18:09 +02:00
//UNSUP net_declRESET yINTERCONNECT signingE rangeListE { VARNET($2); VARDTYPE(x); }
2007-05-14 22:59:58 +02:00
;
2006-08-26 13:35:28 +02:00
2009-05-08 00:28:05 +02:00
net_declRESET:
/* empty */ { VARRESET_NONLIST(UNKNOWN); }
2006-08-26 13:35:28 +02:00
;
2013-02-02 15:33:04 +01:00
net_scalaredE:
/* empty */ { }
2019-06-01 03:05:50 +02:00
// //UNSUP: ySCALARED/yVECTORED ignored
2013-02-02 15:33:04 +01:00
| ySCALARED { }
| yVECTORED { }
;
2019-11-06 02:42:49 +01:00
net_dataTypeE<dtypep>:
2013-02-02 15:33:04 +01:00
// // 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 03:36:14 +01:00
net_type: // ==IEEE: net_type
2009-01-15 19:58:43 +01:00
ySUPPLY0 { VARDECL(SUPPLY0); }
2006-08-26 13:35:28 +02:00
| ySUPPLY1 { VARDECL(SUPPLY1); }
| yTRI { VARDECL(TRIWIRE); }
2012-04-22 03:45:28 +02:00
| yTRI0 { VARDECL(TRI0); }
| yTRI1 { VARDECL(TRI1); }
2019-06-01 03:05:50 +02:00
| yTRIAND { VARDECL(WIRE); BBUNSUP($1, "Unsupported: triand"); }
| yTRIOR { VARDECL(WIRE); BBUNSUP($1, "Unsupported: trior"); }
| yTRIREG { VARDECL(WIRE); BBUNSUP($1, "Unsupported: trireg"); }
| yWAND { VARDECL(WIRE); BBUNSUP($1, "Unsupported: wand"); }
2009-05-08 00:28:05 +02:00
| yWIRE { VARDECL(WIRE); }
2019-06-01 03:05:50 +02:00
| yWOR { VARDECL(WIRE); BBUNSUP($1, "Unsupported: wor"); }
2017-03-31 00:32:37 +02:00
// // VAMS - somewhat hackish
| yWREAL { VARDECL(WREAL); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
varGParamReset:
yPARAMETER { VARRESET_NONLIST(GPARAM); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
varLParamReset:
yLOCALPARAM { VARRESET_NONLIST(LPARAM); }
2006-08-26 13:35:28 +02:00
;
2008-04-14 23:10:34 +02:00
2009-05-08 00:28:05 +02:00
port_direction: // ==IEEE: port_direction + tf_port_direction
// // IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here
2019-06-22 18:43:48 +02:00
// // Only used for ANSI declarations
yINPUT { GRAMMARP->m_pinAnsi=true; VARIO(INPUT); }
| yOUTPUT { GRAMMARP->m_pinAnsi=true; VARIO(OUTPUT); }
| yINOUT { GRAMMARP->m_pinAnsi=true; VARIO(INOUT); }
| yREF { GRAMMARP->m_pinAnsi=true; VARIO(REF); }
| yCONST__REF yREF { GRAMMARP->m_pinAnsi=true; VARIO(CONSTREF); }
2009-05-08 00:28:05 +02:00
;
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); }
2018-10-31 01:50:09 +01:00
| yREF { VARRESET_NONLIST(UNKNOWN); VARIO(REF); }
| yCONST__REF yREF { VARRESET_NONLIST(UNKNOWN); VARIO(CONSTREF); }
2009-05-08 00:28:05 +02:00
;
port_declaration<nodep>: // ==IEEE: port_declaration
2019-06-22 18:43:48 +02:00
// // Non-ANSI; used inside block followed by ';'
2019-11-06 02:42:49 +01:00
// // SEE ALSO port, tf_port_declaration, data_declarationVarFront
2009-05-08 00:28:05 +02:00
//
// // IEEE: inout_declaration
// // IEEE: input_declaration
// // IEEE: output_declaration
// // IEEE: ref_declaration
2009-11-02 14:06:04 +01:00
port_directionReset port_declNetE data_type { VARDTYPE($3); }
list_of_variable_decl_assignments { $$ = $5; }
2009-11-06 01:57:31 +01:00
| port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); }
list_of_variable_decl_assignments { $$ = $6; }
2009-12-18 02:58:14 +01:00
| port_directionReset port_declNetE yVAR implicit_typeE { VARDTYPE($4); }
2009-11-06 01:57:31 +01:00
list_of_variable_decl_assignments { $$ = $6; }
2019-06-22 18:43:48 +02:00
| port_directionReset port_declNetE signingE rangeList { VARDTYPE_NDECL(GRAMMARP->addRange(new AstBasicDType($4->fileline(), LOGIC_IMPLICIT, $3), $4, true)); }
2009-11-02 14:06:04 +01:00
list_of_variable_decl_assignments { $$ = $6; }
2019-06-22 18:43:48 +02:00
| port_directionReset port_declNetE signing { VARDTYPE_NDECL(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $3)); }
2009-11-02 14:06:04 +01:00
list_of_variable_decl_assignments { $$ = $5; }
2019-06-22 18:43:48 +02:00
| port_directionReset port_declNetE /*implicit*/ { VARDTYPE_NDECL(NULL);/*default_nettype*/}
2009-11-02 14:06:04 +01:00
list_of_variable_decl_assignments { $$ = $4; }
2015-01-17 21:35:45 +01:00
// // IEEE: interface_declaration
// // Looks just like variable declaration unless has a period
// // See etcInst
2009-05-08 00:28:05 +02:00
;
tf_port_declaration<nodep>: // ==IEEE: tf_port_declaration
// // Used inside function; followed by ';'
2019-11-06 02:42:49 +01:00
// // SEE ALSO port_declaration, port, data_declarationVarFront
2009-05-08 00:28:05 +02:00
//
2009-12-18 02:58:14 +01:00
port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
2019-06-22 18:43:48 +02:00
| port_directionReset implicit_typeE { VARDTYPE_NDECL($2); } list_of_tf_variable_identifiers ';' { $$ = $4; }
2009-12-18 02:58:14 +01:00
| 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 13:35:28 +02:00
;
2009-11-02 14:06:04 +01:00
integer_atom_type<bdtypep>: // ==IEEE: integer_atom_type
2009-11-03 04:14:11 +01: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 16:45:59 +01:00
| yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); }
2009-10-31 20:12:28 +01:00
;
2009-11-02 14:06:04 +01:00
integer_vector_type<bdtypep>: // ==IEEE: integer_atom_type
yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); }
| yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); }
2009-11-03 04:14:11 +01:00
| yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } // logic==reg
2009-10-31 20:12:28 +01:00
;
2012-03-20 21:01:53 +01:00
non_integer_type<bdtypep>: // ==IEEE: non_integer_type
2011-07-24 21:01:51 +02:00
yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
| yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
2019-11-23 15:16:06 +01:00
| ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); UNSUPREAL($1); }
2011-07-24 21:01:51 +02:00
;
2009-11-02 14:06:04 +01:00
signingE<signstate>: // IEEE: signing - plus empty
2020-04-20 03:19:09 +02:00
/*empty*/ { $$ = VSigning::NOSIGN; }
2009-11-02 14:06:04 +01:00
| signing { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
2009-11-02 14:06:04 +01:00
signing<signstate>: // ==IEEE: signing
2020-04-20 03:19:09 +02:00
ySIGNED { $<fl>$ = $<fl>1; $$ = VSigning::SIGNED; }
| yUNSIGNED { $<fl>$ = $<fl>1; $$ = VSigning::UNSIGNED; }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
//************************************************
// Data Types
2011-03-18 03:25:49 +01: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 21:01:51 +02:00
| non_integer_type { $$ = $1; }
2011-03-18 03:25:49 +01: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 15:57:23 +01:00
data_type<dtypep>: // ==IEEE: data_type
2009-05-08 00:28:05 +02:00
// // This expansion also replicated elsewhere, IE data_type__AndID
data_typeNoRef { $$ = $1; }
2019-12-23 21:03:04 +01:00
//
// // REFERENCES
//
2009-05-08 00:28:05 +02:00
// // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
// // IEEE: class_type
// // IEEE: ps_covergroup_identifier
2019-12-23 21:03:04 +01:00
// // Don't distinguish between types and classes so all these combined
| package_scopeIdFollowsE idRefDType packed_dimensionListE
{ $2->packagep($1);
$$ = GRAMMARP->createArray($2, $3, true); }
| package_scopeIdFollowsE idRefDType parameter_value_assignmentClass packed_dimensionListE
{ $2->packagep($1);
BBUNSUP($3->fileline(), "Unsupported: Parameter classes");
$$ = GRAMMARP->createArray($2, $4, true); }
2009-05-08 00:28:05 +02:00
;
2009-11-05 15:57:23 +01:00
data_typeBasic<dtypep>: // IEEE: part of data_type
2010-04-10 02:40:41 +02:00
integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); }
2009-11-05 15:57:23 +01:00
| integer_atom_type signingE { $1->setSignedState($2); $$ = $1; }
2011-07-24 21:01:51 +02:00
| non_integer_type { $$ = $1; }
2009-11-02 14:06:04 +01:00
;
2009-11-05 15:57:23 +01:00
data_typeNoRef<dtypep>: // ==IEEE: data_type, excluding class_type etc references
2009-11-02 14:06:04 +01:00
data_typeBasic { $$ = $1; }
2014-06-15 17:18:47 +02:00
| struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->s_modTypeImpNum++),
SYMP,VFlagChildDType(),$1),$2,true); }
| enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->s_modTypeImpNum++),
SYMP,VFlagChildDType(),$1); }
2009-12-04 13:05:44 +01:00
| ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
2009-11-24 15:11:25 +01:00
| yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
2020-04-25 21:37:46 +02:00
| yEVENT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::EVENTVALUE); }
2019-12-23 21:03:04 +01:00
// // Rules overlap virtual_interface_declaration
// // Parameters here are SV2009
// // IEEE has ['.' modport] but that will conflict with port
// // declarations which decode '.' modport themselves, so
// // instead see data_typeVar
| yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { $$ = NULL; BBUNSUP($1, "Unsupported: virtual interface"); }
| yVIRTUAL__anyID id/*interface*/ { $$ = NULL; BBUNSUP($1, "Unsupported: virtual data type"); }
2020-01-26 16:28:13 +01:00
| type_reference { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: class_scope: see data_type above
// // IEEE: class_type: see data_type above
// // IEEE: ps_covergroup: see data_type above
;
2013-02-02 15:33:04 +01:00
data_type_or_void<dtypep>: // ==IEEE: data_type_or_void
data_type { $$ = $1; }
2012-07-29 16:16:20 +02:00
//UNSUP yVOID { UNSUP } // No yTAGGED structures
;
2013-02-02 15:33:04 +01:00
var_data_type<dtypep>: // ==IEEE: var_data_type
data_type { $$ = $1; }
| yVAR data_type { $$ = $2; }
| yVAR implicit_typeE { $$ = $2; }
;
2020-01-26 16:28:13 +01:00
type_reference<dtypep>: // ==IEEE: type_reference
yTYPE '(' exprOrDataType ')' { $$ = new AstRefDType($1, AstRefDType::FlagTypeOfExpr(), $3); }
;
2019-12-23 21:03:04 +01:00
2019-12-17 04:46:09 +01:00
struct_unionDecl<uorstructp>: // IEEE: part of data_type
2012-07-29 16:16:20 +02:00
// // packedSigningE is NOP for unpacked
2019-12-17 04:46:09 +01:00
ySTRUCT packedSigningE '{' { $<uorstructp>$ = new AstStructDType($1, $2); SYMP->pushNew($<uorstructp>$); }
2012-07-29 16:16:20 +02:00
/*cont*/ struct_union_memberList '}'
2019-12-17 04:46:09 +01:00
{ $$=$<uorstructp>4; $$->addMembersp($5); SYMP->popScope($$); }
| yUNION taggedE packedSigningE '{' { $<uorstructp>$ = new AstUnionDType($1, $3); SYMP->pushNew($<uorstructp>$); }
2012-07-29 16:16:20 +02:00
/*cont*/ struct_union_memberList '}'
2019-12-17 04:46:09 +01:00
{ $$=$<uorstructp>5; $$->addMembersp($6); SYMP->popScope($$); }
2012-07-29 16:16:20 +02:00
;
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");
2018-03-10 23:44:17 +01:00
$$ = new AstMemberDType($<fl>1, *$1, VFlagChildDType(),
AstNodeDType::cloneTreeNull(GRAMMARP->m_memDTypep, true));
2017-10-06 13:33:52 +02:00
PARSEP->tagNodep($$);
}
2012-07-29 16:16:20 +02:00
| id variable_dimensionListE '=' variable_declExpr
2019-10-28 23:46:13 +01:00
{ $4->v3error("Unsupported: Initial values in struct/union members.");
2020-03-31 02:09:55 +02:00
// But still need error if packed according to IEEE 7.2.2
2019-10-28 23:46:13 +01:00
$$ = NULL; }
2012-07-29 16:16:20 +02:00
| 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
2019-12-23 21:03:04 +01:00
| '=' class_new { NULL; BBUNSUP($1, "Unsupported: member declaration assignment with new()"); }
2012-07-29 16:16:20 +02:00
;
2009-05-08 00:28:05 +02: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 03:12:31 +01:00
{ $$ = VARDONEA($<fl>1,*$1,$2,$3); }
2009-05-08 00:28:05 +02:00
| id variable_dimensionListE sigAttrListE '=' variable_declExpr
2011-01-19 03:12:31 +01:00
{ $$ = VARDONEA($<fl>1,*$1,$2,$3); $$->valuep($5); }
2009-09-07 21:54:12 +02:00
| idSVKwd { $$ = NULL; }
2009-05-08 00:28:05 +02: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
2019-12-23 21:03:04 +01:00
| '=' class_new { NULL; BBUNSUP($1, "Unsupported: declaration assignment with new()"); }
2009-05-08 00:28:05 +02:00
;
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 13:49:19 +02:00
id variable_dimensionListE sigAttrListE
2011-01-19 03:12:31 +01:00
{ $$ = VARDONEA($<fl>1,*$1, $2, $3); }
2009-05-19 13:49:19 +02:00
| id variable_dimensionListE sigAttrListE '=' expr
2011-01-19 03:12:31 +01:00
{ $$ = VARDONEA($<fl>1,*$1, $2, $3);
2019-07-13 18:01:26 +02:00
$$->addNext(new AstAssign($4, new AstVarRef($<fl>1, *$1, true), $5)); }
2009-05-08 00:28:05 +02:00
;
variable_declExpr<nodep>: // IEEE: part of variable_decl_assignment - rhs of expr
expr { $$ = $1; }
2019-12-23 21:03:04 +01:00
| dynamic_array_new { $$ = $1; }
| class_new { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
variable_dimensionListE<rangep>: // IEEE: variable_dimension + empty
/*empty*/ { $$ = NULL; }
| variable_dimensionList { $$ = $1; }
;
variable_dimensionList<rangep>: // IEEE: variable_dimension + empty
variable_dimension { $$ = $1; }
2018-02-02 03:32:58 +01:00
| variable_dimensionList variable_dimension { $$ = VN_CAST($1->addNext($2), NodeRange); }
2009-05-08 00:28:05 +02:00
;
variable_dimension<rangep>: // ==IEEE: variable_dimension
// // IEEE: unsized_dimension
2017-12-17 22:28:58 +01:00
'[' ']' { $$ = new AstUnsizedRange($1); }
2009-05-08 00:28:05 +02:00
// // IEEE: unpacked_dimension
2017-12-17 22:28:58 +01:00
| anyrange { $$ = $1; }
2019-12-01 18:35:49 +01:00
| '[' constExpr ']' { if (VN_IS($2, Unbounded)) { $2->deleteTree(); $$ = new AstQueueRange($1); }
else { $$ = new AstRange($1, new AstConst($1, 0),
new AstSub($1, $2, new AstConst($1, 1))); } }
2009-05-08 00:28:05 +02:00
// // IEEE: associative_dimension
2019-12-01 17:52:48 +01:00
| '[' data_type ']' { $$ = new AstAssocRange($1, $2); }
| yP_BRASTAR ']' { $$ = NULL; v3error("Unsupported: [*] wildcard associative arrays"); }
| '[' '*' ']' { $$ = NULL; v3error("Unsupported: [*] wildcard associative arrays"); }
2009-05-08 00:28:05 +02:00
// // IEEE: queue_dimension
2019-12-01 18:35:49 +01:00
// // '[' '$' ']' -- $ is part of expr, see '[' constExpr ']'
2009-05-08 00:28:05 +02:00
// // '[' '$' ':' expr ']' -- anyrange:expr:$
;
2012-07-29 16:16:20 +02: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>:
2020-04-20 03:19:09 +02:00
// // VSigning::NOSIGN overloaded to indicate not packed
/*empty*/ { $$ = VSigning::NOSIGN; }
| yPACKED signingE { $$ = $2; if ($$ == VSigning::NOSIGN) $$ = VSigning::UNSIGNED; }
2012-07-29 16:16:20 +02:00
;
2009-12-27 14:29:55 +01:00
//************************************************
// enum
// IEEE: part of data_type
enumDecl<dtypep>:
2012-03-31 17:22:19 +02:00
yENUM enum_base_typeE '{' enum_nameList '}' { $$ = new AstEnumDType($1,VFlagChildDType(),$2,$4); }
2009-12-27 14:29:55 +01:00
;
enum_base_typeE<dtypep>: // IEEE: enum_base_type
2019-06-12 02:20:04 +02:00
/* empty */ { $$ = new AstBasicDType(CRELINE(), AstBasicDTypeKwd::INT); }
2009-12-27 14:29:55 +01:00
// // Not in spec, but obviously "enum [1:0]" should work
// // implicit_type expanded, without empty
2013-01-14 04:18:57 +01: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 14:29:55 +01:00
| signing { $$ = new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $1); }
//
| integer_atom_type signingE { $1->setSignedState($2); $$ = $1; }
2013-01-14 04:18:57 +01:00
| integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); }
2012-02-24 04:09:51 +01:00
// // below can be idAny or yaID__aTYPE
// // IEEE requires a type, though no shift conflict if idAny
2020-03-24 22:57:12 +01:00
// // IEEE: type_identifier [ packed_dimension ]
// // however other simulators allow [ class_scope | package_scope ] type_identifier
| idAny rangeListE
{ $$ = GRAMMARP->createArray(new AstRefDType($<fl>1, *$1), $2, true); }
| package_scopeIdFollows idRefDType rangeListE
{ $2->packagep($1); $$ = GRAMMARP->createArray($2, $3, true); }
2009-12-27 14:29:55 +01: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; }
2017-09-13 00:53:57 +02:00
| '[' intnumAsConst ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstConst($1, $2->toSInt()-1)); }
2009-12-27 14:29:55 +01:00
| '[' intnumAsConst ':' intnumAsConst ']' { $$ = new AstRange($1,$2,$4); }
;
enumNameStartE<nodep>: // IEEE: third part of enum_name_declaration
/* empty */ { $$ = NULL; }
| '=' constExpr { $$ = $2; }
;
2017-09-13 00:53:57 +02:00
intnumAsConst<constp>:
2009-12-27 14:29:55 +01:00
yaINTNUM { $$ = new AstConst($<fl>1,*$1); }
;
2009-05-08 00:28:05 +02:00
//************************************************
// Typedef
data_declaration<nodep>: // ==IEEE: data_declaration
2009-05-19 13:49:19 +02:00
// // VARRESET can't be called here - conflicts
2009-05-08 00:28:05 +02:00
data_declarationVar { $$ = $1; }
2009-11-07 05:16:06 +01:00
| type_declaration { $$ = $1; }
2009-11-10 01:07:59 +01:00
| package_import_declaration { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: virtual_interface_declaration
// // "yVIRTUAL yID yID" looks just like a data_declaration
// // Therefore the virtual_interface_declaration term isn't used
2019-12-24 22:15:48 +01:00
// // 1800-2009:
//UNSUP net_type_declaration { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
2019-12-23 21:03:04 +01:00
class_property<nodep>: // ==IEEE: class_property, which is {property_qualifier} data_declaration
memberQualResetListE data_declarationVarClass { $$ = $2; }
| memberQualResetListE type_declaration { $$ = $2; }
| memberQualResetListE package_import_declaration { $$ = $2; }
// // 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 13:49:19 +02:00
data_declarationVar<nodep>: // IEEE: part of data_declaration
2009-05-08 00:28:05 +02:00
// // The first declaration has complications between assuming what's the type vs ID declaring
2012-12-31 19:43:54 +01:00
data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; }
2009-05-08 00:28:05 +02:00
;
2019-12-23 21:03:04 +01:00
data_declarationVarClass<nodep>: // IEEE: part of data_declaration (for class_property)
// // The first declaration has complications between assuming what's the type vs ID declaring
data_declarationVarFrontClass list_of_variable_decl_assignments ';' { $$ = $2; }
;
2009-05-08 00:28:05 +02:00
data_declarationVarFront: // IEEE: part of data_declaration
2019-11-06 02:42:49 +01:00
// // Non-ANSI; used inside block followed by ';'
// // SEE ALSO port_declaration, tf_port_declaration, port
//
2011-07-02 18:45:26 +02:00
// // Expanded: "constE yVAR lifetimeE data_type"
2009-05-08 00:28:05 +02:00
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
2020-04-26 18:45:06 +02:00
/**/ yVAR lifetimeE data_type
{ VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); }
| /**/ yVAR lifetimeE
{ VARRESET_NONLIST(VAR); VARLIFE($2);
VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT)); }
| /**/ yVAR lifetimeE signingE rangeList
{ /*VARRESET-in-ddVar*/ VARLIFE($2);
VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true)); }
2011-07-02 18:45:26 +02:00
//
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
2020-04-26 18:45:06 +02:00
| yCONST__ETC yVAR lifetimeE data_type
{ VARRESET_NONLIST(VAR); VARLIFE($3);
VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), $4)); }
| yCONST__ETC yVAR lifetimeE
{ VARRESET_NONLIST(VAR); VARLIFE($3);
VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), new AstBasicDType($<fl>2, LOGIC_IMPLICIT))); }
| yCONST__ETC yVAR lifetimeE signingE rangeList
{ VARRESET_NONLIST(VAR); VARLIFE($3);
VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(),
GRAMMARP->addRange(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $4), $5,true))); }
2009-05-08 00:28:05 +02:00
//
// // Expanded: "constE lifetimeE data_type"
2012-12-31 19:43:54 +01:00
| /**/ data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
2020-04-26 18:45:06 +02:00
| /**/ lifetime data_type { VARRESET_NONLIST(VAR); VARLIFE($1); VARDTYPE($2); }
| yCONST__ETC lifetimeE data_type
{ VARRESET_NONLIST(VAR); VARLIFE($2);
VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), $3)); }
2009-05-08 00:28:05 +02:00
// // = class_new is in variable_decl_assignment
;
2019-12-23 21:03:04 +01:00
data_declarationVarFrontClass: // IEEE: part of data_declaration (for class_property)
// // VARRESET called before this rule
// // yCONST is removed, added to memberQual rules
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
2020-04-26 18:45:06 +02:00
yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); }
| yVAR lifetimeE { VARRESET_NONLIST(VAR); VARLIFE($2); }
| yVAR lifetimeE signingE rangeList
{ /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true));
VARLIFE($2); }
2019-12-23 21:03:04 +01:00
//
// // Expanded: "constE lifetimeE data_type"
| data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
// // lifetime is removed, added to memberQual rules to avoid conflict
// // yCONST is removed, added to memberQual rules to avoid conflict
// // = class_new is in variable_decl_assignment
;
2019-12-24 22:15:48 +01:00
//UNSUPnet_type_declaration: // IEEE: net_type_declaration
//UNSUP yNETTYPE data_type idAny/*net_type_identifier*/ ';' { }
//UNSUP // // package_scope part of data_type
//UNSUP | yNETTYPE data_type idAny yWITH__ETC package_scopeIdFollows id/*tf_identifier*/ ';' { }
//UNSUP | yNETTYPE package_scopeIdFollows id/*net_type_identifier*/ idAny/*net_type_identifier*/ ';' { }
//UNSUP ;
2009-12-18 02:58:14 +01:00
implicit_typeE<dtypep>: // IEEE: part of *data_type_or_implicit
2009-05-08 00:28:05 +02:00
// // Also expanded in data_declaration
/* empty */ { $$ = NULL; }
2013-01-14 04:18:57 +01:00
| signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); }
2009-11-05 15:57:23 +01:00
| signing { $$ = new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $1); }
2006-08-26 13:35:28 +02:00
;
2019-12-23 22:26:59 +01:00
//UNSUPassertion_variable_declaration: // IEEE: assertion_variable_declaration
//UNSUP // // IEEE: var_data_type expanded
//UNSUP var_data_type list_of_variable_decl_assignments ';' { }
//UNSUP ;
2009-11-07 05:16:06 +01:00
type_declaration<nodep>: // ==IEEE: type_declaration
// // Use idAny, as we can redeclare a typedef on an existing typedef
2014-11-07 13:50:11 +01:00
yTYPEDEF data_type idAny variable_dimensionListE dtypeAttrListE ';'
2019-07-13 18:01:26 +02:00
/**/ { $$ = new AstTypedef($<fl>3, *$3, $5, VFlagChildDType(), GRAMMARP->createArray($2,$4,false));
2017-11-14 00:04:13 +01:00
SYMP->reinsert($$); PARSEP->tagNodep($$); }
2019-11-17 15:01:41 +01:00
| yTYPEDEF id/*interface*/ '.' idAny/*type*/ idAny/*type*/ ';' { $$ = NULL; BBUNSUP($1, "Unsupported: SystemVerilog 2005 typedef in this context"); }
2009-11-07 05:16:06 +01:00
// // 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
2020-05-10 17:01:57 +02:00
//UNSUP // Below should be idAny to allow duplicate forward defs; need to expand
// // data_type to exclude IDs, or add id__SEMI rule
2019-07-13 18:01:26 +02:00
| yTYPEDEF id ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>2, *$2); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF yENUM idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF ySTRUCT idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF yUNION idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
2019-12-23 21:03:04 +01:00
| yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF yINTERFACE yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>4, *$4); SYMP->reinsert($$); PARSEP->tagNodep($$); }
2009-11-07 05:16:06 +01:00
;
2014-11-07 13:50:11 +01:00
dtypeAttrListE<nodep>:
/* empty */ { $$ = NULL; }
| dtypeAttrList { $$ = $1; }
;
dtypeAttrList<nodep>:
dtypeAttr { $$ = $1; }
| dtypeAttrList dtypeAttr { $$ = $1->addNextNull($2); }
;
dtypeAttr<nodep>:
yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::DT_PUBLIC); }
;
2006-08-26 13:35:28 +02:00
//************************************************
2007-05-14 22:59:58 +02:00
// Module Items
2006-08-26 13:35:28 +02:00
2009-01-25 03:36:14 +01:00
module_itemListE<nodep>: // IEEE: Part of module_declaration
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2009-01-25 03:36:14 +01:00
| module_itemList { $$ = $1; }
2006-08-26 13:35:28 +02:00
;
2009-01-25 03:36:14 +01:00
module_itemList<nodep>: // IEEE: Part of module_declaration
module_item { $$ = $1; }
| module_itemList module_item { $$ = $1->addNextNull($2); }
2006-08-26 13:35:28 +02:00
;
2009-01-25 03:36:14 +01:00
module_item<nodep>: // ==IEEE: module_item
2009-05-08 00:28:05 +02:00
port_declaration ';' { $$ = $1; }
| non_port_module_item { $$ = $1; }
;
non_port_module_item<nodep>: // ==IEEE: non_port_module_item
2009-01-25 03:36:14 +01:00
generate_region { $$ = $1; }
2009-01-28 21:27:41 +01:00
| module_or_generate_item { $$ = $1; }
| specify_block { $$ = $1; }
2009-05-08 00:28:05 +02:00
| specparam_declaration { $$ = $1; }
2019-06-01 03:05:50 +02:00
| program_declaration { $$ = NULL; v3error("Unsupported: program decls within module decls"); }
| module_declaration { $$ = NULL; v3error("Unsupported: module decls within module decls"); }
| interface_declaration { $$ = NULL; v3error("Unsupported: interface decls within module decls"); }
2009-11-07 05:16:06 +01:00
| timeunits_declaration { $$ = $1; }
2009-01-25 03:36:14 +01:00
// // Verilator specific
2009-10-31 15:08:38 +01: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 13:35:28 +02:00
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
2012-10-30 08:02:35 +01:00
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); v3Global.dpi(true); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02: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 03:20:13 +02:00
| combinational_body { $$ = $1; }
// // This module_common_item shared with interface_or_generate_item:module_common_item
2009-05-08 00:28:05 +02: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; }
2019-05-31 13:33:57 +02:00
| assertion_item { $$ = $1; }
2013-01-15 05:19:44 +01:00
| bind_directive { $$ = $1; }
2009-01-28 21:27:41 +01:00
| continuous_assign { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: net_alias
2019-06-01 03:05:50 +02:00
| yALIAS variable_lvalue aliasEqList ';' { $$ = NULL; BBUNSUP($1, "Unsupported: alias statements"); }
2009-01-28 21:27:41 +01:00
| initial_construct { $$ = $1; }
| final_construct { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: always_construct
// // Verilator only - event_control attached to always
2013-05-01 04:55:28 +02: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_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); }
2017-12-14 01:49:37 +01:00
| yALWAYS_COMB stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_COMB, NULL, $2); }
2019-06-02 01:40:06 +02:00
//
2009-05-08 00:28:05 +02:00
| loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
2017-11-22 03:10:42 +01:00
| elaboration_system_task { $$ = $1; }
2009-05-08 00:28:05 +02:00
//
| error ';' { $$ = NULL; }
2009-01-28 21:27:41 +01:00
;
2009-01-25 03:36:14 +01:00
2009-01-28 21:27:41 +01:00
continuous_assign<nodep>: // IEEE: continuous_assign
2019-06-02 01:40:06 +02:00
yASSIGN strengthSpecE delayE assignList ';' { $$ = $4; }
2009-01-28 21:27:41 +01: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 13:35:28 +02:00
;
2009-05-08 00:28:05 +02: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; }
2019-06-01 03:05:50 +02:00
| yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';' { $$ = NULL; BBUNSUP($1, "Unsupported: default clocking identifier"); }
2019-06-02 01:40:06 +02:00
//UNSUP yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { }
2019-06-01 03:05:50 +02:00
;
aliasEqList: // IEEE: part of net_alias
'=' variable_lvalue { }
| aliasEqList '=' variable_lvalue { }
2009-05-08 00:28:05 +02:00
;
2013-01-15 05:19:44 +01: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
2019-07-13 18:01:26 +02:00
yBIND bind_target_instance bind_instantiation { $$ = new AstBind($<fl>2, *$2, $3); }
2019-12-23 21:03:04 +01:00
| yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation
{ $$ = NULL; BBUNSUP($1, "Unsupported: Bind with instance list"); }
2013-01-15 05:19:44 +01:00
;
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 13:35:28 +02:00
//************************************************
2007-05-14 22:59:58 +02:00
// Generates
2012-10-09 03:20:13 +02: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 13:35:28 +02:00
2012-03-23 13:49:47 +01:00
generate_region<nodep>: // ==IEEE: generate_region
2020-02-26 00:57:51 +01:00
yGENERATE ~c~genItemList yENDGENERATE { $$ = $2; }
2012-03-23 13:49:47 +01:00
| yGENERATE yENDGENERATE { $$ = NULL; }
;
2019-12-24 22:15:48 +01:00
//UNSUPc_generate_region<nodep>: // IEEE: generate_region (for checkers)
//UNSUP BISONPRE_COPY(generate_region,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2020-02-26 00:57:51 +01:00
generate_block_or_null<nodep>: // IEEE: generate_block_or_null (called from gencase/genif/genfor)
2009-05-08 00:28:05 +02:00
// ';' // is included in
// // IEEE: generate_block
2012-07-21 23:12:42 +02:00
// // Must always return a BEGIN node, or NULL - see GenFor construction
2020-02-26 04:21:16 +01:00
generate_item { $$ = $1 ? (new AstBegin($1->fileline(),"",$1,true,true)) : NULL; }
2006-08-26 13:35:28 +02:00
| genItemBegin { $$ = $1; }
;
2009-01-25 03:36:14 +01:00
genItemBegin<nodep>: // IEEE: part of generate_block
2020-02-26 04:21:16 +01:00
yBEGIN ~c~genItemList yEND { $$ = new AstBegin($1,"",$2,true,false); }
2007-05-12 18:29:25 +02:00
| yBEGIN yEND { $$ = NULL; }
2020-02-26 00:57:51 +01:00
| id ':' yBEGIN ~c~genItemList yEND endLabelE
2020-02-26 04:21:16 +01:00
{ $$ = new AstBegin($<fl>1,*$1,$4,true,false); GRAMMARP->endLabel($<fl>6,*$1,$6); }
2019-12-24 22:15:48 +01:00
| id ':' yBEGIN yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$1,$5); }
2020-02-26 00:57:51 +01:00
| yBEGIN ':' idAny ~c~genItemList yEND endLabelE
2020-02-26 04:21:16 +01:00
{ $$ = new AstBegin($<fl>3,*$3,$4,true,false); GRAMMARP->endLabel($<fl>6,*$3,$6); }
2019-12-24 22:15:48 +01:00
| yBEGIN ':' idAny yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$3,$5); }
2006-08-26 13:35:28 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_genItemBegin<nodep>: // IEEE: part of generate_block (for checkers)
//UNSUP BISONPRE_COPY(genItemBegin,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2012-03-23 13:49:47 +01:00
genItemOrBegin<nodep>: // Not in IEEE, but our begin isn't under generate_item
2012-10-09 03:20:13 +02:00
~c~generate_item { $$ = $1; }
| ~c~genItemBegin { $$ = $1; }
2012-03-23 13:49:47 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_genItemOrBegin<nodep>: // (for checkers)
//UNSUP BISONPRE_COPY(genItemOrBegin,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2008-08-06 18:35:34 +02:00
genItemList<nodep>:
2012-10-09 03:20:13 +02:00
~c~genItemOrBegin { $$ = $1; }
| ~c~genItemList ~c~genItemOrBegin { $$ = $1->addNextNull($2); }
2006-08-26 13:35:28 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_genItemList<nodep>: // (for checkers)
//UNSUP BISONPRE_COPY(genItemList,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2012-03-23 13:49:47 +01: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 21:27:41 +01:00
module_or_generate_item { $$ = $1; }
2012-03-23 13:49:47 +01:00
// // Only legal when in a generate under an interface
2009-05-08 00:28:05 +02:00
//UNSUP interface_or_generate_item { $$ = $1; }
2012-10-09 02:45:39 +02:00
// // IEEE: checker_or_generate_item
// // Only legal when in a generate under a checker
// // so below in c_generate_item
2009-01-28 21:27:41 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_generate_item<nodep>: // IEEE: generate_item (for checkers)
//UNSUP checker_or_generate_item { $$ = $1; }
//UNSUP ;
2009-01-28 21:27:41 +01:00
conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
2019-12-24 22:15:48 +01:00
yCASE '(' expr ')' ~c~case_generate_itemListE yENDCASE
{ $$ = new AstGenCase($1, $3, $5); }
| yIF '(' expr ')' ~c~generate_block_or_null %prec prLOWER_THAN_ELSE
{ $$ = new AstGenIf($1, $3, $5, NULL); }
| yIF '(' expr ')' ~c~generate_block_or_null yELSE ~c~generate_block_or_null
{ $$ = new AstGenIf($1, $3, $5, $7); }
2009-01-28 21:27:41 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_conditional_generate_construct<nodep>: // IEEE: conditional_generate_construct (for checkers)
//UNSUP BISONPRE_COPY(conditional_generate_construct,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2009-01-28 21:27:41 +01:00
loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
2012-10-09 03:20:13 +02:00
yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null
2012-07-21 23:12:42 +02:00
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
2018-02-02 03:32:58 +01:00
AstBegin* lowerBegp = VN_CAST($9, Begin);
2019-07-06 18:57:50 +02:00
UASSERT_OBJ(!($9 && !lowerBegp), $9, "Child of GENFOR should have been begin");
2020-02-26 04:21:16 +01:00
if (!lowerBegp) lowerBegp = new AstBegin($1, "genblk", NULL, true, true); // Empty body
2012-07-21 23:12:42 +02:00
AstNode* lowerNoBegp = lowerBegp->stmtsp();
if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext();
//
2020-02-26 04:21:16 +01:00
AstBegin* blkp = new AstBegin($1, lowerBegp->name(), NULL, true, true);
2012-07-21 23:12:42 +02:00
// V3LinkDot detects BEGIN(GENFOR(...)) as a special case
2011-11-30 00:23:18 +01:00
AstNode* initp = $3; AstNode* varp = $3;
2018-02-02 03:32:58 +01:00
if (VN_IS(varp, Var)) { // Genvar
2011-11-30 00:23:18 +01:00
initp = varp->nextp();
initp->unlinkFrBackWithNext(); // Detach 2nd from varp, make 1st init
blkp->addStmtsp(varp);
}
2012-07-21 23:12:42 +02:00
// Statements are under 'genforp' as cells under this
2011-11-30 00:23:18 +01:00
// for loop won't get an extra layer of hierarchy tacked on
2012-07-21 23:12:42 +02:00
blkp->addGenforp(new AstGenFor($1,initp,$5,$7,lowerNoBegp));
$$ = blkp;
2020-01-17 02:17:11 +01:00
VL_DO_DANGLING(lowerBegp->deleteTree(), lowerBegp);
2012-07-21 23:12:42 +02:00
}
2009-05-08 00:28:05 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_loop_generate_construct<nodep>: // IEEE: loop_generate_construct (for checkers)
//UNSUP BISONPRE_COPY(loop_generate_construct,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2019-09-12 13:22:22 +02:00
genvar_initialization<nodep>: // ==IEEE: genvar_initialization
2009-05-08 00:28:05 +02:00
varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); }
2019-07-13 18:01:26 +02:00
| yGENVAR genvar_identifierDecl '=' constExpr { $$ = $2; $2->addNext(new AstAssign($3,new AstVarRef($2->fileline(),$2,true), $4)); }
2009-05-08 00:28:05 +02:00
;
genvar_iteration<nodep>: // ==IEEE: genvar_iteration
2009-09-16 16:32:14 +02: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-08 00:28:05 +02:00
// // inc_or_dec_operator
2018-06-22 12:35:27 +02:00
// When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstNodeMathStmt?
2019-05-10 02:03:19 +02:00
| yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true), new AstConst($1, AstConst::StringToParse(), "'b1"))); }
| yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true), new AstConst($1, AstConst::StringToParse(), "'b1"))); }
| varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true), new AstConst($2, AstConst::StringToParse(), "'b1"))); }
| varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true), new AstConst($2, AstConst::StringToParse(), "'b1"))); }
2006-08-26 13:35:28 +02:00
;
2009-01-28 21:27:41 +01:00
case_generate_itemListE<nodep>: // IEEE: [{ case_generate_itemList }]
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2009-01-28 21:27:41 +01:00
| case_generate_itemList { $$ = $1; }
2007-05-18 16:03:50 +02:00
;
2009-01-28 21:27:41 +01:00
case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
2012-10-09 03:20:13 +02:00
~c~case_generate_item { $$=$1; }
| ~c~case_generate_itemList ~c~case_generate_item { $$=$1; $1->addNext($2); }
2009-01-28 21:27:41 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_case_generate_itemList<nodep>: // IEEE: { case_generate_item } (for checkers)
//UNSUP BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2009-01-28 21:27:41 +01:00
case_generate_item<nodep>: // ==IEEE: case_generate_item
caseCondList ':' generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); }
2019-07-13 18:01:26 +02:00
| yDEFAULT ':' generate_block_or_null { $$ = new AstCaseItem($1,NULL,$3); }
2009-01-28 21:27:41 +01:00
| yDEFAULT generate_block_or_null { $$ = new AstCaseItem($1,NULL,$2); }
2006-08-26 13:35:28 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPc_case_generate_item<nodep>: // IEEE: case_generate_item (for checkers)
//UNSUP BISONPRE_COPY(case_generate_item,{s/~c~/c_/g}) // {copied}
//UNSUP ;
2006-08-26 13:35:28 +02:00
//************************************************
2007-05-14 22:59:58 +02:00
// Assignments and register declarations
2006-08-26 13:35:28 +02:00
2008-08-06 18:35:34 +02:00
assignList<nodep>:
assignOne { $$ = $1; }
2006-08-26 13:35:28 +02:00
| assignList ',' assignOne { $$ = $1->addNext($3); }
;
2008-08-06 18:35:34 +02:00
assignOne<nodep>:
2009-05-08 00:28:05 +02:00
variable_lvalue '=' expr { $$ = new AstAssignW($2,$1,$3); }
2006-08-26 13:35:28 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPdelay_or_event_controlE<nodep>: // IEEE: delay_or_event_control plus empty
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | delay_control { $$ = $1; }
//UNSUP | event_control { $$ = $1; }
//UNSUP | yREPEAT '(' expr ')' event_control { }
//UNSUP ;
2009-01-25 03:36:14 +01:00
delayE:
/* empty */ { }
2020-04-23 03:31:40 +02:00
| delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); DEL($1); } /* ignored */
2007-05-16 20:19:23 +02:00
;
2020-04-23 03:31:40 +02:00
delay_control<nodep>: //== IEEE: delay_control
'#' delay_value { $$ = $2; }
| '#' '(' minTypMax ')' { $$ = $3; }
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $3; DEL($5); }
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $3; DEL($5); DEL($7); }
2006-08-26 13:35:28 +02:00
;
2020-04-23 03:31:40 +02:00
delay_value<nodep>: // ==IEEE:delay_value
2009-05-08 00:28:05 +02:00
// // IEEE: ps_identifier
2020-04-23 03:31:40 +02:00
ps_id_etc { $$ = $1; }
| yaINTNUM { $$ = new AstConst($<fl>1, *$1); }
| yaFLOATNUM { $$ = new AstConst($<fl>1, AstConst::RealDouble(), $1); }
| timeNumAdjusted { $$ = $1; }
2006-08-26 13:35:28 +02:00
;
2020-04-23 03:31:40 +02:00
delayExpr<nodep>:
expr { $$ = $1; }
2007-05-16 20:19:23 +02:00
;
2020-04-23 03:31:40 +02:00
minTypMax<nodep>: // IEEE: mintypmax_expression and constant_mintypmax_expression
delayExpr { $$ = $1; }
2020-05-06 02:42:19 +02:00
| delayExpr ':' delayExpr ':' delayExpr { $$ = $3; DEL($1); DEL($5); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
netSigList<varp>: // IEEE: list_of_port_identifiers
2008-08-06 18:35:34 +02:00
netSig { $$ = $1; }
2007-05-14 22:59:58 +02:00
| netSigList ',' netSig { $$ = $1; $1->addNext($3); }
;
2009-05-08 00:28:05 +02:00
netSig<varp>: // IEEE: net_decl_assignment - one element from list_of_port_identifiers
2011-01-19 03:12:31 +01:00
netId sigAttrListE { $$ = VARDONEA($<fl>1,*$1, NULL, $2); }
2019-07-13 18:01:26 +02:00
| netId sigAttrListE '=' expr { $$ = VARDONEA($<fl>1,*$1, NULL, $2);
$$->addNext(new AstAssignW($3, new AstVarRef($<fl>1, *$1, true), $4)); }
2013-12-15 01:50:55 +01:00
| netId variable_dimensionList sigAttrListE { $$ = VARDONEA($<fl>1,*$1, $2, $3); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
netId<strp>:
2011-01-19 03:12:31 +01:00
id/*new-net*/ { $$ = $1; $<fl>$=$<fl>1; }
| idSVKwd { $$ = $1; $<fl>$=$<fl>1; }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
sigAttrListE<nodep>:
/* empty */ { $$ = NULL; }
| sigAttrList { $$ = $1; }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
sigAttrList<nodep>:
sigAttr { $$ = $1; }
| sigAttrList sigAttr { $$ = $1->addNextNull($2); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
sigAttr<nodep>:
yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); }
2015-03-13 00:20:46 +01:00
| yVL_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCKER); }
| yVL_NO_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_NO_CLOCKER); }
2009-05-08 00:28:05 +02:00
| yVL_CLOCK_ENABLE { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK_ENABLE); }
2012-10-30 08:02:35 +01: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); }
2014-05-16 02:57:09 +02:00
| yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true);
2010-04-06 02:01:17 +02:00
$$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); }
2009-05-08 00:28:05 +02:00
| yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); }
2011-10-26 14:57:27 +02:00
| yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); }
2010-01-18 01:13:44 +01:00
| yVL_SFORMAT { $$ = new AstAttrOf($1,AstAttrType::VAR_SFORMAT); }
2020-02-29 01:15:08 +01:00
| yVL_SPLIT_VAR { $$ = new AstAttrOf($1,AstAttrType::VAR_SPLIT_VAR); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
rangeListE<rangep>: // IEEE: [{packed_dimension}]
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2006-08-26 13:35:28 +02:00
| rangeList { $$ = $1; }
;
2009-05-08 00:28:05 +02:00
rangeList<rangep>: // IEEE: {packed_dimension}
2008-08-06 18:35:34 +02:00
anyrange { $$ = $1; }
2006-08-26 13:35:28 +02:00
| rangeList anyrange { $$ = $1; $1->addNext($2); }
;
2019-12-23 22:26:59 +01:00
//UNSUPbit_selectE<fl>: // IEEE: constant_bit_select (IEEE included empty)
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | '[' constExpr ']' { $<fl>$=$<fl>1; $$ = "["+$2+"]"; }
//UNSUP ;
2009-05-08 00:28:05 +02:00
// IEEE: select
// Merged into more general idArray
2008-08-06 18:35:34 +02:00
anyrange<rangep>:
'[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
2006-08-26 13:35:28 +02:00
;
2009-11-13 02:33:50 +01:00
packed_dimensionListE<rangep>: // IEEE: [{ packed_dimension }]
2009-11-07 05:16:06 +01:00
/* empty */ { $$ = NULL; }
2009-11-13 02:33:50 +01:00
| packed_dimensionList { $$ = $1; }
;
packed_dimensionList<rangep>: // IEEE: { packed_dimension }
packed_dimension { $$ = $1; }
2018-02-02 03:32:58 +01:00
| packed_dimensionList packed_dimension { $$ = VN_CAST($1->addNext($2), NodeRange); }
2009-11-07 05:16:06 +01:00
;
packed_dimension<rangep>: // ==IEEE: packed_dimension
anyrange { $$ = $1; }
2019-06-01 03:05:50 +02:00
| '[' ']' { $$ = NULL; $<fl>1->v3error("Unsupported: [] dimensions"); }
2009-11-07 05:16:06 +01:00
;
2007-05-14 22:59:58 +02:00
//************************************************
2006-08-26 13:35:28 +02:00
// Parameters
2007-05-14 22:59:58 +02:00
2009-05-08 00:28:05 +02:00
param_assignment<varp>: // ==IEEE: param_assignment
// // IEEE: constant_param_expression
// // constant_param_expression: '$' is in expr
2020-03-21 17:13:55 +01:00
id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr
2014-04-02 05:16:16 +02:00
/**/ { $$ = VARDONEA($<fl>1,*$1, $2, $3); $$->valuep($5); }
2017-09-15 03:20:20 +02:00
| id/*new-parameter*/ variable_dimensionListE sigAttrListE
2019-05-01 01:16:41 +02:00
/**/ { $$ = VARDONEA($<fl>1,*$1, $2, $3);
if ($<fl>1->language() < V3LangCode::L1800_2009) {
$<fl>1->v3error("Parameter requires default value, or use IEEE 1800-2009 or later."); } }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02: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 13:35:28 +02:00
;
2020-03-21 17:13:55 +01:00
type_assignment<varp>: // ==IEEE: type_assignment
// // note exptOrDataType being a data_type is only for yPARAMETER yTYPE
idAny/*new-parameter*/ sigAttrListE '=' data_type
/**/ { $$ = VARDONEA($<fl>1,*$1, NULL, $2); $$->valuep($4); }
;
list_of_type_assignments<varp>: // ==IEEE: list_of_type_assignments
type_assignment { $$ = $1; }
| list_of_type_assignments ',' type_assignment { $$ = $1; $1->addNext($3); }
;
2009-01-25 03:36:14 +01:00
list_of_defparam_assignments<nodep>: //== IEEE: list_of_defparam_assignments
2009-01-15 19:58:43 +01:00
defparam_assignment { $$ = $1; }
| list_of_defparam_assignments ',' defparam_assignment { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2009-01-25 03:36:14 +01:00
defparam_assignment<nodep>: // ==IEEE: defparam_assignment
2009-05-08 00:28:05 +02:00
id '.' id '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); }
//UNSUP More general dotted identifiers
2006-08-26 13:35:28 +02:00
;
2007-05-14 22:59:58 +02:00
//************************************************
2006-08-26 13:35:28 +02:00
// Instances
2009-05-08 00:28:05 +02: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 02:45:39 +02:00
// checker_id name (pins) ; // checker_instantiation
2009-05-08 00:28:05 +02:00
etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_instantiation
instDecl { $$ = $1; }
| gateDecl { $$ = $1; }
2009-01-15 19:58:43 +01:00
;
2007-05-16 14:55:25 +02:00
2009-05-08 00:28:05 +02:00
instDecl<nodep>:
2019-07-14 21:06:49 +02:00
id parameter_value_assignmentE {INSTPREP($<fl>1,*$1,$2);} instnameList ';'
2015-02-22 17:41:10 +01:00
{ $$ = $4; GRAMMARP->m_impliedDecl=false;
2020-01-18 16:29:49 +01:00
if (GRAMMARP->m_instParamp) {
VL_DO_CLEAR(GRAMMARP->m_instParamp->deleteTree(),
GRAMMARP->m_instParamp = NULL);
} }
2015-01-17 21:35:45 +01:00
// // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers
| id/*interface*/ '.' id/*modport*/
{ VARRESET_NONLIST(AstVarType::IFACEREF);
2019-07-14 21:06:49 +02:00
VARDTYPE(new AstIfaceRefDType($<fl>1, $<fl>3, "", *$1, *$3)); }
2015-01-17 21:35:45 +01:00
mpInstnameList ';'
{ $$ = VARDONEP($5,NULL,NULL); }
2009-05-08 00:28:05 +02:00
//UNSUP: strengthSpecE for udp_instantiations
2006-08-26 13:35:28 +02:00
;
2015-01-17 21:35:45 +01:00
mpInstnameList<nodep>: // Similar to instnameList, but for modport instantiations which have no parenthesis
mpInstnameParen { $$ = $1; }
| mpInstnameList ',' mpInstnameParen { $$ = $1->addNext($3); }
;
mpInstnameParen<nodep>: // Similar to instnameParen, but for modport instantiations which have no parenthesis
2019-09-13 01:06:26 +02:00
id instRangeListE sigAttrListE { $$ = VARDONEA($<fl>1,*$1,$2,$3); }
2015-01-17 21:35:45 +01:00
;
2008-08-06 18:35:34 +02:00
instnameList<nodep>:
instnameParen { $$ = $1; }
2007-05-16 14:55:25 +02:00
| instnameList ',' instnameParen { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2014-11-08 20:15:10 +01:00
instnameParen<cellp>:
2015-02-22 17:41:10 +01:00
// // Must clone m_instParamp as may be comma'ed list of instances
2019-09-13 01:06:26 +02:00
id instRangeListE '(' cellpinList ')' { $$ = new AstCell($<fl>1, GRAMMARP->m_instModuleFl,
2019-07-14 21:06:49 +02:00
*$1, GRAMMARP->m_instModule, $4,
2018-03-10 23:44:17 +01:00
AstPin::cloneTreeNull(GRAMMARP->m_instParamp, true),
2017-12-17 22:28:58 +01:00
GRAMMARP->scrubRange($2));
2014-11-08 20:15:10 +01:00
$$->trace(GRAMMARP->allTracingOn($<fl>1)); }
2019-09-13 01:06:26 +02:00
| id instRangeListE { $$ = new AstCell($<fl>1, GRAMMARP->m_instModuleFl,
2019-07-14 21:06:49 +02:00
*$1, GRAMMARP->m_instModule, NULL,
2018-03-10 23:44:17 +01:00
AstPin::cloneTreeNull(GRAMMARP->m_instParamp, true),
2017-12-17 22:28:58 +01:00
GRAMMARP->scrubRange($2));
2014-11-08 20:15:10 +01:00
$$->trace(GRAMMARP->allTracingOn($<fl>1)); }
2019-09-13 01:06:26 +02:00
//UNSUP instRangeListE '(' cellpinList ')' { UNSUP } // UDP
2012-04-25 02:43:15 +02: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 20:19:23 +02:00
;
2019-09-13 01:06:26 +02:00
instRangeListE<rangep>:
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2019-09-13 01:06:26 +02:00
| instRangeList { $$ = $1; }
;
instRangeList<rangep>:
instRange { $$ = $1; }
| instRangeList instRange { $$ = VN_CAST($1->addNextNull($2), Range); }
;
instRange<rangep>:
'[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); }
2007-05-16 20:19:23 +02:00
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
2006-08-26 13:35:28 +02:00
;
2016-03-13 02:54:52 +01:00
cellparamList<pinp>:
{VARRESET_LIST(UNKNOWN);} cellparamItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
;
2008-08-06 18:35:34 +02:00
cellpinList<pinp>:
2009-05-08 00:28:05 +02:00
{VARRESET_LIST(UNKNOWN);} cellpinItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
2006-08-26 13:35:28 +02:00
;
2016-03-13 02:54:52 +01:00
cellparamItList<pinp>: // IEEE: list_of_parameter_assignmente
cellparamItemE { $$ = $1; }
2018-02-02 03:32:58 +01:00
| cellparamItList ',' cellparamItemE { $$ = VN_CAST($1->addNextNull($3), Pin); }
2016-03-13 02:54:52 +01:00
;
cellpinItList<pinp>: // IEEE: list_of_port_connections
2008-08-06 18:35:34 +02:00
cellpinItemE { $$ = $1; }
2018-02-02 03:32:58 +01:00
| cellpinItList ',' cellpinItemE { $$ = VN_CAST($1->addNextNull($3), Pin); }
2006-08-26 13:35:28 +02:00
;
2016-03-13 02:54:52 +01:00
cellparamItemE<pinp>: // IEEE: named_parameter_assignment + empty
2011-01-30 00:00:48 +01:00
// Note empty can match either () or (,); V3LinkCells cleans up ()
2019-06-12 02:20:04 +02:00
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(), PINNUMINC(), "", NULL); }
2009-05-08 00:28:05 +02:00
| yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); }
2019-07-13 18:01:26 +02:00
| '.' idSVKwd { $$ = new AstPin($<fl>2,PINNUMINC(), *$2,
2019-10-05 13:54:14 +02:00
new AstParseRef($<fl>2,VParseRefExp::PX_TEXT,*$2,NULL,NULL));
2019-07-13 18:01:26 +02:00
$$->svImplicit(true);}
| '.' idAny { $$ = new AstPin($<fl>2,PINNUMINC(), *$2,
2019-10-05 13:54:14 +02:00
new AstParseRef($<fl>2,VParseRefExp::PX_TEXT,*$2,NULL,NULL));
2019-07-13 18:01:26 +02:00
$$->svImplicit(true);}
| '.' idAny '(' ')' { $$ = new AstPin($<fl>2,PINNUMINC(),*$2,NULL); }
2010-04-07 00:55:54 +02:00
// // mintypmax is expanded here, as it might be a UDP or gate primitive
2019-07-13 18:01:26 +02:00
| '.' idAny '(' expr ')' { $$ = new AstPin($<fl>2,PINNUMINC(),*$2,$4); }
2010-04-07 00:55:54 +02:00
//UNSUP '.' idAny '(' expr ':' expr ')' { }
//UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { }
2009-05-08 00:28:05 +02:00
// // For parameters
2019-07-13 18:01:26 +02:00
| '.' idAny '(' data_type ')' { $$ = new AstPin($<fl>2, PINNUMINC(), *$2, $4); }
2009-05-08 00:28:05 +02:00
// // For parameters
2016-03-13 02:54:52 +01:00
| data_type { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
//
| expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); }
//UNSUP expr ':' expr { }
//UNSUP expr ':' expr ':' expr { }
;
cellpinItemE<pinp>: // IEEE: named_port_connection + empty
// Note empty can match either () or (,); V3LinkCells cleans up ()
2019-06-12 02:20:04 +02:00
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(), PINNUMINC(), "", NULL); }
2016-03-13 02:54:52 +01:00
| yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); }
2019-10-05 13:54:14 +02:00
| '.' idSVKwd { $$ = new AstPin($<fl>2,PINNUMINC(),*$2,new AstParseRef($<fl>2,VParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->svImplicit(true);}
| '.' idAny { $$ = new AstPin($<fl>2,PINNUMINC(),*$2,new AstParseRef($<fl>2,VParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->svImplicit(true);}
2019-07-13 18:01:26 +02:00
| '.' idAny '(' ')' { $$ = new AstPin($<fl>2,PINNUMINC(),*$2,NULL); }
2016-03-13 02:54:52 +01:00
// // mintypmax is expanded here, as it might be a UDP or gate primitive
2019-12-24 22:15:48 +01:00
//UNSUP pev_expr below
2019-07-13 18:01:26 +02:00
| '.' idAny '(' expr ')' { $$ = new AstPin($<fl>2,PINNUMINC(),*$2,$4); }
2019-12-24 22:15:48 +01:00
//UNSUP '.' idAny '(' pev_expr ':' expr ')' { }
//UNSUP '.' idAny '(' pev_expr ':' expr ':' expr ')' { }
2009-05-08 00:28:05 +02:00
//
2019-10-17 02:05:29 +02:00
| expr { $$ = new AstPin(FILELINE_OR_CRE($1),PINNUMINC(),"",$1); }
2010-04-07 00:55:54 +02:00
//UNSUP expr ':' expr { }
//UNSUP expr ':' expr ':' expr { }
2006-08-26 13:35:28 +02:00
;
2007-05-14 22:59:58 +02:00
//************************************************
2007-10-26 16:58:26 +02:00
// EventControl lists
2007-05-14 22:59:58 +02:00
2020-01-12 10:03:17 +01:00
attr_event_controlE<sentreep>:
/* empty */ { $$ = NULL; }
| attr_event_control { $$ = $1; }
;
2010-04-06 02:01:17 +02:00
attr_event_control<sentreep>: // ==IEEE: event_control
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
| '@' '(' '*' ')' { $$ = NULL; }
| '@' '*' { $$ = NULL; }
;
2009-01-15 19:58:43 +01:00
event_controlE<sentreep>:
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2009-01-15 19:58:43 +01:00
| event_control { $$ = $1; }
2009-01-25 03:36:14 +01:00
;
2007-05-16 21:27:29 +02:00
2009-01-15 19:58:43 +01:00
event_control<sentreep>: // ==IEEE: event_control
2009-05-08 00:28:05 +02:00
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
2009-01-28 21:27:41 +01:00
| '@' '(' '*' ')' { $$ = NULL; }
2009-05-08 00:28:05 +02:00
| '@' '*' { $$ = NULL; }
// // IEEE: hierarchical_event_identifier
2019-12-24 22:15:48 +01:00
// // UNSUP below should be idClassSel
2009-05-08 00:28:05 +02:00
| '@' 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 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
event_expression<senitemp>: // IEEE: event_expression - split over several
2019-12-24 22:15:48 +01:00
//UNSUP // Below are all removed
2008-08-06 18:35:34 +02:00
senitem { $$ = $1; }
2018-02-02 03:32:58 +01:00
| event_expression yOR senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); }
| event_expression ',' senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); } /* Verilog 2001 */
2019-12-24 22:15:48 +01:00
//UNSUP // Above are all removed, replace with:
//UNSUP ev_expr { $$ = $1; }
//UNSUP event_expression ',' ev_expr %prec yOR { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
2008-08-06 18:35:34 +02:00
senitemEdge { $$ = $1; }
2007-05-18 20:48:22 +02:00
| senitemVar { $$ = $1; }
2016-12-22 00:23:14 +01:00
| '(' senitem ')' { $$ = $2; }
2009-05-08 00:28:05 +02:00
//UNSUP expr { UNSUP }
2014-04-22 01:39:28 +02:00
| '{' event_expression '}' { $$ = $2; }
2016-12-22 00:23:14 +01:00
| senitem yP_ANDAND senitem { $$ = new AstSenItem($2, AstSenItem::Illegal()); }
2009-05-08 00:28:05 +02:00
//UNSUP expr yIFF expr { UNSUP }
2011-11-02 23:34:17 +01:00
// Since expr is unsupported we allow and ignore constants (removed in V3Const)
| yaINTNUM { $$ = NULL; }
| yaFLOATNUM { $$ = NULL; }
2007-05-18 20:48:22 +02:00
;
2008-08-06 18:35:34 +02:00
senitemVar<senitemp>:
2019-10-05 13:54:14 +02:00
idClassSel { $$ = new AstSenItem($1->fileline(), VEdgeType::ET_ANYEDGE, $1); }
2006-08-26 13:35:28 +02:00
;
2009-01-25 03:36:14 +01:00
senitemEdge<senitemp>: // IEEE: part of event_expression
2019-12-24 22:15:48 +01:00
//UNSUP // Below are all removed
2019-10-05 13:54:14 +02:00
yPOSEDGE idClassSel { $$ = new AstSenItem($1, VEdgeType::ET_POSEDGE, $2); }
| yNEGEDGE idClassSel { $$ = new AstSenItem($1, VEdgeType::ET_NEGEDGE, $2); }
| yEDGE idClassSel { $$ = new AstSenItem($1, VEdgeType::ET_BOTHEDGE, $2); }
| yPOSEDGE '(' idClassSel ')' { $$ = new AstSenItem($1, VEdgeType::ET_POSEDGE, $3); }
| yNEGEDGE '(' idClassSel ')' { $$ = new AstSenItem($1, VEdgeType::ET_NEGEDGE, $3); }
| yEDGE '(' idClassSel ')' { $$ = new AstSenItem($1, VEdgeType::ET_BOTHEDGE, $3); }
2019-12-24 22:15:48 +01:00
//UNSUP // Above are all removed, replace with:
//UNSUP yPOSEDGE expr { UNSUP }
//UNSUP yPOSEDGE expr yIFF expr { UNSUP }
//UNSUP yNEGEDGE expr { UNSUP }
//UNSUP yNEGEDGE expr yIFF expr { UNSUP }
//UNSUP yEDGE expr { UNSUP }
//UNSUP yEDGE expr yIFF expr { UNSUP }
2006-08-26 13:35:28 +02:00
;
2007-05-14 22:59:58 +02:00
//************************************************
// Statements
2009-01-25 03:36:14 +01:00
stmtBlock<nodep>: // IEEE: statement + seq_block + par_block
2008-08-06 18:35:34 +02:00
stmt { $$ = $1; }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
seq_block<nodep>: // ==IEEE: seq_block
// // IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
2012-10-09 03:20:13 +02:00
// // So need AstBegin's even if unnamed to scope variables down
2012-03-08 02:14:18 +01: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-08 00:28:05 +02:00
;
2019-06-01 03:05:50 +02:00
par_block<nodep>: // ==IEEE: par_block
2019-12-23 21:19:22 +01:00
par_blockFront blockDeclStmtList yJOIN endLabelE
{ $$ = $1; $1->addStmtsp($2);
2020-04-23 03:31:40 +02:00
$1->joinType(VJoinType::JOIN);
2019-12-23 21:19:22 +01:00
SYMP->popScope($1); GRAMMARP->endLabel($<fl>4, $1, $4); }
| par_blockFront /**/ yJOIN endLabelE
{ $$ = $1;
2020-04-23 03:31:40 +02:00
$1->joinType(VJoinType::JOIN);
2019-12-23 21:19:22 +01:00
SYMP->popScope($1); GRAMMARP->endLabel($<fl>3, $1, $3); }
| par_blockFront blockDeclStmtList yJOIN_ANY endLabelE
{ $$ = $1; $1->addStmtsp($2);
2020-04-23 03:31:40 +02:00
$1->joinType(VJoinType::JOIN_ANY);
2019-12-23 21:19:22 +01:00
SYMP->popScope($1); GRAMMARP->endLabel($<fl>4, $1, $4); }
| par_blockFront /**/ yJOIN_ANY endLabelE
{ $$ = $1;
2020-04-23 03:31:40 +02:00
$1->joinType(VJoinType::JOIN_ANY);
2019-12-23 21:19:22 +01:00
SYMP->popScope($1); GRAMMARP->endLabel($<fl>3, $1, $3); }
| par_blockFront blockDeclStmtList yJOIN_NONE endLabelE
{ $$ = $1; $1->addStmtsp($2);
2020-04-23 03:31:40 +02:00
$1->joinType(VJoinType::JOIN_NONE);
2019-12-23 21:19:22 +01:00
SYMP->popScope($1); GRAMMARP->endLabel($<fl>4, $1, $4); }
| par_blockFront /**/ yJOIN_NONE endLabelE
{ $$ = $1;
2020-04-23 03:31:40 +02:00
$1->joinType(VJoinType::JOIN_NONE);
2019-12-23 21:19:22 +01:00
SYMP->popScope($1); GRAMMARP->endLabel($<fl>3, $1, $3); }
2019-06-01 03:05:50 +02:00
;
seq_blockFront<beginp>: // IEEE: part of seq_block
2009-10-31 15:14:04 +01:00
yBEGIN { $$ = new AstBegin($1,"",NULL); SYMP->pushNew($$); }
2019-07-13 18:01:26 +02:00
| yBEGIN ':' idAny/*new-block_identifier*/ { $$ = new AstBegin($<fl>3, *$3, NULL); SYMP->pushNew($$); }
2009-05-08 00:28:05 +02:00
;
2020-04-23 03:31:40 +02:00
par_blockFront<forkp>: // IEEE: part of par_block
yFORK { $$ = new AstFork($1, "", NULL); SYMP->pushNew($$); }
| yFORK ':' idAny/*new-block_identifier*/ { $$ = new AstFork($<fl>3, *$3, NULL); SYMP->pushNew($$); }
2019-06-01 03:05:50 +02:00
;
2009-05-08 00:28:05 +02: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 03:20:13 +02:00
| local_parameter_declaration ';' { $$ = $1; }
2009-05-08 00:28:05 +02:00
| parameter_declaration ';' { $$ = $1; }
2012-10-09 02:45:39 +02:00
//UNSUP let_declaration { $$ = $1; }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
stmtList<nodep>:
stmtBlock { $$ = $1; }
2006-08-26 13:35:28 +02:00
| stmtList stmtBlock { $$ = ($2==NULL)?($1):($1->addNext($2)); }
;
2009-05-08 00:28:05 +02:00
stmt<nodep>: // IEEE: statement_or_null == function_statement_or_null
2019-05-31 13:33:57 +02:00
statement_item { $$ = $1; }
// // S05 block creation rule
2019-07-13 18:01:26 +02:00
| id/*block_identifier*/ ':' statement_item { $$ = new AstBegin($<fl>1, *$1, $3); }
2009-05-08 00:28:05 +02:00
// // from _or_null
| ';' { $$ = NULL; }
;
statement_item<nodep>: // IEEE: statement_item
2009-01-28 21:27:41 +01:00
// // IEEE: operator_assignment
2009-05-08 00:28:05 +02:00
foperator_assignment ';' { $$ = $1; }
//
// // IEEE: blocking_assignment
2012-10-09 02:45:39 +02:00
// // 1800-2009 restricts LHS of assignment to new to not have a range
// // This is ignored to avoid conflicts
2019-12-23 21:03:04 +01:00
| fexprLvalue '=' class_new ';' { $$ = new AstAssign($2, $1, $3); }
| fexprLvalue '=' dynamic_array_new ';' { $$ = new AstAssign($2, $1, $3); }
2009-02-25 23:16:51 +01:00
//
2009-01-28 21:27:41 +01:00
// // IEEE: nonblocking_assignment
2012-12-31 23:05:13 +01:00
| fexprLvalue yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); }
2009-05-08 00:28:05 +02:00
//UNSUP fexprLvalue yP_LTE delay_or_event_controlE expr ';' { UNSUP }
2009-02-25 23:16:51 +01:00
//
2009-01-28 21:27:41 +01:00
// // IEEE: procedural_continuous_assignment
2009-05-08 00:28:05 +02:00
| yASSIGN idClassSel '=' delayE expr ';' { $$ = new AstAssign($1,$2,$5); }
//UNSUP: delay_or_event_controlE above
2019-06-01 03:05:50 +02:00
| yDEASSIGN variable_lvalue ';' { $$ = NULL; BBUNSUP($1, "Unsupported: Verilog 1995 deassign"); }
| yFORCE expr '=' expr ';' { $$ = NULL; BBUNSUP($1, "Unsupported: Verilog 1995 force"); }
| yRELEASE variable_lvalue ';' { $$ = NULL; BBUNSUP($1, "Unsupported: Verilog 1995 release"); }
2009-02-25 23:16:51 +01:00
//
2009-01-28 21:27:41 +01:00
// // IEEE: case_statement
| unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
2010-12-26 03:58:28 +01:00
if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
2009-05-08 00:28:05 +02:00
//UNSUP caseStart caseAttrE yMATCHES case_patternListE yENDCASE { }
2014-01-21 03:59:53 +01: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 23:16:51 +01:00
//
2009-01-28 21:27:41 +01:00
// // IEEE: conditional_statement
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
2016-11-06 17:39:09 +01:00
{ AstIf* newp = new AstIf($2,$4,$6,NULL);
$$ = newp;
if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
if ($1 == uniq_PRIORITY) newp->priorityPragma(true); }
2009-01-28 21:27:41 +01:00
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
2016-11-06 17:39:09 +01:00
{ AstIf* newp = new AstIf($2,$4,$6,$8);
$$ = newp;
if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
if ($1 == uniq_PRIORITY) newp->priorityPragma(true); }
2009-02-25 23:16:51 +01:00
//
2010-12-08 02:18:47 +01:00
| finc_or_dec_expression ';' { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: inc_or_dec_expression
// // Below under expr
//
// // IEEE: subroutine_call_statement
2019-03-10 20:12:20 +01:00
// // IEEE says we then expect a function call
// // (function_subroutine_callNoMethod), but rest of
// // the code expects an AstTask when used as a statement,
// // so parse as if task
// // Alternative would be shim with new AstVoidStmt.
| yVOID yP_TICK '(' task_subroutine_callNoMethod ')' ';'
{ $$ = $4;
FileLine* newfl = new FileLine($$->fileline());
newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
$$->fileline(newfl); }
| yVOID yP_TICK '(' expr '.' task_subroutine_callNoMethod ')' ';'
{ $$ = new AstDot($5, $4, $6);
FileLine* newfl = new FileLine($6->fileline());
newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
$6->fileline(newfl); }
2009-05-08 00:28:05 +02: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 23:05:13 +01:00
| fexpr '.' task_subroutine_callNoMethod ';' { $$ = new AstDot($<fl>2,$1,$3); }
2009-05-08 00:28:05 +02:00
//UNSUP fexprScope ';' { UNSUP }
2009-05-19 13:49:19 +02: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 ')' ] ';' ]
2019-12-23 21:03:04 +01:00
| fexpr '.' class_new ';' { $$ = NULL; BBUNSUP($1, "Unsupported: dotted new"); }
2009-05-08 00:28:05 +02:00
//
2019-12-23 21:03:04 +01:00
| statementVerilatorPragmas { $$ = $1; }
2009-05-08 00:28:05 +02:00
//
// // IEEE: disable_statement
2011-06-29 03:26:49 +02:00
| yDISABLE idAny/*hierarchical_identifier-task_or_block*/ ';' { $$ = new AstDisable($1,*$2); }
2019-06-01 03:05:50 +02:00
| yDISABLE yFORK ';' { $$ = NULL; BBUNSUP($1, "Unsupported: disable fork statements"); }
2009-05-08 00:28:05 +02:00
// // IEEE: event_trigger
2020-04-25 21:37:46 +02:00
| yP_MINUSGT idDotted/*hierarchical_identifier-event*/ ';'
{ // AssignDly because we don't have stratified queue, and need to
// read events, clear next event, THEN apply this set
$$ = new AstAssignDly($1, $2, new AstConst($1, AstConst::LogicTrue())); }
2009-05-08 00:28:05 +02:00
//UNSUP yP_MINUSGTGT delay_or_event_controlE hierarchical_identifier/*event*/ ';' { UNSUP }
2020-04-25 21:37:46 +02:00
// // IEEE remove below
| yP_MINUSGTGT delayE idDotted/*hierarchical_identifier-event*/ ';'
{ $$ = new AstAssignDly($1, $3, new AstConst($1, AstConst::LogicTrue())); }
//
2009-05-08 00:28:05 +02:00
// // IEEE: loop_statement
2009-11-23 01:57:41 +01:00
| yFOREVER stmtBlock { $$ = new AstWhile($1,new AstConst($1,AstConst::LogicTrue()),$2); }
2009-02-26 04:06:59 +01:00
| yREPEAT '(' expr ')' stmtBlock { $$ = new AstRepeat($1,$3,$5);}
2009-01-28 21:27:41 +01:00
| yWHILE '(' expr ')' stmtBlock { $$ = new AstWhile($1,$3,$5);}
2019-09-12 13:22:22 +02:00
// // for's first ';' is in for_initialization
2018-03-13 03:26:34 +01:00
| statementFor { $$ = $1; }
2018-03-10 23:44:17 +01:00
| yDO stmtBlock yWHILE '(' expr ')' ';' { if ($2) {
$$ = $2->cloneTree(true);
$$->addNext(new AstWhile($1,$5,$2));
}
else $$ = new AstWhile($1,$5,NULL); }
2012-10-09 02:45:39 +02:00
// // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
2016-09-20 04:00:13 +02:00
| yFOREACH '(' idClassForeach '[' loop_variables ']' ')' stmtBlock { $$ = new AstForeach($1,$3,$5,$8); }
2009-05-08 00:28:05 +02:00
//
// // IEEE: jump_statement
2010-02-14 16:01:21 +01:00
| yRETURN ';' { $$ = new AstReturn($1); }
| yRETURN expr ';' { $$ = new AstReturn($1,$2); }
| yBREAK ';' { $$ = new AstBreak($1); }
| yCONTINUE ';' { $$ = new AstContinue($1); }
2009-05-08 00:28:05 +02:00
//
2019-06-01 03:05:50 +02:00
| par_block { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: procedural_timing_control_statement + procedural_timing_control
2020-04-23 03:31:40 +02:00
| delay_control stmtBlock { $$ = new AstDelay($1->fileline(), $1); $$->addNextNull($2); }
2009-05-08 00:28:05 +02:00
//UNSUP event_control stmtBlock { UNSUP }
//UNSUP cycle_delay stmtBlock { UNSUP }
//
| seq_block { $$ = $1; }
//
// // IEEE: wait_statement
2019-06-01 03:05:50 +02:00
| yWAIT '(' expr ')' stmtBlock { $$ = NULL; BBUNSUP($1, "Unsupported: wait statements"); }
| yWAIT yFORK ';' { $$ = NULL; BBUNSUP($1, "Unsupported: wait fork statements"); }
2009-05-08 00:28:05 +02:00
//UNSUP yWAIT_ORDER '(' hierarchical_identifierList ')' action_block { UNSUP }
//
// // IEEE: procedural_assertion_statement
2019-05-31 13:33:57 +02:00
| procedural_assertion_statement { $$ = $1; }
2009-05-08 00:28:05 +02:00
//
// // 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
2019-06-01 03:05:50 +02:00
| yRANDCASE case_itemList yENDCASE { $$ = NULL; BBUNSUP($1, "Unsupported: SystemVerilog 2005 randcase statements"); }
2009-05-08 00:28:05 +02:00
//
//UNSUP expect_property_statement { $$ = $1; }
//
| error ';' { $$ = NULL; }
;
2018-03-13 03:26:34 +01:00
statementFor<beginp>: // IEEE: part of statement
yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
2020-02-26 04:21:16 +01:00
{ $$ = new AstBegin($1, "", $3, false, true);
2018-03-13 03:26:34 +01:00
$$->addStmtsp(new AstWhile($1, $4,$8,$6)); }
| yFOR '(' for_initialization ';' for_stepE ')' stmtBlock
2020-02-26 04:21:16 +01:00
{ $$ = new AstBegin($1, "", $3, false, true);
2018-03-13 03:26:34 +01:00
$$->addStmtsp(new AstWhile($1, new AstConst($1,AstConst::LogicTrue()),$7,$5)); }
;
2009-05-08 00:28:05 +02:00
statementVerilatorPragmas<nodep>:
yVL_COVERAGE_BLOCK_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
;
2019-12-24 22:15:48 +01:00
//UNSUPoperator_assignment<nodep>: // IEEE: operator_assignment
//UNSUP ~f~exprLvalue '=' delay_or_event_controlE expr { }
//UNSUP | ~f~exprLvalue yP_PLUSEQ expr { }
//UNSUP | ~f~exprLvalue yP_MINUSEQ expr { }
//UNSUP | ~f~exprLvalue yP_TIMESEQ expr { }
//UNSUP | ~f~exprLvalue yP_DIVEQ expr { }
//UNSUP | ~f~exprLvalue yP_MODEQ expr { }
//UNSUP | ~f~exprLvalue yP_ANDEQ expr { }
//UNSUP | ~f~exprLvalue yP_OREQ expr { }
//UNSUP | ~f~exprLvalue yP_XOREQ expr { }
//UNSUP | ~f~exprLvalue yP_SLEFTEQ expr { }
//UNSUP | ~f~exprLvalue yP_SRIGHTEQ expr { }
//UNSUP | ~f~exprLvalue yP_SSRIGHTEQ expr { }
//UNSUP ;
2009-05-08 00:28:05 +02:00
foperator_assignment<nodep>: // IEEE: operator_assignment (for first part of expression)
2012-12-31 23:05:13 +01:00
fexprLvalue '=' delayE expr { $$ = new AstAssign($2,$1,$4); }
2019-09-27 05:37:22 +02:00
| fexprLvalue '=' yD_FOPEN '(' expr ')' { $$ = NULL; BBUNSUP($3, "Unsupported: $fopen with multichannel descriptor. Add ,\"w\" as second argument to open a file descriptor."); }
2012-12-31 23:05:13 +01:00
| fexprLvalue '=' yD_FOPEN '(' expr ',' expr ')' { $$ = new AstFOpen($3,$1,$5,$7); }
2009-05-08 00:28:05 +02:00
//
//UNSUP ~f~exprLvalue '=' delay_or_event_controlE expr { UNSUP }
2010-12-08 02:18:47 +01:00
//UNSUP ~f~exprLvalue yP_PLUS(etc) expr { UNSUP }
2012-12-31 23:05:13 +01: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)); }
2019-12-24 22:15:48 +01:00
//UNSUP replace above with:
//UNSUP BISONPRE_COPY(operator_assignment,{s/~f~/f/g}) // {copied}
2010-12-08 02:18:47 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPinc_or_dec_expression<nodep>: // ==IEEE: inc_or_dec_expression
//UNSUP // // Need fexprScope instead of variable_lvalue to prevent conflict
//UNSUP ~l~exprScope yP_PLUSPLUS { $<fl>$=$<fl>1; $$ = $1+$2; }
//UNSUP | ~l~exprScope yP_MINUSMINUS { $<fl>$=$<fl>1; $$ = $1+$2; }
//UNSUP // // Need expr instead of variable_lvalue to prevent conflict
//UNSUP | yP_PLUSPLUS expr { $<fl>$=$<fl>1; $$ = $1+$2; }
//UNSUP | yP_MINUSMINUS expr { $<fl>$=$<fl>1; $$ = $1+$2; }
//UNSUP ;
2010-12-08 02:18:47 +01:00
finc_or_dec_expression<nodep>: // ==IEEE: inc_or_dec_expression
2019-12-24 22:15:48 +01:00
//UNSUP: Generic scopes in incrementes, remove below
2019-05-10 02:03:19 +02:00
fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2, AstConst::StringToParse(), "'b1"))); }
| fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2, AstConst::StringToParse(), "'b1"))); }
| yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); }
| yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); }
2019-12-24 22:15:48 +01:00
//UNSUP: Generic scopes in incrementes, remove above
//UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/f/g}) // {copied}
2007-03-06 22:43:38 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPsinc_or_dec_expression<nodep>: // IEEE: inc_or_dec_expression (for sequence_expression)
//UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/s/g}) // {copied}
//UNSUP ;
//UNSUPpinc_or_dec_expression<nodep>: // IEEE: inc_or_dec_expression (for property_expression)
//UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/p/g}) // {copied}
//UNSUP ;
//UNSUPev_inc_or_dec_expression<nodep>: // IEEE: inc_or_dec_expression (for ev_expr)
//UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/ev_/g}) // {copied}
//UNSUP ;
//UNSUPpev_inc_or_dec_expression<nodep>: // IEEE: inc_or_dec_expression (for pev_expr)
//UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/pev_/g}) // {copied}
//UNSUP ;
2019-12-23 21:03:04 +01:00
class_new<nodep>: // ==IEEE: class_new
// // Special precence so (...) doesn't match expr
2020-03-06 04:33:31 +01:00
yNEW__ETC { $$ = new AstNew($1, NULL); }
| yNEW__ETC expr { $$ = new AstNewCopy($1, $2); }
| yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew($1, $3); }
2019-12-23 21:03:04 +01:00
;
dynamic_array_new<nodep>: // ==IEEE: dynamic_array_new
2020-03-06 04:33:31 +01:00
yNEW__ETC '[' expr ']' { $$ = new AstNewDynamic($1, $3, NULL); }
| yNEW__ETC '[' expr ']' '(' expr ')' { $$ = new AstNewDynamic($1, $3, $6); }
2019-12-23 21:03:04 +01:00
;
2007-05-14 22:59:58 +02:00
//************************************************
// Case/If
2006-08-26 13:35:28 +02:00
2009-01-25 03:36:14 +01:00
unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
2008-10-11 01:02:27 +02:00
/*empty*/ { $$ = uniq_NONE; }
| yPRIORITY { $$ = uniq_PRIORITY; }
| yUNIQUE { $$ = uniq_UNIQUE; }
2010-12-26 03:58:28 +01:00
| yUNIQUE0 { $$ = uniq_UNIQUE0; }
2008-10-11 01:02:27 +02:00
;
2009-01-28 21:27:41 +01:00
caseStart<casep>: // IEEE: part of case_statement
2014-01-21 03:59:53 +01: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 13:35:28 +02:00
;
2009-01-25 03:36:14 +01:00
caseAttrE:
/*empty*/ { }
2009-10-31 15:08:38 +01:00
| caseAttrE yVL_FULL_CASE { GRAMMARP->m_caseAttrp->fullPragma(true); }
| caseAttrE yVL_PARALLEL_CASE { GRAMMARP->m_caseAttrp->parallelPragma(true); }
2006-08-26 13:35:28 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPcase_patternListE<nodep>: // IEEE: case_pattern_item
//UNSUP // &&& is part of expr so aliases to case_itemList
//UNSUP case_itemListE { $$ = $1; }
//UNSUP ;
2009-01-25 03:36:14 +01:00
case_itemListE<caseitemp>: // IEEE: [ { case_item } ]
2008-08-06 18:35:34 +02:00
/* empty */ { $$ = NULL; }
2009-01-25 03:36:14 +01:00
| case_itemList { $$ = $1; }
2007-05-18 16:03:50 +02:00
;
2014-01-21 03:59:53 +01:00
case_insideListE<caseitemp>: // IEEE: [ { case_inside_item } ]
/* empty */ { $$ = NULL; }
| case_inside_itemList { $$ = $1; }
;
2009-01-25 03:36:14 +01:00
case_itemList<caseitemp>: // IEEE: { case_item + ... }
2008-08-06 18:35:34 +02:00
caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
2019-07-13 18:01:26 +02:00
| yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($1,NULL,$3); }
2006-08-26 13:35:28 +02:00
| yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); }
2009-01-25 03:36:14 +01: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)); }
2019-07-13 18:01:26 +02:00
| case_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$4)); }
2006-08-26 13:35:28 +02:00
;
2014-01-21 03:59:53 +01:00
case_inside_itemList<caseitemp>: // IEEE: { case_inside_item + open_range_list ... }
open_range_list ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
2019-07-13 18:01:26 +02:00
| yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($1,NULL,$3); }
2014-01-21 03:59:53 +01:00
| 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)); }
2019-07-13 18:01:26 +02:00
| case_inside_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$4)); }
2014-01-21 03:59:53 +01:00
;
2013-02-02 18:55:28 +01: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; }
2019-07-13 18:01:26 +02:00
| '[' expr ':' expr ']' { $$ = new AstInsideRange($1, $2, $4); }
2013-02-02 18:55:28 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPcovergroup_value_range<nodep>: // ==IEEE-2012: covergroup_value_range
//UNSUP cgexpr { $$ = $1; }
//UNSUP | '[' cgexpr ':' cgexpr ']' { }
//UNSUP ;
2009-01-25 03:36:14 +01:00
caseCondList<nodep>: // IEEE: part of case_item
2008-08-06 18:35:34 +02:00
expr { $$ = $1; }
2007-05-14 22:59:58 +02:00
| caseCondList ',' expr { $$ = $1;$1->addNext($3); }
;
2012-08-12 21:15:21 +02:00
patternNoExpr<nodep>: // IEEE: pattern **Excluding Expr*
2019-06-01 03:05:50 +02:00
'.' id/*variable*/ { $$ = NULL; $1->v3error("Unsupported: '{} tagged patterns"); }
| yP_DOTSTAR { $$ = NULL; $1->v3error("Unsupported: '{} tagged patterns"); }
2012-08-12 21:15:21 +02:00
// // IEEE: "expr" excluded; expand in callers
// // "yTAGGED id [expr]" Already part of expr
2019-06-01 03:05:50 +02:00
//UNSUP yTAGGED id/*member_identifier*/ patternNoExpr { $$ = NULL; $1->v3error("Unsupported: '{} tagged patterns"); }
2012-08-12 21:15:21 +02:00
// // "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
2019-10-01 01:22:14 +02:00
expr { if ($1) { $$ = new AstPatMember($1->fileline(),$1,NULL,NULL); } else { $$=NULL; } }
2012-08-12 21:15:21 +02:00
| 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
2019-07-13 18:01:26 +02:00
patternKey ':' expr { $$ = new AstPatMember($1->fileline(),$3,$1,NULL); }
2019-06-01 03:05:50 +02:00
| patternKey ':' patternNoExpr { $$ = NULL; $2->v3error("Unsupported: '{} .* patterns"); }
2012-08-12 21:15:21 +02:00
// // From assignment_pattern_key
2019-07-13 18:01:26 +02:00
| yDEFAULT ':' expr { $$ = new AstPatMember($1,$3,NULL,NULL); $$->isDefault(true); }
2019-06-01 03:05:50 +02:00
| yDEFAULT ':' patternNoExpr { $$ = NULL; $2->v3error("Unsupported: '{} .* patterns"); }
2012-08-12 21:15:21 +02:00
;
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); }
2019-11-17 14:43:04 +01:00
| strAsInt { $$ = $1; }
2012-08-12 21:15:21 +02:00
;
2013-02-14 02:52:38 +01:00
assignment_pattern<patternp>: // ==IEEE: assignment_pattern
2012-08-12 21:15:21 +02: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
2019-10-17 02:05:29 +02:00
| yP_TICKBRA '}' { $$ = new AstPattern($1, NULL); $1->v3error("Unsupported: Empty '{}"); }
2012-08-12 21:15:21 +02:00
;
2009-05-08 00:28:05 +02: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
2019-01-23 01:25:00 +01:00
for_initializationItemList ';' { $$ = $1; }
// // IEEE: 1800-2017 empty initialization
| ';' { $$ = NULL; }
;
for_initializationItemList<nodep>: // IEEE: [for_variable_declaration...]
for_initializationItem { $$ = $1; }
| for_initializationItemList ',' for_initializationItem { $$ = $1; $<fl>2->v3error("Unsupported: for loop initialization after the first comma"); }
;
for_initializationItem<nodep>: // IEEE: variable_assignment + for_variable_declaration
// // IEEE: for_variable_declaration
data_type idAny/*new*/ '=' expr
2012-12-31 19:43:54 +01:00
{ VARRESET_NONLIST(VAR); VARDTYPE($1);
$$ = VARDONEA($<fl>2,*$2,NULL,NULL);
2019-07-13 18:01:26 +02:00
$$->addNext(new AstAssign($3, new AstVarRef($<fl>2, *$2, true), $4));}
2019-01-23 01:25:00 +01:00
// // IEEE-2012:
| yVAR data_type idAny/*new*/ '=' expr
{ VARRESET_NONLIST(VAR); VARDTYPE($2);
$$ = VARDONEA($<fl>3,*$3,NULL,NULL);
2019-07-13 18:01:26 +02:00
$$->addNext(new AstAssign($4, new AstVarRef($<fl>3, *$3, true), $5));}
2019-01-23 01:25:00 +01:00
// // IEEE: variable_assignment
2019-12-24 22:15:48 +01:00
// // UNSUP variable_lvalue below
2019-01-23 01:25:00 +01:00
| varRefBase '=' expr { $$ = new AstAssign($2, $1, $3); }
2009-05-08 00:28:05 +02:00
;
for_stepE<nodep>: // IEEE: for_step + empty
/* empty */ { $$ = NULL; }
| for_step { $$ = $1; }
;
for_step<nodep>: // IEEE: for_step
2019-12-24 22:15:48 +01:00
for_step_assignment { $$ = $1; }
| for_step ',' for_step_assignment { $$ = $1; $<fl>1->v3error("Unsupported: for loop step after the first comma"); }
;
for_step_assignment<nodep>: // ==IEEE: for_step_assignment
//UNSUP operator_assignment { $$ = $1; }
//
//UNSUP inc_or_dec_expression { $$ = $1; }
// // IEEE: subroutine_call
//UNSUP function_subroutine_callNoMethod { $$ = $1; }
// // method_call:array_method requires a '.'
//UNSUP expr '.' array_methodNoRoot { }
//UNSUP exprScope { $$ = $1; }
//UNSUP remove below
2012-03-23 02:02:38 +01:00
genvar_iteration { $$ = $1; }
2019-12-24 22:15:48 +01:00
//UNSUP remove above
2009-05-08 00:28:05 +02:00
;
2016-09-20 04:00:13 +02:00
loop_variables<nodep>: // IEEE: loop_variables
varRefBase { $$ = $1; }
| loop_variables ',' varRefBase { $$ = $1;$1->addNext($3); }
;
2007-05-14 22:59:58 +02:00
//************************************************
// Functions/tasks
2012-12-31 23:05:13 +01: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 22:59:58 +02:00
;
2012-12-31 23:05:13 +01:00
funcRef<nodep>: // IEEE: part of tf_call
2012-10-09 03:20:13 +02: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 02:34:49 +02:00
//
2019-07-13 18:01:26 +02:00
id '(' list_of_argumentsE ')' { $$ = new AstFuncRef($<fl>1, *$1, $3); }
2012-12-31 23:05:13 +01:00
| package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($<fl>2, $1, new AstFuncRef($<fl>2,*$2,$4)); }
2019-12-24 22:15:48 +01:00
//UNSUP list_of_argumentE should be pev_list_of_argumentE
2009-05-08 00:28:05 +02: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; }
2019-12-23 21:03:04 +01:00
//UNSUP funcRef yWITH__PAREN '(' expr ')' { /*UNSUP*/ }
2009-05-08 00:28:05 +02:00
| system_t_call { $$ = $1; }
// // IEEE: method_call requires a "." so is in expr
2019-12-23 21:03:04 +01:00
// // IEEE: ['std::'] not needed, as normal std package resolution will find it
// // IEEE: randomize_call
// // We implement randomize as a normal funcRef, since randomize isn't a keyword
// // Note yNULL is already part of expressions, so they come for free
//UNSUP funcRef yWITH__CUR constraint_block { }
2009-05-08 00:28:05 +02:00
;
function_subroutine_callNoMethod<nodep>: // IEEE: function_subroutine_call (as function)
// // IEEE: tf_call
funcRef { $$ = $1; }
2019-12-23 21:03:04 +01:00
//UNSUP funcRef yWITH__PAREN '(' expr ')' { /*UNSUP*/ }
2009-05-08 00:28:05 +02:00
| system_f_call { $$ = $1; }
// // IEEE: method_call requires a "." so is in expr
2019-12-23 21:03:04 +01:00
// // IEEE: ['std::'] not needed, as normal std package resolution will find it
// // IEEE: randomize_call
// // We implement randomize as a normal funcRef, since randomize isn't a keyword
// // Note yNULL is already part of expressions, so they come for free
//UNSUP funcRef yWITH__CUR constraint_block { }
2009-05-08 00:28:05 +02:00
;
system_t_call<nodep>: // IEEE: system_tf_call (as task)
//
2010-12-30 13:55:31 +01:00
yaD_IGNORE parenE { $$ = new AstSysIgnore($<fl>1,NULL); }
| yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($<fl>1,$3); }
2009-12-04 13:05:44 +01:00
//
2010-01-06 20:21:34 +01:00
| yaD_DPI parenE { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
2019-07-13 18:01:26 +02:00
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($<fl>1, *$1, $3);
GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); }
2009-09-16 15:28:09 +02:00
//
2020-03-02 03:39:23 +01:00
| yD_DUMPPORTS '(' idDotted ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $5); DEL($3);
$$->addNext(new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
new AstConst($<fl>1, 1))); }
| yD_DUMPPORTS '(' ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $4);
$$->addNext(new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
new AstConst($<fl>1, 1))); }
| yD_DUMPFILE '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $3); }
| yD_DUMPVARS parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
new AstConst($<fl>1, 0)); }
| yD_DUMPVARS '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::VARS, $3); }
| yD_DUMPVARS '(' expr ',' idDotted ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::VARS, $3); DEL($5); }
| yD_DUMPALL parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ALL); }
| yD_DUMPALL '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ALL); DEL($3); }
| yD_DUMPFLUSH parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FLUSH); }
| yD_DUMPFLUSH '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FLUSH); DEL($3); }
| yD_DUMPLIMIT '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::LIMIT, $3); }
| yD_DUMPLIMIT '(' expr ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::LIMIT, $3); DEL($5); }
| yD_DUMPOFF parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::OFF); }
| yD_DUMPOFF '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::OFF); DEL($3); }
| yD_DUMPON parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ON); }
| yD_DUMPON '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ON); DEL($3); }
//
2009-09-16 15:28:09 +02:00
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
2020-03-02 03:39:23 +01:00
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1, $3); }
2018-03-09 05:40:19 +01:00
//
2009-05-08 00:28:05 +02:00
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
2020-04-05 16:11:28 +02:00
| yD_FFLUSH parenE { $$ = new AstFFlush($1, NULL); }
2015-10-24 03:53:16 +02:00
| yD_FFLUSH '(' expr ')' { $$ = new AstFFlush($1, $3); }
2009-05-08 00:28:05 +02:00
| yD_FINISH parenE { $$ = new AstFinish($1); }
2012-05-31 05:17:55 +02:00
| yD_FINISH '(' expr ')' { $$ = new AstFinish($1); DEL($3); }
2019-11-17 00:25:47 +01:00
| yD_STOP parenE { $$ = new AstStop($1, false); }
| yD_STOP '(' expr ')' { $$ = new AstStop($1, false); DEL($3); }
2009-05-08 00:28:05 +02:00
//
2020-03-06 03:49:25 +01:00
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6); }
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6); }
| yD_SWRITEB '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'b'); }
| yD_SWRITEH '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'h'); }
| yD_SWRITEO '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'o'); }
2009-11-24 03:24:55 +01:00
//
2019-08-05 03:50:08 +02:00
| yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL); }
| yD_DISPLAY '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3); }
2020-03-06 03:49:25 +01:00
| yD_DISPLAYB parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'b'); }
| yD_DISPLAYB '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'b'); }
| yD_DISPLAYH parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'h'); }
| yD_DISPLAYH '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'h'); }
| yD_DISPLAYO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'o'); }
| yD_DISPLAYO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'o'); }
2019-08-05 03:50:08 +02:00
| yD_WRITE parenE { $$ = NULL; } // NOP
| yD_WRITE '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3); }
2020-03-06 03:49:25 +01:00
| yD_WRITEB parenE { $$ = NULL; } // NOP
| yD_WRITEB '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'b'); }
| yD_WRITEH parenE { $$ = NULL; } // NOP
| yD_WRITEH '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'h'); }
| yD_WRITEO parenE { $$ = NULL; } // NOP
| yD_WRITEO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'o'); }
2019-08-05 03:50:08 +02:00
| yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL); }
| yD_FDISPLAY '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5); }
2020-03-06 03:49:25 +01:00
| yD_FDISPLAYB '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'b'); }
| yD_FDISPLAYB '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'b'); }
| yD_FDISPLAYH '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'h'); }
| yD_FDISPLAYH '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'h'); }
| yD_FDISPLAYO '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'o'); }
| yD_FDISPLAYO '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'o'); }
2019-08-05 03:50:08 +02:00
| yD_FWRITE '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5); }
2020-03-06 03:49:25 +01:00
| yD_FWRITEB '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'b'); }
| yD_FWRITEO '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'h'); }
| yD_FWRITEH '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'o'); }
2019-08-05 03:50:08 +02:00
| yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, NULL); }
| yD_INFO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, $3); }
| yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, NULL); }
| yD_WARNING '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, $3); }
| yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); }
2019-11-17 00:25:47 +01:00
| yD_ERROR '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, NULL, $3); $$->addNext(new AstStop($1, true)); }
| yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, NULL); $$->addNext(new AstStop($1, false)); }
| yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, NULL); $$->addNext(new AstStop($1, false)); DEL($3); }
| yD_FATAL '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, $5); $$->addNext(new AstStop($1, false)); DEL($3); }
2009-05-08 00:28:05 +02:00
//
2020-04-16 01:39:03 +02:00
| yD_PRINTTIMESCALE { $$ = new AstPrintTimeScale($1); }
| yD_PRINTTIMESCALE '(' ')' { $$ = new AstPrintTimeScale($1); }
| yD_PRINTTIMESCALE '(' idClassSel ')' { $$ = new AstPrintTimeScale($1); DEL($3); }
| yD_TIMEFORMAT '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstTimeFormat($1, $3, $5, $7, $9); }
//
2012-12-31 19:47:34 +01: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); }
2018-03-09 05:40:19 +01:00
//
2018-03-12 21:44:01 +01:00
| yD_WRITEMEMH '(' expr ',' idClassSel ')' { $$ = new AstWriteMem($1,$3,$5,NULL,NULL); }
| yD_WRITEMEMH '(' expr ',' idClassSel ',' expr ')' { $$ = new AstWriteMem($1,$3,$5,$7,NULL); }
| yD_WRITEMEMH '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstWriteMem($1,$3,$5,$7,$9); }
//
2018-03-09 05:40:19 +01:00
// Any system function as a task
| system_f_call_or_t { $$ = new AstSysFuncAsTask($<fl>1, $1); }
2009-05-08 00:28:05 +02:00
;
system_f_call<nodep>: // IEEE: system_tf_call (as func)
2019-07-13 18:01:26 +02:00
yaD_IGNORE parenE { $$ = new AstConst($<fl>1, AstConst::StringToParse(), "'b0"); } // Unsized 0
| yaD_IGNORE '(' exprList ')' { $$ = new AstConst($<fl>1, AstConst::StringToParse(), "'b0"); } // Unsized 0
2009-12-04 13:05:44 +01:00
//
2010-01-06 20:13:11 +01:00
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
2019-07-13 18:01:26 +02:00
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($<fl>1,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); }
2009-09-16 15:28:09 +02:00
//
2018-03-09 05:40:19 +01:00
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
//
| system_f_call_or_t { $$ = $1; }
;
system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
yD_ACOS '(' expr ')' { $$ = new AstAcosD($1,$3); }
2018-02-26 10:25:07 +01:00
| yD_ACOSH '(' expr ')' { $$ = new AstAcoshD($1,$3); }
| yD_ASIN '(' expr ')' { $$ = new AstAsinD($1,$3); }
| yD_ASINH '(' expr ')' { $$ = new AstAsinhD($1,$3); }
| yD_ATAN '(' expr ')' { $$ = new AstAtanD($1,$3); }
| yD_ATAN2 '(' expr ',' expr ')' { $$ = new AstAtan2D($1,$3,$5); }
| yD_ATANH '(' expr ')' { $$ = new AstAtanhD($1,$3); }
2017-11-23 16:17:56 +01:00
| yD_BITS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); }
| yD_BITS '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); }
2011-07-24 21:01:51 +02:00
| yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); }
2019-11-23 15:16:06 +01:00
| yD_BITSTOSHORTREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); UNSUPREAL($1); }
2013-01-20 18:19:22 +01:00
| yD_CEIL '(' expr ')' { $$ = new AstCeilD($1,$3); }
2009-05-08 00:28:05 +02:00
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
2018-02-26 10:25:07 +01:00
| yD_COS '(' expr ')' { $$ = new AstCosD($1,$3); }
| yD_COSH '(' expr ')' { $$ = new AstCoshD($1,$3); }
2020-05-10 20:27:22 +02:00
| yD_COUNTBITS '(' expr ',' expr ')' { $$ = new AstCountBits($1,$3,$5); }
| yD_COUNTBITS '(' expr ',' expr ',' expr ')' { $$ = new AstCountBits($1,$3,$5,$7); }
| yD_COUNTBITS '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstCountBits($1,$3,$5,$7,$9); }
| yD_COUNTBITS '(' expr ',' expr ',' expr ',' expr ',' exprList ')'
{$11->v3error("Unsupported: $countbits with more than 3 control fields"); }
2009-05-08 00:28:05 +02:00
| yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); }
2017-11-23 16:17:56 +01:00
| yD_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_DIMENSIONS,$3); }
2013-01-20 18:19:22 +01:00
| yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); }
2009-05-08 00:28:05 +02:00
| yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); }
2020-04-05 17:22:05 +02:00
| yD_FERROR '(' idClassSel ',' idClassSel ')' { $$ = new AstFError($1, $3, $5); }
2009-05-08 00:28:05 +02:00
| yD_FGETC '(' expr ')' { $$ = new AstFGetC($1,$3); }
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
2019-03-08 02:56:53 +01:00
| yD_FREAD '(' idClassSel ',' expr ')' { $$ = new AstFRead($1,$3,$5,NULL,NULL); }
| yD_FREAD '(' idClassSel ',' expr ',' expr ')' { $$ = new AstFRead($1,$3,$5,$7,NULL); }
| yD_FREAD '(' idClassSel ',' expr ',' expr ',' expr ')' { $$ = new AstFRead($1,$3,$5,$7,$9); }
2019-09-04 03:28:15 +02:00
| yD_FREWIND '(' idClassSel ')' { $$ = new AstFRewind($1, $3); }
2013-01-20 18:19:22 +01:00
| yD_FLOOR '(' expr ')' { $$ = new AstFloorD($1,$3); }
2009-10-23 03:16:52 +02:00
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); }
2019-09-04 03:28:15 +02:00
| yD_FSEEK '(' idClassSel ',' expr ',' expr ')' { $$ = new AstFSeek($1,$3,$5,$7); }
| yD_FTELL '(' idClassSel ')' { $$ = new AstFTell($1, $3); }
2017-11-23 16:17:56 +01:00
| yD_HIGH '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,NULL); }
| yD_HIGH '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,$5); }
2018-02-26 10:25:07 +01:00
| yD_HYPOT '(' expr ',' expr ')' { $$ = new AstHypotD($1,$3,$5); }
2017-11-23 16:17:56 +01:00
| yD_INCREMENT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,NULL); }
| yD_INCREMENT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,$5); }
2020-05-08 03:09:14 +02:00
| yD_ISUNBOUNDED '(' expr ')' { $$ = new AstIsUnbounded($1, $3); }
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1, $3); }
2011-07-24 21:01:51 +02:00
| yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); }
2017-11-23 16:17:56 +01:00
| yD_LEFT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,NULL); }
| yD_LEFT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,$5); }
2013-01-20 18:19:22 +01:00
| yD_LN '(' expr ')' { $$ = new AstLogD($1,$3); }
| yD_LOG10 '(' expr ')' { $$ = new AstLog10D($1,$3); }
2017-11-23 16:17:56 +01:00
| yD_LOW '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,NULL); }
| yD_LOW '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,$5); }
2009-05-08 00:28:05 +02:00
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
2018-09-23 21:09:47 +02:00
| yD_PAST '(' expr ')' { $$ = new AstPast($1,$3, NULL); }
| yD_PAST '(' expr ',' expr ')' { $$ = new AstPast($1,$3, $5); }
| yD_PAST '(' expr ',' expr ',' expr ')' { $1->v3error("Unsupported: $past expr2 and clock arguments"); $$ = $3; }
| yD_PAST '(' expr ',' expr ',' expr ',' expr')' { $1->v3error("Unsupported: $past expr2 and clock arguments"); $$ = $3; }
2013-01-20 18:19:22 +01:00
| yD_POW '(' expr ',' expr ')' { $$ = new AstPowD($1,$3,$5); }
2019-06-01 03:05:50 +02:00
| yD_RANDOM '(' expr ')' { $$ = NULL; $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
2010-01-06 20:13:11 +01:00
| yD_RANDOM parenE { $$ = new AstRand($1); }
2020-04-16 01:39:03 +02:00
| yD_REALTIME parenE { $$ = new AstTimeD($1, VTimescale(VTimescale::NONE)); }
2011-07-24 21:01:51 +02:00
| yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits($1,$3); }
2019-11-16 18:21:35 +01:00
| yD_REWIND '(' idClassSel ')' { $$ = new AstFSeek($1, $3, new AstConst($1, 0), new AstConst($1, 0)); }
2017-11-23 16:17:56 +01:00
| yD_RIGHT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,NULL); }
| yD_RIGHT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,$5); }
2011-07-24 21:01:51 +02:00
| yD_RTOI '(' expr ')' { $$ = new AstRToIS($1,$3); }
2020-01-26 19:38:15 +01:00
| yD_SAMPLED '(' expr ')' { $$ = new AstSampled($1, $3); }
2015-10-03 13:12:56 +02:00
| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,false,$4); }
2019-11-23 15:16:06 +01:00
| yD_SHORTREALTOBITS '(' expr ')' { $$ = new AstRealToBits($1,$3); UNSUPREAL($1); }
2009-05-08 00:28:05 +02:00
| yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); }
2018-02-26 10:25:07 +01:00
| yD_SIN '(' expr ')' { $$ = new AstSinD($1,$3); }
| yD_SINH '(' expr ')' { $$ = new AstSinhD($1,$3); }
2017-11-23 16:17:56 +01:00
| yD_SIZE '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,NULL); }
| yD_SIZE '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,$5); }
2013-01-20 18:19:22 +01:00
| yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); }
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
2020-04-16 01:39:03 +02:00
| yD_STIME parenE { $$ = new AstSel($1, new AstTime($1, VTimescale(VTimescale::NONE)), 0, 32); }
2018-02-26 10:25:07 +01:00
| yD_TAN '(' expr ')' { $$ = new AstTanD($1,$3); }
| yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); }
2009-11-19 23:04:21 +01:00
| yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); }
2020-04-16 01:39:03 +02:00
| yD_TIME parenE { $$ = new AstTime($1, VTimescale(VTimescale::NONE)); }
2020-01-26 19:21:25 +01:00
| yD_TYPENAME '(' exprOrDataType ')' { $$ = new AstAttrOf($1, AstAttrType::TYPENAME, $3); }
2019-11-16 18:55:10 +01:00
| yD_UNGETC '(' expr ',' expr ')' { $$ = new AstFUngetC($1, $5, $3); } // Arg swap to file first
2017-11-23 16:17:56 +01:00
| yD_UNPACKED_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_UNPK_DIMENSIONS,$3); }
2009-05-08 00:28:05 +02:00
| yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); }
2017-05-19 04:41:43 +02:00
| yD_VALUEPLUSARGS '(' expr ',' expr ')' { $$ = new AstValuePlusArgs($1,$3,$5); }
2009-05-08 00:28:05 +02:00
;
2017-11-22 03:10:42 +01:00
elaboration_system_task<nodep>: // IEEE: elaboration_system_task (1800-2009)
// // TODO: These currently just make initial statements, should instead give runtime error
elaboration_system_task_guts ';' { $$ = new AstInitial($<fl>1, $1); }
;
elaboration_system_task_guts<nodep>: // IEEE: part of elaboration_system_task (1800-2009)
// // $fatal first argument is exit number, must be constant
2019-08-05 04:34:54 +02:00
yD_INFO parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_INFO, NULL); }
| yD_INFO '(' exprList ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_INFO, $3); }
| yD_WARNING parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_WARNING, NULL); }
| yD_WARNING '(' exprList ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_WARNING, $3); }
| yD_ERROR parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_ERROR, NULL); }
| yD_ERROR '(' exprList ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_ERROR, $3); }
| yD_FATAL parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_FATAL, NULL); }
| yD_FATAL '(' expr ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_FATAL, NULL); DEL($3); }
| yD_FATAL '(' expr ',' exprListE ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_FATAL, $5); DEL($3); }
2017-11-22 03:10:42 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPproperty_actual_arg<nodep>: // ==IEEE: property_actual_arg
//UNSUP // // IEEE: property_expr
//UNSUP // // IEEE: sequence_actual_arg
//UNSUP pev_expr { $$ = $1; }
//UNSUP // // IEEE: sequence_expr
//UNSUP // // property_expr already includes sequence_expr
//UNSUP ;
2016-03-15 02:51:31 +01:00
exprOrDataType<nodep>: // expr | data_type: combined to prevent conflicts
expr { $$ = $1; }
// // data_type includes id that overlaps expr, so special flavor
| data_type { $$ = $1; }
2017-11-23 16:17:56 +01:00
// // not in spec, but needed for $past(sig,1,,@(posedge clk))
//UNSUP event_control { }
2016-03-15 02:51:31 +01:00
;
2019-12-24 22:15:48 +01:00
//UNSUPexprOrDataTypeOrMinTypMax<nodep>: // exprOrDataType or mintypmax_expression
//UNSUP expr { $$ = $1; }
//UNSUP | expr ':' expr ':' expr { $$ = $3; }
//UNSUP // // data_type includes id that overlaps expr, so special flavor
//UNSUP | data_type { $$ = $1; }
//UNSUP // // not in spec, but needed for $past(sig,1,,@(posedge clk))
//UNSUP | event_control { $$ = $1; }
//UNSUP ;
//UNSUPexprOrDataTypeList<nodep>:
//UNSUP exprOrDataType { $$ = $1; }
//UNSUP | exprOrDataTypeList ',' exprOrDataType { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
2009-05-08 00:28:05 +02:00
list_of_argumentsE<nodep>: // IEEE: [list_of_arguments]
2013-08-18 02:34:49 +02:00
argsDottedList { $$ = $1; }
2018-02-02 03:32:58 +01:00
| argsExprListE { if (VN_IS($1, Arg) && VN_CAST($1, Arg)->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()'
2013-08-18 02:34:49 +02:00
/*cont*/ else $$ = $1; }
| argsExprListE ',' argsDottedList { $$ = $1->addNextNull($3); }
2006-08-26 13:35:28 +02:00
;
2009-11-03 04:50:31 +01:00
task_declaration<ftaskp>: // ==IEEE: task_declaration
2009-05-08 00:28:05 +02:00
yTASK lifetimeE taskId tfGuts yENDTASK endLabelE
2012-03-08 02:14:18 +01:00
{ $$ = $3; $$->addStmtsp($4); SYMP->popScope($$);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2012-03-08 02:14:18 +01:00
GRAMMARP->endLabel($<fl>6,$$,$6); }
2007-05-16 21:27:29 +02:00
;
2009-12-03 12:55:29 +01:00
task_prototype<ftaskp>: // ==IEEE: task_prototype
yTASK taskId '(' tf_port_listE ')' { $$=$2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); }
2018-10-09 04:18:09 +02:00
| yTASK taskId { $$=$2; $$->prototype(true); SYMP->popScope($$); }
2009-12-03 12:55:29 +01:00
;
2009-11-03 04:50:31 +01:00
function_declaration<ftaskp>: // IEEE: function_declaration + function_body_declaration
2009-11-03 04:14:11 +01:00
yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE
2009-11-03 04:50:31 +01:00
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2012-03-08 02:14:18 +01:00
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7,$$,$7); }
2019-12-23 21:03:04 +01:00
| yFUNCTION lifetimeE funcIdNew funcIsolateE tfGuts yENDFUNCTION endLabelE
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
2020-04-26 18:45:06 +02:00
$$->lifetime($2);
2019-12-23 21:03:04 +01:00
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7,$$,$7); }
2006-08-26 13:35:28 +02:00
;
2009-12-03 12:55:29 +01:00
function_prototype<ftaskp>: // IEEE: function_prototype
yFUNCTION funcId '(' tf_port_listE ')' { $$=$2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); }
2018-10-09 04:18:09 +02:00
| yFUNCTION funcId { $$=$2; $$->prototype(true); SYMP->popScope($$); }
2009-12-03 12:55:29 +01:00
;
2019-12-23 21:03:04 +01:00
class_constructor_prototype<ftaskp>: // ==IEEE: class_constructor_prototype
yFUNCTION funcIdNew '(' tf_port_listE ')' ';' { $$ = $2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); }
| yFUNCTION funcIdNew ';' { $$ = $2; $$->prototype(true); SYMP->popScope($$); }
;
2009-11-03 04:14:11 +01:00
funcIsolateE<cint>:
/* empty */ { $$ = 0; }
| yVL_ISOLATE_ASSIGNMENTS { $$ = 1; }
;
2013-12-21 12:51:15 +01:00
method_prototype:
task_prototype { }
| function_prototype { }
;
2020-04-26 18:45:06 +02:00
lifetimeE<lifetime>: // IEEE: [lifetime]
/* empty */ { $$ = VLifetime::NONE; }
| lifetime { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
2020-04-26 18:45:06 +02:00
lifetime<lifetime>: // ==IEEE: lifetime
2009-05-19 13:49:19 +02:00
// // Note lifetime used by members is instead under memberQual
2020-04-26 18:45:06 +02:00
ySTATIC__ETC { $$ = VLifetime::STATIC; BBUNSUP($1, "Unsupported: Static in this context"); }
| yAUTOMATIC { $$ = VLifetime::AUTOMATIC; }
2007-01-30 16:51:16 +01:00
;
2009-12-02 03:55:56 +01:00
taskId<ftaskp>:
2009-10-31 15:14:04 +01:00
tfIdScoped
{ $$ = new AstTask($<fl>1, *$<strp>1, NULL);
SYMP->pushNewUnder($$, NULL); }
2009-05-08 00:28:05 +02:00
;
2009-11-03 04:50:31 +01:00
funcId<ftaskp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
2009-10-31 15:08:38 +01: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 04:14:11 +01:00
/**/ tfIdScoped
2019-06-12 02:20:04 +02:00
{ $$ = new AstFunc($<fl>1,*$<strp>1,NULL,
new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
2009-11-03 04:14:11 +01:00
SYMP->pushNewUnder($$, NULL); }
| signingE rangeList tfIdScoped
2019-06-12 02:20:04 +02:00
{ $$ = new AstFunc($<fl>3,*$<strp>3,NULL,
GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
2009-11-03 04:14:11 +01:00
SYMP->pushNewUnder($$, NULL); }
| signing tfIdScoped
2019-06-12 02:20:04 +02:00
{ $$ = new AstFunc($<fl>2,*$<strp>2,NULL,
new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
2009-11-03 04:14:11 +01:00
SYMP->pushNewUnder($$, NULL); }
| data_type tfIdScoped
2019-06-12 02:20:04 +02:00
{ $$ = new AstFunc($<fl>2,*$<strp>2,NULL,$1);
2009-11-03 04:50:31 +01:00
SYMP->pushNewUnder($$, NULL); }
// // To verilator tasks are the same as void functions (we separately detect time passing)
| yVOID tfIdScoped
2019-06-12 02:20:04 +02:00
{ $$ = new AstTask($<fl>2,*$<strp>2,NULL);
2009-10-31 15:14:04 +01:00
SYMP->pushNewUnder($$, NULL); }
;
2019-12-23 21:03:04 +01:00
funcIdNew<ftaskp>: // IEEE: from class_constructor_declaration
yNEW__ETC
{ $$ = new AstFunc($<fl>1, "new", NULL, NULL);
2020-04-05 15:30:23 +02:00
$$->isConstructor(true);
2019-12-23 21:03:04 +01:00
SYMP->pushNewUnder($$, NULL); }
| yNEW__PAREN
{ $$ = new AstFunc($<fl>1, "new", NULL, NULL);
2020-04-05 15:30:23 +02:00
$$->isConstructor(true);
2019-12-23 21:03:04 +01:00
SYMP->pushNewUnder($$, NULL); }
| class_scopeWithoutId yNEW__PAREN
{ $$ = new AstFunc($<fl>2, "new", NULL, NULL);
BBUNSUP($<fl>2, "Unsupported: scoped new constructor");
2020-04-05 15:30:23 +02:00
$$->isConstructor(true);
2019-12-23 21:03:04 +01:00
SYMP->pushNewUnder($$, NULL); }
;
2009-10-31 15:14:04 +01:00
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
// // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
id { $<fl>$=$<fl>1; $<strp>$ = $1; }
2019-12-23 21:03:04 +01:00
| id/*interface_identifier*/ '.' id { $<fl>$=$<fl>3; $<strp>$ = $3; BBUNSUP($2, "Unsupported: Out of block function declaration"); }
| class_scopeIdFollows id { $<fl>$=$<fl>2; $<scp>$=$<scp>1; $<strp>$=$<strp>2;
BBUNSUP($<fl>1, "Unsupported: Out of class block function declaration"); }
2009-05-08 00:28:05 +02:00
;
2009-01-28 21:27:41 +01:00
tfGuts<nodep>:
2009-05-08 00:28:05 +02:00
'(' tf_port_listE ')' ';' tfBodyE { $$ = $2->addNextNull($5); }
| ';' tfBodyE { $$ = $2; }
2007-06-20 01:43:14 +02:00
;
2009-05-08 00:28:05 +02: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 13:35:28 +02:00
;
2009-05-08 00:28:05 +02: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 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
tf_item_declarationVerilator<nodep>: // Verilator extensions
2012-10-30 08:02:35 +01:00
yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); v3Global.dpi(true); }
2006-10-11 17:41:42 +02:00
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
tf_port_listE<nodep>: // IEEE: tf_port_list + empty
// // Empty covered by tf_port_item
2009-11-25 04:16:28 +01:00
{VARRESET_LIST(UNKNOWN); VARIO(INPUT); }
2010-01-22 02:08:45 +01:00
tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
2009-05-08 00:28:05 +02: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 14:06:04 +01:00
data_type { VARDTYPE($1); }
2013-01-14 04:18:57 +01:00
| signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1), $2, true)); }
2009-11-05 15:57:23 +01:00
| signing { VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $1)); }
2009-11-06 01:57:31 +01:00
| yVAR data_type { VARDTYPE($2); }
2009-12-18 02:58:14 +01:00
| yVAR implicit_typeE { VARDTYPE($2); }
2009-05-08 00:28:05 +02:00
//
2009-11-02 14:06:04 +01:00
| tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ }
| tf_port_itemDir data_type { VARDTYPE($2); }
2013-01-14 04:18:57 +01:00
| tf_port_itemDir signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2),$3,true)); }
2009-11-05 15:57:23 +01:00
| tf_port_itemDir signing { VARDTYPE(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $2)); }
2009-11-06 01:57:31 +01:00
| tf_port_itemDir yVAR data_type { VARDTYPE($3); }
2009-12-18 02:58:14 +01:00
| tf_port_itemDir yVAR implicit_typeE { VARDTYPE($3); }
2009-05-08 00:28:05 +02: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 13:49:19 +02:00
id variable_dimensionListE sigAttrListE
2011-01-19 03:12:31 +01:00
{ $$ = VARDONEA($<fl>1, *$1, $2, $3); }
2009-05-19 13:49:19 +02:00
| id variable_dimensionListE sigAttrListE '=' expr
2011-01-19 03:12:31 +01:00
{ $$ = VARDONEA($<fl>1, *$1, $2, $3); $$->valuep($5); }
2009-05-08 00:28:05 +02:00
;
2009-01-25 03:36:14 +01:00
parenE:
/* empty */ { }
2007-09-17 19:54:02 +02:00
| '(' ')' { }
;
2009-05-08 00:28:05 +02: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
2017-09-14 01:37:47 +02:00
array_methodNoRoot<nodep>:
yOR { $$ = new AstFuncRef($1, "or", NULL); }
| yAND { $$ = new AstFuncRef($1, "and", NULL); }
| yXOR { $$ = new AstFuncRef($1, "xor", NULL); }
2020-05-10 19:12:22 +02:00
| yUNIQUE { $$ = new AstFuncRef($1, "unique", NULL); }
2017-09-14 01:37:47 +02:00
;
2009-05-08 00:28:05 +02:00
2009-12-03 12:55:29 +01:00
dpi_import_export<nodep>: // ==IEEE: dpi_import_export
yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';'
2020-05-10 19:12:22 +02:00
{ $$ = $5; if (*$4 != "") $5->cname(*$4);
$5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE);
2009-12-04 13:05:44 +01: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 12:55:29 +01:00
| yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';'
2020-05-10 19:12:22 +02:00
{ $$ = $5; if (*$4 != "") $5->cname(*$4);
$5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE);
2009-12-04 13:05:44 +01: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($$); }
2020-05-10 19:12:22 +02:00
| yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';'
{ $$ = new AstDpiExport($<fl>5, *$5, *$3);
GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); }
| yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';'
{ $$ = new AstDpiExport($<fl>5, *$5, *$3);
GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); }
2009-12-03 12:55:29 +01:00
;
dpi_importLabelE<strp>: // IEEE: part of dpi_import_export
2018-10-14 05:06:36 +02:00
/* empty */ { static string s; $$ = &s; }
2009-12-03 12:55:29 +01:00
| 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 22:59:58 +02:00
//************************************************
// Expressions
2009-05-08 00:28:05 +02: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 22:59:58 +02:00
2008-08-06 18:35:34 +02:00
constExpr<nodep>:
expr { $$ = $1; }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02: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 12:03:07 +02:00
| '-' ~r~expr %prec prUNARYARITH { $$ = new AstNegate ($1,$2); }
2009-05-08 00:28:05 +02: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); }
2019-06-12 02:20:04 +02:00
| yP_NAND ~r~expr %prec prREDUCTION { $$ = new AstLogNot($1, new AstRedAnd($1, $2)); }
| yP_NOR ~r~expr %prec prREDUCTION { $$ = new AstLogNot($1, new AstRedOr($1, $2)); }
2009-05-08 00:28:05 +02:00
| 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); }
2019-06-02 01:40:06 +02:00
| ~l~expr yP_LTMINUSGT ~r~expr { $$ = new AstLogEq ($2,$1,$3); }
2019-12-24 22:15:48 +01:00
//
// // IEEE: expr yP_MINUSGT expr (1800-2009)
// // Conflicts with constraint_expression:"expr yP_MINUSGT constraint_set"
// // To duplicating expr for constraints, just allow the more general form
// // Later Ast processing must ignore constraint terms where inappropriate
//UNSUP ~l~expr yP_MINUSGT constraint_set { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
//UNSUP remove line below
| ~l~expr yP_MINUSGT ~r~expr { $$ = new AstLogIf($2, $1, $3); }
//
2009-05-08 00:28:05 +02:00
// // <= 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.
2019-12-24 22:15:48 +01:00
| ~l~expr yP_LTE~f__IGNORE~ ~r~expr { $$ = new AstLte($2, $1, $3); }
2009-05-08 00:28:05 +02:00
//
// // IEEE: conditional_expression
| ~l~expr '?' ~r~expr ':' ~r~expr { $$ = new AstCond($2,$1,$3,$5); }
//
// // IEEE: inside_expression
2013-02-02 18:55:28 +01:00
| ~l~expr yINSIDE '{' open_range_list '}' { $$ = new AstInside($2,$1,$4); }
2009-05-08 00:28:05 +02:00
//
// // IEEE: tagged_union_expression
//UNSUP yTAGGED id/*member*/ %prec prTAGGED { UNSUP }
//UNSUP yTAGGED id/*member*/ %prec prTAGGED expr { UNSUP }
//
//======================// IEEE: primary/constant_primary
//
// // IEEE: primary_literal (minus string, which is handled specially)
2009-10-31 15:08:38 +01:00
| yaINTNUM { $$ = new AstConst($<fl>1,*$1); }
2011-07-24 21:01:51 +02:00
| yaFLOATNUM { $$ = new AstConst($<fl>1,AstConst::RealDouble(),$1); }
2020-04-16 01:39:03 +02:00
| timeNumAdjusted { $$ = $1; }
2009-05-08 00:28:05 +02:00
| strAsInt~noStr__IGNORE~ { $$ = $1; }
//
// // IEEE: "... hierarchical_identifier select" see below
//
2018-03-13 03:26:34 +01:00
// // IEEE: empty_queue (IEEE 1800-2017 empty_unpacked_array_concatenation)
2019-06-01 03:05:50 +02:00
| '{' '}' { $$ = new AstConst($1, AstConst::LogicFalse());
$<fl>1->v3error("Unsupported: empty queues (\"{ }\")"); }
2009-02-25 23:16:51 +01:00
//
2009-01-28 21:27:41 +01:00
// // IEEE: concatenation/constant_concatenation
2009-05-08 00:28:05 +02:00
// // Part of exprOkLvalue below
//
// // IEEE: multiple_concatenation/constant_multiple_concatenation
2019-07-13 18:01:26 +02:00
| '{' constExpr '{' cateList '}' '}' { $$ = new AstReplicate($3, $4, $2); }
2019-12-24 22:15:48 +01:00
// // UNSUP some other rules above
2009-02-25 23:16:51 +01:00
//
2009-05-08 00:28:05 +02:00
| function_subroutine_callNoMethod { $$ = $1; }
// // method_call
2012-12-31 23:05:13 +01:00
| ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2,$1,$3); }
2009-05-08 00:28:05 +02:00
// // method_call:array_method requires a '.'
2017-09-14 01:37:47 +02:00
| ~l~expr '.' array_methodNoRoot { $$ = new AstDot($2,$1,$3); }
2009-02-25 23:16:51 +01:00
//
2012-10-09 02:45:39 +02:00
// // IEEE: let_expression
// // see funcRef
//
2009-05-08 00:28:05 +02:00
// // IEEE: '(' mintypmax_expression ')'
| ~noPar__IGNORE~'(' expr ')' { $$ = $2; }
2019-06-01 03:05:50 +02:00
| ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $$ = $2; BBUNSUP($1, "Unsupported: min typ max expressions"); }
2009-05-08 00:28:05 +02:00
// // PSL rule
2014-11-22 16:14:14 +01:00
| '_' '(' expr ')' { $$ = $3; } // Arbitrary Verilog inside PSL
2009-02-25 23:16:51 +01:00
//
2009-05-08 00:28:05 +02:00
// // IEEE: cast/constant_cast
2019-07-13 18:01:26 +02:00
| casting_type yP_TICK '(' expr ')' { $$ = new AstCast($1->fileline(), $4, $1); }
2011-03-18 03:25:49 +01:00
// // expanded from casting_type
| ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1,$4); }
| yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1,$4); }
2009-05-08 00:28:05 +02:00
// // Spec only allows primary with addition of a type reference
// // We'll be more general, and later assert LHS was a type.
2014-12-24 04:11:31 +01:00
| ~l~expr yP_TICK '(' expr ')' { $$ = new AstCastParse($2,$4,$1); }
2009-02-25 23:16:51 +01:00
//
2009-05-08 00:28:05 +02:00
// // IEEE: assignment_pattern_expression
// // IEEE: streaming_concatenation
// // See exprOkLvalue
2009-02-25 23:16:51 +01:00
//
2009-05-08 00:28:05 +02:00
// // IEEE: sequence_method_call
// // Indistinguishable from function_subroutine_call:method_call
//
2019-12-01 18:35:49 +01:00
| '$' { $$ = new AstUnbounded($<fl>1); }
2019-12-23 21:03:04 +01:00
| yNULL { $$ = new AstConst($1, AstConst::LogicFalse()); }
2009-05-08 00:28:05 +02:00
// // IEEE: yTHIS
// // See exprScope
//
//----------------------
//
2012-12-31 23:05:13 +01:00
// // Part of expr that may also be used as lvalue
2009-05-08 00:28:05 +02:00
| ~l~exprOkLvalue { $$ = $1; }
//
//----------------------
//
// // IEEE: cond_predicate - here to avoid reduce problems
// // Note expr includes cond_pattern
2019-06-01 03:05:50 +02:00
| ~l~expr yP_ANDANDAND ~r~expr { $$ = new AstConst($2, AstConst::LogicFalse());
2019-11-17 15:01:41 +01:00
BBUNSUP($<fl>2, "Unsupported: &&& expression"); }
2009-05-08 00:28:05 +02:00
//
// // 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 13:35:28 +02:00
;
2012-12-31 23:05:13 +01: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}
;
2019-12-24 22:15:48 +01:00
//UNSUPev_expr<nodep>: // IEEE: event_expression
//UNSUP // // for yOR/, see event_expression
//UNSUP //
//UNSUP // // IEEE: [ edge_identifier ] expression [ yIFF expression ]
//UNSUP // // expr alone see below
//UNSUP senitemEdge { $$ = $1; }
//UNSUP | ev_expr yIFF expr { }
//UNSUP //
//UNSUP // // IEEE: sequence_instance [ yIFF expression ]
//UNSUP // // seq_inst is in expr, so matches senitem rule above
//UNSUP //
//UNSUP // // IEEE: event_expression yOR event_expression
//UNSUP | ev_expr yOR ev_expr { }
//UNSUP // // IEEE: event_expression ',' event_expression
//UNSUP // // See real event_expression rule
//UNSUP //
//UNSUP //---------------------
//UNSUP // // IEEE: expr
//UNSUP | BISONPRE_COPY(expr,{s/~l~/ev_/g; s/~r~/ev_/g; s/~p~/ev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g;}) // {copied}
//UNSUP //
//UNSUP // // IEEE: '(' event_expression ')'
//UNSUP // // expr:'(' x ')' conflicts with event_expression:'(' event_expression ')'
//UNSUP // // so we use a special expression class
//UNSUP | '(' event_expression ')' { $<fl>$=$<fl>1; $$ = "(...)"; }
//UNSUP // // IEEE: From normal expr: '(' expr ':' expr ':' expr ')'
//UNSUP // // But must avoid conflict
//UNSUP | '(' event_expression ':' expr ':' expr ')' { $<fl>$=$<fl>1; $$ = "(...)"; }
//UNSUP ;
2009-05-08 00:28:05 +02: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
2014-05-04 02:20:15 +02:00
// // Replicate(1) required as otherwise "{a}" would not be self-determined
| '{' cateList '}' { $$ = new AstReplicate($1,$2,1); }
2019-03-14 00:52:23 +01:00
| '{' cateList '}' '[' expr ']' { $$ = new AstSelBit($4, new AstReplicate($1,$2,1), $5); }
| '{' cateList '}' '[' constExpr ':' constExpr ']'
{ $$ = new AstSelExtract($4, new AstReplicate($1,$2,1), $5, $7); }
| '{' cateList '}' '[' expr yP_PLUSCOLON constExpr ']'
{ $$ = new AstSelPlus($4, new AstReplicate($1,$2,1), $5, $7); }
| '{' cateList '}' '[' expr yP_MINUSCOLON constExpr ']'
{ $$ = new AstSelMinus($4, new AstReplicate($1,$2,1), $5, $7); }
2009-05-08 00:28:05 +02:00
// // IEEE: assignment_pattern_expression
2012-10-09 02:45:39 +02:00
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
2009-05-08 00:28:05 +02:00
// // We allow more here than the spec requires
//UNSUP ~l~exprScope assignment_pattern { UNSUP }
2019-10-16 01:06:00 +02:00
| data_type assignment_pattern { $$ = $2; if ($2) $2->childDTypep($1); }
2012-08-12 21:15:21 +02:00
| assignment_pattern { $$ = $1; }
2009-05-08 00:28:05 +02:00
//
2014-04-10 02:29:35 +02:00
| streaming_concatenation { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
2012-12-31 23:05:13 +01:00
fexprOkLvalue<nodep>: // exprOkLValue, For use as first part of statement (disambiguates <=)
BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g}) // {copied}
;
2019-12-24 22:15:48 +01:00
//UNSUPsexprOkLvalue<nodep>: // exprOkLValue, For use by sequence_expr
//UNSUP BISONPRE_COPY(exprOkLvalue,{s/~l~/s/g}) // {copied}
//UNSUP ;
//UNSUPpexprOkLvalue<nodep>: // exprOkLValue, For use by property_expr
//UNSUP BISONPRE_COPY(exprOkLvalue,{s/~l~/p/g}) // {copied}
//UNSUP ;
//UNSUPev_exprOkLvalue<nodep>: // exprOkLValue, For use by ev_expr
//UNSUP BISONPRE_COPY(exprOkLvalue,{s/~l~/ev_/g}) // {copied}
//UNSUP ;
//UNSUPpev_exprOkLvalue<nodep>: // exprOkLValue, For use by ev_expr
//UNSUP BISONPRE_COPY(exprOkLvalue,{s/~l~/pev_/g}) // {copied}
//UNSUP ;
2012-12-31 23:05:13 +01:00
fexprLvalue<nodep>: // For use as first part of statement (disambiguates <=)
fexprOkLvalue { $<fl>$=$<fl>1; $$ = $1; }
;
2009-05-08 00:28:05 +02: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 02:45:39 +02:00
// // (note method_call_root was simplified to require a primary in 1800-2009)
2009-05-08 00:28:05 +02: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
2019-12-23 21:03:04 +01:00
yTHIS { $$ = new AstConst($1, AstConst::LogicFalse());
BBUNSUP($1, "Unsupported: this"); }
2020-05-02 14:29:20 +02:00
| yD_ROOT { $$ = new AstParseRef($<fl>1, VParseRefExp::PX_ROOT, "$root"); }
2019-12-23 21:03:04 +01:00
| idArrayed { $$ = $1; }
2012-12-31 23:05:13 +01:00
| package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
2019-12-23 21:03:04 +01:00
| class_scopeIdFollows idArrayed { $$ = $2; BBUNSUP($<fl>1, "Unsupported: scoped class reference"); }
2012-12-31 23:05:13 +01:00
| ~l~expr '.' idArrayed { $$ = new AstDot($<fl>2,$1,$3); }
2009-05-08 00:28:05 +02:00
// // expr below must be a "yTHIS"
2019-12-23 21:03:04 +01:00
| ~l~expr '.' ySUPER { $$ = $1; BBUNSUP($3, "Unsupported: super"); }
2009-05-08 00:28:05 +02:00
// // Part of implicit_class_handle
2019-12-23 21:03:04 +01:00
| ySUPER { $$ = new AstConst($1, AstConst::LogicFalse());
BBUNSUP($1, "Unsupported: super"); }
2006-08-26 13:35:28 +02:00
;
2012-12-31 23:05:13 +01:00
fexprScope<nodep>: // exprScope, For use as first part of statement (disambiguates <=)
BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied}
;
2019-12-24 22:15:48 +01:00
//UNSUPsexprScope<nodep>: // exprScope, For use by sequence_expr
//UNSUP BISONPRE_COPY(exprScope,{s/~l~/s/g}) // {copied}
//UNSUP ;
//UNSUPpexprScope<nodep>: // exprScope, For use by property_expr
//UNSUP BISONPRE_COPY(exprScope,{s/~l~/p/g}) // {copied}
//UNSUP ;
//UNSUPev_exprScope<nodep>: // exprScope, For use by ev_expr
//UNSUP BISONPRE_COPY(exprScope,{s/~l~/ev_/g}) // {copied}
//UNSUP ;
//UNSUPpev_exprScope<nodep>: // exprScope, For use by ev_expr
//UNSUP BISONPRE_COPY(exprScope,{s/~l~/pev_/g}) // {copied}
//UNSUP ;
2006-08-26 13:35:28 +02: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 18:35:34 +02:00
exprStrText<nodep>:
exprNoStr { $$ = $1; }
2006-08-26 13:35:28 +02:00
| strAsText { $$ = $1; }
;
2008-08-06 18:35:34 +02:00
cStrList<nodep>:
exprStrText { $$ = $1; }
2006-08-26 13:35:28 +02:00
| exprStrText ',' cStrList { $$ = $1;$1->addNext($3); }
;
2008-08-06 18:35:34 +02:00
cateList<nodep>:
2009-05-08 00:28:05 +02:00
// // Not just 'expr' to prevent conflict via stream_concOrExprOrType
stream_expression { $$ = $1; }
| cateList ',' stream_expression { $$ = new AstConcat($2,$1,$3); }
2006-08-26 13:35:28 +02:00
;
2017-01-10 01:19:21 +01:00
exprListE<nodep>:
/* empty */ { $$ = NULL; }
| exprList { $$ = $1; }
;
2008-08-06 18:35:34 +02:00
exprList<nodep>:
expr { $$ = $1; }
2007-05-14 22:59:58 +02:00
| exprList ',' expr { $$ = $1;$1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
commaEListE<nodep>:
/* empty */ { $$ = NULL; }
2007-05-14 22:59:58 +02:00
| ',' exprList { $$ = $2; }
2007-03-06 22:43:38 +01:00
;
2008-08-06 18:35:34 +02:00
vrdList<nodep>:
2009-05-08 00:28:05 +02:00
idClassSel { $$ = $1; }
| vrdList ',' idClassSel { $$ = $1;$1->addNext($3); }
2008-07-01 20:15:10 +02:00
;
2008-08-06 18:35:34 +02:00
commaVRDListE<nodep>:
/* empty */ { $$ = NULL; }
2008-07-01 20:15:10 +02:00
| ',' vrdList { $$ = $2; }
;
2009-05-19 13:49:19 +02:00
argsExprList<nodep>: // IEEE: part of list_of_arguments (used where ,, isn't legal)
2009-05-08 00:28:05 +02:00
expr { $$ = $1; }
| argsExprList ',' expr { $$ = $1->addNext($3); }
;
2013-08-18 02:34:49 +02:00
argsExprListE<nodep>: // IEEE: part of list_of_arguments
argsExprOneE { $$ = $1; }
| argsExprListE ',' argsExprOneE { $$ = $1->addNext($3); }
;
2019-12-24 22:15:48 +01:00
//UNSUPpev_argsExprListE<nodep>: // IEEE: part of list_of_arguments - pev_expr at bottom
//UNSUP pev_argsExprOneE { $$ = $1; }
//UNSUP | pev_argsExprListE ',' pev_argsExprOneE { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
2013-08-18 02:34:49 +02:00
argsExprOneE<nodep>: // IEEE: part of list_of_arguments
2019-06-12 02:20:04 +02:00
/*empty*/ { $$ = new AstArg(CRELINE(), "", NULL); }
2019-07-13 18:01:26 +02:00
| expr { $$ = new AstArg($1->fileline(), "", $1); }
2013-08-18 02:34:49 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPpev_argsExprOneE<nodep>: // IEEE: part of list_of_arguments - pev_expr at bottom
//UNSUP /*empty*/ { $$ = NULL; } // ,, is legal in list_of_arguments
//UNSUP | pev_expr { $$ = $1; }
//UNSUP ;
2013-08-18 02:34:49 +02:00
argsDottedList<nodep>: // IEEE: part of list_of_arguments
argsDotted { $$ = $1; }
| argsDottedList ',' argsDotted { $$ = $1->addNextNull($3); }
;
2019-12-24 22:15:48 +01:00
//UNSUPpev_argsDottedList<nodep>: // IEEE: part of list_of_arguments - pev_expr at bottom
//UNSUP pev_argsDotted { $$ = $1; }
//UNSUP | pev_argsDottedList ',' pev_argsDotted { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
2013-08-18 02:34:49 +02:00
argsDotted<nodep>: // IEEE: part of list_of_arguments
2019-07-13 18:01:26 +02:00
'.' idAny '(' ')' { $$ = new AstArg($<fl>2, *$2, NULL); }
| '.' idAny '(' expr ')' { $$ = new AstArg($<fl>2, *$2, $4); }
2013-08-18 02:34:49 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPpev_argsDotted<nodep>: // IEEE: part of list_of_arguments - pev_expr at bottom
//UNSUP '.' idAny '(' ')' { $$ = new AstArg($<fl>2, *$2, NULL); }
//UNSUP | '.' idAny '(' pev_expr ')' { $$ = new AstArg($<fl>2, *$2, $4); }
//UNSUP ;
2014-04-10 02:29:35 +02:00
streaming_concatenation<nodep>: // ==IEEE: streaming_concatenation
// // Need to disambiguate {<< expr-{ ... expr-} stream_concat }
// // From {<< stream-{ ... stream-} }
// // Likewise simple_type's idScoped from constExpr's idScope
// // Thus we allow always any two operations. Sorry
// // IEEE: "'{' yP_SL/R stream_concatenation '}'"
// // IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'"
// // IEEE: "'{' yP_SL/R constExpr stream_concatenation '}'"
2019-07-13 18:01:26 +02:00
'{' yP_SLEFT stream_concOrExprOrType '}' { $$ = new AstStreamL($2, $3, new AstConst($2,1)); }
| '{' yP_SRIGHT stream_concOrExprOrType '}' { $$ = new AstStreamR($2, $3, new AstConst($2,1)); }
| '{' yP_SLEFT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamL($2, $4, $3); }
| '{' yP_SRIGHT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamR($2, $4, $3); }
2014-04-10 02:29:35 +02:00
;
stream_concOrExprOrType<nodep>: // IEEE: stream_concatenation | slice_size:simple_type | slice_size:constExpr
cateList { $$ = $1; }
| simple_type { $$ = $1; }
// // stream_concatenation found via cateList:stream_expr:'{-normal-concat'
// // simple_typeRef found via cateList:stream_expr:expr:id
// // constant_expression found via cateList:stream_expr:expr
;
stream_concatenation<nodep>: // ==IEEE: stream_concatenation
'{' cateList '}' { $$ = $2; }
;
2009-05-08 00:28:05 +02: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 22:59:58 +02:00
//************************************************
2006-08-26 13:35:28 +02:00
// Gate declarations
2007-05-14 22:59:58 +02:00
2008-08-06 18:35:34 +02:00
gateDecl<nodep>:
2009-01-06 17:57:25 +01: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 21:26:06 +02: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 17:03:57 +01:00
| yPULLUP delayE gatePullupList ';' { $$ = $3; }
| yPULLDOWN delayE gatePulldownList ';' { $$ = $3; }
2012-04-24 02:13:07 +02: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 04:08:48 +01: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 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateBufList<nodep>:
gateBuf { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateBufList ',' gateBuf { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2009-01-06 17:57:25 +01:00
gateBufif0List<nodep>:
gateBufif0 { $$ = $1; }
| gateBufif0List ',' gateBufif0 { $$ = $1->addNext($3); }
;
gateBufif1List<nodep>:
gateBufif1 { $$ = $1; }
| gateBufif1List ',' gateBufif1 { $$ = $1->addNext($3); }
;
2008-08-06 18:35:34 +02:00
gateNotList<nodep>:
gateNot { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateNotList ',' gateNot { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2009-01-06 17:57:25 +01:00
gateNotif0List<nodep>:
gateNotif0 { $$ = $1; }
| gateNotif0List ',' gateNotif0 { $$ = $1->addNext($3); }
;
gateNotif1List<nodep>:
gateNotif1 { $$ = $1; }
| gateNotif1List ',' gateNotif1 { $$ = $1->addNext($3); }
;
2008-08-06 18:35:34 +02:00
gateAndList<nodep>:
gateAnd { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateAndList ',' gateAnd { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateNandList<nodep>:
gateNand { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateNandList ',' gateNand { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateOrList<nodep>:
gateOr { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateOrList ',' gateOr { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateNorList<nodep>:
gateNor { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateNorList ',' gateNor { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateXorList<nodep>:
gateXor { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateXorList ',' gateXor { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateXnorList<nodep>:
gateXnor { $$ = $1; }
2008-05-06 16:52:53 +02:00
| gateXnorList ',' gateXnor { $$ = $1->addNext($3); }
2006-08-26 13:35:28 +02:00
;
2009-01-06 17:03:57 +01:00
gatePullupList<nodep>:
gatePullup { $$ = $1; }
| gatePullupList ',' gatePullup { $$ = $1->addNext($3); }
;
gatePulldownList<nodep>:
gatePulldown { $$ = $1; }
| gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); }
;
2010-01-08 04:08:48 +01:00
gateUnsupList<nodep>:
gateUnsup { $$ = $1; }
| gateUnsupList ',' gateUnsup { $$ = $1->addNext($3); }
;
2006-08-26 13:35:28 +02:00
2014-05-16 02:57:09 +02:00
gateRangeE<nodep>:
2019-09-13 01:06:26 +02:00
instRangeListE { $$ = $1; GATERANGE(GRAMMARP->scrubRange($1)); }
2014-05-16 02:57:09 +02:00
;
2009-10-31 04:17:56 +01:00
gateBuf<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gatePinExpr ')'
{ $$ = new AstAssignW($<fl>1, $2, $4); DEL($1); }
2020-05-10 17:01:57 +02:00
// UNSUP // IEEE: Multiple output variable_lvalues
// UNSUP // Causes conflict - need to take in variable_lvalue or a gatePinExpr
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateBufif0<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstBufIf1($<fl>1, new AstNot($<fl>1, $6), $4)); DEL($1); }
2009-01-06 17:57:25 +01:00
;
2009-10-31 04:17:56 +01:00
gateBufif1<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstBufIf1($<fl>1, $6, $4)); DEL($1); }
2009-01-06 17:57:25 +01:00
;
2009-10-31 04:17:56 +01:00
gateNot<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gatePinExpr ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstNot($<fl>1, $4)); DEL($1); }
2020-05-10 17:01:57 +02:00
// UNSUP // IEEE: Multiple output variable_lvalues
// UNSUP // Causes conflict - need to take in variable_lvalue or a gatePinExpr
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateNotif0<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstBufIf1($<fl>1, new AstNot($<fl>1, $6),
new AstNot($<fl>1, $4))); DEL($1); }
2009-01-06 17:57:25 +01:00
;
2009-10-31 04:17:56 +01:00
gateNotif1<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstBufIf1($<fl>1, $6, new AstNot($<fl>1, $4))); DEL($1); }
2009-01-06 17:57:25 +01:00
;
2009-10-31 04:17:56 +01:00
gateAnd<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gateAndPinList ')'
{ $$ = new AstAssignW($<fl>1, $2, $4); DEL($1); }
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateNand<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gateAndPinList ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstNot($<fl>1, $4)); DEL($1); }
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateOr<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gateOrPinList ')'
{ $$ = new AstAssignW($<fl>1, $2, $4); DEL($1); }
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateNor<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gateOrPinList ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstNot($<fl>1, $4)); DEL($1); }
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateXor<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gateXorPinList ')'
{ $$ = new AstAssignW($<fl>1, $2, $4); DEL($1); }
2006-08-26 13:35:28 +02:00
;
2009-10-31 04:17:56 +01:00
gateXnor<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ',' gateXorPinList ')'
{ $$ = new AstAssignW($<fl>1, $2, new AstNot($<fl>1, $4)); DEL($1); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
gatePullup<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ')' { $$ = new AstPull($<fl>1, $2, true); DEL($1); }
2009-01-06 17:03:57 +01:00
;
2009-05-08 00:28:05 +02:00
gatePulldown<nodep>:
2019-07-13 18:01:26 +02:00
gateFront variable_lvalue ')' { $$ = new AstPull($<fl>1, $2, false); DEL($1); }
2009-01-06 17:03:57 +01:00
;
2010-01-08 04:08:48 +01:00
gateUnsup<nodep>:
2019-07-13 18:01:26 +02:00
gateFront gateUnsupPinList ')' { $$ = new AstImplicit($<fl>1, $2); DEL($1); }
2010-01-08 04:08:48 +01:00
;
2019-07-13 18:01:26 +02:00
gateFront<nodep>:
id/*gate*/ gateRangeE '(' { $$ = $2; $<fl>$ = $<fl>1; }
| gateRangeE '(' { $$ = $1; $<fl>$ = $<fl>2; }
2007-05-14 22:59:58 +02:00
;
2008-08-06 18:35:34 +02:00
gateAndPinList<nodep>:
2014-05-16 02:57:09 +02:00
gatePinExpr { $$ = $1; }
| gateAndPinList ',' gatePinExpr { $$ = new AstAnd($2,$1,$3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateOrPinList<nodep>:
2014-05-16 02:57:09 +02:00
gatePinExpr { $$ = $1; }
| gateOrPinList ',' gatePinExpr { $$ = new AstOr($2,$1,$3); }
2006-08-26 13:35:28 +02:00
;
2008-08-06 18:35:34 +02:00
gateXorPinList<nodep>:
2014-05-16 02:57:09 +02:00
gatePinExpr { $$ = $1; }
| gateXorPinList ',' gatePinExpr { $$ = new AstXor($2,$1,$3); }
2006-08-26 13:35:28 +02:00
;
2010-01-08 04:08:48 +01:00
gateUnsupPinList<nodep>:
2014-05-16 02:57:09 +02:00
gatePinExpr { $$ = $1; }
| gateUnsupPinList ',' gatePinExpr { $$ = $1->addNext($3); }
;
gatePinExpr<nodep>:
expr { $$ = GRAMMARP ->createGatePin($1); }
2010-01-08 04:08:48 +01:00
;
2006-08-26 13:35:28 +02:00
2019-06-01 03:05:50 +02:00
// This list is also hardcoded in VParseLex.l
strength: // IEEE: strength0+strength1 - plus HIGHZ/SMALL/MEDIUM/LARGE
ygenSTRENGTH { BBUNSUP($1, "Unsupported: Verilog 1995 strength specifiers"); }
| ySUPPLY0 { BBUNSUP($1, "Unsupported: Verilog 1995 strength specifiers"); }
| ySUPPLY1 { BBUNSUP($1, "Unsupported: Verilog 1995 strength specifiers"); }
;
2009-05-08 00:28:05 +02:00
strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
/* empty */ { }
2019-06-01 03:05:50 +02:00
| strengthSpec { }
;
strengthSpec: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
yP_PAR__STRENGTH strength ')' { }
| yP_PAR__STRENGTH strength ',' strength ')' { }
2009-05-08 00:28:05 +02:00
;
2007-05-16 14:55:25 +02:00
//************************************************
// Tables
2009-11-21 01:53:40 +01:00
2012-10-09 03:20:13 +02:00
combinational_body<nodep>: // IEEE: combinational_body + sequential_body
2009-11-21 01:53:40 +01:00
yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); }
;
tableEntryList<nodep>: // IEEE: { combinational_entry | sequential_entry }
tableEntry { $$ = $1; }
2019-10-16 01:06:00 +02:00
| tableEntryList tableEntry { $$ = $1->addNextNull($2); }
2009-11-21 01:53:40 +01:00
;
tableEntry<nodep>: // IEEE: combinational_entry + sequential_entry
2010-01-09 21:44:06 +01:00
yaTABLELINE { $$ = new AstUdpTableLine($<fl>1,*$1); }
2009-11-21 01:53:40 +01:00
| error { $$ = NULL; }
;
2007-05-16 14:55:25 +02:00
2006-08-26 13:35:28 +02:00
//************************************************
// Specify
2007-05-14 22:59:58 +02:00
2009-01-28 21:27:41 +01:00
specify_block<nodep>: // ==IEEE: specify_block
ySPECIFY specifyJunkList yENDSPECIFY { $$ = NULL; }
| ySPECIFY yENDSPECIFY { $$ = NULL; }
;
2009-01-25 03:36:14 +01:00
specifyJunkList:
specifyJunk { } /* ignored */
| specifyJunkList specifyJunk { } /* ignored */
;
2007-05-18 20:48:22 +02:00
2009-01-25 03:36:14 +01:00
specifyJunk:
BISONPRE_NOT(ySPECIFY,yENDSPECIFY) { }
| ySPECIFY specifyJunk yENDSPECIFY { }
2007-05-18 20:48:22 +02:00
| error {}
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
specparam_declaration<nodep>: // ==IEEE: specparam_declaration
2010-02-18 14:43:16 +01:00
ySPECPARAM junkToSemiList ';' { $$ = NULL; }
2009-05-08 00:28:05 +02:00
;
2010-02-18 14:43:16 +01:00
junkToSemiList:
junkToSemi { } /* ignored */
| junkToSemiList junkToSemi { } /* ignored */
;
2011-05-10 05:58:38 +02:00
2009-05-08 00:28:05 +02:00
junkToSemi:
BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { }
| error {}
;
2006-08-26 13:35:28 +02:00
//************************************************
// IDs
2006-12-21 22:53:51 +01:00
2009-05-08 00:28:05 +02:00
id<strp>:
2009-10-31 15:08:38 +01:00
yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
2009-05-08 00:28:05 +02:00
;
idAny<strp>: // Any kind of identifier
2009-11-08 03:05:02 +01:00
yaID__aPACKAGE { $$ = $1; $<fl>$=$<fl>1; }
| yaID__aTYPE { $$ = $1; $<fl>$=$<fl>1; }
2009-11-07 05:16:06 +01:00
| yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
2009-05-08 00:28:05 +02:00
;
2019-12-23 21:03:04 +01:00
idRefDType<refdtypep>: // IEEE: class_identifier or other type identifier
// Used where reference is needed
yaID__aTYPE { $$ = new AstRefDType($<fl>1, *$1); }
;
2009-09-07 21:54:12 +02:00
idSVKwd<strp>: // Warn about non-forward compatible Verilog 2001 code
// // yBIT, yBYTE won't work here as causes conflicts
2011-01-19 03:12:31 +01: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 21:54:12 +02:00
;
2009-05-08 00:28:05 +02: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 }
2014-04-10 02:29:35 +02:00
| streaming_concatenation { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
variable_lvalueConcList<nodep>: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}'
variable_lvalue { $$ = $1; }
| variable_lvalueConcList ',' variable_lvalue { $$ = new AstConcat($2,$1,$3); }
;
2019-12-24 22:15:48 +01:00
//UNSUPvariable_lvalueList<nodep>: // IEEE: part of variable_lvalue: variable_lvalue { ',' variable_lvalue }
//UNSUP variable_lvalue { $$ = $1; }
//UNSUP | variable_lvalueList ',' variable_lvalue { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
2007-05-14 22:59:58 +02:00
// VarRef to dotted, and/or arrayed, and/or bit-ranged variable
2012-12-31 23:05:13 +01:00
idClassSel<nodep>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
idDotted { $$ = $1; }
2009-05-08 00:28:05 +02:00
// // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
2019-12-23 21:03:04 +01:00
| yTHIS '.' idDotted { $$ = $3; BBUNSUP($1, "Unsupported: this"); }
| ySUPER '.' idDotted { $$ = $3; BBUNSUP($1, "Unsupported: super"); }
| yTHIS '.' ySUPER '.' idDotted { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); }
2009-05-08 00:28:05 +02:00
// // Expanded: package_scope idDotted
2019-12-23 21:03:04 +01:00
| class_scopeIdFollows idDotted { $$ = $2; BBUNSUP($2, "Unsupported: package scoped id"); }
| package_scopeIdFollows idDotted { $$ = $2; BBUNSUP($2, "Unsupported: class scoped id"); }
2007-05-14 22:59:58 +02:00
;
2008-08-06 18:35:34 +02:00
idDotted<nodep>:
2020-05-02 14:29:20 +02:00
yD_ROOT '.' idDottedMore
{ $$ = new AstDot($2, new AstParseRef($<fl>1, VParseRefExp::PX_ROOT, "$root"), $3); }
| idDottedMore { $$ = $1; }
2009-05-08 00:28:05 +02:00
;
idDottedMore<nodep>:
2008-08-06 18:35:34 +02:00
idArrayed { $$ = $1; }
2012-12-03 00:03:34 +01:00
| idDottedMore '.' idArrayed { $$ = new AstDot($2,$1,$3); }
2007-05-14 22:59:58 +02:00
;
2006-12-21 22:53:51 +01: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-08 00:28:05 +02:00
// id below includes:
// enum_identifier
idArrayed<nodep>: // IEEE: id + select
2019-10-05 13:54:14 +02:00
id { $$ = new AstParseRef($<fl>1,VParseRefExp::PX_TEXT,*$1,NULL,NULL); }
2009-02-25 23:16:51 +01:00
// // IEEE: id + part_select_range/constant_part_select_range
2006-12-21 22:53:51 +01: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 23:16:51 +01:00
// // IEEE: id + indexed_range/constant_indexed_range
2007-05-14 22:59:58 +02:00
| idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus($2,$1,$3,$5); }
2007-05-12 18:29:25 +02:00
| idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); }
2006-08-26 13:35:28 +02:00
;
2016-09-20 04:00:13 +02:00
idClassForeach<nodep>:
idForeach { $$ = $1; }
| package_scopeIdFollows idForeach { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
;
idForeach<nodep>:
varRefBase { $$ = $1; }
| idForeach '.' varRefBase { $$ = new AstDot($2,$1,$3); }
;
2006-12-21 22:53:51 +01:00
// VarRef without any dots or vectorizaion
2010-01-08 04:08:48 +01:00
varRefBase<varrefp>:
2011-01-19 03:12:31 +01:00
id { $$ = new AstVarRef($<fl>1,*$1,false);}
2006-08-26 13:35:28 +02:00
;
2009-10-23 03:16:52 +02:00
// yaSTRING shouldn't be used directly, instead via an abstraction below
str<strp>: // yaSTRING but with \{escapes} need decoded
2009-10-31 15:08:38 +01:00
yaSTRING { $$ = PARSEP->newString(GRAMMARP->deQuote($<fl>1,*$1)); }
2009-10-23 03:16:52 +02:00
;
2008-08-06 18:35:34 +02:00
strAsInt<nodep>:
2019-05-10 02:03:19 +02:00
yaSTRING { $$ = new AstConst($<fl>1, AstConst::VerilogStringLiteral(), GRAMMARP->deQuote($<fl>1, *$1));}
2006-12-20 17:10:47 +01:00
;
2009-05-08 00:28:05 +02:00
strAsIntIgnore<nodep>: // strAsInt, but never matches for when expr shouldn't parse strings
yaSTRING__IGNORE { $$ = NULL; yyerror("Impossible token"); }
2006-08-26 13:35:28 +02:00
;
2009-05-08 00:28:05 +02:00
strAsText<nodep>:
2009-10-31 15:08:38 +01:00
yaSTRING { $$ = GRAMMARP->createTextQuoted($<fl>1,*$1);}
2006-08-26 13:35:28 +02:00
;
2012-03-08 02:14:18 +01:00
endLabelE<strp>:
/* empty */ { $$ = NULL; $<fl>$=NULL; }
| ':' idAny { $$ = $2; $<fl>$=$<fl>2; }
2019-12-23 21:03:04 +01:00
| ':' yNEW__ETC { static string n = "new"; $$ = &n; $<fl>$=$<fl>2; }
2007-07-18 19:58:53 +02:00
;
2007-05-14 22:59:58 +02:00
//************************************************
2009-05-08 00:28:05 +02:00
// Clocking
2006-08-26 13:35:28 +02:00
2008-08-06 18:52:39 +02:00
clocking_declaration<nodep>: // IEEE: clocking_declaration (INCOMPLETE)
2019-12-23 22:26:59 +01:00
//UNSUP: vvv remove this -- vastly simplified grammar:
2008-08-06 23:51:36 +02:00
yDEFAULT yCLOCKING '@' '(' senitemEdge ')' ';' yENDCLOCKING
2019-07-13 18:01:26 +02:00
{ $$ = new AstClocking($2, $5, NULL); }
2019-12-23 22:26:59 +01:00
//UNSUP: ^^^ remove this -- vastly simplified grammar:
//UNSUP clockingFront clocking_event ';'
//UNSUP clocking_itemListE yENDCLOCKING endLabelE { SYMP->popScope($$); }
;
//UNSUPclockingFront: // IEEE: part of class_declaration
//UNSUP yCLOCKING { PARSEP->symPushNewAnon(VAstType::CLOCKING); }
//UNSUP | yCLOCKING idAny/*clocking_identifier*/ { SYMP->pushNew($$); }
//UNSUP | yDEFAULT yCLOCKING { PARSEP->symPushNewAnon(VAstType::CLOCKING); }
//UNSUP | yDEFAULT yCLOCKING idAny/*clocking_identifier*/ { SYMP->pushNew($$); }
//UNSUP | yGLOBAL__CLOCKING yCLOCKING { PARSEP->symPushNewAnon(VAstType::CLOCKING); }
//UNSUP | yGLOBAL__CLOCKING yCLOCKING idAny/*clocking_identifier*/ { SYMP->pushNew($$); }
//UNSUP ;
//UNSUPclocking_event: // ==IEEE: clocking_event
//UNSUP '@' id { }
//UNSUP | '@' '(' event_expression ')' { }
//UNSUP ;
//UNSUPclocking_itemListE:
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | clocking_itemList { $$ = $1; }
//UNSUP ;
//UNSUPclocking_itemList: // IEEE: [ clocking_item ]
//UNSUP clocking_item { $$ = $1; }
//UNSUP | clocking_itemList clocking_item { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPclocking_item: // ==IEEE: clocking_item
//UNSUP yDEFAULT default_skew ';' { }
//UNSUP | clocking_direction list_of_clocking_decl_assign ';' { }
//UNSUP | assertion_item_declaration { }
//UNSUP ;
//UNSUPdefault_skew: // ==IEEE: default_skew
//UNSUP yINPUT clocking_skew { }
//UNSUP | yOUTPUT clocking_skew { }
//UNSUP | yINPUT clocking_skew yOUTPUT clocking_skew { }
//UNSUP ;
//UNSUPclocking_direction: // ==IEEE: clocking_direction
//UNSUP yINPUT clocking_skewE { }
//UNSUP | yOUTPUT clocking_skewE { }
//UNSUP | yINPUT clocking_skewE yOUTPUT clocking_skewE { }
//UNSUP | yINOUT { }
//UNSUP ;
//UNSUPlist_of_clocking_decl_assign: // ==IEEE: list_of_clocking_decl_assign
//UNSUP clocking_decl_assign { $$ = $1; }
//UNSUP | list_of_clocking_decl_assign ',' clocking_decl_assign { }
//UNSUP ;
//UNSUPclocking_decl_assign: // ==IEEE: clocking_decl_assign
//UNSUP idAny/*new-signal_identifier*/ { $$ = $1; }
//UNSUP | idAny/*new-signal_identifier*/ '=' expr { }
//UNSUP ;
//UNSUPclocking_skewE: // IEEE: [clocking_skew]
//UNSUP /* empty */ { $$ = NULL;}
//UNSUP | clocking_skew { $$ = $1; }
//UNSUP ;
//UNSUPclocking_skew: // ==IEEE: clocking_skew
//UNSUP yPOSEDGE { }
//UNSUP | yPOSEDGE delay_control { }
//UNSUP | yNEGEDGE { }
//UNSUP | yNEGEDGE delay_control { }
//UNSUP | yEDGE { NEED_S09($<fl>1,"edge"); }
//UNSUP | yEDGE delay_control { NEED_S09($<fl>1,"edge"); }
//UNSUP | delay_control { $$ = $1; }
//UNSUP ;
//UNSUPcycle_delay: // ==IEEE: cycle_delay
//UNSUP yP_POUNDPOUND yaINTNUM { }
//UNSUP | yP_POUNDPOUND id { }
//UNSUP | yP_POUNDPOUND '(' expr ')' { }
//UNSUP ;
2008-08-06 18:52:39 +02:00
2009-05-08 00:28:05 +02:00
//************************************************
// Asserts
2019-12-23 22:26:59 +01:00
//UNSUPassertion_item_declaration: // ==IEEE: assertion_item_declaration
//UNSUP property_declaration { $$ = $1; }
//UNSUP | sequence_declaration { $$ = $1; }
//UNSUP | let_declaration { $$ = $1; }
//UNSUP ;
2019-05-31 13:33:57 +02:00
assertion_item<nodep>: // ==IEEE: assertion_item
concurrent_assertion_item { $$ = $1; }
2019-12-17 03:43:52 +01:00
| deferred_immediate_assertion_item
{ $$ = $1 ? new AstAlways($1->fileline(), VAlwaysKwd::ALWAYS_COMB, NULL, $1) : NULL; }
2019-05-31 13:33:57 +02:00
;
deferred_immediate_assertion_item<nodep>: // ==IEEE: deferred_immediate_assertion_item
deferred_immediate_assertion_statement { $$ = $1; }
| id/*block_identifier*/ ':' deferred_immediate_assertion_statement
2020-02-26 04:21:16 +01:00
{ $$ = new AstBegin($<fl>1, *$1, $3, false, true); }
2019-05-31 13:33:57 +02:00
;
procedural_assertion_statement<nodep>: // ==IEEE: procedural_assertion_statement
concurrent_assertion_statement { $$ = $1; }
| immediate_assertion_statement { $$ = $1; }
// // IEEE: checker_instantiation
// // Unlike modules, checkers are the only "id id (...)" form in statements.
2019-06-01 03:05:50 +02:00
//UNSUP checker_instantiation { $$ = $1; }
2019-05-31 13:33:57 +02:00
;
immediate_assertion_statement<nodep>: // ==IEEE: immediate_assertion_statement
simple_immediate_assertion_statement { $$ = $1; }
| deferred_immediate_assertion_statement { $$ = $1; }
;
simple_immediate_assertion_statement<nodep>: // ==IEEE: simple_immediate_assertion_statement
2019-12-17 03:43:52 +01:00
// // action_block expanded here, for compatibility with AstAssert
yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstAssert($1, $3, $5, NULL, true); }
| yASSERT '(' expr ')' yELSE stmtBlock { $$ = new AstAssert($1, $3, NULL, $6, true); }
| yASSERT '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstAssert($1, $3, $5, $7, true); }
// // action_block expanded here, for compatibility with AstAssert
| yASSUME '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstAssert($1, $3, $5, NULL, true); }
| yASSUME '(' expr ')' yELSE stmtBlock { $$ = new AstAssert($1, $3, NULL, $6, true); }
| yASSUME '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstAssert($1, $3, $5, $7, true); }
2019-05-31 13:33:57 +02:00
// // IEEE: simple_immediate_cover_statement
2019-12-17 03:43:52 +01:00
| yCOVER '(' expr ')' stmt { $$ = new AstCover($1, $3, $5, true); }
2019-05-31 13:33:57 +02:00
;
final_zero: // IEEE: part of deferred_immediate_assertion_statement
'#' yaINTNUM
2020-01-31 02:23:57 +01:00
{ if ($2->isNeqZero()) { $<fl>2->v3error("Deferred assertions must use '#0' (IEEE 1800-2017 16.4)"); } }
2019-05-31 13:33:57 +02:00
// // 1800-2012:
| yFINAL { }
;
deferred_immediate_assertion_statement<nodep>: // ==IEEE: deferred_immediate_assertion_statement
// // IEEE: deferred_immediate_assert_statement
2019-12-17 03:43:52 +01:00
yASSERT final_zero '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstAssert($1, $4, $6, NULL, true); }
| yASSERT final_zero '(' expr ')' yELSE stmtBlock { $$ = new AstAssert($1, $4, NULL, $7, true); }
| yASSERT final_zero '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstAssert($1, $4, $6, $8, true); }
2019-05-31 13:33:57 +02:00
// // IEEE: deferred_immediate_assume_statement
2019-12-17 03:43:52 +01:00
| yASSUME final_zero '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstAssert($1, $4, $6, NULL, true); }
| yASSUME final_zero '(' expr ')' yELSE stmtBlock { $$ = new AstAssert($1, $4, NULL, $7, true); }
| yASSUME final_zero '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstAssert($1, $4, $6, $8, true); }
2019-05-31 13:33:57 +02:00
// // IEEE: deferred_immediate_cover_statement
2019-12-17 03:43:52 +01:00
| yCOVER final_zero '(' expr ')' stmt { $$ = new AstCover($1, $4, $6, true); }
2008-08-06 18:52:39 +02:00
;
2019-12-23 22:26:59 +01:00
//UNSUPexpect_property_statement<nodep>: // ==IEEE: expect_property_statement
//UNSUP yEXPECT '(' property_spec ')' action_block { }
//UNSUP ;
2009-05-08 00:28:05 +02:00
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
concurrent_assertion_statement { $$ = $1; }
2020-02-26 04:21:16 +01:00
| id/*block_identifier*/ ':' concurrent_assertion_statement
{ $$ = new AstBegin($<fl>1, *$1, $3, false, true); }
2012-10-09 03:20:13 +02:00
// // IEEE: checker_instantiation
// // identical to module_instantiation; see etcInst
2008-08-06 18:52:39 +02:00
;
2009-05-08 00:28:05 +02:00
concurrent_assertion_statement<nodep>: // ==IEEE: concurrent_assertion_statement
2019-05-31 13:33:57 +02:00
// // IEEE: assert_property_statement
2019-12-24 22:15:48 +01:00
//UNSUP remove below:
2019-12-17 03:43:52 +01:00
yASSERT yPROPERTY '(' property_spec ')' elseStmtBlock { $$ = new AstAssert($1, $4, NULL, $6, false); }
2019-12-24 22:15:48 +01:00
//UNSUP yASSERT yPROPERTY '(' property_spec ')' action_block { }
// // IEEE: assume_property_statement
//UNSUP yASSUME yPROPERTY '(' property_spec ')' action_block { }
2019-05-31 13:33:57 +02:00
// // IEEE: cover_property_statement
2019-12-17 03:43:52 +01:00
| yCOVER yPROPERTY '(' property_spec ')' stmtBlock { $$ = new AstCover($1, $4, $6, false); }
2019-12-24 22:15:48 +01:00
// // IEEE: cover_sequence_statement
//UNSUP yCOVER ySEQUENCE '(' sexpr ')' stmt { }
// // IEEE: yCOVER ySEQUENCE '(' clocking_event sexpr ')' stmt
// // sexpr already includes "clocking_event sexpr"
//UNSUP yCOVER ySEQUENCE '(' clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt { }
//UNSUP yCOVER ySEQUENCE '(' yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt { }
2018-09-23 21:20:12 +02:00
// // IEEE: restrict_property_statement
2019-12-17 03:43:52 +01:00
| yRESTRICT yPROPERTY '(' property_spec ')' ';' { $$ = new AstRestrict($1, $4); }
2018-03-11 15:37:20 +01:00
;
elseStmtBlock<nodep>: // Part of concurrent_assertion_statement
';' { $$ = NULL; }
| yELSE stmtBlock { $$ = $2; }
2008-08-06 18:52:39 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPproperty_declaration<nodep>: // ==IEEE: property_declaration
//UNSUP property_declarationFront property_port_listE ';' property_declarationBody
//UNSUP yENDPROPERTY endLabelE
//UNSUP { SYMP->popScope($$); }
//UNSUP ;
//UNSUPproperty_declarationFront<nodep>: // IEEE: part of property_declaration
//UNSUP yPROPERTY idAny/*property_identifier*/
//UNSUP { SYMP->pushNew($$); }
//UNSUP ;
//UNSUPproperty_port_listE<nodep>: // IEEE: [ ( [ property_port_list ] ) ]
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | '(' {VARRESET_LIST(""); VARIO("input"); } property_port_list ')'
//UNSUP { VARRESET_NONLIST(""); }
//UNSUP ;
//UNSUPproperty_port_list<nodep>: // ==IEEE: property_port_list
//UNSUP property_port_item { $$ = $1; }
//UNSUP | property_port_list ',' property_port_item { }
//UNSUP ;
//UNSUPproperty_port_item<nodep>: // IEEE: property_port_item/sequence_port_item
//UNSUP // // Merged in sequence_port_item
//UNSUP // // IEEE: property_lvar_port_direction ::= yINPUT
//UNSUP // // prop IEEE: [ yLOCAL [ yINPUT ] ] property_formal_type
//UNSUP // // id {variable_dimension} [ '=' property_actual_arg ]
//UNSUP // // seq IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
//UNSUP // // id {variable_dimension} [ '=' sequence_actual_arg ]
//UNSUP property_port_itemFront property_port_itemAssignment { }
//UNSUP ;
//UNSUPproperty_port_itemFront: // IEEE: part of property_port_item/sequence_port_item
//UNSUP property_port_itemDirE property_formal_typeNoDt { VARDTYPE($2); }
//UNSUP // // data_type_or_implicit
//UNSUP | property_port_itemDirE data_type { VARDTYPE($2); }
//UNSUP | property_port_itemDirE yVAR data_type { VARDTYPE($3); }
//UNSUP | property_port_itemDirE yVAR implicit_typeE { VARDTYPE($3); }
//UNSUP | property_port_itemDirE signingE rangeList { VARDTYPE(SPACED($2,$3)); }
//UNSUP | property_port_itemDirE /*implicit*/ { /*VARDTYPE-same*/ }
//UNSUP ;
//UNSUPproperty_port_itemAssignment<nodep>: // IEEE: part of property_port_item/sequence_port_item/checker_port_direction
//UNSUP portSig variable_dimensionListE { VARDONE($<fl>1, $1, $2, ""); PINNUMINC(); }
//UNSUP | portSig variable_dimensionListE '=' property_actual_arg
//UNSUP { VARDONE($<fl>1, $1, $2, $4); PINNUMINC(); }
//UNSUP ;
//UNSUPproperty_port_itemDirE:
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | yLOCAL__ETC { }
//UNSUP | yLOCAL__ETC port_direction { }
//UNSUP ;
//UNSUPproperty_declarationBody<nodep>: // IEEE: part of property_declaration
//UNSUP assertion_variable_declarationList property_statement_spec { }
//UNSUP // // IEEE-2012: Incorectly hasyCOVER ySEQUENCE then property_spec here.
//UNSUP // // Fixed in IEEE 1800-2017
//UNSUP | property_statement_spec { $$ = $1; }
//UNSUP ;
//UNSUPassertion_variable_declarationList: // IEEE: part of assertion_variable_declaration
//UNSUP assertion_variable_declaration { $$ = $1; }
//UNSUP | assertion_variable_declarationList assertion_variable_declaration { }
//UNSUP ;
//UNSUPsequence_declaration<nodep>: // ==IEEE: sequence_declaration
//UNSUP sequence_declarationFront sequence_port_listE ';' sequence_declarationBody
//UNSUP yENDSEQUENCE endLabelE
//UNSUP { SYMP->popScope($$); }
//UNSUP ;
//UNSUPsequence_declarationFront<nodep>: // IEEE: part of sequence_declaration
//UNSUP ySEQUENCE idAny/*new_sequence*/
//UNSUP { SYMP->pushNew($$); }
//UNSUP ;
//UNSUPsequence_port_listE<nodep>: // IEEE: [ ( [ sequence_port_list ] ) ]
//UNSUP // // IEEE: sequence_lvar_port_direction ::= yINPUT | yINOUT | yOUTPUT
//UNSUP // // IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
//UNSUP // // id {variable_dimension} [ '=' sequence_actual_arg ]
//UNSUP // // All this is almost identically the same as a property.
//UNSUP // // Difference is only yINOUT/yOUTPUT (which might be added to 1800-2012)
//UNSUP // // and yPROPERTY. So save some work.
//UNSUP property_port_listE { $$ = $1; }
//UNSUP ;
//UNSUPproperty_formal_typeNoDt<nodep>: // IEEE: property_formal_type (w/o implicit)
//UNSUP sequence_formal_typeNoDt { $$ = $1; }
//UNSUP | yPROPERTY { }
//UNSUP ;
//UNSUPsequence_formal_typeNoDt<nodep>: // ==IEEE: sequence_formal_type (w/o data_type_or_implicit)
//UNSUP // // IEEE: data_type_or_implicit
//UNSUP // // implicit expanded where used
//UNSUP ySEQUENCE { }
//UNSUP // // IEEE-2009: yEVENT
//UNSUP // // already part of data_type. Removed in 1800-2012.
//UNSUP | yUNTYPED { }
//UNSUP ;
//UNSUPsequence_declarationBody<nodep>: // IEEE: part of sequence_declaration
//UNSUP // // 1800-2012 makes ';' optional
//UNSUP assertion_variable_declarationList sexpr { }
//UNSUP | assertion_variable_declarationList sexpr ';' { }
//UNSUP | sexpr { $$ = $1; }
//UNSUP | sexpr ';' { $$ = $1; }
//UNSUP ;
2008-08-06 18:52:39 +02:00
property_spec<nodep>: // IEEE: property_spec
2009-05-08 00:28:05 +02:00
//UNSUP: This rule has been super-specialized to what is supported now
2019-12-24 22:15:48 +01:00
//UNSUP remove below
2019-12-24 22:04:28 +01:00
'@' '(' senitemEdge ')' yDISABLE yIFF '(' expr ')' pexpr
2019-12-17 03:43:52 +01:00
{ $$ = new AstPropClocked($1, $3, $8, $10); }
2019-12-24 22:04:28 +01:00
| '@' '(' senitemEdge ')' pexpr { $$ = new AstPropClocked($1, $3, NULL, $5); }
2019-12-24 22:15:48 +01:00
//UNSUP remove above
2019-12-24 22:04:28 +01:00
| yDISABLE yIFF '(' expr ')' pexpr { $$ = new AstPropClocked($4->fileline(), NULL, $4, $6); }
| pexpr { $$ = new AstPropClocked($1->fileline(), NULL, NULL, $1); }
2008-08-06 18:52:39 +02:00
;
2019-12-24 22:15:48 +01:00
//UNSUPproperty_statement_spec<nodep>: // ==IEEE: property_statement_spec
//UNSUP // // IEEE: [ clocking_event ] [ yDISABLE yIFF '(' expression_or_dist ')' ] property_statement
//UNSUP property_statement { $$ = $1; }
//UNSUP | yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statement { }
//UNSUP // // IEEE: clocking_event property_statement
//UNSUP // // IEEE: clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statement
//UNSUP // // Both overlap pexpr:"clocking_event pexpr" the difference is
//UNSUP // // property_statement:property_statementCaseIf so replicate it
//UNSUP | clocking_event property_statementCaseIf { }
//UNSUP | clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statementCaseIf { }
//UNSUP ;
//UNSUPproperty_statement<nodep>: // ==IEEE: property_statement
//UNSUP // // Doesn't make sense to have "pexpr ;" in pexpr rule itself, so we split out case/if
//UNSUP pexpr ';' { $$ = $1; }
//UNSUP // // Note this term replicated in property_statement_spec
//UNSUP // // If committee adds terms, they may need to be there too.
//UNSUP | property_statementCaseIf { $$ = $1; }
//UNSUP ;
//UNSUPproperty_statementCaseIf<nodep>: // IEEE: property_statement - minus pexpr
//UNSUP yCASE '(' expr/*expression_or_dist*/ ')' property_case_itemList yENDCASE { }
//UNSUP | yCASE '(' expr/*expression_or_dist*/ ')' yENDCASE { }
//UNSUP | yIF '(' expr/*expression_or_dist*/ ')' pexpr %prec prLOWER_THAN_ELSE { }
//UNSUP | yIF '(' expr/*expression_or_dist*/ ')' pexpr yELSE pexpr { }
//UNSUP ;
//UNSUPproperty_case_itemList<nodep>: // IEEE: {property_case_item}
//UNSUP property_case_item { $$ = $1; }
//UNSUP | property_case_itemList ',' property_case_item { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
//UNSUPproperty_case_item<nodep>: // ==IEEE: property_case_item
//UNSUP // // IEEE: expression_or_dist { ',' expression_or_dist } ':' property_statement
//UNSUP // // IEEE 1800-2012 changed from property_statement to property_expr
//UNSUP // // IEEE 1800-2017 changed to require the semicolon
//UNSUP caseCondList ':' pexpr { }
//UNSUP | caseCondList ':' pexpr ';' { }
//UNSUP | yDEFAULT pexpr { }
//UNSUP | yDEFAULT ':' pexpr ';' { }
//UNSUP ;
//UNSUPpev_expr<nodep>: // IEEE: property_actual_arg | expr
//UNSUP // // which expands to pexpr | event_expression
//UNSUP // // Used in port and function calls, when we can't know yet if something
//UNSUP // // is a function/sequence/property or instance/checker pin.
//UNSUP //
//UNSUP // // '(' pev_expr ')'
//UNSUP // // Already in pexpr
//UNSUP // // IEEE: event_expression ',' event_expression
//UNSUP // // ','s are legal in event_expressions, but parens required to avoid conflict with port-sep-,
//UNSUP // // IEEE: event_expression yOR event_expression
//UNSUP // // Already in pexpr - needs removal there
//UNSUP // // IEEE: event_expression yIFF expr
//UNSUP // // Already in pexpr - needs removal there
//UNSUP //
//UNSUP senitemEdge { $$ = $1; }
//UNSUP //
//UNSUP //============= pexpr rules copied for pev_expr
//UNSUP | BISONPRE_COPY_ONCE(pexpr,{s/~o~p/pev_/g; }) // {copied}
//UNSUP //
//UNSUP //============= sexpr rules copied for pev_expr
//UNSUP | BISONPRE_COPY_ONCE(sexpr,{s/~p~s/pev_/g; }) // {copied}
//UNSUP //
//UNSUP //============= expr rules copied for pev_expr
//UNSUP | BISONPRE_COPY_ONCE(expr,{s/~l~/pev_/g; s/~p~/pev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied}
//UNSUP ;
2019-12-24 22:04:28 +01:00
pexpr<nodep>: // IEEE: property_expr (The name pexpr is important as regexps just add an "p" to expr.)
2019-12-23 22:49:18 +01:00
//UNSUP: This rule has been super-specialized to what is supported now
2019-12-24 22:15:48 +01:00
//UNSUP remove below
2019-12-24 22:04:28 +01:00
expr yP_ORMINUSGT pexpr { $$ = new AstLogOr($2, new AstLogNot($2, $1), $3); }
//UNSUP expr yP_OREQGT pexpr { $$ = new AstLogOr($2, new AstLogNot($2, new AstPast($2, $1, NULL)), $3); } // This handles disable iff in the past time step incorrectly
| expr { $$ = $1; }
2019-12-24 22:15:48 +01:00
//UNSUP remove above, use below:
//
// // IEEE: sequence_expr
// // Expanded below
//
// // IEEE: '(' pexpr ')'
// // Expanded below
//
//UNSUP yNOT pexpr %prec prNEGATION { }
//UNSUP ySTRONG '(' sexpr ')' { }
//UNSUP yWEAK '(' sexpr ')' { }
// // IEEE: pexpr yOR pexpr
// // IEEE: pexpr yAND pexpr
// // Under ~p~sexpr and/or ~p~sexpr
//
// // IEEE: "sequence_expr yP_ORMINUSGT pexpr"
// // Instead we use pexpr to prevent conflicts
//UNSUP ~o~pexpr yP_ORMINUSGT pexpr { }
//UNSUP ~o~pexpr yP_OREQGT pexpr { }
//
// // IEEE-2009: property_statement
// // IEEE-2012: yIF and yCASE
//UNSUP property_statementCaseIf { }
//
//UNSUP ~o~pexpr/*sexpr*/ yP_POUNDMINUSPD pexpr { }
//UNSUP ~o~pexpr/*sexpr*/ yP_POUNDEQPD pexpr { }
//UNSUP yNEXTTIME pexpr { }
//UNSUP yS_NEXTTIME pexpr { }
//UNSUP yNEXTTIME '[' expr/*const*/ ']' pexpr %prec yNEXTTIME { }
//UNSUP yS_NEXTTIME '[' expr/*const*/ ']' pexpr %prec yS_NEXTTIME { }
//UNSUP yALWAYS pexpr { }
//UNSUP yALWAYS '[' cycle_delay_const_range_expression ']' pexpr %prec yALWAYS { }
//UNSUP yS_ALWAYS '[' constant_range ']' pexpr %prec yS_ALWAYS { }
//UNSUP yS_EVENTUALLY pexpr { }
//UNSUP yEVENTUALLY '[' constant_range ']' pexpr %prec yEVENTUALLY { }
//UNSUP yS_EVENTUALLY '[' cycle_delay_const_range_expression ']' pexpr %prec yS_EVENTUALLY { }
//UNSUP ~o~pexpr yUNTIL pexpr { }
//UNSUP ~o~pexpr yS_UNTIL pexpr { }
//UNSUP ~o~pexpr yUNTIL_WITH pexpr { }
//UNSUP ~o~pexpr yS_UNTIL_WITH pexpr { }
//UNSUP ~o~pexpr yIMPLIES pexpr { }
// // yIFF also used by event_expression
//UNSUP ~o~pexpr yIFF ~o~pexpr { }
//UNSUP yACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec yACCEPT_ON { }
//UNSUP yREJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec yREJECT_ON { }
//UNSUP ySYNC_ACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_ACCEPT_ON { }
//UNSUP ySYNC_REJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_REJECT_ON { }
//
// // IEEE: "property_instance"
// // Looks just like a function/method call
//
// // Note "clocking_event pexpr" overlaps property_statement_spec: clocking_event property_statement
//
// // Include property_specDisable to match property_spec rule
//UNSUP clocking_event yDISABLE yIFF '(' expr ')' pexpr %prec prSEQ_CLOCKING { }
//
//============= sexpr rules copied for property_expr
//UNSUP BISONPRE_COPY_ONCE(sexpr,{s/~p~s/p/g; }) // {copied}
//
//============= expr rules copied for property_expr
//UNSUP BISONPRE_COPY_ONCE(expr,{s/~l~/p/g; s/~p~/p/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied}
;
//UNSUPsexpr<nodep>: // ==IEEE: sequence_expr (The name sexpr is important as regexps just add an "s" to expr.)
//UNSUP // // ********* RULES COPIED IN sequence_exprProp
//UNSUP // // For precedence, see IEEE 17.7.1
//UNSUP //
//UNSUP // // IEEE: "cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
//UNSUP // // IEEE: "sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
//UNSUP // // Both rules basically mean we can repeat sequences, so make it simpler:
//UNSUP cycle_delay_range sexpr %prec yP_POUNDPOUND { }
//UNSUP | ~p~sexpr cycle_delay_range sexpr %prec prPOUNDPOUND_MULTI { }
//UNSUP //
//UNSUP // // IEEE: expression_or_dist [ boolean_abbrev ]
//UNSUP // // Note expression_or_dist includes "expr"!
//UNSUP // // sexpr/*sexpression_or_dist*/ --- Hardcoded below
//UNSUP | ~p~sexpr/*sexpression_or_dist*/ boolean_abbrev { }
//UNSUP //
//UNSUP // // IEEE: "sequence_instance [ sequence_abbrev ]"
//UNSUP // // version without sequence_abbrev looks just like normal function call
//UNSUP // // version w/sequence_abbrev matches above; expression_or_dist:expr:func boolean_abbrev:sequence_abbrev
//UNSUP //
//UNSUP // // IEEE: '(' expression_or_dist {',' sequence_match_item } ')' [ boolean_abbrev ]
//UNSUP // // IEEE: '(' sexpr {',' sequence_match_item } ')' [ sequence_abbrev ]
//UNSUP // // As sequence_expr includes expression_or_dist, and boolean_abbrev includes sequence_abbrev:
//UNSUP // // '(' sequence_expr {',' sequence_match_item } ')' [ boolean_abbrev ]
//UNSUP // // "'(' sexpr ')' boolean_abbrev" matches "[sexpr:'(' expr ')'] boolean_abbrev" so we can simply drop it
//UNSUP | '(' ~p~sexpr ')' { $<fl>$=$<fl>1; $$=$1+$2+$3; }
//UNSUP | '(' ~p~sexpr ',' sequence_match_itemList ')' { }
//UNSUP //
//UNSUP // // AND/OR are between pexprs OR sexprs
//UNSUP | ~p~sexpr yAND ~p~sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
//UNSUP | ~p~sexpr yOR ~p~sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
//UNSUP // // Intersect always has an sexpr rhs
//UNSUP | ~p~sexpr yINTERSECT sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
//UNSUP //
//UNSUP | yFIRST_MATCH '(' sexpr ')' { }
//UNSUP | yFIRST_MATCH '(' sexpr ',' sequence_match_itemList ')' { }
//UNSUP | ~p~sexpr/*sexpression_or_dist*/ yTHROUGHOUT sexpr { }
//UNSUP // // Below pexpr's are really sequence_expr, but avoid conflict
//UNSUP // // IEEE: sexpr yWITHIN sexpr
//UNSUP | ~p~sexpr yWITHIN sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
//UNSUP // // Note concurrent_assertion had duplicate rule for below
//UNSUP | clocking_event ~p~sexpr %prec prSEQ_CLOCKING { }
//UNSUP //
//UNSUP //============= expr rules copied for sequence_expr
//UNSUP | BISONPRE_COPY_ONCE(expr,{s/~l~/s/g; s/~p~/s/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied}
//UNSUP ;
//UNSUPcycle_delay_range<nodep>: // IEEE: ==cycle_delay_range
//UNSUP // // These three terms in 1800-2005 ONLY
//UNSUP yP_POUNDPOUND yaINTNUM { }
//UNSUP | yP_POUNDPOUND id { }
//UNSUP | yP_POUNDPOUND '(' constExpr ')' { }
//UNSUP // // In 1800-2009 ONLY:
//UNSUP // // IEEE: yP_POUNDPOUND constant_primary
//UNSUP // // UNSUP: This causes a big grammer ambiguity
//UNSUP // // as ()'s mismatch between primary and the following statement
//UNSUP // // the sv-ac committee has been asked to clarify (Mantis 1901)
//UNSUP | yP_POUNDPOUND '[' cycle_delay_const_range_expression ']' { }
//UNSUP | yP_POUNDPOUND yP_BRASTAR ']' { }
//UNSUP | yP_POUNDPOUND yP_BRAPLUSKET { }
//UNSUP ;
//UNSUPsequence_match_itemList<nodep>: // IEEE: [sequence_match_item] part of sequence_expr
//UNSUP sequence_match_item { $$ = $1; }
//UNSUP | sequence_match_itemList ',' sequence_match_item { }
//UNSUP ;
//UNSUPsequence_match_item<nodep>: // ==IEEE: sequence_match_item
//UNSUP // // IEEE says: operator_assignment
//UNSUP // // IEEE says: inc_or_dec_expression
//UNSUP // // IEEE says: subroutine_call
//UNSUP // // This is the same list as...
//UNSUP for_step_assignment { $$ = $1; }
//UNSUP ;
//UNSUPboolean_abbrev<nodep>: // ==IEEE: boolean_abbrev
//UNSUP // // IEEE: consecutive_repetition
//UNSUP yP_BRASTAR const_or_range_expression ']' { }
//UNSUP | yP_BRASTAR ']' { }
//UNSUP | yP_BRAPLUSKET { $$ = $1; }
//UNSUP // // IEEE: non_consecutive_repetition
//UNSUP | yP_BRAEQ const_or_range_expression ']' { }
//UNSUP // // IEEE: goto_repetition
//UNSUP | yP_BRAMINUSGT const_or_range_expression ']' { }
//UNSUP ;
//UNSUPconst_or_range_expression<nodep>: // ==IEEE: const_or_range_expression
//UNSUP constExpr { $$ = $1; }
//UNSUP | cycle_delay_const_range_expression { }
//UNSUP ;
//UNSUPconstant_range<nodep>: // ==IEEE: constant_range
//UNSUP constExpr ':' constExpr { }
//UNSUP ;
//UNSUPcycle_delay_const_range_expression<nodep>: // ==IEEE: cycle_delay_const_range_expression
//UNSUP // // Note '$' is part of constExpr
//UNSUP constExpr ':' constExpr { }
//UNSUP ;
2019-12-23 22:49:18 +01:00
2019-06-02 01:40:06 +02:00
//************************************************
// Let
2009-05-08 00:28:05 +02:00
//************************************************
// Covergroup
2019-12-23 22:26:59 +01:00
//UNSUPcovergroup_declaration<nodep>: // ==IEEE: covergroup_declaration
//UNSUP covergroup_declarationFront coverage_eventE ';' coverage_spec_or_optionListE
//UNSUP yENDGROUP endLabelE
//UNSUP { PARSEP->endgroupCb($<fl>5,$5);
//UNSUP SYMP->popScope($$); }
//UNSUP | covergroup_declarationFront '(' tf_port_listE ')' coverage_eventE ';' coverage_spec_or_optionListE
//UNSUP yENDGROUP endLabelE
//UNSUP { PARSEP->endgroupCb($<fl>8,$8);
//UNSUP SYMP->popScope($$); }
//UNSUP ;
//UNSUPcovergroup_declarationFront: // IEEE: part of covergroup_declaration
//UNSUP yCOVERGROUP idAny
//UNSUP { SYMP->pushNew($$);
//UNSUP PARSEP->covergroupCb($<fl>1,$1,$2); }
//UNSUP ;
//UNSUPcgexpr<nodep>: // IEEE-2012: covergroup_expression, before that just expression
//UNSUP expr { $$ = $1; }
//UNSUP ;
//UNSUPcoverage_spec_or_optionListE<nodep>: // IEEE: [{coverage_spec_or_option}]
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | coverage_spec_or_optionList { $$ = $1; }
//UNSUP ;
//UNSUPcoverage_spec_or_optionList<nodep>: // IEEE: {coverage_spec_or_option}
//UNSUP coverage_spec_or_option { $$ = $1; }
//UNSUP | coverage_spec_or_optionList coverage_spec_or_option { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPcoverage_spec_or_option<nodep>: // ==IEEE: coverage_spec_or_option
//UNSUP // // IEEE: coverage_spec
//UNSUP cover_point { $$ = $1; }
//UNSUP | cover_cross { $$ = $1; }
//UNSUP | coverage_option ';' { $$ = $1; }
//UNSUP | error { $$ = NULL; }
//UNSUP ;
//UNSUPcoverage_option: // ==IEEE: coverage_option
//UNSUP // // option/type_option aren't really keywords
//UNSUP id/*yOPTION | yTYPE_OPTION*/ '.' idAny/*member_identifier*/ '=' expr { }
//UNSUP ;
//UNSUPcover_point: // ==IEEE: cover_point
//UNSUP /**/ yCOVERPOINT expr iffE bins_or_empty { }
//UNSUP // // IEEE-2012: class_scope before an ID
//UNSUP | /**/ /**/ /**/ id ':' yCOVERPOINT expr iffE bins_or_empty { }
//UNSUP | class_scope_id ':' yCOVERPOINT expr iffE bins_or_empty { }
//UNSUP | class_scope_id id data_type id ':' yCOVERPOINT expr iffE bins_or_empty { }
//UNSUP | class_scope_id id /**/ id ':' yCOVERPOINT expr iffE bins_or_empty { }
//UNSUP | /**/ id /**/ id ':' yCOVERPOINT expr iffE bins_or_empty { }
//UNSUP // // IEEE-2012:
//UNSUP | bins_or_empty { $$ = $1; }
//UNSUP ;
//UNSUPiffE<nodep>: // IEEE: part of cover_point, others
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | yIFF '(' expr ')' { }
//UNSUP ;
//UNSUPbins_or_empty<nodep>: // ==IEEE: bins_or_empty
//UNSUP '{' bins_or_optionsList '}' { $$ = $2; }
//UNSUP | '{' '}' { $$ = NULL; }
//UNSUP | ';' { $$ = NULL; }
//UNSUP ;
//UNSUPbins_or_optionsList<nodep>: // IEEE: { bins_or_options ';' }
//UNSUP bins_or_options ';' { $$ = $1; }
//UNSUP | bins_or_optionsList bins_or_options ';' { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPbins_or_options<nodep>: // ==IEEE: bins_or_options
//UNSUP // // Superset of IEEE - we allow []'s in more places
//UNSUP coverage_option { $$ = $1; }
//UNSUP // // Can't use wildcardE as results in conflicts
//UNSUP | /**/ bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' iffE { }
//UNSUP | yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' iffE { }
//UNSUP | /**/ bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' yWITH__CUR '{' cgexpr ')' iffE { }
//UNSUP | yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' yWITH__CUR '{' cgexpr ')' iffE { }
//UNSUP //
//UNSUP // // cgexpr part of trans_list
//UNSUP //
//UNSUP | /**/ bins_keyword id/*bin_identifier*/ bins_orBraE '=' trans_list iffE { }
//UNSUP | yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' trans_list iffE { }
//UNSUP //
//UNSUP | bins_keyword id/*bin_identifier*/ bins_orBraE '=' yDEFAULT iffE { }
//UNSUP //
//UNSUP | bins_keyword id/*bin_identifier*/ bins_orBraE '=' yDEFAULT ySEQUENCE iffE { }
//UNSUP ;
//UNSUPbins_orBraE<nodep>: // IEEE: part of bins_or_options:
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | '[' ']' { }
//UNSUP | '[' cgexpr ']' { }
//UNSUP ;
//UNSUPbins_keyword: // ==IEEE: bins_keyword
//UNSUP yBINS { }
//UNSUP | yILLEGAL_BINS { }
//UNSUP | yIGNORE_BINS { }
//UNSUP ;
//UNSUPcovergroup_range_list: // ==IEEE: covergroup_range_list
//UNSUP covergroup_value_range { $$ = $1; }
//UNSUP | covergroup_range_list ',' covergroup_value_range { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
//UNSUPtrans_list: // ==IEEE: trans_list
//UNSUP '(' trans_set ')' { $$ = $2; }
//UNSUP | trans_list ',' '(' trans_set ')' { }
//UNSUP ;
//UNSUPtrans_set: // ==IEEE: trans_set
//UNSUP trans_range_list { $$ = $1; }
//UNSUP // // Note the { => } in the grammer, this is really a list
//UNSUP | trans_set yP_EQGT trans_range_list { }
//UNSUP ;
//UNSUPtrans_range_list: // ==IEEE: trans_range_list
//UNSUP trans_item { $$ = $1; }
//UNSUP | trans_item yP_BRASTAR repeat_range ']' { }
//UNSUP | trans_item yP_BRAMINUSGT repeat_range ']' { }
//UNSUP | trans_item yP_BRAEQ repeat_range ']' { }
//UNSUP ;
//UNSUPtrans_item: // ==IEEE: range_list
//UNSUP covergroup_range_list { $$ = $1; }
//UNSUP ;
//UNSUPrepeat_range: // ==IEEE: repeat_range
//UNSUP cgexpr { $$ = $1; }
//UNSUP | cgexpr ':' cgexpr { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
//UNSUPcover_cross: // ==IEEE: cover_cross
//UNSUP id/*cover_point_identifier*/ ':' yCROSS list_of_cross_items iffE cross_body { }
//UNSUP | /**/ yCROSS list_of_cross_items iffE cross_body { }
//UNSUP ;
//UNSUPlist_of_cross_items<nodep>: // ==IEEE: list_of_cross_items
//UNSUP cross_item ',' cross_item { $$ = AstNode::addNextNull($1, $3); }
//UNSUP | cross_item ',' cross_item ',' cross_itemList { }
//UNSUP ;
//UNSUPcross_itemList<nodep>: // IEEE: part of list_of_cross_items
//UNSUP cross_item { $$ = NULL; }
//UNSUP | cross_itemList ',' cross_item { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
//UNSUPcross_item<nodep>: // ==IEEE: cross_item
//UNSUP idAny/*cover_point_identifier or variable_identifier*/ { $$ = $1; }
//UNSUP ;
//UNSUPcross_body: // ==IEEE: cross_body
//UNSUP '{' '}' { $$ = NULL; }
//UNSUP // // IEEE-2012: No semicolon here, mistake in spec
//UNSUP | '{' cross_body_itemSemiList '}' { $$ = $1; }
//UNSUP | ';' { $$ = NULL; }
//UNSUP ;
//UNSUPcross_body_itemSemiList: // IEEE: part of cross_body
//UNSUP cross_body_item ';' { $$ = $1; }
//UNSUP | cross_body_itemSemiList cross_body_item ';' { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPcross_body_item<nodep>: // ==IEEE: cross_body_item
//UNSUP // // IEEE: our semicolon is in the list
//UNSUP bins_selection_or_option { $$ = $1; }
//UNSUP | function_declaration { $$ = $1; }
//UNSUP ;
//UNSUPbins_selection_or_option<nodep>: // ==IEEE: bins_selection_or_option
//UNSUP coverage_option { $$ = $1; }
//UNSUP | bins_selection { $$ = $1; }
//UNSUP ;
//UNSUPbins_selection: // ==IEEE: bins_selection
//UNSUP bins_keyword idAny/*new-bin_identifier*/ '=' select_expression iffE { }
//UNSUP ;
//UNSUPselect_expression: // ==IEEE: select_expression
//UNSUP // // IEEE: select_condition expanded here
//UNSUP yBINSOF '(' bins_expression ')' { }
//UNSUP | yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}' { }
//UNSUP | yWITH__PAREN '(' cgexpr ')' { }
//UNSUP // // IEEE-2012: Need clarification as to precedence
//UNSUP //UNSUP yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr { }
//UNSUP | '!' yBINSOF '(' bins_expression ')' { }
//UNSUP | '!' yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}' { }
//UNSUP | '!' yWITH__PAREN '(' cgexpr ')' { }
//UNSUP // // IEEE-2012: Need clarification as to precedence
//UNSUP //UNSUP '!' yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr { }
//UNSUP | select_expression yP_ANDAND select_expression { }
//UNSUP | select_expression yP_OROR select_expression { }
//UNSUP | '(' select_expression ')' { $$ = $2; }
//UNSUP // // IEEE-2012: cross_identifier
//UNSUP // // Part of covergroup_expression - generic identifier
//UNSUP // // IEEE-2012: Need clarification as to precedence
//UNSUP //UNSUP covergroup_expression [ yMATCHES covergroup_expression ]
//UNSUP ;
//UNSUPbins_expression: // ==IEEE: bins_expression
//UNSUP // // "cover_point_identifier" and "variable_identifier" look identical
//UNSUP id/*variable_identifier or cover_point_identifier*/ { $$ = $1; }
//UNSUP | id/*cover_point_identifier*/ '.' idAny/*bins_identifier*/ { }
//UNSUP ;
//UNSUPcoverage_eventE: // IEEE: [ coverage_event ]
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | clocking_event { $$ = $1; }
//UNSUP | yWITH__ETC function idAny/*"sample"*/ '(' tf_port_listE ')' { }
//UNSUP | yP_ATAT '(' block_event_expression ')' { }
//UNSUP ;
//UNSUPblock_event_expression: // ==IEEE: block_event_expression
//UNSUP block_event_expressionTerm { $$ = $1; }
//UNSUP | block_event_expression yOR block_event_expressionTerm { }
//UNSUP ;
//UNSUPblock_event_expressionTerm: // IEEE: part of block_event_expression
//UNSUP yBEGIN hierarchical_btf_identifier { }
//UNSUP | yEND hierarchical_btf_identifier { }
//UNSUP ;
//UNSUPhierarchical_btf_identifier: // ==IEEE: hierarchical_btf_identifier
//UNSUP // // hierarchical_tf_identifier + hierarchical_block_identifier
//UNSUP hierarchical_identifier/*tf_or_block*/ { $$ = $1; }
//UNSUP // // method_identifier
//UNSUP | hierarchical_identifier class_scope_id { }
//UNSUP | hierarchical_identifier id { }
//UNSUP ;
2009-05-08 00:28:05 +02:00
//**********************************************************************
// Randsequence
2019-12-23 22:26:59 +01:00
//UNSUPrandsequence_statement<nodep>: // ==IEEE: randsequence_statement
//UNSUP yRANDSEQUENCE '(' ')' productionList yENDSEQUENCE { }
//UNSUP | yRANDSEQUENCE '(' id/*production_identifier*/ ')' productionList yENDSEQUENCE { }
//UNSUP ;
//UNSUPproductionList<nodep>: // IEEE: production+
//UNSUP production { $$ = $1; }
//UNSUP | productionList production { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPproduction<nodep>: // ==IEEE: production
//UNSUP productionFront ':' rs_ruleList ';' { }
//UNSUP ;
//UNSUPproductionFront<nodep>: // IEEE: part of production
//UNSUP function_data_type id/*production_identifier*/ { }
//UNSUP | /**/ id/*production_identifier*/ { $$ = $1; }
//UNSUP | function_data_type id/*production_identifier*/ '(' tf_port_listE ')' { }
//UNSUP | /**/ id/*production_identifier*/ '(' tf_port_listE ')' { }
//UNSUP ;
//UNSUPrs_ruleList<nodep>: // IEEE: rs_rule+ part of production
//UNSUP rs_rule { $$ = $1; }
//UNSUP | rs_ruleList '|' rs_rule { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
//UNSUPrs_rule<nodep>: // ==IEEE: rs_rule
//UNSUP rs_production_list { $$ = $1; }
//UNSUP | rs_production_list yP_COLONEQ weight_specification { }
//UNSUP | rs_production_list yP_COLONEQ weight_specification rs_code_block { }
//UNSUP ;
//UNSUPrs_production_list<nodep>: // ==IEEE: rs_production_list
//UNSUP rs_prodList { $$ = $1; }
//UNSUP | yRAND yJOIN /**/ production_item production_itemList { }
//UNSUP | yRAND yJOIN '(' expr ')' production_item production_itemList { }
//UNSUP ;
//UNSUPweight_specification<nodep>: // ==IEEE: weight_specification
//UNSUP yaINTNUM { $$ = $1; }
//UNSUP | idClassSel/*ps_identifier*/ { $$ = $1; }
//UNSUP | '(' expr ')' { $$ = $2; }
//UNSUP ;
//UNSUPrs_code_block<nodep>: // ==IEEE: rs_code_block
//UNSUP '{' '}' { $$ = NULL; }
//UNSUP | '{' rs_code_blockItemList '}' { $$ = $2; }
//UNSUP ;
//UNSUPrs_code_blockItemList<nodep>: // IEEE: part of rs_code_block
//UNSUP rs_code_blockItem { $$ = $1; }
//UNSUP | rs_code_blockItemList rs_code_blockItem { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPrs_code_blockItem<nodep>: // IEEE: part of rs_code_block
//UNSUP data_declaration { $$ = $1; }
//UNSUP | stmt { $$ = $1; }
//UNSUP ;
//UNSUPrs_prodList<nodep>: // IEEE: rs_prod+
//UNSUP rs_prod { $$ = $1; }
//UNSUP | rs_prodList rs_prod { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPrs_prod<nodep>: // ==IEEE: rs_prod
//UNSUP production_item { $$ = $1; }
//UNSUP | rs_code_block { $$ = $1; }
//UNSUP // // IEEE: rs_if_else
//UNSUP | yIF '(' expr ')' production_item %prec prLOWER_THAN_ELSE { }
//UNSUP | yIF '(' expr ')' production_item yELSE production_item { }
//UNSUP // // IEEE: rs_repeat
//UNSUP | yREPEAT '(' expr ')' production_item { }
//UNSUP // // IEEE: rs_case
//UNSUP | yCASE '(' expr ')' rs_case_itemList yENDCASE { }
//UNSUP ;
//UNSUPproduction_itemList<nodep>: // IEEE: production_item+
//UNSUP production_item { $$ = $1; }
//UNSUP | production_itemList production_item { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPproduction_item<nodep>: // ==IEEE: production_item
//UNSUP id/*production_identifier*/ { $$ = $1; }
//UNSUP | id/*production_identifier*/ '(' list_of_argumentsE ')' { }
//UNSUP ;
//UNSUPrs_case_itemList<nodep>: // IEEE: rs_case_item+
//UNSUP rs_case_item { $$ = $1; }
//UNSUP | rs_case_itemList rs_case_item { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPrs_case_item<nodep>: // ==IEEE: rs_case_item
//UNSUP caseCondList ':' production_item ';' { }
//UNSUP | yDEFAULT production_item ';' { }
//UNSUP | yDEFAULT ':' production_item ';' { }
//UNSUP ;
2019-06-02 01:40:06 +02:00
//**********************************************************************
// Checker
2019-12-23 22:26:59 +01:00
//UNSUPchecker_declaration<nodep>: // ==IEEE: part of checker_declaration
//UNSUP checkerFront checker_port_listE ';'
//UNSUP checker_or_generate_itemListE yENDCHECKER endLabelE
//UNSUP { SYMP->popScope($$); }
//UNSUP ;
//UNSUPcheckerFront<nodep>: // IEEE: part of checker_declaration
//UNSUP yCHECKER idAny/*checker_identifier*/
//UNSUP { SYMP->pushNew($$); }
//UNSUP ;
//UNSUPchecker_port_listE<nodep>: // IEEE: [ ( [ checker_port_list ] ) ]
//UNSUP // // checker_port_item is basically the same as property_port_item, minus yLOCAL::
//UNSUP // // Want to bet 1800-2012 adds local to checkers?
//UNSUP property_port_listE { $$ = $1; }
//UNSUP ;
//UNSUPchecker_or_generate_itemListE<nodep>: // IEEE: [{ checker_or_generate_itemList }]
//UNSUP /* empty */ { $$ = NULL; }
//UNSUP | checker_or_generate_itemList { $$ = $1; }
//UNSUP ;
//UNSUPchecker_or_generate_itemList<nodep>: // IEEE: { checker_or_generate_itemList }
//UNSUP checker_or_generate_item { $$ = $1; }
//UNSUP | checker_or_generate_itemList checker_or_generate_item { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPchecker_or_generate_item<nodep>: // ==IEEE: checker_or_generate_item
//UNSUP checker_or_generate_item_declaration { $$ = $1; }
//UNSUP | initial_construct { $$ = $1; }
//UNSUP // // IEEE: checker_construct
//UNSUP | yALWAYS stmtBlock { }
//UNSUP | final_construct { $$ = $1; }
//UNSUP | assertion_item { $$ = $1; }
//UNSUP | continuous_assign { $$ = $1; }
//UNSUP | checker_generate_item { $$ = $1; }
//UNSUP ;
//UNSUPchecker_or_generate_item_declaration<nodep>: // ==IEEE: checker_or_generate_item_declaration
//UNSUP data_declaration { $$ = $1; }
//UNSUP | yRAND data_declaration { }
//UNSUP | function_declaration { $$ = $1; }
//UNSUP | checker_declaration { $$ = $1; }
//UNSUP | assertion_item_declaration { $$ = $1; }
//UNSUP | covergroup_declaration { $$ = $1; }
//UNSUP // // IEEE deprecated: overload_declaration
//UNSUP | genvar_declaration { $$ = $1; }
//UNSUP | clocking_declaration { $$ = $1; }
//UNSUP | yDEFAULT yCLOCKING id/*clocking_identifier*/ ';' { }
//UNSUP | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { }
//UNSUP | ';' { $$ = NULL; }
//UNSUP ;
//UNSUPchecker_generate_item<nodep>: // ==IEEE: checker_generate_item
//UNSUP // // Specialized for checker so need "c_" prefixes here
//UNSUP c_loop_generate_construct { $$ = $1; }
//UNSUP | c_conditional_generate_construct { $$ = $1; }
//UNSUP | c_generate_region { $$ = $1; }
//UNSUP //
//UNSUP | elaboration_system_task { $$ = $1; }
//UNSUP ;
//UNSUPchecker_instantiation<nodep>:
//UNSUP // // Only used for procedural_assertion_item's
//UNSUP // // Version in concurrent_assertion_item looks like etcInst
//UNSUP // // Thus instead of *_checker_port_connection we can use etcInst's cellpinList
//UNSUP id/*checker_identifier*/ id '(' cellpinList ')' ';' { }
//UNSUP ;
2009-05-08 00:28:05 +02:00
//**********************************************************************
// Class
2019-12-23 21:03:04 +01:00
class_declaration<nodep>: // ==IEEE: part of class_declaration
// // IEEE-2012: using this also for interface_class_declaration
// // The classExtendsE rule relys on classFront having the
// // new class scope correct via classFront
classFront parameter_port_listE classExtendsE classImplementsE ';'
class_itemListE yENDCLASS endLabelE
{ $$ = $1; $1->addMembersp($2);
2020-04-05 15:30:23 +02:00
$1->extendsp($3);
$1->addMembersp($4);
$1->addMembersp($6);
2019-12-23 21:03:04 +01:00
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7, $1, $8); }
;
classFront<classp>: // IEEE: part of class_declaration
classVirtualE yCLASS lifetimeE idAny/*class_identifier*/
{ $$ = new AstClass($2, *$4);
2020-04-26 18:45:06 +02:00
$$->lifetime($3);
2020-04-05 15:30:23 +02:00
SYMP->pushNew($<classp>$); }
2019-12-23 21:03:04 +01:00
// // IEEE: part of interface_class_declaration
| yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/
{ $$ = new AstClass($2, *$4);
2020-04-26 18:45:06 +02:00
$$->lifetime($3);
2019-12-23 21:03:04 +01:00
SYMP->pushNew($<classp>$);
BBUNSUP($2, "Unsupported: interface classes"); }
;
classVirtualE:
/* empty */ { }
| yVIRTUAL__CLASS { BBUNSUP($1, "Unsupported: virtual classes"); }
;
classExtendsE<nodep>: // IEEE: part of class_declaration
// // The classExtendsE rule relys on classFront having the
// // new class scope correct via classFront
/* empty */ { $$ = NULL; }
| yEXTENDS classExtendsList { $$ = $2; }
;
classExtendsList<nodep>: // IEEE: part of class_declaration
classExtendsOne { $$ = $1; }
2020-01-16 02:18:12 +01:00
| classExtendsList ',' classExtendsOne
2020-01-31 02:23:57 +01:00
{ $$ = $3; BBUNSUP($3, "Multiple inheritance illegal on non-interface classes (IEEE 1800-2017 8.13)"
2020-01-16 02:18:12 +01:00
", and unsupported for interface classes."); }
2019-12-23 21:03:04 +01:00
;
classExtendsOne<nodep>: // IEEE: part of class_declaration
2020-01-16 02:18:12 +01:00
class_typeWithoutId
2020-04-05 15:30:23 +02:00
{ $$ = new AstClassExtends($1->fileline(), $1); }
2019-12-23 21:03:04 +01:00
// // IEEE: Might not be legal to have more than one set of parameters in an extends
2020-01-16 02:18:12 +01:00
| class_typeWithoutId '(' list_of_argumentsE ')'
2020-04-05 15:30:23 +02:00
{ $$ = new AstClassExtends($1->fileline(), $1);
if ($3) BBUNSUP($3, "Unsupported: extends with parameters"); }
2019-12-23 21:03:04 +01:00
;
classImplementsE<nodep>: // IEEE: part of class_declaration
// // All 1800-2012
/* empty */ { $$ = NULL; }
| yIMPLEMENTS classImplementsList { $$ = $2; }
;
classImplementsList<nodep>: // IEEE: part of class_declaration
// // All 1800-2012
class_typeWithoutId { $$ = NULL; BBUNSUP($1, "Unsupported: implements class"); }
| classImplementsList ',' class_typeWithoutId { $$ = AstNode::addNextNull($1, $3); }
;
2009-05-08 00:28:05 +02:00
//=========
// 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}
2020-04-23 03:31:40 +02:00
ps_id_etc<varrefp>: // package_scope + general id
package_scopeIdFollowsE varRefBase { $$ = $2; $2->packagep($1); }
2009-11-07 05:16:06 +01:00
;
2020-03-07 17:00:57 +01:00
ps_type<refdtypep>: // IEEE: ps_parameter_identifier | ps_type_identifier
2009-11-07 05:16:06 +01:00
// 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.
2019-12-23 21:03:04 +01:00
package_scopeIdFollowsE idRefDType { $$ = $2; $2->packagep($1); }
2012-10-09 02:45:39 +02:00
// // Simplify typing - from ps_covergroup_identifier
2009-05-08 00:28:05 +02:00
;
//=== Below rules assume special scoping per above
2020-03-07 17:00:57 +01:00
class_typeWithoutId<refdtypep>: // as with class_typeWithoutId but allow yaID__aTYPE
2019-12-23 21:03:04 +01:00
// // and we thus don't need to resolve it in specified package
package_scopeIdFollowsE class_typeOneList { $$ = $2; $2->packagep($1); }
;
class_scopeWithoutId<nodep>: // class_type standalone without following id
// // and we thus don't need to resolve it in specified package
class_scopeIdFollows { $$ = $1; }
;
class_scopeIdFollows<nodep>: // IEEE: class_scope + type
// // IEEE: "class_type yP_COLONCOLON"
// // IMPORTANT: The lexer will parse the following ID to be in the found package
// // But class_type:'::' conflicts with class_scope:'::' so expand here
package_scopeIdFollowsE class_typeOneListColonIdFollows
{ $$ = NULL; BBUNSUP(CRELINE(), "Unsupported: scoped class reference"); }
;
class_typeOneListColonIdFollows: // IEEE: class_type :: but allow yaID__aTYPE
class_typeOneList yP_COLONCOLON { BBUNSUP($2, "Unsupported: Hierarchical class references"); }
;
class_typeOneList<refdtypep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
// // If you follow the rules down, class_type is really a list via ps_class_identifier
// // Must propagate scp up for next id
class_typeOne { $$ = $1; }
| class_typeOneListColonIdFollows class_typeOne { $$ = $2; /*UNSUP*/ }
;
class_typeOne<refdtypep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
// // If you follow the rules down, class_type is really a list via ps_class_identifier
// // Not listed in IEEE, but see bug627 any parameter type maybe a class
idRefDType parameter_value_assignmentE
{ $$ = $1; if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); }
;
2009-11-08 03:05:02 +01:00
package_scopeIdFollowsE<packagep>: // IEEE: [package_scope]
2009-05-08 00:28:05 +02:00
// // IMPORTANT: The lexer will parse the following ID to be in the found package
2012-10-09 02:45:39 +02:00
// // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
2009-11-08 03:05:02 +01: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); }
2018-02-02 03:32:58 +01:00
/*cont*/ yP_COLONCOLON { $$ = VN_CAST($<scp>1, Package); }
2012-10-09 02:45:39 +02:00
//UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
2009-05-08 00:28:05 +02:00
;
2019-12-23 21:03:04 +01:00
//^^^=========
class_itemListE<nodep>:
/* empty */ { $$ = NULL; }
| class_itemList { $$ = $1; }
;
class_itemList<nodep>:
class_item { $$ = $1; }
| class_itemList class_item { $$ = AstNode::addNextNull($1, $2); }
;
class_item<nodep>: // ==IEEE: class_item
class_property { $$ = $1; }
| class_method { $$ = $1; }
//UNSUP class_constraint { $$ = $1; }
//
| class_declaration { $$ = NULL; BBUNSUP($1, "Unsupported: class within class"); }
| timeunits_declaration { $$ = $1; }
//UNSUP covergroup_declaration { $$ = $1; }
| local_parameter_declaration ';' { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009
| parameter_declaration ';' { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009
| ';' { $$ = NULL; }
//
| error ';' { $$ = NULL; }
;
class_method<nodep>: // ==IEEE: class_method
memberQualResetListE task_declaration { $$ = $2; }
| memberQualResetListE function_declaration { $$ = $2; }
| yPURE yVIRTUAL__ETC memberQualResetListE method_prototype ';'
{ $$ = NULL; BBUNSUP($1, "Unsupported: pure virtual class method"); }
| yEXTERN memberQualResetListE method_prototype ';'
{ $$ = NULL; BBUNSUP($1, "Unsupported: extern class method prototype"); }
// // IEEE: "method_qualifierE class_constructor_declaration"
// // part of function_declaration
| yEXTERN memberQualResetListE class_constructor_prototype
{ $$ = NULL; BBUNSUP($1, "Unsupported: extern class"); }
;
// IEEE: class_constructor_prototype
// See function_declaration
class_item_qualifier<nodep>: // IEEE: class_item_qualifier minus ySTATIC
// // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
2020-03-06 04:33:31 +01:00
yPROTECTED { $$ = NULL; } // Ignoring protected until warning implemented
| yLOCAL__ETC { $$ = NULL; } // Ignoring local until warning implemented
2019-12-23 21:03:04 +01:00
| ySTATIC__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: 'static' class item"); }
;
memberQualResetListE<nodep>: // Called from class_property for all qualifiers before yVAR
// // Also before method declarations, to prevent grammar conflict
// // Thus both types of qualifiers (method/property) are here
/*empty*/ { $$ = NULL; }
| memberQualList { $$ = $1; }
;
memberQualList<nodep>:
memberQualOne { $$ = $1; }
| memberQualList memberQualOne { $$ = AstNode::addNextNull($1, $2); }
;
memberQualOne<nodep>: // IEEE: property_qualifier + method_qualifier
// // Part of method_qualifier and property_qualifier
class_item_qualifier { $$ = $1; }
// // Part of method_qualifier only
| yVIRTUAL__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: virtual class member qualifier"); }
// // Part of property_qualifier only
| random_qualifier { $$ = NULL; }
// // Part of lifetime, but here as ySTATIC can be in different positions
| yAUTOMATIC { $$ = NULL; BBUNSUP($1, "Unsupported: automatic class member qualifier"); }
// // Part of data_declaration, but not in data_declarationVarFrontClass
| yCONST__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: const class member qualifier"); }
;
2019-06-02 01:40:06 +02:00
//**********************************************************************
// Constraints
2019-12-23 22:26:59 +01:00
//UNSUPclass_constraint<nodep>: // ==IEEE: class_constraint
//UNSUP // // IEEE: constraint_declaration
//UNSUP constraintStaticE yCONSTRAINT idAny constraint_block { }
//UNSUP // // IEEE: constraint_prototype + constraint_prototype_qualifier
//UNSUP | constraintStaticE yCONSTRAINT idAny ';' { }
//UNSUP | yEXTERN constraintStaticE yCONSTRAINT idAny ';' { }
//UNSUP | yPURE constraintStaticE yCONSTRAINT idAny ';' { }
//UNSUP ;
//UNSUPconstraint_block<nodep>: // ==IEEE: constraint_block
//UNSUP '{' constraint_block_itemList '}' { $$ = $1; }
//UNSUP ;
//UNSUPconstraint_block_itemList<nodep>: // IEEE: { constraint_block_item }
//UNSUP constraint_block_item { $$ = $1; }
//UNSUP | constraint_block_itemList constraint_block_item { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPconstraint_block_item: // ==IEEE: constraint_block_item
//UNSUP ySOLVE solve_before_list yBEFORE solve_before_list ';' { }
//UNSUP | constraint_expression { $$ = $1; }
//UNSUP ;
//UNSUPsolve_before_list: // ==IEEE: solve_before_list
//UNSUP constraint_primary { $$ = $1; }
//UNSUP | solve_before_list ',' constraint_primary { }
//UNSUP ;
//UNSUPconstraint_primary: // ==IEEE: constraint_primary
//UNSUP // // exprScope more general than: [ implicit_class_handle '.' | class_scope ] hierarchical_identifier select
//UNSUP exprScope { $$ = $1; }
//UNSUP ;
//UNSUPconstraint_expressionList<nodep>: // ==IEEE: { constraint_expression }
//UNSUP constraint_expression { $$ = $1; }
//UNSUP | constraint_expressionList constraint_expression { $$ = AstNode::addNextNull($1, $2); }
//UNSUP ;
//UNSUPconstraint_expression<nodep>: // ==IEEE: constraint_expression
//UNSUP expr/*expression_or_dist*/ ';' { $$ = $1; }
//UNSUP // // 1800-2012:
//UNSUP | ySOFT expr/*expression_or_dist*/ ';' { }
//UNSUP // // 1800-2012:
//UNSUP // // IEEE: uniqueness_constraint ';'
//UNSUP | yUNIQUE '{' open_range_list '}' { }
//UNSUP // // IEEE: expr yP_MINUSGT constraint_set
//UNSUP // // Conflicts with expr:"expr yP_MINUSGT expr"; rule moved there
//UNSUP //
//UNSUP | yIF '(' expr ')' constraint_set %prec prLOWER_THAN_ELSE { }
//UNSUP | yIF '(' expr ')' constraint_set yELSE constraint_set { }
//UNSUP // // IEEE says array_identifier here, but dotted accepted in VMM + 1800-2009
//UNSUP | yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' constraint_set { }
//UNSUP // // soft is 1800-2012
//UNSUP | yDISABLE ySOFT expr/*constraint_primary*/ ';' { }
//UNSUP ;
//UNSUPconstraint_set<nodep>: // ==IEEE: constraint_set
//UNSUP constraint_expression { $$ = $1; }
//UNSUP | '{' constraint_expressionList '}' { $$ = $2; }
//UNSUP ;
//UNSUPdist_list<nodep>: // ==IEEE: dist_list
//UNSUP dist_item { $$ = $1; }
//UNSUP | dist_list ',' dist_item { $$ = AstNode::addNextNull($1, $3); }
//UNSUP ;
//UNSUPdist_item: // ==IEEE: dist_item + dist_weight
//UNSUP value_range { $$ = $1; }
//UNSUP | value_range yP_COLONEQ expr { }
//UNSUP | value_range yP_COLONDIV expr { }
//UNSUP ;
//UNSUPextern_constraint_declaration: // ==IEEE: extern_constraint_declaration
//UNSUP constraintStaticE yCONSTRAINT class_scope_id constraint_block { }
//UNSUP ;
//UNSUPconstraintStaticE<bool>: // IEEE: part of extern_constraint_declaration
//UNSUP /* empty */ { $$ = false; }
//UNSUP | ySTATIC__CONSTRAINT { $$ = true; }
//UNSUP ;
2020-04-16 01:39:03 +02:00
//**********************************************************************
// Constants
timeNumAdjusted<nodep>: // Time constant, adjusted to module's time units/precision
yaTIMENUM
{ $$ = new AstTimeImport($<fl>1, new AstConst($<fl>1, AstConst::RealDouble(), $1)); }
;
2010-01-21 12:11:30 +01:00
//**********************************************************************
// VLT Files
vltItem:
2020-01-12 10:03:17 +01:00
vltOffFront { V3Config::addIgnore($1, false, "*", 0, 0); }
| vltOffFront yVLT_D_FILE yaSTRING
{ V3Config::addIgnore($1, false, *$3, 0, 0); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addIgnore($1, false, *$3, $5->toUInt(), $5->toUInt()+1); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
{ V3Config::addIgnore($1, false, *$3, $5->toUInt(), $7->toUInt()+1); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_MATCH yaSTRING
{ if (($1==V3ErrorCode::I_COVERAGE) || ($1==V3ErrorCode::I_TRACING)) {
$<fl>1->v3error("Argument -match only supported for lint_off"<<endl);
} else {
V3Config::addWaiver($1,*$3,*$5);
}}
| vltOnFront { V3Config::addIgnore($1, true, "*", 0, 0); }
| vltOnFront yVLT_D_FILE yaSTRING
{ V3Config::addIgnore($1, true, *$3, 0, 0); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addIgnore($1, true, *$3, $5->toUInt(), $5->toUInt()+1); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
{ V3Config::addIgnore($1, true, *$3, $5->toUInt(), $7->toUInt()+1); }
| vltVarAttrFront vltDModuleE vltDFTaskE vltVarAttrVarE attr_event_controlE
{ V3Config::addVarAttr($<fl>1, *$2, *$3, *$4, $1, $5); }
| vltInlineFront vltDModuleE vltDFTaskE
{ V3Config::addInline($<fl>1, *$2, *$3, $1); }
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING
{ V3Config::addCoverageBlockOff(*$3, 0); }
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addCoverageBlockOff(*$3, $5->toUInt()); }
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_MODULE yaSTRING yVLT_D_BLOCK yaSTRING
{ V3Config::addCoverageBlockOff(*$3, *$5); }
| yVLT_FULL_CASE yVLT_D_FILE yaSTRING
{ V3Config::addCaseFull(*$3, 0); }
| yVLT_FULL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addCaseFull(*$3, $5->toUInt()); }
| yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING
{ V3Config::addCaseParallel(*$3, 0); }
| yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addCaseParallel(*$3, $5->toUInt()); }
2010-01-21 12:11:30 +01:00
;
vltOffFront<errcodeen>:
yVLT_COVERAGE_OFF { $$ = V3ErrorCode::I_COVERAGE; }
| yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; }
2010-12-30 12:58:02 +01:00
| yVLT_LINT_OFF { $$ = V3ErrorCode::I_LINT; }
2010-01-21 12:11:30 +01:00
| yVLT_LINT_OFF yVLT_D_MSG yaID__ETC
2019-12-30 19:15:43 +01:00
{ $$ = V3ErrorCode((*$3).c_str());
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); }
2020-01-03 17:27:51 +01:00
$2->v3warn(DEPRECATED, "Deprecated -msg in configuration files, use -rule instead."<<endl); }
2019-12-30 19:15:43 +01:00
| yVLT_LINT_OFF yVLT_D_RULE yaID__ETC
2010-01-21 12:11:30 +01:00
{ $$ = V3ErrorCode((*$3).c_str());
2010-02-02 02:15:48 +01:00
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
2010-01-21 12:11:30 +01:00
;
2015-07-23 02:14:58 +02:00
vltOnFront<errcodeen>:
yVLT_COVERAGE_ON { $$ = V3ErrorCode::I_COVERAGE; }
| yVLT_TRACING_ON { $$ = V3ErrorCode::I_TRACING; }
| yVLT_LINT_ON { $$ = V3ErrorCode::I_LINT; }
| yVLT_LINT_ON yVLT_D_MSG yaID__ETC
2019-12-30 19:15:43 +01:00
{ $$ = V3ErrorCode((*$3).c_str());
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); }
2020-01-03 17:27:51 +01:00
$2->v3warn(DEPRECATED, "Deprecated -msg in configuration files, use -rule instead."<<endl); }
2019-12-30 19:15:43 +01:00
| yVLT_LINT_ON yVLT_D_RULE yaID__ETC
2015-07-23 02:14:58 +02:00
{ $$ = V3ErrorCode((*$3).c_str());
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
;
2020-01-12 10:03:17 +01:00
vltDModuleE<strp>:
/* empty */ { static string unit = "__024unit"; $$ = &unit; }
| yVLT_D_MODULE str { $$ = $2; }
;
vltDFTaskE<strp>:
/* empty */ { static string empty = ""; $$ = ∅ }
| yVLT_D_FUNCTION str { $$ = $2; }
| yVLT_D_TASK str { $$ = $2; }
;
vltInlineFront<cbool>:
yVLT_INLINE { $$ = true; }
| yVLT_NO_INLINE { $$ = false; }
;
vltVarAttrVarE<strp>:
/* empty */ { static string empty = ""; $$ = ∅ }
| yVLT_D_VAR str { $$ = $2; }
;
vltVarAttrFront<attrtypeen>:
yVLT_CLOCK_ENABLE { $$ = AstAttrType::VAR_CLOCK_ENABLE; }
| yVLT_CLOCKER { $$ = AstAttrType::VAR_CLOCKER; }
| yVLT_ISOLATE_ASSIGNMENTS { $$ = AstAttrType::VAR_ISOLATE_ASSIGNMENTS; }
| yVLT_NO_CLOCKER { $$ = AstAttrType::VAR_NO_CLOCKER; }
| yVLT_PUBLIC { $$ = AstAttrType::VAR_PUBLIC; v3Global.dpi(true); }
| yVLT_PUBLIC_FLAT { $$ = AstAttrType::VAR_PUBLIC_FLAT; v3Global.dpi(true); }
| yVLT_PUBLIC_FLAT_RD { $$ = AstAttrType::VAR_PUBLIC_FLAT_RD; v3Global.dpi(true); }
| yVLT_PUBLIC_FLAT_RW { $$ = AstAttrType::VAR_PUBLIC_FLAT_RW; v3Global.dpi(true); }
| yVLT_SC_BV { $$ = AstAttrType::VAR_SC_BV; }
| yVLT_SFORMAT { $$ = AstAttrType::VAR_SFORMAT; }
2020-04-03 14:08:23 +02:00
| yVLT_SPLIT_VAR { $$ = AstAttrType::VAR_SPLIT_VAR; }
2020-01-12 10:03:17 +01:00
;
2006-08-26 13:35:28 +02:00
//**********************************************************************
%%
2019-06-12 03:19:44 +02:00
// For implementation functions see V3ParseGrammar.cpp
2006-08-26 13:35:28 +02:00
2009-05-05 19:39:25 +02:00
//YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead
// --report=lookahead
// --report=itemset
// --graph