1 // -*- C++ -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilog-Perl bison parser
4 //
5 // This file is part of Verilog-Perl.
6 //
7 // Author: Wilson Snyder <wsnyder@wsnyder.org>
8 //
9 // Code available from: https://www.veripool.org/verilog-perl
10 //
11 //*************************************************************************
12 //
13 // Copyright 2001-2021 by Wilson Snyder. This program is free software;
14 // you can redistribute it and/or modify it under the terms of either the GNU
15 // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 //*************************************************************************
23
24 %{
25
26 #include <cstdio>
27 #include <fstream>
28 #include <stack>
29 #include <vector>
30 #include <map>
31 #include <deque>
32 #include <cassert>
33 #include <cstring>
34 #include <cerrno>
35 #include <cstdlib>
36 #include <climits>
37
38 #include "VParse.h"
39 #include "VParseGrammar.h"
40
41 #define YYERROR_VERBOSE 1
42 #define YYINITDEPTH 5000 // Large as the stack won't grow, since YYSTYPE_IS_TRIVIAL isn't defined
43 #define YYMAXDEPTH 5000
44
45 // See VParseGrammar.h for the C++ interface to this parser
46 // Include that instead of VParseBison.h
47
48 //*************************************************************************
49
50 #define GRAMMARP VParseGrammar::staticGrammarp()
51 #define PARSEP VParseGrammar::staticParsep()
52
53 #define NEWSTRING(text) (string((text)))
54 #define SPACED(a,b) ((a)+(((a)=="" || (b)=="")?"":" ")+(b))
55
56 #define VARS_PUSH() { GRAMMARP->m_varStack.push_back(GRAMMARP->m_var); }
57 #define VARS_POP() { GRAMMARP->m_var = GRAMMARP->m_varStack.back(); GRAMMARP->m_varStack.pop_back(); }
58
59 #define VARRESET_LIST(decl) { GRAMMARP->pinNum(1); VARRESET(); VARDECL(decl); } // Start of pinlist
60 #define VARRESET_NONLIST(decl) { GRAMMARP->pinNum(0); VARRESET(); VARDECL(decl); } // Not in a pinlist
61 #define VARRESET() { VARDECL(""); VARIO(""); VARNET(""); VARDTYPE(""); } // Start of one variable decl
62
63 // VARDECL("") indicates inside a port list or IO list and we shouldn't declare the variable
64 #define VARDECL(type) \
65 { GRAMMARP->m_var.m_decl = (type); } // genvar, parameter, localparam
66 #define VARIO(type) \
67 { GRAMMARP->m_var.m_io = (type); } // input, output, inout, ref, const ref
68 #define VARNET(type) \
69 { GRAMMARP->m_var.m_net = (type); } // supply*,wire,tri
70 #define VARDTYPE(type) \
71 { GRAMMARP->m_var.m_dtype = (type); } // "signed", "int", etc
72
73 #define PINNUMINC() { GRAMMARP->pinNumInc(); }
74
75 #define INSTPREP(cellmod,cellparam,withinInst) { GRAMMARP->pinNum(1); GRAMMARP->m_cellMod=(cellmod); GRAMMARP->m_cellParam=(cellparam); GRAMMARP->m_withinInst = 1; }
76 #define INSTDONE() { GRAMMARP->m_withinInst = 0; }
77
78 enum net_idx {NI_NETNAME = 0, NI_MSB, NI_LSB};
79
VARDONE(VFileLine * fl,const string & name,const string & array,const string & value)80 static void VARDONE(VFileLine * fl, const string& name, const string& array, const string& value) {
81 if (GRAMMARP->m_var.m_io != "" && GRAMMARP->m_var.m_decl == "")
82 GRAMMARP->m_var.m_decl = "port";
83 if (GRAMMARP->m_var.m_decl != "") {
84 PARSEP->varCb(fl, GRAMMARP->m_var.m_decl, name, PARSEP->symObjofUpward(),
85 GRAMMARP->m_var.m_net, GRAMMARP->m_var.m_dtype, array, value);
86 }
87 if (GRAMMARP->m_var.m_io != "" || GRAMMARP->pinNum()) {
88 PARSEP->portCb(fl, name, PARSEP->symObjofUpward(), GRAMMARP->m_var.m_io,
89 GRAMMARP->m_var.m_dtype, array, GRAMMARP->pinNum());
90 }
91 if (GRAMMARP->m_var.m_dtype == "type") {
92 PARSEP->syms().replaceInsert(VAstType::TYPE, name);
93 }
94 }
95
VARDONETYPEDEF(VFileLine * fl,const string & name,const string & type,const string & array)96 static void VARDONETYPEDEF(VFileLine* fl, const string& name, const string& type, const string& array) {
97 VARRESET(); VARDECL("typedef"); VARDTYPE(type);
98 VARDONE(fl,name,array,"");
99 // TYPE shouldn't override a more specific node type, as often is forward reference
100 PARSEP->syms().replaceInsert(VAstType::TYPE, name);
101 }
102
parse_net_constants(VFileLine * fl,VParseHashElem nets[][3])103 static void parse_net_constants(VFileLine* fl, VParseHashElem nets[][3]) {
104 VParseHashElem (*net)[3] = &nets[0];
105 VParseHashElem* nhp = net[0];
106
107 std::deque<VParseNet>::iterator it = GRAMMARP->m_portStack.begin();
108 while (it != GRAMMARP->m_portStack.end()) {
109 // Default net name is simply the complete token
110 const char* netnamep = it->m_name.c_str();
111
112 size_t delim = it->m_name.find_first_of("'");
113 if (it->m_name[0] != '\\' && it->m_msb.empty()
114 && delim != string::npos && it->m_name[delim] == '\'') {
115 // Handle sized integer constants (e.g., 7'b0) specifically but ignore replications (e.g., {4{w}})
116 if (delim != 0 && netnamep[0] != '{') {
117 // Handle the first part that indicates the width for sized constants (guaranteed to be a decimal)
118 char* endp;
119 errno = 0;
120 long l = strtol(netnamep, &endp, 10);
121 if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX || l <= 0) {
122 fl->error((string)"Unexpected length in size of integer constant: \""+netnamep+"\".");
123 return;
124 }
125 // Skip whitespace
126 while (endp < netnamep + delim && isspace(*endp)) {
127 endp++;
128 }
129 if (endp != netnamep + delim) {
130 fl->error((string)"Could not convert size of integer constant: \""+netnamep+"\".");
131 return;
132 }
133 int count = l;
134
135 // Skip characters up to the delimiter ' to determine new netnamep
136 netnamep += delim;
137
138 // Test for legal base specifiers:
139 // d, D, h, H, o, O , b, or B for the decimal, hexadecimal, octal, and binary bases, respectively
140 char base = netnamep[1];
141 // 's' indicates a signed constant, is followed by the actual base; currently ignored
142 if (base == 's' || base == 'S') {
143 base = netnamep[2];
144 }
145 if (strchr("dDhHoObB", base) == NULL) {
146 fl->error((string)"Base specifier \""+base+"\" is not valid in integer constant \""+it->m_name.c_str()+"\".");
147 return;
148 }
149
150 // These assignments could be prettified with C++11
151 nhp[NI_MSB].keyp = "msb";
152 nhp[NI_MSB].val_type = VParseHashElem::ELEM_INT;
153 nhp[NI_MSB].val_int = count - 1;
154 nhp[NI_LSB].keyp = "lsb";
155 nhp[NI_LSB].val_type = VParseHashElem::ELEM_INT;
156 nhp[NI_LSB].val_int = 0;
157 } else {
158 // fl->error increases the error count which would create regressions for no good reasons.
159 // There is no ->warn or similar though but we could print, e.g., to stderr in these cases
160 //fl->error((string)"Neither unsized integer constant nor replications are not fully supported in nets (\""+netnamep+"\").");
161 //fprintf(stderr, "Neither unsized integer constant nor replications are not fully supported in nets (\"%s\").\n", netnamep);
162 }
163 } else {
164 // Ordinary net names might have a range attached or not.
165 // If it does then parse its bounds into proper integers.
166 const char *msbstr = it->m_msb.c_str();
167 if (msbstr[0] != '\0') {
168 { // Parse NI_MSB
169 char* endp;
170 errno = 0;
171 long l = strtol(msbstr, &endp, 10);
172 // Test for range within int, and proper parsing
173 if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX || l < 0
174 || (endp && l == 0 && errno == ERANGE)) {
175 fl->error((string)"Unexpected length in msb specification of \""+netnamep+"\" (endp="+endp+", errno="+strerror(errno)+").");
176 return;
177 }
178 nhp[NI_MSB].keyp = "msb";
179 nhp[NI_MSB].val_type = VParseHashElem::ELEM_INT;
180 nhp[NI_MSB].val_int = (int)l;
181 }
182 { // Parse NI_LSB
183 char* endp;
184 errno = 0;
185 long l = strtol(it->m_lsb.c_str(), &endp, 10);
186 if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX || l < 0
187 || (endp && l == 0 && errno == ERANGE)) {
188 fl->error((string)"Unexpected length in lsb specification of \""+netnamep+"\".");
189 return;
190 }
191 nhp[NI_LSB].keyp = "lsb";
192 nhp[NI_LSB].val_type = VParseHashElem::ELEM_INT;
193 nhp[NI_LSB].val_int = (int)l;
194 }
195 } else {
196 nhp[NI_MSB].keyp = NULL;
197 nhp[NI_LSB].keyp = NULL;
198 }
199 }
200
201 nhp[NI_NETNAME].keyp = "netname";
202 nhp[NI_NETNAME].val_type = VParseHashElem::ELEM_STR;
203 nhp[NI_NETNAME].val_str = netnamep;
204 *it++;
205 nhp += 3; // We operate on three elements in each iteration
206 }
207 }
208
PINDONE(VFileLine * fl,const string & name,const string & expr)209 static void PINDONE(VFileLine* fl, const string& name, const string& expr) {
210 if (GRAMMARP->m_cellParam) {
211 // Stack them until we create the instance itself
212 GRAMMARP->m_pinStack.push_back(VParseGPin(fl, name, expr, GRAMMARP->pinNum()));
213 } else {
214 PARSEP->pinCb(fl, name, expr, GRAMMARP->pinNum());
215 if (PARSEP->usePinSelects()) {
216 if (GRAMMARP->m_portStack.empty()) {
217 string netname;
218 if (GRAMMARP->m_portNextNetName.empty()) {
219 netname = expr;
220 } else {
221 netname = GRAMMARP->m_portNextNetName;
222 }
223 size_t elem_cnt = GRAMMARP->m_portNextNetMsb.empty() ? 1 : 3;
224 VParseHashElem nets[elem_cnt];
225 // These assignments could be prettified with C++11
226 nets[NI_NETNAME].keyp = "netname";
227 nets[NI_NETNAME].val_type = VParseHashElem::ELEM_STR;
228 nets[NI_NETNAME].val_str = netname;
229 if (elem_cnt > 1) {
230 nets[NI_MSB].keyp = "msb";
231 nets[NI_MSB].val_type = VParseHashElem::ELEM_STR;
232 nets[NI_MSB].val_str = GRAMMARP->m_portNextNetMsb;
233 nets[NI_LSB].keyp = "lsb";
234 nets[NI_LSB].val_type = VParseHashElem::ELEM_STR;
235 nets[NI_LSB].val_str = GRAMMARP->m_portNextNetLsb;
236 }
237 PARSEP->pinselectsCb(fl, name, 1, elem_cnt, &nets[0], GRAMMARP->pinNum());
238 } else {
239 // Connection with multiple pins was parsed completely.
240 // There might be one net left in the pipe...
241 if (GRAMMARP->m_portNextNetValid) {
242 GRAMMARP->m_portStack.push_front(VParseNet(GRAMMARP->m_portNextNetName, GRAMMARP->m_portNextNetMsb, GRAMMARP->m_portNextNetLsb));
243 }
244
245 unsigned int arraycnt = GRAMMARP->m_portStack.size();
246 VParseHashElem nets[arraycnt][3];
247 parse_net_constants(fl, nets);
248 PARSEP->pinselectsCb(fl, name, arraycnt, 3, &nets[0][0], GRAMMARP->pinNum());
249 }
250 // Clear all pin-related fields
251 GRAMMARP->m_portNextNetValid = false;
252 GRAMMARP->m_portNextNetName.clear();
253 GRAMMARP->m_portStack.clear();
254 GRAMMARP->m_portNextNetMsb.clear();
255 GRAMMARP->m_portNextNetLsb.clear();
256 }
257 }
258 }
259
PINPARAMS()260 static void PINPARAMS() {
261 // Throw out all the "pins" we found before we could do instanceCb
262 while (!GRAMMARP->m_pinStack.empty()) {
263 VParseGPin& pinr = GRAMMARP->m_pinStack.front();
264 PARSEP->parampinCb(pinr.m_fl, pinr.m_name, pinr.m_conn, pinr.m_number);
265 GRAMMARP->m_pinStack.pop_front();
266 }
267 GRAMMARP->m_withinPin = true;
268 }
269
PORTNET(VFileLine * fl,const string & name)270 static void PORTNET(VFileLine* fl, const string& name) {
271 if (!GRAMMARP->m_withinInst) {
272 return;
273 }
274 GRAMMARP->m_portNextNetValid = true;
275 GRAMMARP->m_portNextNetName = name;
276 GRAMMARP->m_portNextNetMsb.clear();
277 GRAMMARP->m_portNextNetLsb.clear();
278 }
279
PORTRANGE(const string & msb,const string & lsb)280 static void PORTRANGE(const string& msb, const string& lsb) {
281 if (!GRAMMARP->m_withinInst) {
282 return;
283 }
284 GRAMMARP->m_portNextNetMsb = msb;
285 GRAMMARP->m_portNextNetLsb = lsb;
286 }
287
PIN_CONCAT_APPEND(const string & expr)288 static void PIN_CONCAT_APPEND(const string& expr) {
289 if (!GRAMMARP->m_withinPin) {
290 return;
291 }
292 if (!GRAMMARP->m_portNextNetValid) {
293 // Only while not within a valid net term the expression is part
294 // of a replication constant. If that's detected ignore the
295 // previous expression (that is actually just the contained
296 // concatenation) in favor of the full replication expression.
297 if (expr[0] == '{') {
298 if (expr.find_first_of("{", 1) != string::npos) {
299 // fprintf(stderr, "%d: ignoring \"%s\" in favor of \"%s\".\n", __LINE__, GRAMMARP->m_portStack.front().m_name.c_str(), expr.c_str());
300 GRAMMARP->m_portStack.pop_front();
301 GRAMMARP->m_portStack.push_front(VParseNet(expr));
302 }
303 } else {
304 GRAMMARP->m_portStack.push_front(VParseNet(expr));
305 }
306 } else {
307 GRAMMARP->m_portStack.push_front(VParseNet(GRAMMARP->m_portNextNetName, GRAMMARP->m_portNextNetMsb, GRAMMARP->m_portNextNetLsb));
308 }
309 GRAMMARP->m_portNextNetValid = false;
310 }
311
312 /* Yacc */
VParseBisonlex(VParseBisonYYSType * yylvalp)313 static int VParseBisonlex(VParseBisonYYSType* yylvalp) { return PARSEP->lexToBison(yylvalp); }
314
VParseBisonerror(const char * s)315 static void VParseBisonerror(const char *s) { VParseGrammar::bisonError(s); }
316
ERRSVKWD(VFileLine * fileline,const string & tokname)317 static void ERRSVKWD(VFileLine* fileline, const string& tokname) {
318 static int toldonce = 0;
319 fileline->error((string)"Unexpected \""+tokname+"\": \""+tokname+"\" is a SystemVerilog keyword misused as an identifier.");
320 if (!toldonce++) fileline->error("Modify the Verilog-2001 code to avoid SV keywords, or use `begin_keywords or --language.");
321 }
322
NEED_S09(VFileLine *,const string &)323 static void NEED_S09(VFileLine*, const string&) {
324 //Let lint tools worry about it
325 //fileline->error((string)"Advanced feature: \""+tokname+"\" is a 1800-2009 construct, but used under --language 1800-2005 or earlier.");
326 }
327
328 %}
329
330 BISONPRE_VERSION(0.0, 2.999, %pure_parser)
331 BISONPRE_VERSION(3.0, %pure-parser)
332 BISONPRE_VERSION(0.0, 2.999, %token_table)
333 BISONPRE_VERSION(3.0, %token-table)
334 BISONPRE_VERSION(2.4, 2.999, %define lr.keep_unreachable_states)
335 BISONPRE_VERSION(3.0, %define lr.keep-unreachable-state)
336
337 // When writing Bison patterns we use yTOKEN instead of "token",
338 // so Bison will error out on unknown "token"s.
339
340 // Generic lexer tokens, for example a number
341 // IEEE: real_number
342 %token<str> yaFLOATNUM "FLOATING-POINT NUMBER"
343
344 // IEEE: identifier, class_identifier, class_variable_identifier,
345 // covergroup_variable_identifier, dynamic_array_variable_identifier,
346 // enum_identifier, interface_identifier, interface_instance_identifier,
347 // package_identifier, type_identifier, variable_identifier,
348 %token<str> yaID__ETC "IDENTIFIER"
349 %token<str> yaID__LEX "IDENTIFIER-in-lex"
350 %token<str> yaID__aPACKAGE "PACKAGE-IDENTIFIER"
351 %token<str> yaID__aTYPE "TYPE-IDENTIFIER"
352 // aCOVERGROUP is same as aTYPE
353 // Can't predecode aFUNCTION, can declare after use
354 // Can't predecode aINTERFACE, can declare after use
355 // Can't predecode aTASK, can declare after use
356
357 // IEEE: integral_number
358 %token<str> yaINTNUM "INTEGER NUMBER"
359 // IEEE: time_literal + time_unit
360 %token<str> yaTIMENUM "TIME NUMBER"
361 // IEEE: string_literal
362 %token<str> yaSTRING "STRING"
363 %token<str> yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed
364
365 %token<str> yaTIMINGSPEC "TIMING SPEC ELEMENT"
366
367 %token<str> ygenGATE "GATE keyword"
368 %token<str> ygenCONFIGKEYWORD "CONFIG keyword (cell/use/design/etc)"
369 %token<str> ygenOPERATOR "OPERATOR"
370 %token<str> ygenSTRENGTH "STRENGTH keyword (strong1/etc)"
371 %token<str> ygenSYSCALL "SYSCALL"
372
373 %token<str> '!'
374 %token<str> '#'
375 %token<str> '%'
376 %token<str> '&'
377 %token<str> '('
378 %token<str> ')'
379 %token<str> '*'
380 %token<str> '+'
381 %token<str> ','
382 %token<str> '-'
383 %token<str> '.'
384 %token<str> '/'
385 %token<str> ':'
386 %token<str> ';'
387 %token<str> '<'
388 %token<str> '='
389 %token<str> '>'
390 %token<str> '?'
391 %token<str> '@'
392 %token<str> '['
393 %token<str> ']'
394 %token<str> '^'
395 %token<str> '{'
396 %token<str> '|'
397 %token<str> '}'
398 %token<str> '~'
399
400 // Specific keywords
401 // yKEYWORD means match "keyword"
402 // Other cases are yXX_KEYWORD where XX makes it unique,
403 // for example yP_ for punctuation based operators.
404 // Double underscores "yX__Y" means token X followed by Y,
405 // and "yX__ETC" means X folled by everything but Y(s).
406 %token<str> yACCEPT_ON "accept_on"
407 %token<str> yALIAS "alias"
408 %token<str> yALWAYS "always"
409 %token<str> yAND "and"
410 %token<str> yASSERT "assert"
411 %token<str> yASSIGN "assign"
412 %token<str> yASSUME "assume"
413 %token<str> yAUTOMATIC "automatic"
414 %token<str> yBEFORE "before"
415 %token<str> yBEGIN "begin"
416 %token<str> yBIND "bind"
417 %token<str> yBINS "bins"
418 %token<str> yBINSOF "binsof"
419 %token<str> yBIT "bit"
420 %token<str> yBREAK "break"
421 %token<str> yBUF "buf"
422 %token<str> yBYTE "byte"
423 %token<str> yCASE "case"
424 %token<str> yCASEX "casex"
425 %token<str> yCASEZ "casez"
426 %token<str> yCHANDLE "chandle"
427 %token<str> yCHECKER "checker"
428 %token<str> yCLASS "class"
429 %token<str> yCLOCK "clock"
430 %token<str> yCLOCKING "clocking"
431 %token<str> yCONSTRAINT "constraint"
432 %token<str> yCONST__ETC "const"
433 %token<str> yCONST__LEX "const-in-lex"
434 %token<str> yCONST__LOCAL "const-then-local"
435 %token<str> yCONST__REF "const-then-ref"
436 %token<str> yCONTEXT "context"
437 %token<str> yCONTINUE "continue"
438 %token<str> yCOVER "cover"
439 %token<str> yCOVERGROUP "covergroup"
440 %token<str> yCOVERPOINT "coverpoint"
441 %token<str> yCROSS "cross"
442 %token<str> yDEASSIGN "deassign"
443 %token<str> yDEFAULT "default"
444 %token<str> yDEFPARAM "defparam"
445 %token<str> yDISABLE "disable"
446 %token<str> yDIST "dist"
447 %token<str> yDO "do"
448 %token<str> yEDGE "edge"
449 %token<str> yELSE "else"
450 %token<str> yEND "end"
451 %token<str> yENDCASE "endcase"
452 %token<str> yENDCHECKER "endchecker"
453 %token<str> yENDCLASS "endclass"
454 %token<str> yENDCLOCKING "endclocking"
455 %token<str> yENDFUNCTION "endfunction"
456 %token<str> yENDGENERATE "endgenerate"
457 %token<str> yENDGROUP "endgroup"
458 %token<str> yENDINTERFACE "endinterface"
459 %token<str> yENDMODULE "endmodule"
460 %token<str> yENDPACKAGE "endpackage"
461 %token<str> yENDPROGRAM "endprogram"
462 %token<str> yENDPROPERTY "endproperty"
463 %token<str> yENDSEQUENCE "endsequence"
464 %token<str> yENDSPECIFY "endspecify"
465 %token<str> yENDTABLE "endtable"
466 %token<str> yENDTASK "endtask"
467 %token<str> yENUM "enum"
468 %token<str> yEVENT "event"
469 %token<str> yEVENTUALLY "eventually"
470 %token<str> yEXPECT "expect"
471 %token<str> yEXPORT "export"
472 %token<str> yEXTENDS "extends"
473 %token<str> yEXTERN "extern"
474 %token<str> yFINAL "final"
475 %token<str> yFIRST_MATCH "first_match"
476 %token<str> yFOR "for"
477 %token<str> yFORCE "force"
478 %token<str> yFOREACH "foreach"
479 %token<str> yFOREVER "forever"
480 %token<str> yFORK "fork"
481 %token<str> yFORKJOIN "forkjoin"
482 %token<str> yFUNCTION__ETC "function"
483 %token<str> yFUNCTION__LEX "function-in-lex"
484 %token<str> yFUNCTION__aPUREV "function-is-pure-virtual"
485 %token<str> yGENERATE "generate"
486 %token<str> yGENVAR "genvar"
487 %token<str> yGLOBAL__CLOCKING "global-then-clocking"
488 %token<str> yGLOBAL__LEX "global-in-lex"
489 %token<str> yIF "if"
490 %token<str> yIFF "iff"
491 %token<str> yIGNORE_BINS "ignore_bins"
492 %token<str> yILLEGAL_BINS "illegal_bins"
493 %token<str> yIMPLEMENTS "implements"
494 %token<str> yIMPLIES "implies"
495 %token<str> yIMPORT "import"
496 %token<str> yINITIAL "initial"
497 %token<str> yINOUT "inout"
498 %token<str> yINPUT "input"
499 %token<str> yINSIDE "inside"
500 %token<str> yINT "int"
501 %token<str> yINTEGER "integer"
502 %token<str> yINTERCONNECT "interconnect"
503 %token<str> yINTERFACE "interface"
504 %token<str> yINTERSECT "intersect"
505 %token<str> yJOIN "join"
506 %token<str> yLET "let"
507 %token<str> yLOCALPARAM "localparam"
508 %token<str> yLOCAL__COLONCOLON "local-then-::"
509 %token<str> yLOCAL__ETC "local"
510 %token<str> yLOCAL__LEX "local-in-lex"
511 %token<str> yLOGIC "logic"
512 %token<str> yLONGINT "longint"
513 %token<str> yMATCHES "matches"
514 %token<str> yMODPORT "modport"
515 %token<str> yMODULE "module"
516 %token<str> yNAND "nand"
517 %token<str> yNEGEDGE "negedge"
518 %token<str> yNETTYPE "nettype"
519 %token<str> yNEW__ETC "new"
520 %token<str> yNEW__LEX "new-in-lex"
521 %token<str> yNEW__PAREN "new-then-paren"
522 %token<str> yNEXTTIME "nexttime"
523 %token<str> yNOR "nor"
524 %token<str> yNOT "not"
525 %token<str> yNULL "null"
526 %token<str> yOR "or"
527 %token<str> yOUTPUT "output"
528 %token<str> yPACKAGE "package"
529 %token<str> yPACKED "packed"
530 %token<str> yPARAMETER "parameter"
531 %token<str> yPOSEDGE "posedge"
532 %token<str> yPRIORITY "priority"
533 %token<str> yPROGRAM "program"
534 %token<str> yPROPERTY "property"
535 %token<str> yPROTECTED "protected"
536 %token<str> yPURE "pure"
537 %token<str> yRAND "rand"
538 %token<str> yRANDC "randc"
539 %token<str> yRANDCASE "randcase"
540 %token<str> yRANDSEQUENCE "randsequence"
541 %token<str> yREAL "real"
542 %token<str> yREALTIME "realtime"
543 %token<str> yREF "ref"
544 %token<str> yREG "reg"
545 %token<str> yREJECT_ON "reject_on"
546 %token<str> yRELEASE "release"
547 %token<str> yREPEAT "repeat"
548 %token<str> yRESTRICT "restrict"
549 %token<str> yRETURN "return"
550 %token<str> ySCALARED "scalared"
551 %token<str> ySEQUENCE "sequence"
552 %token<str> ySHORTINT "shortint"
553 %token<str> ySHORTREAL "shortreal"
554 %token<str> ySIGNED "signed"
555 %token<str> ySOFT "soft"
556 %token<str> ySOLVE "solve"
557 %token<str> ySPECIFY "specify"
558 %token<str> ySPECPARAM "specparam"
559 %token<str> ySTATIC__CONSTRAINT "static-then-constraint"
560 %token<str> ySTATIC__ETC "static"
561 %token<str> ySTATIC__LEX "static-in-lex"
562 %token<str> ySTRING "string"
563 %token<str> ySTRONG "strong"
564 %token<str> ySTRUCT "struct"
565 %token<str> ySUPER "super"
566 %token<str> ySUPPLY0 "supply0"
567 %token<str> ySUPPLY1 "supply1"
568 %token<str> ySYNC_ACCEPT_ON "sync_accept_on"
569 %token<str> ySYNC_REJECT_ON "sync_reject_on"
570 %token<str> yS_ALWAYS "s_always"
571 %token<str> yS_EVENTUALLY "s_eventually"
572 %token<str> yS_NEXTTIME "s_nexttime"
573 %token<str> yS_UNTIL "s_until"
574 %token<str> yS_UNTIL_WITH "s_until_with"
575 %token<str> yTABLE "table"
576 %token<str> yTAGGED "tagged"
577 %token<str> yTASK__ETC "task"
578 %token<str> yTASK__LEX "task-in-lex"
579 %token<str> yTASK__aPUREV "task-is-pure-virtual"
580 %token<str> yTHIS "this"
581 %token<str> yTHROUGHOUT "throughout"
582 %token<str> yTIME "time"
583 %token<str> yTIMEPRECISION "timeprecision"
584 %token<str> yTIMEUNIT "timeunit"
585 %token<str> yTRI "tri"
586 %token<str> yTRI0 "tri0"
587 %token<str> yTRI1 "tri1"
588 %token<str> yTRIAND "triand"
589 %token<str> yTRIOR "trior"
590 %token<str> yTRIREG "trireg"
591 %token<str> yTYPE "type"
592 %token<str> yTYPEDEF "typedef"
593 %token<str> yUNION "union"
594 %token<str> yUNIQUE "unique"
595 %token<str> yUNIQUE0 "unique0"
596 %token<str> yUNSIGNED "unsigned"
597 %token<str> yUNTIL "until"
598 %token<str> yUNTIL_WITH "until_with"
599 %token<str> yUNTYPED "untyped"
600 %token<str> yVAR "var"
601 %token<str> yVECTORED "vectored"
602 %token<str> yVIRTUAL__CLASS "virtual-then-class"
603 %token<str> yVIRTUAL__ETC "virtual"
604 %token<str> yVIRTUAL__INTERFACE "virtual-then-interface"
605 %token<str> yVIRTUAL__LEX "virtual-in-lex"
606 %token<str> yVIRTUAL__anyID "virtual-then-identifier"
607 %token<str> yVOID "void"
608 %token<str> yWAIT "wait"
609 %token<str> yWAIT_ORDER "wait_order"
610 %token<str> yWAND "wand"
611 %token<str> yWEAK "weak"
612 %token<str> yWHILE "while"
613 %token<str> yWILDCARD "wildcard"
614 %token<str> yWIRE "wire"
615 %token<str> yWITHIN "within"
616 %token<str> yWITH__BRA "with-then-["
617 %token<str> yWITH__CUR "with-then-{"
618 %token<str> yWITH__ETC "with"
619 %token<str> yWITH__LEX "with-in-lex"
620 %token<str> yWITH__PAREN "with-then-("
621 %token<str> yWOR "wor"
622 %token<str> yXNOR "xnor"
623 %token<str> yXOR "xor"
624
625 %token<str> yD_ERROR "$error"
626 %token<str> yD_FATAL "$fatal"
627 %token<str> yD_INFO "$info"
628 %token<str> yD_ROOT "$root"
629 %token<str> yD_UNIT "$unit"
630 %token<str> yD_WARNING "$warning"
631
632 %token<str> yP_TICK "'"
633 %token<str> yP_TICKBRA "'{"
634 %token<str> yP_OROR "||"
635 %token<str> yP_ANDAND "&&"
636 %token<str> yP_NOR "~|"
637 %token<str> yP_XNOR "^~"
638 %token<str> yP_NAND "~&"
639 %token<str> yP_EQUAL "=="
640 %token<str> yP_NOTEQUAL "!="
641 %token<str> yP_CASEEQUAL "==="
642 %token<str> yP_CASENOTEQUAL "!=="
643 %token<str> yP_WILDEQUAL "==?"
644 %token<str> yP_WILDNOTEQUAL "!=?"
645 %token<str> yP_GTE ">="
646 %token<str> yP_LTE "<="
647 %token<str> yP_LTE__IGNORE "<=-ignored" // Used when expr:<= means assignment
648 %token<str> yP_SLEFT "<<"
649 %token<str> yP_SRIGHT ">>"
650 %token<str> yP_SSRIGHT ">>>"
651 %token<str> yP_POW "**"
652
653 %token<str> yP_PAR__IGNORE "(-ignored" // Used when sequence_expr:expr:( is ignored
654 %token<str> yP_PAR__STRENGTH "(-for-strength"
655
656 %token<str> yP_LTMINUSGT "<->"
657 %token<str> yP_PLUSCOLON "+:"
658 %token<str> yP_MINUSCOLON "-:"
659 %token<str> yP_MINUSGT "->"
660 %token<str> yP_MINUSGTGT "->>"
661 %token<str> yP_EQGT "=>"
662 %token<str> yP_ASTGT "*>"
663 %token<str> yP_ANDANDAND "&&&"
664 %token<str> yP_POUNDPOUND "##"
665 %token<str> yP_POUNDMINUSPD "#-#"
666 %token<str> yP_POUNDEQPD "#=#"
667 %token<str> yP_DOTSTAR ".*"
668
669 %token<str> yP_ATAT "@@"
670 %token<str> yP_COLONCOLON "::"
671 %token<str> yP_COLONEQ ":="
672 %token<str> yP_COLONDIV ":/"
673 %token<str> yP_ORMINUSGT "|->"
674 %token<str> yP_OREQGT "|=>"
675 %token<str> yP_BRASTAR "[*"
676 %token<str> yP_BRAEQ "[="
677 %token<str> yP_BRAMINUSGT "[->"
678 %token<str> yP_BRAPLUSKET "[+]"
679
680 %token<str> yP_PLUSPLUS "++"
681 %token<str> yP_MINUSMINUS "--"
682 %token<str> yP_PLUSEQ "+="
683 %token<str> yP_MINUSEQ "-="
684 %token<str> yP_TIMESEQ "*="
685 %token<str> yP_DIVEQ "/="
686 %token<str> yP_MODEQ "%="
687 %token<str> yP_ANDEQ "&="
688 %token<str> yP_OREQ "|="
689 %token<str> yP_XOREQ "^="
690 %token<str> yP_SLEFTEQ "<<="
691 %token<str> yP_SRIGHTEQ ">>="
692 %token<str> yP_SSRIGHTEQ ">>>="
693
694 // '( is not a operator, as "' (" is legal
695
696 //********************
697 // Verilog op precedence
698
699 %token<str> prUNARYARITH
700 %token<str> prREDUCTION
701 %token<str> prNEGATION
702 %token<str> prEVENTBEGIN
703 %token<str> prTAGGED
704
705 // These prevent other conflicts
706 %left yP_ANDANDAND
707 %left yMATCHES
708 %left prTAGGED
709 %left prSEQ_CLOCKING
710
711 // Lowest precedence
712 // These are in IEEE 17.7.1
713 %nonassoc yALWAYS yS_ALWAYS yEVENTUALLY yS_EVENTUALLY yACCEPT_ON yREJECT_ON ySYNC_ACCEPT_ON ySYNC_REJECT_ON
714
715 %right yP_ORMINUSGT yP_OREQGT yP_POUNDMINUSPD yP_POUNDEQPD
716 %right yUNTIL yS_UNTIL yUNTIL_WITH yS_UNTIL_WITH yIMPLIES
717 %right yIFF
718 %left yOR
719 %left yAND
720 %nonassoc yNOT yNEXTTIME yS_NEXTTIME
721 %left yINTERSECT
722 %left yWITHIN
723 %right yTHROUGHOUT
724 %left prPOUNDPOUND_MULTI
725 %left yP_POUNDPOUND
726 %left yP_BRASTAR yP_BRAEQ yP_BRAMINUSGT yP_BRAPLUSKET
727
728 // Not specified, but needed higher than yOR, lower than normal non-pexpr expressions
729 %left yPOSEDGE yNEGEDGE yEDGE
730
731 %left '{' '}'
732 //%nonassoc '=' yP_PLUSEQ yP_MINUSEQ yP_TIMESEQ yP_DIVEQ yP_MODEQ yP_ANDEQ yP_OREQ yP_XOREQ yP_SLEFTEQ yP_SRIGHTEQ yP_SSRIGHTEQ yP_COLONEQ yP_COLONDIV yP_LTE
733 %right yP_MINUSGT yP_LTMINUSGT
734 %right '?' ':'
735 %left yP_OROR
736 %left yP_ANDAND
737 %left '|' yP_NOR
738 %left '^' yP_XNOR
739 %left '&' yP_NAND
740 %left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
741 %left '>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE yDIST
742 %left yP_SLEFT yP_SRIGHT yP_SSRIGHT
743 %left '+' '-'
744 %left '*' '/' '%'
745 %left yP_POW
746 %left prUNARYARITH yP_MINUSMINUS yP_PLUSPLUS prREDUCTION prNEGATION
747 %left '.'
748 // Not in IEEE, but need to avoid conflicts; TICK should bind tightly just lower than COLONCOLON
749 %left yP_TICK
750 //%left '(' ')' '[' ']' yP_COLONCOLON '.'
751
752 %nonassoc prLOWER_THAN_ELSE
753 %nonassoc yELSE
754
755 //BISONPRE_TYPES
756 // Blank lines for type insertion
757 // Blank lines for type insertion
758 // Blank lines for type insertion
759 // Blank lines for type insertion
760 // Blank lines for type insertion
761 // Blank lines for type insertion
762 // Blank lines for type insertion
763 // Blank lines for type insertion
764 // Blank lines for type insertion
765 // Blank lines for type insertion
766 // Blank lines for type insertion
767 // Blank lines for type insertion
768 // Blank lines for type insertion
769 // Blank lines for type insertion
770 // Blank lines for type insertion
771 // Blank lines for type insertion
772 // Blank lines for type insertion
773 // Blank lines for type insertion
774 // Blank lines for type insertion
775 // Blank lines for type insertion
776 // Blank lines for type insertion
777 // Blank lines for type insertion
778 // Blank lines for type insertion
779 // Blank lines for type insertion
780 // Blank lines for type insertion
781 // Blank lines for type insertion
782 // Blank lines for type insertion
783 // Blank lines for type insertion
784 // Blank lines for type insertion
785 // Blank lines for type insertion
786
787 %start source_text
788
789 %%
790 //**********************************************************************
791 // Feedback to the Lexer
792 // Note we read a parenthesis ahead, so this may not change the lexer at the right point.
793
794 statePushVlg: // For PSL lexing, escape current state into Verilog state
795 /* empty */ { }
796 ;
797 statePop: // Return to previous lexing state
798 /* empty */ { }
799 ;
800
801 //**********************************************************************
802 // Files
803
804 source_text: // ==IEEE: source_text
805 /* empty */ { }
806 // // timeunits_declaration moved into description:package_item
807 | descriptionList { }
808 ;
809
810 descriptionList: // IEEE: part of source_text
811 description { }
812 | descriptionList description { }
813 ;
814
815 description: // ==IEEE: description
816 module_declaration { }
817 // // udp_declaration moved into module_declaration
818 | interface_declaration { }
819 | program_declaration { }
820 | package_declaration { }
821 | package_item { }
822 | bind_directive { }
823 // unsupported // IEEE: config_declaration
824 | error { }
825 ;
826
827 timeunits_declaration: // ==IEEE: timeunits_declaration
828 yTIMEUNIT yaTIMENUM ';' { }
829 | yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';' { NEED_S09($<fl>1,"timeunit /"); }
830 | yTIMEPRECISION yaTIMENUM ';' { }
831 ;
832
833 //**********************************************************************
834 // Packages
835
836 package_declaration: // ==IEEE: package_declaration
837 packageFront package_itemListE yENDPACKAGE endLabelE
838 { PARSEP->endpackageCb($<fl>3,$3);
839 PARSEP->symPopScope(VAstType::PACKAGE); }
840 ;
841
842 packageFront:
843 // // Lifetime is 1800-2009
844 yPACKAGE lifetimeE idAny ';'
845 { PARSEP->symPushNew(VAstType::PACKAGE, $3);
846 PARSEP->packageCb($<fl>1,$1, $3); }
847 ;
848
849 package_itemListE: // IEEE: [{ package_item }]
850 /* empty */ { }
851 | package_itemList { }
852 ;
853
854 package_itemList: // IEEE: { package_item }
855 package_item { }
856 | package_itemList package_item { }
857 ;
858
859 package_item: // ==IEEE: package_item
860 package_or_generate_item_declaration { }
861 | anonymous_program { }
862 | package_export_declaration { }
863 | timeunits_declaration { }
864 ;
865
866 package_or_generate_item_declaration: // ==IEEE: package_or_generate_item_declaration
867 net_declaration { }
868 | data_declaration { }
869 | task_declaration { }
870 | function_declaration { }
871 | checker_declaration { }
872 | dpi_import_export { }
873 | extern_constraint_declaration { }
874 | class_declaration { }
875 // // class_constructor_declaration is part of function_declaration
876 | local_parameter_declaration ';' { }
877 | parameter_declaration ';' { }
878 | covergroup_declaration { }
879 | overload_declaration { }
880 | assertion_item_declaration { }
881 | ';' { }
882 ;
883
884 package_import_declarationList:
885 package_import_declaration { }
886 | package_import_declarationList package_import_declaration { }
887 ;
888
889 package_import_declaration: // ==IEEE: package_import_declaration
890 yIMPORT package_import_itemList ';' { }
891 ;
892
893 package_import_itemList:
894 package_import_item { }
895 | package_import_itemList ',' package_import_item { }
896 ;
897
898 package_import_item: // ==IEEE: package_import_item
899 yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
900 { PARSEP->syms().import($<fl>1,$1,$3);
901 PARSEP->importCb($<fl>1,$1,$3); }
902 ;
903
904 package_import_itemObj<str>: // IEEE: part of package_import_item
905 idAny { $<fl>$=$<fl>1; $$=$1; }
906 | '*' { $<fl>$=$<fl>1; $$=$1; }
907 ;
908
909 package_export_declaration<str>: // IEEE: package_export_declaration
910 yEXPORT '*' yP_COLONCOLON '*' ';' { }
911 | yEXPORT package_import_itemList ';' { }
912 ;
913
914 //**********************************************************************
915 // Module headers
916
917 module_declaration: // ==IEEE: module_declaration
918 // // timeunits_declaration instead in module_item
919 // // IEEE: module_nonansi_header + module_ansi_header
920 modFront importsAndParametersE portsStarE ';'
921 module_itemListE yENDMODULE endLabelE
922 { PARSEP->endmoduleCb($<fl>6,$6);
923 PARSEP->symPopScope(VAstType::MODULE); }
924 //
925 | yEXTERN modFront importsAndParametersE portsStarE ';'
926 { PARSEP->symPopScope(VAstType::MODULE); }
927 ;
928
929 modFront:
930 // // General note: all *Front functions must call symPushNew before
931 // // any formal arguments, as the arguments must land in the new scope.
932 yMODULE lifetimeE idAny
933 { PARSEP->symPushNew(VAstType::MODULE, $3);
934 PARSEP->moduleCb($<fl>1,$1,$3,false,PARSEP->inCellDefine()); }
935 ;
936
937 importsAndParametersE: // IEEE: common part of module_declaration, interface_declaration, program_declaration
938 // // { package_import_declaration } [ parameter_port_list ]
939 parameter_port_listE { }
940 | package_import_declarationList parameter_port_listE { }
941 ;
942
943 parameter_value_assignmentE: // IEEE: [ parameter_value_assignment ]
944 /* empty */ { }
945 | '#' '(' cellpinList ')' { }
946 // // Side effect of combining *_instantiations
947 | '#' delay_value { }
948 ;
949
950 parameter_port_listE: // IEEE: parameter_port_list + empty == parameter_value_assignment
951 /* empty */ { }
952 | '#' '(' ')' { }
953 // // IEEE: '#' '(' list_of_param_assignments { ',' parameter_port_declaration } ')'
954 // // IEEE: '#' '(' parameter_port_declaration { ',' parameter_port_declaration } ')'
955 // // Can't just do that as "," conflicts with between vars and between stmts, so
956 // // split into pre-comma and post-comma parts
957 | '#' '(' {VARRESET_LIST("parameter");} paramPortDeclOrArgList ')' { VARRESET_NONLIST(""); }
958 // // Note legal to start with "a=b" with no parameter statement
959 ;
960
961 paramPortDeclOrArgList: // IEEE: list_of_param_assignments + { parameter_port_declaration }
962 paramPortDeclOrArg { }
963 | paramPortDeclOrArgList ',' paramPortDeclOrArg { }
964 ;
965
966 paramPortDeclOrArg: // IEEE: param_assignment + parameter_port_declaration
967 // // We combine the two as we can't tell which follows a comma
968 param_assignment { }
969 | parameter_port_declarationFront param_assignment { }
970 ;
971
972 portsStarE: // IEEE: .* + list_of_ports + list_of_port_declarations + empty
973 /* empty */ { }
974 // // .* expanded from module_declaration
975 // // '(' ')' handled by list_of_ports:portE
976 | '(' yP_DOTSTAR ')' { }
977 | '(' {VARRESET_LIST("");} list_of_portsE ')' { VARRESET_NONLIST(""); }
978 ;
979
980 list_of_portsE: // IEEE: list_of_ports + list_of_port_declarations
981 portE { }
982 | list_of_portsE ',' portE { }
983 ;
984
985 portE: // ==IEEE: [ port ]
986 // // Though not type for interfaces, we factor out the port direction and type
987 // // so we can simply handle it in one place
988 //
989 // // IEEE: interface_port_header port_identifier { unpacked_dimension }
990 // // Expanded interface_port_header
991 // // We use instantCb here because the non-port form looks just like a module instantiation
992 /* empty */ { }
993 | portDirNetE id/*interface*/ idAny/*port*/ variable_dimensionListE sigAttrListE
994 { VARDTYPE($2); VARIO("interface"); VARDONE($<fl>2, $3, $4, ""); PINNUMINC();
995 PARSEP->instantCb($<fl>2, $2, $3, $4); PARSEP->endcellCb($<fl>2,""); }
996 | portDirNetE yINTERFACE idAny/*port*/ variable_dimensionListE sigAttrListE
997 { VARDTYPE($2); VARIO("interface"); VARDONE($<fl>2, $3, $4, ""); PINNUMINC(); }
998 | portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ variable_dimensionListE sigAttrListE
999 { VARDTYPE($2+"."+$4); VARIO("interface"); VARDONE($<fl>2, $5, $6, ""); PINNUMINC();
1000 PARSEP->instantCb($<fl>2, $2, $5, $6); PARSEP->endcellCb($<fl>2,""); }
1001 | portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ variable_dimensionListE sigAttrListE
1002 { VARDTYPE($2+"."+$4); VARIO("interface"); VARDONE($<fl>2, $5, $6, ""); PINNUMINC(); }
1003 //
1004 // // IEEE: ansi_port_declaration, with [port_direction] removed
1005 // // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ]
1006 // // IEEE: [ net_port_header | variable_port_header ] '.' port_identifier '(' [ expression ] ')'
1007 // // IEEE: [ variable_port_header ] port_identifier { variable_dimension } [ '=' constant_expression ]
1008 // // Substitute net_port_header = [ port_direction ] net_port_type
1009 // // Substitute variable_port_header = [ port_direction ] variable_port_type
1010 // // Substitute net_port_type = [ net_type ] data_type_or_implicit
1011 // // Substitute variable_port_type = var_data_type
1012 // // [ [ port_direction ] net_port_type | interface_port_header ] port_identifier { unpacked_dimension }
1013 // // [ [ port_direction ] var_data_type ] port_identifier variable_dimensionListE [ '=' constant_expression ]
1014 // // [ [ port_direction ] net_port_type | [ port_direction ] var_data_type ] '.' port_identifier '(' [ expression ] ')'
1015 //
1016 // // Remove optional '[...] id' is in portAssignment
1017 // // Remove optional '[port_direction]' is in port
1018 // // net_port_type | interface_port_header port_identifier { unpacked_dimension }
1019 // // net_port_type | interface_port_header port_identifier { unpacked_dimension }
1020 // // var_data_type port_identifier variable_dimensionListE [ '=' constExpr ]
1021 // // net_port_type | [ port_direction ] var_data_type '.' port_identifier '(' [ expr ] ')'
1022 // // Expand implicit_type
1023 //
1024 // // IEEE-2012: Since a net_type_identifier is a data_type, it falls into
1025 // // the rules here without change.
1026 //
1027 // // variable_dimensionListE instead of rangeListE to avoid conflicts
1028 //
1029 // // Note implicit rules looks just line declaring additional followon port
1030 // // No VARDECL("port") for implicit, as we don't want to declare variables for them
1031 | portDirNetE var_data_type '.' portSig '(' portAssignExprE ')' sigAttrListE
1032 { VARDTYPE($2); VARDONE($<fl>4, $4, "", ""); PINNUMINC(); }
1033 | portDirNetE signing '.' portSig '(' portAssignExprE ')' sigAttrListE
1034 { VARDTYPE($2); VARDONE($<fl>4, $4, "", ""); PINNUMINC(); }
1035 | portDirNetE signingE variable_dimensionList '.' portSig '(' portAssignExprE ')' sigAttrListE
1036 { VARDTYPE(SPACED($2,$3)); VARDONE($<fl>5, $5, "", ""); PINNUMINC(); }
1037 | portDirNetE yINTERCONNECT signingE variable_dimensionListE '.' portSig '(' portAssignExprE ')' sigAttrListE
1038 { VARDTYPE(SPACED(SPACED($2,$3),$4)); VARDONE($<fl>6, $6, "", ""); PINNUMINC(); }
1039 | portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE
1040 { /*VARDTYPE-same*/ VARDONE($<fl>3, $3, "", ""); PINNUMINC(); }
1041 //
1042 | portDirNetE var_data_type portSig variable_dimensionListE sigAttrListE
1043 { VARDTYPE($2); VARDONE($<fl>3, $3, $4, ""); PINNUMINC(); }
1044 | portDirNetE signing portSig variable_dimensionListE sigAttrListE
1045 { VARDTYPE($2); VARDONE($<fl>3, $3, $4, ""); PINNUMINC(); }
1046 | portDirNetE signingE variable_dimensionList portSig variable_dimensionListE sigAttrListE
1047 { VARDTYPE(SPACED($2,$3)); VARDONE($<fl>4, $4, $5, ""); PINNUMINC(); }
1048 | portDirNetE yINTERCONNECT signingE variable_dimensionList portSig variable_dimensionListE sigAttrListE
1049 { VARDTYPE(SPACED(SPACED($2,$3),$4)); VARDONE($<fl>5, $5, $6, ""); PINNUMINC(); }
1050 | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE
1051 { /*VARDTYPE-same*/ VARDONE($<fl>2, $2, $3, ""); PINNUMINC(); }
1052 //
1053 | portDirNetE var_data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
1054 { VARDTYPE($2); VARDONE($<fl>3, $3, $4, $7); PINNUMINC(); }
1055 | portDirNetE signing portSig variable_dimensionListE sigAttrListE '=' constExpr
1056 { VARDTYPE($2); VARDONE($<fl>3, $3, $4, $7); PINNUMINC(); }
1057 | portDirNetE signingE variable_dimensionList portSig variable_dimensionListE sigAttrListE '=' constExpr
1058 { VARDTYPE(SPACED($2,$3)); VARDONE($<fl>4, $4, $5, $8); PINNUMINC(); }
1059 | portDirNetE yINTERCONNECT signingE variable_dimensionList portSig variable_dimensionListE sigAttrListE '=' constExpr
1060 { VARDTYPE(SPACED(SPACED($2,$3),$4)); VARDONE($<fl>5, $5, $6, $9); PINNUMINC(); }
1061 | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
1062 { /*VARDTYPE-same*/ VARDONE($<fl>2, $2, $3, $6); PINNUMINC(); }
1063 //
1064 | '{' list_of_portsE '}' { }
1065 ;
1066
1067 portDirNetE: // IEEE: part of port, optional net type and/or direction
1068 /* empty */ { }
1069 // // Per spec, if direction given default the nettype.
1070 // // The higher level rule may override this VARDTYPE with one later in the parse.
1071 | port_direction { VARDTYPE(""/*default_nettype*/); }
1072 | port_direction net_type { VARDTYPE(""/*default_nettype*/); } // net_type calls VARNET
1073 | net_type { } // net_type calls VARNET
1074 ;
1075
1076 port_declNetE: // IEEE: part of port_declaration, optional net type
1077 /* empty */ { }
1078 | net_type { } // net_type calls VARNET
1079 ;
1080
1081 portAssignExprE: // IEEE: part of port, optional expression
1082 /* empty */ { }
1083 | expr { }
1084 ;
1085
1086 portSig<str>:
1087 id/*port*/ { $<fl>$=$<fl>1; $$=$1; }
1088 | idSVKwd { $<fl>$=$<fl>1; $$=$1; }
1089 ;
1090
1091 //**********************************************************************
1092 // Interface headers
1093
1094 interface_declaration: // IEEE: interface_declaration + interface_nonansi_header + interface_ansi_header:
1095 // // timeunits_delcarationE is instead in interface_item
1096 intFront importsAndParametersE portsStarE ';'
1097 interface_itemListE yENDINTERFACE endLabelE
1098 { PARSEP->endinterfaceCb($<fl>6, $6);
1099 PARSEP->symPopScope(VAstType::INTERFACE); }
1100 | yEXTERN intFront importsAndParametersE portsStarE ';' { }
1101 ;
1102
1103 intFront:
1104 yINTERFACE lifetimeE idAny/*new_interface*/
1105 { PARSEP->symPushNew(VAstType::INTERFACE,$3);
1106 PARSEP->interfaceCb($<fl>1,$1,$3); }
1107 ;
1108
1109 interface_itemListE:
1110 /* empty */ { }
1111 | interface_itemList { }
1112 ;
1113
1114 interface_itemList:
1115 interface_item { }
1116 | interface_itemList interface_item { }
1117 ;
1118
1119 interface_item: // IEEE: interface_item + non_port_interface_item
1120 port_declaration ';' { }
1121 // // IEEE: non_port_interface_item
1122 | generate_region { }
1123 | interface_or_generate_item { }
1124 | program_declaration { }
1125 // // IEEE 1800-2017: modport_item
1126 // // See instead old 2012 position in interface_or_generate_item
1127 | interface_declaration { }
1128 | timeunits_declaration { }
1129 // // See note in interface_or_generate item
1130 | module_common_item { }
1131 ;
1132
1133 interface_or_generate_item: // ==IEEE: interface_or_generate_item
1134 // // module_common_item in interface_item, as otherwise duplicated
1135 // // with module_or_generate_item:module_common_item
1136 // // IEEE 1800-2017 removes modport_declaration here
1137 // // but for 2012 compatibility we retain it
1138 modport_declaration { }
1139 | extern_tf_declaration { }
1140 ;
1141
1142 //**********************************************************************
1143 // Program headers
1144
1145 anonymous_program: // ==IEEE: anonymous_program
1146 // // See the spec - this doesn't change the scope, items still go up "top"
1147 yPROGRAM ';' anonymous_program_itemListE yENDPROGRAM { }
1148 ;
1149
1150 anonymous_program_itemListE: // IEEE: { anonymous_program_item }
1151 /* empty */ { }
1152 | anonymous_program_itemList { }
1153 ;
1154
1155 anonymous_program_itemList: // IEEE: { anonymous_program_item }
1156 anonymous_program_item { }
1157 | anonymous_program_itemList anonymous_program_item { }
1158 ;
1159
1160 anonymous_program_item: // ==IEEE: anonymous_program_item
1161 task_declaration { }
1162 | function_declaration { }
1163 | class_declaration { }
1164 | covergroup_declaration { }
1165 // // class_constructor_declaration is part of function_declaration
1166 | ';' { }
1167 ;
1168
1169 program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header:
1170 // // timeunits_delcarationE is instead in program_item
1171 pgmFront importsAndParametersE portsStarE ';'
1172 program_itemListE yENDPROGRAM endLabelE
1173 { PARSEP->endprogramCb($<fl>6,$6);
1174 PARSEP->symPopScope(VAstType::PROGRAM); }
1175 | yEXTERN pgmFront importsAndParametersE portsStarE ';'
1176 { PARSEP->symPopScope(VAstType::PROGRAM); }
1177 ;
1178
1179 pgmFront:
1180 yPROGRAM lifetimeE idAny/*new_program*/
1181 { PARSEP->symPushNew(VAstType::PROGRAM,$3);
1182 PARSEP->programCb($<fl>1,$1, $3);
1183 }
1184 ;
1185
1186 program_itemListE: // ==IEEE: [{ program_item }]
1187 /* empty */ { }
1188 | program_itemList { }
1189 ;
1190
1191 program_itemList: // ==IEEE: { program_item }
1192 program_item { }
1193 | program_itemList program_item { }
1194 ;
1195
1196 program_item: // ==IEEE: program_item
1197 port_declaration ';' { }
1198 | non_port_program_item { }
1199 ;
1200
1201 non_port_program_item: // ==IEEE: non_port_program_item
1202 continuous_assign { }
1203 | module_or_generate_item_declaration { }
1204 | initial_construct { }
1205 | final_construct { }
1206 | concurrent_assertion_item { }
1207 | timeunits_declaration { }
1208 | program_generate_item { }
1209 ;
1210
1211 program_generate_item: // ==IEEE: program_generate_item
1212 loop_generate_construct { }
1213 | conditional_generate_construct { }
1214 | generate_region { }
1215 | elaboration_system_task { }
1216 ;
1217
1218 extern_tf_declaration: // ==IEEE: extern_tf_declaration
1219 yEXTERN task_prototype ';' { }
1220 | yEXTERN function_prototype ';' { }
1221 | yEXTERN yFORKJOIN task_prototype ';' { }
1222 ;
1223
1224 modport_declaration: // ==IEEE: modport_declaration
1225 yMODPORT modport_itemList ';' { }
1226 ;
1227
1228 modport_itemList: // IEEE: part of modport_declaration
1229 modport_item { }
1230 | modport_itemList ',' modport_item { }
1231 ;
1232
1233 modport_item: // ==IEEE: modport_item
1234 modport_idFront '(' {VARRESET_LIST("");} modportPortsDeclList ')'
1235 { VARRESET_NONLIST("");
1236 PARSEP->endmodportCb($<fl>1, "endmodport");
1237 PARSEP->symPopScope(VAstType::MODPORT); }
1238 ;
1239
1240 modport_idFront:
1241 id/*new-modport*/
1242 { PARSEP->symPushNew(VAstType::MODPORT,$1);
1243 PARSEP->modportCb($<fl>1,"modport",$1); }
1244 ;
1245
1246 modportPortsDeclList:
1247 modportPortsDecl { }
1248 | modportPortsDeclList ',' modportPortsDecl { }
1249 ;
1250
1251 // IEEE: modport_ports_declaration + modport_simple_ports_declaration
1252 // + (modport_tf_ports_declaration+import_export) + modport_clocking_declaration
1253 // We've expanded the lists each take to instead just have standalone ID ports.
1254 // We track the type as with the V2k series of defines, then create as each ID is seen.
1255 modportPortsDecl:
1256 // // IEEE: modport_simple_ports_declaration
1257 port_direction modportSimplePort { }
1258 // // IEEE: modport_clocking_declaration
1259 | yCLOCKING idAny/*clocking_identifier*/ { }
1260 | yIMPORT modport_tf_port { }
1261 | yEXPORT modport_tf_port { }
1262 // Continuations of above after a comma.
1263 // // IEEE: modport_simple_ports_declaration
1264 | modportSimplePort { }
1265 ;
1266
1267 modportSimplePort: // IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
1268 // // Note 'init' field is used to say what to connect to
1269 id { VARDONE($<fl>1,$1,"",$1); PINNUMINC(); }
1270 | '.' idAny '(' ')' { VARDONE($<fl>1,$2,"",""); PINNUMINC(); }
1271 | '.' idAny '(' expr ')' { VARDONE($<fl>1,$2,"",$4); PINNUMINC(); }
1272 ;
1273
1274 modport_tf_port: // ==IEEE: modport_tf_port
1275 id/*tf_identifier*/ { }
1276 | method_prototype { }
1277 ;
1278
1279 //************************************************
1280 // Variable Declarations
1281
1282 genvar_declaration: // ==IEEE: genvar_declaration
1283 yGENVAR list_of_genvar_identifiers ';' { }
1284 ;
1285
1286 list_of_genvar_identifiers: // IEEE: list_of_genvar_identifiers (for declaration)
1287 genvar_identifierDecl { }
1288 | list_of_genvar_identifiers ',' genvar_identifierDecl { }
1289 ;
1290
1291 genvar_identifierDecl: // IEEE: genvar_identifier (for declaration)
1292 id/*new-genvar_identifier*/ sigAttrListE { VARRESET_NONLIST("genvar"); VARDONE($<fl>1, $1, "", ""); }
1293 ;
1294
1295 local_parameter_declaration: // IEEE: local_parameter_declaration
1296 // // See notes in parameter_declaration
1297 local_parameter_declarationFront list_of_param_assignments { }
1298 ;
1299
1300 parameter_declaration: // IEEE: parameter_declaration
1301 // // IEEE: yPARAMETER yTYPE list_of_type_assignments ';'
1302 // // Instead of list_of_type_assignments
1303 // // we use list_of_param_assignments because for port handling
1304 // // it already must accept types, so simpler to have code only one place
1305 parameter_declarationFront list_of_param_assignments { }
1306 ;
1307
1308 local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
1309 varLParamReset implicit_typeE { VARRESET(); VARDECL("localparam"); VARDTYPE($2); }
1310 | varLParamReset data_type { VARRESET(); VARDECL("localparam"); VARDTYPE($2); }
1311 | varLParamReset yTYPE { VARRESET(); VARDECL("localparam"); VARDTYPE($2); }
1312 ;
1313
1314 parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
1315 varGParamReset implicit_typeE { VARRESET(); VARDECL("parameter"); VARDTYPE($2); }
1316 | varGParamReset data_type { VARRESET(); VARDECL("parameter"); VARDTYPE($2); }
1317 | varGParamReset yTYPE { VARRESET(); VARDECL("parameter"); VARDTYPE($2); }
1318 ;
1319
1320 parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment
1321 // // IEEE: parameter_declaration (minus assignment)
1322 parameter_declarationFront { }
1323 | local_parameter_declarationFront { /*NEED_S09(CURLINE(),"port localparams");*/ }
1324 //
1325 | data_type { VARDTYPE($1); }
1326 | yTYPE { VARDTYPE($1); }
1327 ;
1328
1329 net_declaration: // IEEE: net_declaration - excluding implict
1330 net_declarationFront netSigList ';' { }
1331 ;
1332
1333 net_declarationFront: // IEEE: beginning of net_declaration
1334 net_declRESET net_type strengthSpecE net_scalaredE net_dataType { VARDTYPE(SPACED($4,$5)); }
1335 | net_declRESET yINTERCONNECT signingE rangeListE { VARNET($2); VARDTYPE(SPACED($3,$4)); }
1336 ;
1337
1338 net_declRESET:
1339 /* empty */ { VARRESET_NONLIST("net"); }
1340 ;
1341
1342 net_scalaredE<str>:
1343 /* empty */ { $$=""; }
1344 | ySCALARED { $<fl>$=$<fl>1; $$=$1; }
1345 | yVECTORED { $<fl>$=$<fl>1; $$=$1; }
1346 ;
1347
1348 net_dataType<str>:
1349 // // If there's a SV data type there shouldn't be a delay on this wire
1350 // // Otherwise #(...) can't be determined to be a delay or parameters
1351 // // Submit this as a footnote to the committee
1352 var_data_type { $<fl>$=$<fl>1; $$=$1; }
1353 | signingE rangeList delayE { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1354 | signing delayE { $<fl>$=$<fl>1; $$=$1; }
1355 | /*implicit*/ delayE { $<fl>$=$<fl>1; $$=""; }
1356 ;
1357
1358 net_type: // ==IEEE: net_type
1359 ySUPPLY0 { VARNET($1); }
1360 | ySUPPLY1 { VARNET($1); }
1361 | yTRI { VARNET($1); }
1362 | yTRI0 { VARNET($1); }
1363 | yTRI1 { VARNET($1); }
1364 | yTRIAND { VARNET($1); }
1365 | yTRIOR { VARNET($1); }
1366 | yTRIREG { VARNET($1); }
1367 | yWAND { VARNET($1); }
1368 | yWIRE { VARNET($1); }
1369 | yWOR { VARNET($1); }
1370 ;
1371
1372 varGParamReset:
1373 yPARAMETER { VARRESET_NONLIST($1); }
1374 ;
1375
1376 varLParamReset:
1377 yLOCALPARAM { VARRESET_NONLIST($1); }
1378 ;
1379
1380 port_direction: // ==IEEE: port_direction + tf_port_direction
1381 // // IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here
1382 yINPUT { VARIO($1); }
1383 | yOUTPUT { VARIO($1); }
1384 | yINOUT { VARIO($1); }
1385 | yREF { VARIO($1); }
1386 | yCONST__REF yREF { VARIO($1); }
1387 ;
1388
1389 port_directionReset: // IEEE: port_direction that starts a port_declaraiton
1390 // // Used only for declarations outside the port list
1391 yINPUT { VARRESET_NONLIST(""); VARIO($1); }
1392 | yOUTPUT { VARRESET_NONLIST(""); VARIO($1); }
1393 | yINOUT { VARRESET_NONLIST(""); VARIO($1); }
1394 | yREF { VARRESET_NONLIST(""); VARIO($1); }
1395 | yCONST__REF yREF { VARRESET_NONLIST(""); VARIO($1); }
1396 ;
1397
1398 port_declaration: // ==IEEE: port_declaration
1399 // // Used inside block; followed by ';'
1400 // // SIMILAR to tf_port_declaration
1401 //
1402 // // IEEE: inout_declaration
1403 // // IEEE: input_declaration
1404 // // IEEE: output_declaration
1405 // // IEEE: ref_declaration
1406 port_directionReset port_declNetE var_data_type { VARDTYPE($3); } list_of_variable_decl_assignments { }
1407 | port_directionReset port_declNetE signingE rangeList { VARDTYPE(SPACED($3,$4)); } list_of_variable_decl_assignments { }
1408 | port_directionReset port_declNetE signing { VARDTYPE($3); } list_of_variable_decl_assignments { }
1409 | port_directionReset port_declNetE /*implicit*/ { VARDTYPE("");/*default_nettype*/} list_of_variable_decl_assignments { }
1410 // // IEEE: interface_declaration
1411 // // Looks just like variable declaration unless has a period
1412 // // See etcInst
1413 ;
1414
1415 tf_port_declaration: // ==IEEE: tf_port_declaration
1416 // // Used inside function; followed by ';'
1417 // // SIMILAR to port_declaration
1418 //
1419 port_directionReset var_data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { }
1420 | port_directionReset implicit_typeE { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { }
1421 ;
1422
1423 integer_atom_type<str>: // ==IEEE: integer_atom_type
1424 yBYTE { $<fl>$=$<fl>1; $$=$1; }
1425 | ySHORTINT { $<fl>$=$<fl>1; $$=$1; }
1426 | yINT { $<fl>$=$<fl>1; $$=$1; }
1427 | yLONGINT { $<fl>$=$<fl>1; $$=$1; }
1428 | yINTEGER { $<fl>$=$<fl>1; $$=$1; }
1429 | yTIME { $<fl>$=$<fl>1; $$=$1; }
1430 ;
1431
1432 integer_vector_type<str>: // ==IEEE: integer_atom_type
1433 yBIT { $<fl>$=$<fl>1; $$=$1; }
1434 | yLOGIC { $<fl>$=$<fl>1; $$=$1; }
1435 | yREG { $<fl>$=$<fl>1; $$=$1; }
1436 ;
1437
1438 non_integer_type<str>: // ==IEEE: non_integer_type
1439 ySHORTREAL { $<fl>$=$<fl>1; $$=$1; }
1440 | yREAL { $<fl>$=$<fl>1; $$=$1; }
1441 | yREALTIME { $<fl>$=$<fl>1; $$=$1; }
1442 ;
1443
1444 signingE<str>: // IEEE: signing - plus empty
1445 /*empty*/ { $$=""; }
1446 | signing { $<fl>$=$<fl>1; $$=$1; }
1447 ;
1448
1449 signing<str>: // ==IEEE: signing
1450 ySIGNED { $<fl>$=$<fl>1; $$=$1; }
1451 | yUNSIGNED { $<fl>$=$<fl>1; $$=$1; }
1452 ;
1453
1454 //************************************************
1455 // Data Types
1456
1457 casting_type<str>: // IEEE: casting_type
1458 simple_type { $<fl>$=$<fl>1; $$=$1; }
1459 // // IEEE: constant_primary
1460 // // In expr:cast this is expanded to just "expr"
1461 //
1462 // // IEEE: signing
1463 | ySIGNED { $<fl>$=$<fl>1; $$=$1; }
1464 | yUNSIGNED { $<fl>$=$<fl>1; $$=$1; }
1465 | ySTRING { $<fl>$=$<fl>1; $$=$1; }
1466 | yCONST__ETC/*then `*/ { $<fl>$=$<fl>1; $$=$1; }
1467 ;
1468
1469 simple_type<str>: // ==IEEE: simple_type
1470 // // IEEE: integer_type
1471 integer_atom_type { $<fl>$=$<fl>1; $$=$1; }
1472 | integer_vector_type { $<fl>$=$<fl>1; $$=$1; }
1473 | non_integer_type { $<fl>$=$<fl>1; $$=$1; }
1474 // // IEEE: ps_type_identifier
1475 // // IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE)
1476 | package_scopeIdFollowsE yaID__aTYPE { $<fl>$=$<fl>1; $$=$1+$2; }
1477 // // { generate_block_identifer ... } '.'
1478 // // Need to determine if generate_block_identifier can be lex-detected
1479 ;
1480
1481 data_typeVar<str>: // IEEE: data_type + virtual_interface_declaration
1482 data_type { $<fl>$=$<fl>1; $$=$1; }
1483 // // IEEE-2009: virtual_interface_declaration
1484 // // IEEE-2012: part of data_type
1485 | yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ parameter_value_assignmentE '.' id/*modport*/
1486 { $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1487 | yVIRTUAL__anyID id/*interface*/ parameter_value_assignmentE '.' id/*modport*/
1488 { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1489 ;
1490
1491 data_type<str>: // ==IEEE: data_type, excluding class_type etc references
1492 integer_vector_type signingE rangeListE { $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1493 | integer_atom_type signingE { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1494 | non_integer_type { $<fl>$=$<fl>1; $$=$1; }
1495 | ySTRUCT packedSigningE '{' { PARSEP->symPushNewAnon(VAstType::STRUCT); }
1496 /*cont*/ struct_union_memberList '}' packed_dimensionListE
1497 { $<fl>$=$<fl>1; $$=$1; PARSEP->symPopScope(VAstType::STRUCT); }
1498 | yUNION taggedE packedSigningE '{' { PARSEP->symPushNewAnon(VAstType::UNION); }
1499 /*cont*/ struct_union_memberList '}' packed_dimensionListE
1500 { $<fl>$=$<fl>1; $$=$1; PARSEP->symPopScope(VAstType::UNION); }
1501 | enumDecl { $<fl>$=$<fl>1; $$=$1; }
1502 | ySTRING { $<fl>$=$<fl>1; $$=$1; }
1503 | yCHANDLE { $<fl>$=$<fl>1; $$=$1; }
1504 // // Rules overlap virtual_interface_declaration
1505 // // Parameters here are SV2009
1506 // // IEEE has ['.' modport] but that will conflict with port
1507 // // declarations which decode '.' modport themselves, so
1508 // // instead see data_typeVar
1509 | yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ parameter_value_assignmentE
1510 { $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1511 | yVIRTUAL__anyID id/*interface*/ parameter_value_assignmentE
1512 { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1513 //
1514 // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
1515 // // See data_type
1516 // // IEEE: class_type
1517 // // See data_type
1518 | yEVENT { $<fl>$=$<fl>1; $$=$1; }
1519 | type_reference { $<fl>$=$<fl>1; $$=$1; }
1520 //
1521 //----------------------
1522 // // REFERENCES
1523 //
1524 // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
1525 // // IEEE: class_type
1526 // // IEEE: ps_covergroup_identifier
1527 // // Don't distinguish between types and classes so all these combined
1528 | package_scopeIdFollowsE class_typeOneList packed_dimensionListE { $<fl>$=$<fl>1; $$=$<str>1+$<str>2+$3; }
1529 ;
1530
1531 // IEEE: struct_union - not needed, expanded in data_type
1532
1533 data_type_or_void<str>: // ==IEEE: data_type_or_void
1534 data_type { $<fl>$=$<fl>1; $$=$1; }
1535 | yVOID { $<fl>$=$<fl>1; $$=$1; }
1536 ;
1537
1538 var_data_type<str>: // ==IEEE: var_data_type
1539 data_type { $<fl>$=$<fl>1; $$=$1; }
1540 | yVAR data_type { $<fl>$=$<fl>1; $$=$1; }
1541 | yVAR implicit_typeE { $<fl>$=$<fl>1; $$=$1; }
1542 ;
1543
1544 type_reference<str>: // ==IEEE: type_reference
1545 yTYPE '(' exprOrDataType ')' { $<fl>$=$<fl>1; $$="type("+$3+")"; }
1546 ;
1547
1548 struct_union_memberList: // IEEE: { struct_union_member }
1549 struct_union_member { }
1550 | struct_union_memberList struct_union_member { }
1551 ;
1552
1553 struct_union_member: // ==IEEE: struct_union_member
1554 random_qualifierE data_type_or_void
1555 { VARS_PUSH(); // Structs can be recursive, or under a parameter typs
1556 VARRESET_NONLIST("member"); VARDTYPE(SPACED($1,$2)); }
1557 /*cont*/ list_of_variable_decl_assignments ';'
1558 { VARS_POP(); }
1559 ;
1560
1561 list_of_variable_decl_assignments: // ==IEEE: list_of_variable_decl_assignments
1562 variable_decl_assignment { }
1563 | list_of_variable_decl_assignments ',' variable_decl_assignment { }
1564 ;
1565
1566 variable_decl_assignment: // ==IEEE: variable_decl_assignment
1567 id variable_dimensionListE sigAttrListE
1568 { VARDONE($<fl>1, $1, $2, ""); }
1569 | id variable_dimensionListE sigAttrListE '=' variable_declExpr
1570 { VARDONE($<fl>1, $1, $2, $5); }
1571 | idSVKwd { }
1572 //
1573 // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
1574 // // Matches above with variable_dimensionE = "[]"
1575 // // IEEE: "class_variable_identifier [ '=' class_new ]"
1576 // // variable_dimensionE must be empty
1577 // // Pushed into variable_declExpr:dynamic_array_new
1578 //
1579 // // IEEE: "[ covergroup_variable_identifier ] '=' class_new
1580 // // Pushed into variable_declExpr:class_new
1581 | '=' class_new { }
1582 ;
1583
1584 list_of_tf_variable_identifiers: // ==IEEE: list_of_tf_variable_identifiers
1585 tf_variable_identifier { }
1586 | list_of_tf_variable_identifiers ',' tf_variable_identifier { }
1587 ;
1588
1589 tf_variable_identifier: // IEEE: part of list_of_tf_variable_identifiers
1590 id variable_dimensionListE sigAttrListE
1591 { VARDONE($<fl>1, $1, $2, ""); }
1592 | id variable_dimensionListE sigAttrListE '=' expr
1593 { VARDONE($<fl>1, $1, $2, $5); }
1594 ;
1595
1596 variable_declExpr<str>: // IEEE: part of variable_decl_assignment - rhs of expr
1597 expr { $<fl>$=$<fl>1; $$=$1; }
1598 | dynamic_array_new { $<fl>$=$<fl>1; $$=$1; }
1599 | class_new { $<fl>$=$<fl>1; $$=$1; }
1600 ;
1601
1602 variable_dimensionListE<str>: // IEEE: variable_dimension + empty
1603 /*empty*/ { $$=""; }
1604 | variable_dimensionList { $<fl>$=$<fl>1; $$=$1; }
1605 ;
1606
1607 variable_dimensionList<str>: // IEEE: variable_dimension + empty
1608 variable_dimension { $<fl>$=$<fl>1; $$=$1; }
1609 | variable_dimensionList variable_dimension { $<fl>$=$<fl>1; $$=$1+$2; }
1610 ;
1611
1612 variable_dimension<str>: // ==IEEE: variable_dimension
1613 // // IEEE: unsized_dimension
1614 '[' ']' { $<fl>$=$<fl>1; $$=""; }
1615 // // IEEE: unpacked_dimension
1616 | anyrange { $<fl>$=$<fl>1; $$=$1; }
1617 // // IEEE: unpacked_dimension (if const_expr)
1618 // // IEEE: associative_dimension (if data_type)
1619 // // Can't tell which until see if expr is data type or not
1620 | '[' exprOrDataType ']' { $<fl>$=$<fl>1; $$="["+$2+"]"; }
1621 | yP_BRASTAR ']' { $<fl>$=$<fl>1; $$="[*]"; }
1622 | '[' '*' ']' { $<fl>$=$<fl>1; $$="[*]"; }
1623 // // IEEE: queue_dimension
1624 // // '[' '$' ']' -- $ is part of expr
1625 // // '[' '$' ':' expr ']' -- anyrange:expr:$
1626 ;
1627
1628 random_qualifierE<str>: // IEEE: random_qualifier + empty
1629 /*empty*/ { $$=""; }
1630 | random_qualifier { $<fl>$=$<fl>1; $$=$1; }
1631 ;
1632
1633 random_qualifier<str>: // ==IEEE: random_qualifier
1634 yRAND { $<fl>$=$<fl>1; $$=$1; }
1635 | yRANDC { $<fl>$=$<fl>1; $$=$1; }
1636 ;
1637
1638 taggedE:
1639 /*empty*/ { }
1640 | yTAGGED { }
1641 ;
1642
1643 packedSigningE:
1644 /*empty*/ { }
1645 | yPACKED signingE { }
1646 ;
1647
1648 //************************************************
1649 // enum
1650
1651 // IEEE: part of data_type
1652 enumDecl<str>:
1653 yENUM enum_base_typeE '{' enum_nameList '}' rangeListE { $$=$2; }
1654 ;
1655
1656 enum_base_typeE<str>: // IEEE: enum_base_type
1657 /* empty */ { $$="enum"; }
1658 // // Not in spec, but obviously "enum [1:0]" should work
1659 // // implicit_type expanded, without empty
1660 | signingE rangeList { $<fl>$=$<fl>1; $$=$1+$2; }
1661 | signing { $<fl>$=$<fl>1; $$=$1; }
1662 //
1663 | integer_atom_type signingE { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1664 | integer_vector_type signingE regrangeE { $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1665 // // below can be idAny or yaID__aTYPE
1666 // // IEEE requires a type, though no shift conflict if idAny
1667 // // IEEE: type_identifier [ packed_dimension ]
1668 // // however other simulators allow [ class_scope | package_scope ] type_identifier
1669 | idAny regrangeE { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1670 | package_scopeIdFollows idAny rangeListE
1671 { $<fl>$=$<fl>1; $$ = $<str>1+$<str>2+$3; }
1672 ;
1673
1674 enum_nameList:
1675 enum_name_declaration { }
1676 | enum_nameList ',' enum_name_declaration { }
1677 ;
1678
1679 enum_name_declaration: // ==IEEE: enum_name_declaration
1680 idAny/*enum_identifier*/ enumNameRangeE enumNameStartE { }
1681 ;
1682
1683 enumNameRangeE: // IEEE: second part of enum_name_declaration
1684 /* empty */ { }
1685 | '[' intnumAsConst ']' { }
1686 | '[' intnumAsConst ':' intnumAsConst ']' { }
1687 ;
1688
1689 enumNameStartE: // IEEE: third part of enum_name_declaration
1690 /* empty */ { }
1691 | '=' constExpr { }
1692 ;
1693
1694 intnumAsConst:
1695 yaINTNUM { }
1696 ;
1697
1698 //************************************************
1699 // Typedef
1700
1701 data_declaration: // ==IEEE: data_declaration
1702 // // VARRESET can't be called here - conflicts
1703 data_declarationVar { }
1704 | type_declaration { }
1705 | package_import_declaration { }
1706 // // IEEE 2005: virtual_interface_declaration
1707 // // IEEE 2009 removed this
1708 // // "yVIRTUAL yID yID" looks just like a data_declaration
1709 // // Therefore the virtual_interface_declaration term isn't used
1710 // // 1800-2009:
1711 | net_type_declaration { }
1712 ;
1713
1714 class_property: // ==IEEE: class_property, which is {property_qualifier} data_declaration
1715 memberQualResetListE data_declarationVarClass { }
1716 | memberQualResetListE type_declaration { }
1717 | memberQualResetListE package_import_declaration { }
1718 // // IEEE: virtual_interface_declaration
1719 // // "yVIRTUAL yID yID" looks just like a data_declaration
1720 // // Therefore the virtual_interface_declaration term isn't used
1721 ;
1722
1723 data_declarationVar: // IEEE: part of data_declaration
1724 // // The first declaration has complications between assuming what's the type vs ID declaring
1725 data_declarationVarFront list_of_variable_decl_assignments ';' { }
1726 ;
1727
1728 data_declarationVarClass: // IEEE: part of data_declaration (for class_property)
1729 // // The first declaration has complications between assuming what's the type vs ID declaring
1730 data_declarationVarFrontClass list_of_variable_decl_assignments ';' { }
1731 ;
1732
1733 data_declarationVarFront: // IEEE: part of data_declaration
1734 // // implicit_type expanded into /*empty*/ or "signingE rangeList"
1735 constE yVAR lifetimeE data_type { VARRESET(); VARDECL("var"); VARDTYPE(SPACED($1,$4)); }
1736 | constE yVAR lifetimeE { VARRESET(); VARDECL("var"); VARDTYPE($1); }
1737 | constE yVAR lifetimeE signingE rangeList { VARRESET(); VARDECL("var"); VARDTYPE(SPACED($1,SPACED($4,$5))); }
1738 //
1739 // // Expanded: "constE lifetimeE data_type"
1740 | /**/ data_typeVar { VARRESET(); VARDECL("var"); VARDTYPE($1); }
1741 | /**/ lifetime data_typeVar { VARRESET(); VARDECL("var"); VARDTYPE($2); }
1742 | yCONST__ETC lifetimeE data_typeVar { VARRESET(); VARDECL("var"); VARDTYPE(SPACED($1,$3)); }
1743 // // = class_new is in variable_decl_assignment
1744 //
1745 // // IEEE: virtual_interface_declaration
1746 // // data_type includes VIRTUAL_INTERFACE, so added to data_typeVar
1747 ;
1748
1749 data_declarationVarFrontClass: // IEEE: part of data_declaration (for class_property)
1750 // // VARRESET called before this rule
1751 // // yCONST is removed, added to memberQual rules
1752 // // implicit_type expanded into /*empty*/ or "signingE rangeList"
1753 yVAR lifetimeE data_type { VARDECL("var"); VARDTYPE(SPACED(GRAMMARP->m_var.m_dtype, $3)); }
1754 | yVAR lifetimeE { VARDECL("var"); VARDTYPE(GRAMMARP->m_var.m_dtype); }
1755 | yVAR lifetimeE signingE rangeList { VARDECL("var"); VARDTYPE(SPACED(GRAMMARP->m_var.m_dtype, SPACED($3, $4))); }
1756 //
1757 // // Expanded: "constE lifetimeE data_type"
1758 | /**/ data_typeVar { VARDECL("var"); VARDTYPE(SPACED(GRAMMARP->m_var.m_dtype, $1)); }
1759 // // lifetime is removed, added to memberQual rules to avoid conflict
1760 // // yCONST is removed, added to memberQual rules to avoid conflict
1761 // // = class_new is in variable_decl_assignment
1762 ;
1763
1764 net_type_declaration: // IEEE: net_type_declaration
1765 yNETTYPE data_type idAny/*net_type_identifier*/ ';'
1766 { PARSEP->syms().replaceInsert(VAstType::TYPE, $3); }
1767 // // package_scope part of data_type
1768 | yNETTYPE data_type idAny yWITH__ETC package_scopeIdFollowsE id/*tf_identifier*/ ';'
1769 { PARSEP->syms().replaceInsert(VAstType::TYPE, $3); }
1770 | yNETTYPE package_scopeIdFollowsE id/*net_type_identifier*/ idAny/*net_type_identifier*/ ';'
1771 { PARSEP->syms().replaceInsert(VAstType::TYPE, $4); }
1772 ;
1773
1774 constE<str>: // IEEE: part of data_declaration
1775 /* empty */ { $$ = ""; }
1776 | yCONST__ETC { $$ = $1; }
1777 ;
1778
1779 implicit_typeE<str>: // IEEE: part of *data_type_or_implicit
1780 // // Also expanded in data_declaration
1781 /* empty */ { $$ = ""; }
1782 | signingE rangeList { $$ = SPACED($1,$2); }
1783 | signing { $$ = $1; }
1784 ;
1785
1786 assertion_variable_declaration: // IEEE: assertion_variable_declaration
1787 // // IEEE: var_data_type expanded
1788 var_data_type list_of_variable_decl_assignments ';' { }
1789 ;
1790
1791 type_declaration: // ==IEEE: type_declaration
1792 // // Use idAny, as we can redeclare a typedef on an existing typedef
1793 yTYPEDEF data_type idAny variable_dimensionListE ';'
1794 { VARDONETYPEDEF($<fl>1,$3,$2,$4); }
1795 | yTYPEDEF id/*interface*/ bit_selectE '.' idAny/*type*/ idAny/*type*/ ';'
1796 { VARDONETYPEDEF($<fl>1,$6,$2+$3+"."+$5,""); }
1797 // // Combines into above "data_type id" rule
1798 | yTYPEDEF id ';' { VARDONETYPEDEF($<fl>1,$2,"",""); }
1799 | yTYPEDEF yENUM idAny ';' { PARSEP->syms().replaceInsert(VAstType::ENUM, $3); }
1800 | yTYPEDEF ySTRUCT idAny ';' { PARSEP->syms().replaceInsert(VAstType::STRUCT, $3); }
1801 | yTYPEDEF yUNION idAny ';' { PARSEP->syms().replaceInsert(VAstType::UNION, $3); }
1802 | yTYPEDEF yCLASS idAny ';' { PARSEP->syms().replaceInsert(VAstType::CLASS, $3); }
1803 | yTYPEDEF yINTERFACE yCLASS idAny ';' { PARSEP->syms().replaceInsert(VAstType::CLASS, $3); }
1804 ;
1805
1806 //************************************************
1807 // Module Items
1808
1809 module_itemListE: // IEEE: Part of module_declaration
1810 /* empty */ { }
1811 | module_itemList { }
1812 ;
1813
1814 module_itemList: // IEEE: Part of module_declaration
1815 module_item { }
1816 | module_itemList module_item { }
1817 ;
1818
1819 module_item: // ==IEEE: module_item
1820 port_declaration ';' { }
1821 | non_port_module_item { }
1822 ;
1823
1824 non_port_module_item: // ==IEEE: non_port_module_item
1825 generate_region { }
1826 | module_or_generate_item { }
1827 | specify_block { }
1828 | specparam_declaration { }
1829 | program_declaration { }
1830 | module_declaration { }
1831 | interface_declaration { }
1832 | timeunits_declaration { }
1833 ;
1834
1835 module_or_generate_item: // ==IEEE: module_or_generate_item
1836 // // IEEE: parameter_override
1837 yDEFPARAM list_of_defparam_assignments ';' { }
1838 // // IEEE: gate_instantiation + udp_instantiation + module_instantiation
1839 // // not here, see etcInst in module_common_item
1840 // // We joined udp & module definitions, so this goes here
1841 | combinational_body { }
1842 // // This module_common_item shared with interface_or_generate_item:module_common_item
1843 | module_common_item { }
1844 ;
1845
1846 module_common_item: // ==IEEE: module_common_item
1847 module_or_generate_item_declaration { }
1848 // // IEEE: interface_instantiation
1849 // // + IEEE: program_instantiation
1850 // // + module_instantiation from module_or_generate_item
1851 | etcInst { }
1852 | assertion_item { }
1853 | bind_directive { }
1854 | continuous_assign { }
1855 // // IEEE: net_alias
1856 | yALIAS variable_lvalue aliasEqList ';' { }
1857 | initial_construct { }
1858 | final_construct { }
1859 // // IEEE: always_construct
1860 | yALWAYS stmtBlock { }
1861 | loop_generate_construct { }
1862 | conditional_generate_construct { }
1863 | elaboration_system_task { }
1864 //
1865 | error ';' { }
1866 ;
1867
1868 continuous_assign: // IEEE: continuous_assign
1869 yASSIGN strengthSpecE delayE assignList ';' { }
1870 ;
1871
1872 initial_construct: // IEEE: initial_construct
1873 yINITIAL stmtBlock { }
1874 ;
1875
1876 final_construct: // IEEE: final_construct
1877 yFINAL stmtBlock { }
1878 ;
1879
1880 module_or_generate_item_declaration: // ==IEEE: module_or_generate_item_declaration
1881 package_or_generate_item_declaration { }
1882 | genvar_declaration { }
1883 | clocking_declaration { }
1884 | yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';' { }
1885 | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { }
1886 ;
1887
1888 aliasEqList: // IEEE: part of net_alias
1889 '=' variable_lvalue { }
1890 | aliasEqList '=' variable_lvalue { }
1891 ;
1892
1893 bind_directive: // ==IEEE: bind_directive + bind_target_scope
1894 // // ';' - Note IEEE grammar is wrong, includes extra ';' - it's already in module_instantiation
1895 // // We merged the rules - id may be a bind_target_instance or module_identifier or interface_identifier
1896 yBIND bind_target_instance bind_instantiation { }
1897 | yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation { }
1898 ;
1899
1900 bind_target_instance_list: // ==IEEE: bind_target_instance_list
1901 bind_target_instance { }
1902 | bind_target_instance_list ',' bind_target_instance { }
1903 ;
1904
1905 bind_target_instance: // ==IEEE: bind_target_instance
1906 hierarchical_identifierBit { }
1907 ;
1908
1909 bind_instantiation: // ==IEEE: bind_instantiation
1910 // // IEEE: program_instantiation
1911 // // IEEE: + module_instantiation
1912 // // IEEE: + interface_instantiation
1913 etcInst { }
1914 ;
1915
1916 //************************************************
1917 // Generates
1918 //
1919 // Way down in generate_item is speced a difference between module,
1920 // interface and checker generates. modules and interfaces are almost
1921 // identical (minus DEFPARAMs) so we overlap them. Checkers are too
1922 // different, so we copy all rules for checkers.
1923
1924 generate_region: // ==IEEE: generate_region
1925 yGENERATE ~c~genItemList yENDGENERATE { }
1926 | yGENERATE yENDGENERATE { }
1927 ;
1928
1929 c_generate_region: // IEEE: generate_region (for checkers)
1930 BISONPRE_COPY(generate_region,{s/~c~/c_/g}) // {copied}
1931 ;
1932
1933 generate_block: // IEEE: generate_block
1934 // // Either a single item, or a begin-end block
1935 ~c~generate_item { }
1936 | ~c~genItemBegin { }
1937 ;
1938
1939 c_generate_block: // IEEE: generate_block (for checkers)
1940 BISONPRE_COPY(generate_block,{s/~c~/c_/g}) // {copied}
1941 ;
1942
1943 genItemBegin: // IEEE: part of generate_block
1944 yBEGIN ~c~genItemList yEND { }
1945 | yBEGIN yEND { }
1946 | id ':' yBEGIN ~c~genItemList yEND endLabelE { }
1947 | id ':' yBEGIN yEND endLabelE { }
1948 | yBEGIN ':' idAny ~c~genItemList yEND endLabelE { }
1949 | yBEGIN ':' idAny yEND endLabelE { }
1950 ;
1951
1952 c_genItemBegin: // IEEE: part of generate_block (for checkers)
1953 BISONPRE_COPY(genItemBegin,{s/~c~/c_/g}) // {copied}
1954 ;
1955
1956 genItemOrBegin: // Not in IEEE, but our begin isn't under generate_item
1957 ~c~generate_item { }
1958 | ~c~genItemBegin { }
1959 ;
1960
1961 c_genItemOrBegin: // (for checkers)
1962 BISONPRE_COPY(genItemOrBegin,{s/~c~/c_/g}) // {copied}
1963 ;
1964
1965 genItemList:
1966 ~c~genItemOrBegin { }
1967 | ~c~genItemList ~c~genItemOrBegin { }
1968 ;
1969
1970 c_genItemList: // (for checkers)
1971 BISONPRE_COPY(genItemList,{s/~c~/c_/g}) // {copied}
1972 ;
1973
1974 generate_item: // IEEE: module_or_interface_or_generate_item
1975 // // Only legal when in a generate under a module (or interface under a module)
1976 module_or_generate_item { }
1977 // // Only legal when in a generate under an interface
1978 | interface_or_generate_item { }
1979 // // IEEE: checker_or_generate_item
1980 // // Only legal when in a generate under a checker
1981 // // so below in c_generate_item
1982 ;
1983
1984 c_generate_item: // IEEE: generate_item (for checkers)
1985 checker_or_generate_item { }
1986 ;
1987
1988 conditional_generate_construct: // ==IEEE: conditional_generate_construct
1989 // // IEEE: case_generate_construct
1990 yCASE '(' expr ')' yENDCASE { }
1991 | yCASE '(' expr ')' ~c~case_generate_itemList yENDCASE { }
1992 // // IEEE: if_generate_construct
1993 | yIF '(' expr ')' ~c~generate_block %prec prLOWER_THAN_ELSE { }
1994 | yIF '(' expr ')' ~c~generate_block yELSE ~c~generate_block { }
1995 ;
1996
1997 c_conditional_generate_construct: // IEEE: conditional_generate_construct (for checkers)
1998 BISONPRE_COPY(conditional_generate_construct,{s/~c~/c_/g}) // {copied}
1999 ;
2000
2001 loop_generate_construct: // ==IEEE: loop_generate_construct
2002 yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block
2003 { }
2004 ;
2005
2006 c_loop_generate_construct: // IEEE: loop_generate_construct (for checkers)
2007 BISONPRE_COPY(loop_generate_construct,{s/~c~/c_/g}) // {copied}
2008 ;
2009
2010 genvar_initialization: // ==IEEE: genvar_initalization
2011 id '=' constExpr { }
2012 | yGENVAR genvar_identifierDecl '=' constExpr { }
2013 ;
2014
2015 genvar_iteration: // ==IEEE: genvar_iteration
2016 // // IEEE: assignment_operator plus IDs
2017 | id '=' expr { }
2018 | id yP_PLUSEQ expr { }
2019 | id yP_MINUSEQ expr { }
2020 | id yP_TIMESEQ expr { }
2021 | id yP_DIVEQ expr { }
2022 | id yP_MODEQ expr { }
2023 | id yP_ANDEQ expr { }
2024 | id yP_OREQ expr { }
2025 | id yP_XOREQ expr { }
2026 | id yP_SLEFTEQ expr { }
2027 | id yP_SRIGHTEQ expr { }
2028 | id yP_SSRIGHTEQ expr { }
2029 // // inc_or_dec_operator
2030 | yP_PLUSPLUS id { }
2031 | yP_MINUSMINUS id { }
2032 | id yP_PLUSPLUS { }
2033 | id yP_MINUSMINUS { }
2034 ;
2035
2036 case_generate_itemList: // IEEE: { case_generate_item }
2037 ~c~case_generate_item { }
2038 | ~c~case_generate_itemList ~c~case_generate_item { }
2039 ;
2040
2041 c_case_generate_itemList: // IEEE: { case_generate_item } (for checkers)
2042 BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied}
2043 ;
2044
2045 case_generate_item: // ==IEEE: case_generate_item
2046 caseCondList ':' ~c~generate_block { }
2047 | yDEFAULT ':' ~c~generate_block { }
2048 | yDEFAULT ~c~generate_block { }
2049 ;
2050
2051 c_case_generate_item: // IEEE: case_generate_item (for checkers)
2052 BISONPRE_COPY(case_generate_item,{s/~c~/c_/g}) // {copied}
2053 ;
2054
2055 //************************************************
2056 // Assignments and register declarations
2057
2058 assignList:
2059 assignOne { }
2060 | assignList ',' assignOne { }
2061 ;
2062
2063 assignOne:
2064 variable_lvalue '=' expr { PARSEP->contassignCb($<fl>2,"assign",$1,$3); }
2065 ;
2066
2067 delay_or_event_controlE: // IEEE: delay_or_event_control plus empty
2068 /* empty */ { }
2069 | delay_control { } /* ignored */
2070 | event_control { } /* ignored */
2071 | yREPEAT '(' expr ')' event_control { } /* ignored */
2072 ;
2073
2074 delayE:
2075 /* empty */ { }
2076 | delay_control { } /* ignored */
2077 ;
2078
2079 delay_control: // ==IEEE: delay_control
2080 '#' delay_value { } /* ignored */
2081 | '#' '(' minTypMax ')' { } /* ignored */
2082 | '#' '(' minTypMax ',' minTypMax ')' { } /* ignored */
2083 | '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { } /* ignored */
2084 ;
2085
2086 delay_value: // ==IEEE:delay_value
2087 // // IEEE: ps_identifier
2088 ps_id_etc { }
2089 | yaINTNUM { }
2090 | yaFLOATNUM { }
2091 | yaTIMENUM { }
2092 ;
2093
2094 delayExpr:
2095 expr { }
2096 ;
2097
2098 minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression
2099 delayExpr { }
2100 | delayExpr ':' delayExpr ':' delayExpr { }
2101 ;
2102
2103 netSigList: // IEEE: list_of_port_identifiers
2104 netSig { }
2105 | netSigList ',' netSig { }
2106 ;
2107
2108 netSig: // IEEE: net_decl_assignment - one element from list_of_port_identifiers
2109 netId sigAttrListE { VARDONE($<fl>1, $1, "", ""); }
2110 | netId sigAttrListE '=' expr { VARDONE($<fl>1, $1, "", $4); }
2111 | netId variable_dimensionList sigAttrListE { VARDONE($<fl>1, $1, $2, ""); }
2112 ;
2113
2114 netId<str>:
2115 id/*new-net*/ { $<fl>$=$<fl>1; $$=$1; }
2116 | idSVKwd { $<fl>$=$<fl>1; $$=$1; }
2117 ;
2118
2119 sigAttrListE:
2120 /* empty */ { }
2121 ;
2122
2123 rangeListE<str>: // IEEE: [{packed_dimension}]
2124 /* empty */ { $$=""; }
2125 | rangeList { $<fl>$=$<fl>1; $$ = $1; }
2126 ;
2127
2128 rangeList<str>: // IEEE: {packed_dimension}
2129 anyrange { $<fl>$=$<fl>1; $$ = $1; }
2130 | rangeList anyrange { $<fl>$=$<fl>1; $$ = $1+$2; }
2131 ;
2132
2133 regrangeE<str>:
2134 /* empty */ { $$=""; }
2135 | anyrange { $<fl>$=$<fl>1; $$=$1; }
2136 ;
2137
2138 bit_selectE<str>: // IEEE: constant_bit_select (IEEE included empty)
2139 /* empty */ { $$ = ""; }
2140 | '[' constExpr ']' { $<fl>$=$<fl>1; $$ = "["+$2+"]"; }
2141 ;
2142
2143 // IEEE: select
2144 // Merged into more general idArray
2145
2146 anyrange<str>:
2147 '[' constExpr ':' constExpr ']' { $<fl>$=$<fl>1; $$ = "["+$2+":"+$4+"]"; }
2148 ;
2149
2150 packed_dimensionListE<str>: // IEEE: [{ packed_dimension }]
2151 /* empty */ { $$=""; }
2152 | packed_dimensionList { $<fl>$=$<fl>1; $$=$1; }
2153 ;
2154
2155 packed_dimensionList<str>: // IEEE: { packed_dimension }
2156 packed_dimension { $<fl>$=$<fl>1; $$=$1; }
2157 | packed_dimensionList packed_dimension { $<fl>$=$<fl>1; $$=$1+$2; }
2158 ;
2159
2160 packed_dimension<str>: // ==IEEE: packed_dimension
2161 anyrange { $<fl>$=$<fl>1; $$=$1; }
2162 | '[' ']' { $$="[]"; }
2163 ;
2164
2165 //************************************************
2166 // Parameters
2167
2168 param_assignment: // ==IEEE: param_assignment
2169 // // IEEE: constant_param_expression
2170 // // param_expression: '$' is in expr
2171 id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' exprOrDataTypeOrMinTypMax
2172 { $<fl>$=$<fl>1; VARDONE($<fl>1, $1, $2, $5); }
2173 // // only legal in port list; throws error if not set
2174 | id/*new-parameter*/ variable_dimensionListE sigAttrListE
2175 { $<fl>$=$<fl>1; VARDONE($<fl>1, $1, $2, ""); NEED_S09($<fl>1,"optional parameter defaults"); }
2176 ;
2177
2178 list_of_param_assignments: // ==IEEE: list_of_param_assignments
2179 param_assignment { }
2180 | list_of_param_assignments ',' param_assignment { }
2181 ;
2182
2183 list_of_defparam_assignments: // ==IEEE: list_of_defparam_assignments
2184 defparam_assignment { }
2185 | list_of_defparam_assignments ',' defparam_assignment { }
2186 ;
2187
2188 defparam_assignment: // ==IEEE: defparam_assignment
2189 hierarchical_identifier/*parameter*/ '=' expr { PARSEP->defparamCb($<fl>2,"defparam",$1,$3); }
2190 ;
2191
2192 //************************************************
2193 // Instances
2194 // We don't know identifier types, so this matches all module,udp,etc instantiation
2195 // module_id [#(params)] name (pins) [, name ...] ; // module_instantiation
2196 // gate (strong0) [#(delay)] [name] (pins) [, (pins)...] ; // gate_instantiation
2197 // program_id [#(params}] name ; // program_instantiation
2198 // interface_id [#(params}] name ; // interface_instantiation
2199 // checker_id name (pins) ; // checker_instantiation
2200
2201 etcInst: // IEEE: module_instantiation + gate_instantiation + udp_instantiation
2202 instName { INSTPREP($1,1,0); } strengthSpecE parameter_value_assignmentE { INSTPREP($1,0,1); } instnameList ';'
2203 { INSTDONE(); }
2204 // // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers
2205 | instName { INSTPREP($1,1,0); } '.' id {INSTPREP($1,0,0);} mpInstnameList ';'
2206 { INSTDONE(); }
2207 ;
2208
2209 instName<str>:
2210 gateKwd { $<fl>$=$<fl>1; $$=$1; }
2211 // // id is-a: interface_identifier
2212 // // or program_identifier
2213 // // or udp_identifier
2214 // // or module_identifier
2215 | id { $<fl>$=$<fl>1; $$=$1; }
2216 ;
2217
2218 mpInstnameList: // Similar to instnameList, but for modport instantiations which have no parenthesis
2219 mpInstnameParen { }
2220 | mpInstnameList ',' mpInstnameParen { }
2221 ;
2222
2223 mpInstnameParen: // Similar to instnameParen, but for modport instantiations which have no parenthesis
2224 mpInstname { PARSEP->endcellCb($<fl>1,""); }
2225 ;
2226
2227 mpInstname: // Similar to instname, but for modport instantiations which have no parenthesis
2228 // // id is-a: interface_port_identifier (interface.modport)
2229 id instRangeListE { PARSEP->instantCb($<fl>1, GRAMMARP->m_cellMod, $1, $2); }
2230 ;
2231
2232 instnameList:
2233 instnameParen { }
2234 | instnameList ',' instnameParen { }
2235 ;
2236
2237 instnameParen:
2238 instname cellpinList ')' { PARSEP->endcellCb($<fl>3,""); }
2239 ;
2240
2241 instname:
2242 // // id is-a: hierarchical_instance (interface)
2243 // // or instance_identifier (module)
2244 // // or instance_identifier (program)
2245 // // or udp_instance (udp)
2246 id instRangeListE '(' { PARSEP->instantCb($<fl>1, GRAMMARP->m_cellMod, $1, $2); PINPARAMS(); }
2247 | instRangeListE '(' { PARSEP->instantCb($<fl>2, GRAMMARP->m_cellMod, "", $1); PINPARAMS(); } // UDP
2248 ;
2249
2250 instRangeListE<str>:
2251 /* empty */ { $$ = ""; }
2252 | instRangeList { $<fl>$=$<fl>1; $$ = $1; }
2253 ;
2254
2255 instRangeList<str>:
2256 instRange { $<fl>$=$<fl>1; $$ = $1; }
2257 | instRangeList instRange { $<fl>$=$<fl>1; $$ = $1+$2; }
2258 ;
2259
2260 instRange<str>:
2261 '[' constExpr ']' { $<fl>$=$<fl>1; $$ = "["+$2+"]"; }
2262 | '[' constExpr ':' constExpr ']' { $<fl>$=$<fl>1; $$ = "["+$2+":"+$4+"]"; }
2263 ;
2264
2265 cellpinList:
2266 { VARRESET_LIST(""); } cellpinItList { VARRESET_NONLIST(""); GRAMMARP->m_withinPin = false; }
2267 ;
2268
2269 cellpinItList: // IEEE: list_of_port_connections + list_of_parameter_assignmente
2270 { GRAMMARP->m_portNextNetName.clear(); } cellpinItemE { }
2271 | cellpinItList ',' cellpinItemE { }
2272 ;
2273
2274 cellpinItemE: // IEEE: named_port_connection + named_parameter_assignment + empty
2275 /* empty: ',,' is legal */ { PINNUMINC(); } /*PINDONE(yylval.fl,"",""); <- No, as then () implies a pin*/
2276 | yP_DOTSTAR { PINDONE($<fl>1,"*","*");PINNUMINC(); }
2277 | '.' idSVKwd { PINDONE($<fl>1,$2,$2); PINNUMINC(); }
2278 | '.' idAny { PINDONE($<fl>1,$2,$2); PINNUMINC(); }
2279 | '.' idAny '(' ')' { PINDONE($<fl>1,$2,""); PINNUMINC(); }
2280 // // mintypmax is expanded here, as it might be a UDP or gate primitive
2281 // // For checkers, this needs to not just expr, but include events + properties
2282 | '.' idAny '(' pev_expr ')' { PINDONE($<fl>1,$2,$4); PINNUMINC(); }
2283 | '.' idAny '(' pev_expr ':' expr ')' { PINDONE($<fl>1,$2,$4); PINNUMINC(); }
2284 | '.' idAny '(' pev_expr ':' expr ':' expr ')' { PINDONE($<fl>1,$2,$4); PINNUMINC(); }
2285 // // For parameters
2286 | '.' idAny '(' data_type ')' { PINDONE($<fl>1,$2,$4); PINNUMINC(); }
2287 // // For parameters
2288 | data_type { PINDONE($<fl>1,"",$1); PINNUMINC(); }
2289 //
2290 | expr { PINDONE($<fl>1,"",$1); PINNUMINC(); }
2291 | expr ':' expr { PINDONE($<fl>1,"",$1); PINNUMINC(); }
2292 | expr ':' expr ':' expr { PINDONE($<fl>1,"",$1); PINNUMINC(); }
2293 ;
2294
2295 //************************************************
2296 // EventControl lists
2297
2298 event_control: // ==IEEE: event_control
2299 '@' '(' event_expression ')' { }
2300 | '@' '*' { }
2301 | '@' '(' '*' ')' { }
2302 // // IEEE: hierarchical_event_identifier
2303 | '@' idClassSel/*event_id or ps_or_hierarchical_sequence_identifier*/ { }
2304 // // IEEE: ps_or_hierarchical_sequence_identifier
2305 // // sequence_instance without parens matches idClassSel above.
2306 // // Ambiguity: "'@' sequence (-for-sequence" versus expr:delay_or_event_controlE "'@' id (-for-expr
2307 // // For now we avoid this, as it's very unlikely someone would mix
2308 // // 1995 delay with a sequence with parameters.
2309 // // Alternatively split this out of event_control, and delay_or_event_controlE
2310 // // and anywhere delay_or_event_controlE is called allow two expressions
2311 ;
2312
2313 event_expression: // IEEE: event_expression - split over several
2314 // // ',' rules aren't valid in port lists - ev_expr is there.
2315 // // Also eliminates left recursion to appease conflicts
2316 ev_expr { }
2317 | event_expression ',' ev_expr %prec yOR { } /* Verilog 2001 */
2318 ;
2319
2320 senitemEdge<str>: // IEEE: part of event_expression
2321 // // Also called by pev_expr
2322 yPOSEDGE expr { $<fl>$=$<fl>1; $$=$1+" "+$2; }
2323 | yPOSEDGE expr yIFF expr { $<fl>$=$<fl>1; $$=$1+" "+$2+" iff "+$4; }
2324 | yNEGEDGE expr { $<fl>$=$<fl>1; $$=$1+" "+$2; }
2325 | yNEGEDGE expr yIFF expr { $<fl>$=$<fl>1; $$=$1+" "+$2+" iff "+$4; }
2326 | yEDGE expr { $<fl>$=$<fl>1; $$=$1+" "+$2; NEED_S09($<fl>1,"edge"); }
2327 | yEDGE expr yIFF expr { $<fl>$=$<fl>1; $$=$1+" "+$2+" iff "+$4; NEED_S09($<fl>1,"edge"); }
2328 ;
2329
2330 //************************************************
2331 // Statements
2332
2333 stmtBlock: // IEEE: statement + seq_block + par_block
2334 stmt { }
2335 ;
2336
2337 seq_block: // ==IEEE: seq_block
2338 // // IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
2339 seq_blockFront blockDeclStmtList yEND endLabelE { PARSEP->symPopScope(VAstType::BLOCK); }
2340 | seq_blockFront /**/ yEND endLabelE { PARSEP->symPopScope(VAstType::BLOCK); }
2341 ;
2342
2343 par_block: // ==IEEE: par_block
2344 par_blockFront blockDeclStmtList yJOIN endLabelE { PARSEP->symPopScope(VAstType::FORK); }
2345 | par_blockFront /**/ yJOIN endLabelE { PARSEP->symPopScope(VAstType::FORK); }
2346 ;
2347
2348 seq_blockFront: // IEEE: part of seq_block
2349 yBEGIN { PARSEP->symPushNewAnon(VAstType::BLOCK); }
2350 | yBEGIN ':' idAny/*new-block_identifier*/ { PARSEP->symPushNew(VAstType::BLOCK,$1); }
2351 ;
2352
2353 par_blockFront: // IEEE: part of par_block
2354 yFORK { PARSEP->symPushNewAnon(VAstType::FORK); }
2355 | yFORK ':' idAny/*new-block_identifier*/ { PARSEP->symPushNew(VAstType::FORK,$1); }
2356 ;
2357
2358 blockDeclStmtList: // IEEE: { block_item_declaration } { statement or null }
2359 // // The spec seems to suggest a empty declaration isn't ok, but most simulators take it
2360 block_item_declarationList { }
2361 | block_item_declarationList stmtList { }
2362 | stmtList { }
2363 ;
2364
2365 block_item_declarationList: // IEEE: [ block_item_declaration ]
2366 block_item_declaration { }
2367 | block_item_declarationList block_item_declaration { }
2368 ;
2369
2370 block_item_declaration: // ==IEEE: block_item_declaration
2371 data_declaration { }
2372 | local_parameter_declaration ';' { }
2373 | parameter_declaration ';' { }
2374 | overload_declaration { }
2375 | let_declaration { }
2376 ;
2377
2378 stmtList:
2379 stmtBlock { }
2380 | stmtList stmtBlock { }
2381 ;
2382
2383 stmt: // IEEE: statement_or_null == function_statement_or_null
2384 statement_item { }
2385 // // S05 block creation rule
2386 | id/*block_identifier*/ ':' statement_item { }
2387 // // from _or_null
2388 | ';' { }
2389 ;
2390
2391 statement_item: // IEEE: statement_item
2392 // // IEEE: operator_assignment
2393 foperator_assignment ';' { }
2394 //
2395 // // IEEE: blocking_assignment
2396 // // 1800-2009 restricts LHS of assignment to new to not have a range
2397 // // This is ignored to avoid conflicts
2398 | fexprLvalue '=' class_new ';' { }
2399 | fexprLvalue '=' dynamic_array_new ';' { }
2400 //
2401 // // IEEE: nonblocking_assignment
2402 | fexprLvalue yP_LTE delay_or_event_controlE expr ';' { }
2403 //
2404 // // IEEE: procedural_continuous_assignment
2405 | yASSIGN expr '=' delay_or_event_controlE expr ';' { }
2406 | yDEASSIGN variable_lvalue ';' { }
2407 | yFORCE expr '=' expr ';' { }
2408 | yRELEASE variable_lvalue ';' { }
2409 //
2410 // // IEEE: case_statement
2411 | unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { }
2412 | unique_priorityE caseStart caseAttrE yMATCHES case_patternListE yENDCASE { }
2413 | unique_priorityE caseStart caseAttrE yINSIDE case_insideListE yENDCASE { }
2414 //
2415 // // IEEE: conditional_statement
2416 | unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { }
2417 | unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock { }
2418 //
2419 | finc_or_dec_expression ';' { }
2420 // // IEEE: inc_or_dec_expression
2421 // // Below under expr
2422 //
2423 // // IEEE: subroutine_call_statement
2424 | yVOID yP_TICK '(' function_subroutine_callNoMethod ')' ';' { }
2425 | yVOID yP_TICK '(' expr '.' function_subroutine_callNoMethod ')' ';' { }
2426 // // Expr included here to resolve our not knowing what is a method call
2427 // // Expr here must result in a subroutine_call
2428 | task_subroutine_callNoMethod ';' { }
2429 | fexpr '.' array_methodNoRoot ';' { }
2430 | fexpr '.' task_subroutine_callNoMethod ';' { }
2431 | fexprScope ';' { }
2432 // // Not here in IEEE; from class_constructor_declaration
2433 // // Because we've joined class_constructor_declaration into generic functions
2434 // // Way over-permissive;
2435 // // IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ]
2436 | fexpr '.' class_new ';' { }
2437 //
2438 // // IEEE: disable_statement
2439 | yDISABLE hierarchical_identifier/*task_or_block*/ ';' { }
2440 | yDISABLE yFORK ';' { }
2441 // // IEEE: event_trigger
2442 | yP_MINUSGT hierarchical_identifier/*event*/ ';' { }
2443 | yP_MINUSGTGT delay_or_event_controlE hierarchical_identifier/*event*/ ';' { }
2444 // // IEEE: loop_statement
2445 | yFOREVER stmtBlock { }
2446 | yREPEAT '(' expr ')' stmtBlock { }
2447 | yWHILE '(' expr ')' stmtBlock { }
2448 // // for's first ';' is in for_initalization
2449 | yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
2450 { }
2451 | yFOR '(' for_initialization ';' for_stepE ')' stmtBlock
2452 { }
2453 | yDO stmtBlock yWHILE '(' expr ')' ';' { }
2454 // // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
2455 | yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' stmt { }
2456 //
2457 // // IEEE: jump_statement
2458 | yRETURN ';' { }
2459 | yRETURN expr ';' { }
2460 | yBREAK ';' { }
2461 | yCONTINUE ';' { }
2462 //
2463 | par_block { }
2464 // // IEEE: procedural_timing_control_statement + procedural_timing_control
2465 | delay_control stmtBlock { }
2466 | event_control stmtBlock { }
2467 | cycle_delay stmtBlock { }
2468 //
2469 | seq_block { }
2470 //
2471 // // IEEE: wait_statement
2472 | yWAIT '(' expr ')' stmtBlock { }
2473 | yWAIT yFORK ';' { }
2474 | yWAIT_ORDER '(' hierarchical_identifierList ')' action_block { }
2475 //
2476 // // IEEE: procedural_assertion_statement
2477 | procedural_assertion_statement { }
2478 //
2479 // // IEEE: clocking_drive ';'
2480 // // clockvar_expression made to fexprLvalue to prevent reduce conflict
2481 // // Note LTE in this context is highest precedence, so first on left wins
2482 | fexprLvalue yP_LTE cycle_delay expr ';' { }
2483 //
2484 | randsequence_statement { }
2485 //
2486 // // IEEE: randcase_statement
2487 | yRANDCASE case_itemList yENDCASE { }
2488 //
2489 | expect_property_statement { }
2490 //
2491 | error ';' { }
2492 ;
2493
2494 operator_assignment: // IEEE: operator_assignment
2495 ~f~exprLvalue '=' delay_or_event_controlE expr { }
2496 | ~f~exprLvalue yP_PLUSEQ expr { }
2497 | ~f~exprLvalue yP_MINUSEQ expr { }
2498 | ~f~exprLvalue yP_TIMESEQ expr { }
2499 | ~f~exprLvalue yP_DIVEQ expr { }
2500 | ~f~exprLvalue yP_MODEQ expr { }
2501 | ~f~exprLvalue yP_ANDEQ expr { }
2502 | ~f~exprLvalue yP_OREQ expr { }
2503 | ~f~exprLvalue yP_XOREQ expr { }
2504 | ~f~exprLvalue yP_SLEFTEQ expr { }
2505 | ~f~exprLvalue yP_SRIGHTEQ expr { }
2506 | ~f~exprLvalue yP_SSRIGHTEQ expr { }
2507 ;
2508
2509 foperator_assignment<str>: // IEEE: operator_assignment (for first part of expression)
2510 BISONPRE_COPY(operator_assignment,{s/~f~/f/g}) // {copied}
2511 ;
2512
2513 inc_or_dec_expression<str>: // ==IEEE: inc_or_dec_expression
2514 // // Need fexprScope instead of variable_lvalue to prevent conflict
2515 ~l~exprScope yP_PLUSPLUS { $<fl>$=$<fl>1; $$ = $1+$2; }
2516 | ~l~exprScope yP_MINUSMINUS { $<fl>$=$<fl>1; $$ = $1+$2; }
2517 // // Need expr instead of variable_lvalue to prevent conflict
2518 | yP_PLUSPLUS expr { $<fl>$=$<fl>1; $$ = $1+$2; }
2519 | yP_MINUSMINUS expr { $<fl>$=$<fl>1; $$ = $1+$2; }
2520 ;
2521
2522 finc_or_dec_expression<str>: // IEEE: inc_or_dec_expression (for first part of expression)
2523 BISONPRE_COPY(inc_or_dec_expression,{s/~l~/f/g}) // {copied}
2524 ;
2525
2526 sinc_or_dec_expression<str>: // IEEE: inc_or_dec_expression (for sequence_expression)
2527 BISONPRE_COPY(inc_or_dec_expression,{s/~l~/s/g}) // {copied}
2528 ;
2529
2530 pinc_or_dec_expression<str>: // IEEE: inc_or_dec_expression (for property_expression)
2531 BISONPRE_COPY(inc_or_dec_expression,{s/~l~/p/g}) // {copied}
2532 ;
2533
2534 ev_inc_or_dec_expression<str>: // IEEE: inc_or_dec_expression (for ev_expr)
2535 BISONPRE_COPY(inc_or_dec_expression,{s/~l~/ev_/g}) // {copied}
2536 ;
2537
2538 pev_inc_or_dec_expression<str>: // IEEE: inc_or_dec_expression (for pev_expr)
2539 BISONPRE_COPY(inc_or_dec_expression,{s/~l~/pev_/g}) // {copied}
2540 ;
2541
2542 class_new<str>: // ==IEEE: class_new
2543 // // Special precence so (...) doesn't match expr
2544 yNEW__ETC { $<fl>$=$<fl>1; $$ = $1; }
2545 | yNEW__ETC expr { $<fl>$=$<fl>1; $$ = $1+" "+$2; }
2546 // // Grammer abiguity; we assume "new (x)" the () are a argument, not expr
2547 | yNEW__PAREN '(' list_of_argumentsE ')' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2548 ;
2549
2550 dynamic_array_new<str>: // ==IEEE: dynamic_array_new
2551 yNEW__ETC '[' expr ']' { $<fl>$=$<fl>1; $$=$1+"["+$3+"]"; }
2552 | yNEW__ETC '[' expr ']' '(' expr ')' { $<fl>$=$<fl>1; $$=$1+"["+$3+"]("+$6+")"; }
2553 ;
2554
2555 //************************************************
2556 // Case/If
2557
2558 unique_priorityE: // IEEE: unique_priority + empty
2559 /*empty*/ { }
2560 | yPRIORITY { }
2561 | yUNIQUE { }
2562 | yUNIQUE0 { NEED_S09($<fl>1, "unique0"); }
2563 ;
2564
2565 action_block: // ==IEEE: action_block
2566 stmt %prec prLOWER_THAN_ELSE { }
2567 | stmt yELSE stmt { }
2568 | yELSE stmt { }
2569 ;
2570
2571 caseStart: // IEEE: part of case_statement
2572 yCASE '(' expr ')' { }
2573 | yCASEX '(' expr ')' { }
2574 | yCASEZ '(' expr ')' { }
2575 ;
2576
2577 caseAttrE:
2578 /*empty*/ { }
2579 ;
2580
2581 case_patternListE: // IEEE: case_pattern_item
2582 // &&& is part of expr so aliases to case_itemList
2583 case_itemListE { }
2584 ;
2585
2586 case_itemListE: // IEEE: [ { case_item } ]
2587 /* empty */ { }
2588 | case_itemList { }
2589 ;
2590
2591 case_insideListE: // IEEE: [ { case_inside_item } ]
2592 /* empty */ { }
2593 | case_inside_itemList { }
2594 ;
2595
2596 case_itemList: // IEEE: { case_item + ... }
2597 caseCondList ':' stmtBlock { }
2598 | yDEFAULT ':' stmtBlock { }
2599 | yDEFAULT stmtBlock { }
2600 | case_itemList caseCondList ':' stmtBlock { }
2601 | case_itemList yDEFAULT stmtBlock { }
2602 | case_itemList yDEFAULT ':' stmtBlock { }
2603 ;
2604
2605 case_inside_itemList: // IEEE: { case_inside_item + open_range_list ... }
2606 open_range_list ':' stmtBlock { }
2607 | yDEFAULT ':' stmtBlock { }
2608 | yDEFAULT stmtBlock { }
2609 | case_inside_itemList open_range_list ':' stmtBlock { }
2610 | case_inside_itemList yDEFAULT stmtBlock { }
2611 | case_inside_itemList yDEFAULT ':' stmtBlock { }
2612 ;
2613
2614 open_range_list: // ==IEEE: open_range_list + open_value_range
2615 open_value_range { }
2616 | open_range_list ',' open_value_range { }
2617 ;
2618
2619 open_value_range: // ==IEEE: open_value_range
2620 value_range { }
2621 ;
2622
2623 value_range: // ==IEEE: value_range
2624 expr { }
2625 | '[' expr ':' expr ']' { }
2626 ;
2627
2628 covergroup_value_range: // ==IEEE-2012: covergroup_value_range
2629 cgexpr { }
2630 | '[' cgexpr ':' cgexpr ']' { }
2631 ;
2632
2633 caseCondList: // IEEE: part of case_item
2634 expr { }
2635 | caseCondList ',' expr { }
2636 ;
2637
2638 patternNoExpr<str>: // IEEE: pattern **Excluding Expr*
2639 '.' id/*variable*/ { $<fl>$=$<fl>1; $$="."+$2; }
2640 | yP_DOTSTAR { $<fl>$=$<fl>1; $$=".*"; }
2641 // // IEEE: "expr" excluded; expand in callers
2642 // // "yTAGGED id [expr]" Already part of expr
2643 | yTAGGED id/*member_identifier*/ patternNoExpr { $<fl>$=$<fl>1; $$=" tagged "+$2+" "+$3; }
2644 // // "yP_TICKBRA patternList '}'" part of expr under assignment_pattern
2645 ;
2646
2647 patternList<str>: // IEEE: part of pattern
2648 patternOne { $<fl>$=$<fl>1; $$=$1; }
2649 | patternList ',' patternOne { $<fl>$=$<fl>1; $$=$1+","+$3; }
2650 ;
2651
2652 patternOne<str>: // IEEE: part of pattern
2653 expr { $<fl>$=$<fl>1; $$=$1; }
2654 | expr '{' argsExprList '}' { $<fl>$=$<fl>1; $$=$1; }
2655 | patternNoExpr { $<fl>$=$<fl>1; $$=$1; }
2656 ;
2657
2658 patternMemberList<str>: // IEEE: part of pattern and assignment_pattern
2659 patternKey ':' expr { $<fl>$=$<fl>1; $$=$1+" : "+$2; }
2660 | patternKey ':' patternNoExpr { $<fl>$=$<fl>1; $$=$1+" : "+$2; }
2661 | patternMemberList ',' patternKey ':' expr { $<fl>$=$<fl>1; $$=$1+","+$3+":"+$4; }
2662 | patternMemberList ',' patternKey ':' patternNoExpr { $<fl>$=$<fl>1; $$=$1+","+$3+":"+$4; }
2663 ;
2664
2665 patternKey<str>: // IEEE: merge structure_pattern_key, array_pattern_key, assignment_pattern_key
2666 // // IEEE: structure_pattern_key
2667 // // id/*member*/ is part of constExpr below
2668 constExpr { $<fl>$=$<fl>1; $$=$1; }
2669 // // IEEE: assignment_pattern_key
2670 | yDEFAULT { $<fl>$=$<fl>1; $$=$1; }
2671 | simple_type { $<fl>$=$<fl>1; $$=$1; }
2672 // // simple_type reference looks like constExpr
2673 ;
2674
2675 assignment_pattern<str>: // ==IEEE: assignment_pattern
2676 // This doesn't match the text of the spec. I think a : is missing, or example code needed
2677 // yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; }
2678 // // "'{ const_expression }" is same as patternList with one entry
2679 // // From patternNoExpr
2680 // // also IEEE: "''{' expression { ',' expression } '}'"
2681 // // matches since patternList includes expr
2682 yP_TICKBRA patternList '}' { $<fl>$=$<fl>1; $$="'{"+$2+"}"; }
2683 // // From patternNoExpr
2684 // // also IEEE "''{' structure_pattern_key ':' ...
2685 // // also IEEE "''{' array_pattern_key ':' ...
2686 | yP_TICKBRA patternMemberList '}' { $<fl>$=$<fl>1; $$="'{"+$2+"}"; }
2687 // // IEEE: Not in grammar, but in VMM
2688 | yP_TICKBRA '}' { $<fl>$=$<fl>1; $$="'{}"; }
2689 ;
2690
2691 // "datatype id = x {, id = x }" | "yaId = x {, id=x}" is legal
2692 for_initialization: // ==IEEE: for_initialization + for_variable_declaration + extra terminating ";"
2693 // // IEEE: for_variable_declaration
2694 for_initializationItemList ';' { }
2695 // // IEEE: 1800-2017 empty initialization
2696 | ';' { }
2697 ;
2698
2699 for_initializationItemList: // IEEE: [for_variable_declaration...]
2700 for_initializationItem { }
2701 | for_initializationItemList ',' for_initializationItem { }
2702 ;
2703
2704 for_initializationItem: // IEEE: variable_assignment + for_variable_declaration
2705 // // IEEE: for_variable_declaration
2706 data_type idAny/*new*/ '=' expr { VARDTYPE($1); }
2707 // // IEEE-2012:
2708 | yVAR data_type idAny/*new*/ '=' expr { VARDTYPE($1); }
2709 // // IEEE: variable_assignment
2710 | variable_lvalue '=' expr { }
2711 ;
2712
2713 for_stepE: // IEEE: for_step + empty
2714 /* empty */ { }
2715 | for_step { }
2716 ;
2717
2718 for_step: // IEEE: for_step
2719 for_step_assignment { }
2720 | for_step ',' for_step_assignment { }
2721 ;
2722
2723 for_step_assignment: // ==IEEE: for_step_assignment
2724 operator_assignment { }
2725 //
2726 | inc_or_dec_expression { }
2727 // // IEEE: subroutine_call
2728 | function_subroutine_callNoMethod { }
2729 // // method_call:array_method requires a '.'
2730 | expr '.' array_methodNoRoot { }
2731 | exprScope { }
2732 ;
2733
2734 loop_variables<str>: // ==IEEE: loop_variables
2735 id { $<fl>$=$<fl>1; $$=$1; }
2736 | loop_variables ',' id { $<fl>$=$<fl>1; $$=$1+","+$3; }
2737 ;
2738
2739 //************************************************
2740 // Functions/tasks
2741
2742 funcRef<str>: // IEEE: part of tf_call
2743 // // package_scope/hierarchical_... is part of expr, so just need ID
2744 // // making-a id-is-a
2745 // // ----------------- ------------------
2746 // // tf_call tf_identifier expr (list_of_arguments)
2747 // // method_call(post .) function_identifier expr (list_of_arguments)
2748 // // property_instance property_identifier property_actual_arg
2749 // // sequence_instance sequence_identifier sequence_actual_arg
2750 // // let_expression let_identifier let_actual_arg
2751 //
2752 id '(' pev_list_of_argumentsE ')' { $<fl>$=$<fl>1; $$=$1+"("+$3+")"; }
2753 | package_scopeIdFollows id '(' pev_list_of_argumentsE ')' { $<fl>$=$<fl>2; $$=$1+$2+"("+$4+")"; }
2754 | class_scope_id '(' pev_list_of_argumentsE ')' { $<fl>$=$<fl>1; $$=$<str>1+"("+$3+")"; }
2755 ;
2756
2757 task_subroutine_callNoMethod<str>: // function_subroutine_callNoMethod (as task)
2758 // // IEEE: tf_call
2759 funcRef { $<fl>$=$<fl>1; $$=$1; }
2760 | funcRef yWITH__PAREN '(' expr ')' { $<fl>$=$<fl>1; $$=$1+" "+$2+$3+$4+$5; }
2761 | system_t_call { $<fl>$=$<fl>1; $$=$1; }
2762 // // IEEE: method_call requires a "." so is in expr
2763 // // IEEE: ['std::'] not needed, as normal std package resolution will find it
2764 // // IEEE: randomize_call
2765 // // We implement randomize as a normal funcRef, since randomize isn't a keyword
2766 // // Note yNULL is already part of expressions, so they come for free
2767 | funcRef yWITH__CUR constraint_block { $<fl>$=$<fl>1; $$=$1+" with..."; }
2768 ;
2769
2770 function_subroutine_callNoMethod<str>: // IEEE: function_subroutine_call (as function)
2771 // // IEEE: tf_call
2772 funcRef { $<fl>$=$<fl>1; $$=$1; }
2773 | funcRef yWITH__PAREN '(' expr ')' { $<fl>$=$<fl>1; $$=$1+" "+$2+$3+$4+$5; }
2774 | system_f_call { $<fl>$=$<fl>1; $$=$1; }
2775 // // IEEE: method_call requires a "." so is in expr
2776 // // IEEE: ['std::'] not needed, as normal std package resolution will find it
2777 // // IEEE: randomize_call
2778 // // We implement randomize as a normal funcRef, since randomize isn't a keyword
2779 // // Note yNULL is already part of expressions, so they come for free
2780 | funcRef yWITH__CUR constraint_block { $<fl>$=$<fl>1; $$=$1+" with..."; }
2781 ;
2782
2783 system_t_call<str>: // IEEE: system_tf_call (as task)
2784 system_f_call { $<fl>$=$<fl>1; $$ = $1; }
2785 ;
2786
2787 system_f_call<str>: // IEEE: system_tf_call (as func)
2788 ygenSYSCALL parenE { $<fl>$=$<fl>1; $$ = $1; }
2789 // // Allow list of data_type to support "x,,,y"
2790 | ygenSYSCALL '(' exprOrDataTypeList ')' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2791 // // Standard doesn't explicity list system calls
2792 // // But these match elaboration calls in 1800-2009
2793 | yD_FATAL parenE { $<fl>$=$<fl>1; $$ = $1; }
2794 | yD_FATAL '(' exprOrDataTypeList ')' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2795 | yD_ERROR parenE { $<fl>$=$<fl>1; $$ = $1; }
2796 | yD_ERROR '(' exprOrDataTypeList ')' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2797 | yD_WARNING parenE { $<fl>$=$<fl>1; $$ = $1; }
2798 | yD_WARNING '(' exprOrDataTypeList ')' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2799 | yD_INFO parenE { $<fl>$=$<fl>1; $$ = $1; }
2800 | yD_INFO '(' exprOrDataTypeList ')' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2801 ;
2802
2803 elaboration_system_task<str>: // IEEE: elaboration_system_task (1800-2009)
2804 // // $fatal first argument is exit number, must be constant
2805 yD_FATAL parenE ';' { $<fl>$=$<fl>1; $$ = $1; NEED_S09($<fl>1,"elaboration system tasks"); }
2806 | yD_FATAL '(' exprOrDataTypeList ')' ';' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2807 | yD_ERROR parenE ';' { $<fl>$=$<fl>1; $$ = $1; NEED_S09($<fl>1,"elaboration system tasks"); }
2808 | yD_ERROR '(' exprOrDataTypeList ')' ';' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2809 | yD_WARNING parenE ';' { $<fl>$=$<fl>1; $$ = $1; NEED_S09($<fl>1,"elaboration system tasks"); }
2810 | yD_WARNING '(' exprOrDataTypeList ')' ';' {$<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2811 | yD_INFO parenE ';' { $<fl>$=$<fl>1; $$ = $1; NEED_S09($<fl>1,"elaboration system tasks"); }
2812 | yD_INFO '(' exprOrDataTypeList ')' ';' { $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2813 ;
2814
2815 property_actual_arg<str>: // ==IEEE: property_actual_arg
2816 // // IEEE: property_expr
2817 // // IEEE: sequence_actual_arg
2818 pev_expr { $<fl>$=$<fl>1; $$=$1; }
2819 // // IEEE: sequence_expr
2820 // // property_expr already includes sequence_expr
2821 ;
2822
2823 task<fl>:
2824 yTASK__ETC { $<fl>$=$<fl>1; }
2825 | yTASK__aPUREV { $<fl>$=$<fl>1; }
2826 ;
2827
2828 task_declaration: // IEEE: task_declaration
2829 yTASK__ETC lifetimeE taskId tfGuts yENDTASK endLabelE
2830 { PARSEP->endtaskfuncCb($<fl>5,$5);
2831 PARSEP->symPopScope(VAstType::TASK); }
2832 | yTASK__aPUREV lifetimeE taskId tfGutsPureV
2833 { PARSEP->endtaskfuncCb($<fl>1,"endtask");
2834 PARSEP->symPopScope(VAstType::TASK); }
2835 ;
2836
2837 task_prototype: // ==IEEE: task_prototype
2838 // // IEEE: has '(' tf_port_list ')'
2839 // // However the () should be optional for OVA
2840 task taskId '(' tf_port_listE ')' { PARSEP->symPopScope(VAstType::TASK); PARSEP->endtaskfuncCb($<fl>1,"endtask"); }
2841 | task taskId { PARSEP->symPopScope(VAstType::TASK); PARSEP->endtaskfuncCb($<fl>1,"endtask"); }
2842 ;
2843
2844 function<fl>:
2845 yFUNCTION__ETC { $<fl>$=$<fl>1; }
2846 | yFUNCTION__aPUREV { $<fl>$=$<fl>1; }
2847 ;
2848
2849 function_declaration: // IEEE: function_declaration + function_body_declaration
2850 yFUNCTION__ETC lifetimeE funcId tfGuts yENDFUNCTION endLabelE
2851 { PARSEP->endtaskfuncCb($<fl>5,$5);
2852 PARSEP->symPopScope(VAstType::FUNCTION); }
2853 | yFUNCTION__ETC lifetimeE funcIdNew tfGuts yENDFUNCTION endLabelE
2854 { PARSEP->endtaskfuncCb($<fl>5,$5);
2855 PARSEP->symPopScope(VAstType::FUNCTION); }
2856 | yFUNCTION__aPUREV lifetimeE funcId tfGutsPureV
2857 { PARSEP->endtaskfuncCb($<fl>1,"endfunction");
2858 PARSEP->symPopScope(VAstType::FUNCTION); }
2859 | yFUNCTION__aPUREV lifetimeE funcIdNew tfGutsPureV
2860 { PARSEP->endtaskfuncCb($<fl>1,"endfunction");
2861 PARSEP->symPopScope(VAstType::FUNCTION); }
2862 ;
2863
2864 function_prototype: // IEEE: function_prototype
2865 // // IEEE: has '(' tf_port_list ')'
2866 // // However the () should be optional for OVA
2867 function funcId '(' tf_port_listE ')' { PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2868 | function funcId { PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2869 ;
2870
2871 class_constructor_prototype: // ==IEEE: class_constructor_prototype
2872 function funcIdNew '(' tf_port_listE ')' ';' { PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2873 | function funcIdNew ';' { PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2874 ;
2875
2876 method_prototype:
2877 task_prototype { }
2878 | function_prototype { }
2879 ;
2880
2881 lifetimeE: // IEEE: [lifetime]
2882 /* empty */ { }
2883 | lifetime { }
2884 ;
2885
2886 lifetime: // ==IEEE: lifetime
2887 // // Note lifetime used by members is instead under memberQual
2888 ySTATIC__ETC { }
2889 | yAUTOMATIC { }
2890 ;
2891
2892 taskId:
2893 tfIdScoped
2894 { PARSEP->symPushNewUnder(VAstType::TASK, $<str>1, $<scp>1);
2895 PARSEP->taskCb($<fl>1,"task",$<str>1); }
2896 ;
2897
2898 funcId: // IEEE: function_data_type_or_implicit + part of function_body_declaration
2899 // // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
2900 // // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
2901 /**/ tfIdScoped
2902 { PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>1, $<scp>1);
2903 PARSEP->functionCb($<fl>1,"function",$<str>1,""); }
2904 | signingE rangeList tfIdScoped
2905 { PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>3, $<scp>3);
2906 PARSEP->functionCb($<fl>3,"function",$<str>3,SPACED($1,$2)); }
2907 | signing tfIdScoped
2908 { PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>2, $<scp>2);
2909 PARSEP->functionCb($<fl>2,"function",$<str>2,$1); }
2910 | yVOID tfIdScoped
2911 { PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>2, $<scp>2);
2912 PARSEP->functionCb($<fl>2,"function",$<str>2,$1); }
2913 | data_type tfIdScoped
2914 { PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>2, $<scp>2);
2915 PARSEP->functionCb($<fl>2,"function",$<str>2,$1); }
2916 ;
2917
2918 funcIdNew: // IEEE: from class_constructor_declaration
2919 yNEW__ETC
2920 { PARSEP->symPushNewUnder(VAstType::FUNCTION, "new", NULL);
2921 PARSEP->functionCb($<fl>1,"function","new",""); }
2922 | yNEW__PAREN
2923 { PARSEP->symPushNewUnder(VAstType::FUNCTION, "new", NULL);
2924 PARSEP->functionCb($<fl>1,"function","new",""); }
2925 | class_scopeWithoutId yNEW__PAREN
2926 { PARSEP->symPushNewUnder(VAstType::FUNCTION, "new", $<scp>1);
2927 PARSEP->functionCb($<fl>2,"function","new",""); }
2928 ;
2929
2930 tfIdScoped<str_scp>: // IEEE: part of function_body_declaration/task_body_declaration
2931 // // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
2932 id { $<fl>$=$<fl>1; $<scp>$=NULL; $<str>$ = $1; }
2933 | id/*interface_identifier*/ '.' id { $<fl>$=$<fl>1; $<scp>$=NULL; $<str>$ = $1+"."+$2; }
2934 | class_scope_id { $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$ = $<str>1; }
2935 ;
2936
2937 tfGuts:
2938 '(' tf_port_listE ')' ';' tfBodyE { }
2939 | ';' tfBodyE { }
2940 ;
2941
2942 tfGutsPureV:
2943 '(' tf_port_listE ')' ';' { }
2944 | ';' { }
2945 ;
2946
2947 tfBodyE: // IEEE: part of function_body_declaration/task_body_declaration
2948 /* empty */ { }
2949 | tf_item_declarationList { }
2950 | tf_item_declarationList stmtList { }
2951 | stmtList { }
2952 ;
2953
2954 function_data_type<str>: // IEEE: function_data_type
2955 yVOID { $$ = $1; }
2956 | data_type { $$ = $1; }
2957 ;
2958
2959 tf_item_declarationList:
2960 tf_item_declaration { }
2961 | tf_item_declarationList tf_item_declaration { }
2962 ;
2963
2964 tf_item_declaration: // ==IEEE: tf_item_declaration
2965 block_item_declaration { }
2966 | tf_port_declaration { }
2967 ;
2968
2969 tf_port_listE: // IEEE: tf_port_list + empty
2970 // // Empty covered by tf_port_item
2971 { VARRESET_LIST(""); VARIO("input"); }
2972 tf_port_listList { VARRESET_NONLIST(""); }
2973 ;
2974
2975 tf_port_listList: // IEEE: part of tf_port_list
2976 tf_port_item { }
2977 | tf_port_listList ',' tf_port_item { }
2978 ;
2979
2980 tf_port_item: // ==IEEE: tf_port_item
2981 // // We split tf_port_item into the type and assignment as don't know what follows a comma
2982 /* empty */ { PINNUMINC(); } // For example a ",," port
2983 | tf_port_itemFront tf_port_itemAssignment { PINNUMINC(); }
2984 | tf_port_itemAssignment { PINNUMINC(); }
2985 ;
2986
2987 tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type
2988 data_type { VARDTYPE($1); }
2989 | signingE rangeList { VARDTYPE(SPACED($1,$2)); }
2990 | signing { VARDTYPE($1); }
2991 | yVAR data_type { VARDTYPE($2); }
2992 | yVAR implicit_typeE { VARDTYPE($2); }
2993 //
2994 | tf_port_itemDir /*implicit*/ { VARDTYPE(""); /*default_nettype-see spec*/ }
2995 | tf_port_itemDir data_type { VARDTYPE($2); }
2996 | tf_port_itemDir signingE rangeList { VARDTYPE(SPACED($2,$3)); }
2997 | tf_port_itemDir signing { VARDTYPE($2); }
2998 | tf_port_itemDir yVAR data_type { VARDTYPE($3); }
2999 | tf_port_itemDir yVAR implicit_typeE { VARDTYPE($3); }
3000 ;
3001
3002 tf_port_itemDir: // IEEE: part of tf_port_item, direction
3003 port_direction { } // port_direction sets VARIO
3004 ;
3005
3006 tf_port_itemAssignment: // IEEE: part of tf_port_item, which has assignment
3007 id variable_dimensionListE sigAttrListE
3008 { VARDONE($<fl>1, $1, $2, ""); }
3009 | id variable_dimensionListE sigAttrListE '=' expr
3010 { VARDONE($<fl>1, $1, $2, $5); }
3011 ;
3012
3013 parenE:
3014 /* empty */ { }
3015 | '(' ')' { }
3016 ;
3017
3018 // method_call: // ==IEEE: method_call + method_call_body
3019 // // IEEE: method_call_root '.' method_identifier [ '(' list_of_arguments ')' ]
3020 // // "method_call_root '.' method_identifier" looks just like "expr '.' id"
3021 // // "method_call_root '.' method_identifier (...)" looks just like "expr '.' tf_call"
3022 // // IEEE: built_in_method_call
3023 // // method_call_root not needed, part of expr resolution
3024 // // What's left is below array_methodNoRoot
3025
3026 array_methodNoRoot<str>: // ==IEEE: built_in_method_call without root
3027 // // method_call_root not needed, part of expr resolution
3028 array_method_nameNoId method_callWithE { $<fl>$=$<fl>1; $$=$1+$2; }
3029 | array_method_nameNoId '(' list_of_argumentsE ')' method_callWithE { $<fl>$=$<fl>1; $$=$1+$2+$3+$4+$5; }
3030 // // "method_call_root '.' randomize_call" matches function_subroutine_call:randomize_call
3031 ;
3032
3033 method_callWithE<str>:
3034 // // Code duplicated elsewhere
3035 /* empty */ { $$=""; }
3036 | yWITH__PAREN '(' expr ')' { $<fl>$=$<fl>1; $$=$1+$2+$3+$4; }
3037 ;
3038
3039 array_method_nameNoId<str>: // IEEE: array_method_name minus method_identifier
3040 yUNIQUE { $<fl>$=$<fl>1; $$=$1; }
3041 | yAND { $<fl>$=$<fl>1; $$=$1; }
3042 | yOR { $<fl>$=$<fl>1; $$=$1; }
3043 | yXOR { $<fl>$=$<fl>1; $$=$1; }
3044 ;
3045
3046 dpi_import_export: // ==IEEE: dpi_import_export
3047 yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';' { }
3048 | yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';' { }
3049 | yEXPORT yaSTRING dpi_importLabelE function idAny ';' { }
3050 | yEXPORT yaSTRING dpi_importLabelE task idAny ';' { }
3051 ;
3052
3053 dpi_importLabelE: // IEEE: part of dpi_import_export
3054 /* empty */ { }
3055 | idAny/*c_identifier*/ '=' { }
3056 ;
3057
3058 dpi_tf_import_propertyE: // IEEE: [ dpi_function_import_property + dpi_task_import_property ]
3059 /* empty */ { }
3060 | yCONTEXT { }
3061 | yPURE { }
3062 ;
3063
3064 overload_declaration: // ==IEEE: overload_declaration
3065 // // OLD: Overloads deprecated in IEEE 1800-2017
3066 yBIND overload_operator function data_type idAny/*new-function_identifier*/
3067 '(' overload_proto_formals ')' ';' { }
3068 ;
3069
3070 overload_operator<str>: // ==IEEE: overload_operator
3071 "+" { $$="+"; }
3072 | yP_PLUSPLUS { $$="++"; }
3073 | "-" { $$="-"; }
3074 | yP_MINUSMINUS { $$="--"; }
3075 | "*" { $$="*"; }
3076 | yP_POW { $$="**"; }
3077 | "/" { $$="/"; }
3078 | "%" { $$="%"; }
3079 | yP_EQUAL { $$="=="; }
3080 | yP_NOTEQUAL { $$="!="; }
3081 | "<" { $$="<"; }
3082 | yP_LTE { $$="<="; }
3083 | ">" { $$=">"; }
3084 | yP_GTE { $$=">="; }
3085 | "=" { $$="="; }
3086 ;
3087
3088 overload_proto_formals: // ==IEEE: overload_proto_formals
3089 data_type { }
3090 | overload_proto_formals ',' data_type { }
3091 ;
3092
3093 //************************************************
3094 // Expressions
3095 //
3096 // ~l~ means this is the (l)eft hand side of any operator
3097 // it will get replaced by "", "f" or "s"equence
3098 // ~r~ means this is a (r)ight hand later expansion in the same statement,
3099 // not under parenthesis for <= disambiguation
3100 // it will get replaced by "", or "f"
3101 // ~p~ means this is a (p)arenthetized expression
3102 // it will get replaced by "", or "s"equence
3103
3104 constExpr<str>:
3105 expr { $<fl>$=$<fl>1; $$ = $1; }
3106 ;
3107
3108 expr<str>: // IEEE: part of expression/constant_expression/primary
3109 // *SEE BELOW* // IEEE: primary/constant_primary
3110 //
3111 // // IEEE: unary_operator primary
3112 '+' ~r~expr %prec prUNARYARITH { $<fl>$=$<fl>1; $$ = $1+$2; }
3113 | '-' ~r~expr %prec prUNARYARITH { $<fl>$=$<fl>1; $$ = $1+$2; }
3114 | '!' ~r~expr %prec prNEGATION { $<fl>$=$<fl>1; $$ = $1+$2; }
3115 | '&' ~r~expr %prec prREDUCTION { $<fl>$=$<fl>1; $$ = $1+$2; }
3116 | '~' ~r~expr %prec prNEGATION { $<fl>$=$<fl>1; $$ = $1+$2; }
3117 | '|' ~r~expr %prec prREDUCTION { $<fl>$=$<fl>1; $$ = $1+$2; }
3118 | '^' ~r~expr %prec prREDUCTION { $<fl>$=$<fl>1; $$ = $1+$2; }
3119 | yP_NAND ~r~expr %prec prREDUCTION { $<fl>$=$<fl>1; $$ = $1+$2; }
3120 | yP_NOR ~r~expr %prec prREDUCTION { $<fl>$=$<fl>1; $$ = $1+$2; }
3121 | yP_XNOR ~r~expr %prec prREDUCTION { $<fl>$=$<fl>1; $$ = $1+$2; }
3122 //
3123 // // IEEE: inc_or_dec_expression
3124 | ~l~inc_or_dec_expression { $<fl>$=$<fl>1; $$ = $1; }
3125 //
3126 // // IEEE: '(' operator_assignment ')'
3127 // // Need exprScope of variable_lvalue to prevent conflict
3128 | '(' ~p~exprScope '=' expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3129 | '(' ~p~exprScope yP_PLUSEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3130 | '(' ~p~exprScope yP_MINUSEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3131 | '(' ~p~exprScope yP_TIMESEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3132 | '(' ~p~exprScope yP_DIVEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3133 | '(' ~p~exprScope yP_MODEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3134 | '(' ~p~exprScope yP_ANDEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3135 | '(' ~p~exprScope yP_OREQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3136 | '(' ~p~exprScope yP_XOREQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3137 | '(' ~p~exprScope yP_SLEFTEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3138 | '(' ~p~exprScope yP_SRIGHTEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3139 | '(' ~p~exprScope yP_SSRIGHTEQ expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3140 //
3141 // // IEEE: expression binary_operator expression
3142 | ~l~expr '+' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3143 | ~l~expr '-' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3144 | ~l~expr '*' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3145 | ~l~expr '/' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3146 | ~l~expr '%' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3147 | ~l~expr yP_EQUAL ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3148 | ~l~expr yP_NOTEQUAL ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3149 | ~l~expr yP_CASEEQUAL ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3150 | ~l~expr yP_CASENOTEQUAL ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3151 | ~l~expr yP_WILDEQUAL ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3152 | ~l~expr yP_WILDNOTEQUAL ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3153 | ~l~expr yP_ANDAND ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3154 | ~l~expr yP_OROR ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3155 | ~l~expr yP_POW ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3156 | ~l~expr '<' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3157 | ~l~expr '>' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3158 | ~l~expr yP_GTE ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3159 | ~l~expr '&' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3160 | ~l~expr '|' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3161 | ~l~expr '^' ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3162 | ~l~expr yP_XNOR ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3163 | ~l~expr yP_NOR ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3164 | ~l~expr yP_NAND ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3165 | ~l~expr yP_SLEFT ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3166 | ~l~expr yP_SRIGHT ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3167 | ~l~expr yP_SSRIGHT ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3168 | ~l~expr yP_LTMINUSGT ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3169 //
3170 // // IEEE: expr yP_MINUSGT expr (1800-2009)
3171 // // Conflicts with constraint_expression:"expr yP_MINUSGT constraint_set"
3172 // // To duplicating expr for constraints, just allow the more general form
3173 // // Later Ast processing must ignore constraint terms where inappropriate
3174 | ~l~expr yP_MINUSGT constraint_set { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3175 //
3176 // // <= is special, as we need to disambiguate it with <= assignment
3177 // // We copy all of expr to fexpr and rename this token to a fake one.
3178 | ~l~expr yP_LTE~f__IGNORE~ ~r~expr { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3179 //
3180 // // IEEE: conditional_expression
3181 | ~l~expr '?' ~r~expr ':' ~r~expr { $<fl>$=$<fl>1; $$ = $1+"?"+$3+":"+$5; }
3182 //
3183 // // IEEE: inside_expression
3184 | ~l~expr yINSIDE '{' open_range_list '}' { $<fl>$=$<fl>1; $$ = $1+" inside {"+$3+"}"; }
3185 //
3186 // // IEEE: tagged_union_expression
3187 | yTAGGED id/*member*/ %prec prTAGGED { $<fl>$=$<fl>1; $$ = " tagged "+$1; }
3188 | yTAGGED id/*member*/ %prec prTAGGED expr { $<fl>$=$<fl>1; $$ = " tagged "+$1+" "+$2; }
3189 //
3190 //======================// IEEE: primary/constant_primary
3191 //
3192 // // IEEE: primary_literal (minus string, which is handled specially)
3193 | yaINTNUM { $<fl>$=$<fl>1; $$ = $1; }
3194 | yaFLOATNUM { $<fl>$=$<fl>1; $$ = $1; }
3195 | yaTIMENUM { $<fl>$=$<fl>1; $$ = $1; }
3196 | strAsInt~noStr__IGNORE~ { $<fl>$=$<fl>1; $$ = $1; }
3197 //
3198 // // IEEE: "... hierarchical_identifier select" see below
3199 //
3200 // // IEEE: empty_queue (IEEE 1800-2017 empty_unpacked_array_concatenation)
3201 | '{' '}'
3202 //
3203 // // IEEE: concatenation/constant_concatenation
3204 // // Part of exprOkLvalue below
3205 //
3206 // // IEEE: multiple_concatenation/constant_multiple_concatenation
3207 | '{' constExpr '{' cateList '}' '}' { $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}"; }
3208 // // IEEE: multiple_concatenation/constant_multiple_concatenation+ range_expression (1800-2009)
3209 | '{' constExpr '{' cateList '}' '}' '[' expr ']'
3210 { $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+"]"; NEED_S09($<fl>6,"{}[]"); }
3211 | '{' constExpr '{' cateList '}' '}' '[' expr ':' expr ']'
3212 { $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+$9+$10+"]"; NEED_S09($<fl>6,"{}[]"); }
3213 | '{' constExpr '{' cateList '}' '}' '[' expr yP_PLUSCOLON expr ']'
3214 { $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+$9+$10+"]"; NEED_S09($<fl>6,"{}[]"); }
3215 | '{' constExpr '{' cateList '}' '}' '[' expr yP_MINUSCOLON expr ']'
3216 { $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+$9+$10+"]"; NEED_S09($<fl>6,"{}[]"); }
3217 //
3218 | function_subroutine_callNoMethod { $$ = $1; }
3219 // // method_call
3220 | ~l~expr '.' function_subroutine_callNoMethod { $<fl>$=$<fl>1; $$=$1+"."+$3; }
3221 // // method_call:array_method requires a '.'
3222 | ~l~expr '.' array_methodNoRoot { $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3223 //
3224 // // IEEE: let_expression
3225 // // see funcRef
3226 //
3227 // // IEEE: '(' mintypmax_expression ')'
3228 | ~noPar__IGNORE~'(' expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+")"; }
3229 | ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $<fl>$=$<fl>1; $$ = "("+$2+":"+$4+":"+$5+")"; }
3230 // // PSL rule
3231 | '_' '(' statePushVlg expr statePop ')' { $<fl>$=$<fl>1; $$ = "_("+$4+")"; } // Arbitrary Verilog inside PSL
3232 //
3233 // // IEEE: cast/constant_cast
3234 | casting_type yP_TICK '(' expr ')' { $<fl>$=$<fl>1; $$ = $1+"'("+$4+")"; }
3235 // // Spec only allows primary with addition of a type reference
3236 // // We'll be more general, and later assert LHS was a type.
3237 | ~l~expr yP_TICK '(' expr ')' { $<fl>$=$<fl>1; $$ = $1+"'("+$4+")"; }
3238 //
3239 // // IEEE: assignment_pattern_expression
3240 // // IEEE: streaming_concatenation
3241 // // See exprOkLvalue
3242 //
3243 // // IEEE: sequence_method_call
3244 // // Indistinguishable from function_subroutine_call:method_call
3245 //
3246 | '$' { $<fl>$=$<fl>1; $$ = "$"; }
3247 | yNULL { $<fl>$=$<fl>1; $$ = $1; }
3248 // // IEEE: yTHIS
3249 // // See exprScope
3250 //
3251 //----------------------
3252 //
3253 // // Part of expr that may also be used as lvalue
3254 | ~l~exprOkLvalue { $<fl>$=$<fl>1; $$ = $1; }
3255 //
3256 //----------------------
3257 //
3258 // // IEEE: cond_predicate - here to avoid reduce problems
3259 // // Note expr includes cond_pattern
3260 | ~l~expr yP_ANDANDAND ~r~expr { $<fl>$=$<fl>1; $$ = $1 + "&&&" + $3; }
3261 //
3262 // // IEEE: cond_pattern - here to avoid reduce problems
3263 // // "expr yMATCHES pattern"
3264 // // IEEE: pattern - expanded here to avoid conflicts
3265 | ~l~expr yMATCHES patternNoExpr { $<fl>$=$<fl>1; $$ = $1 + " matches " + $3; }
3266 | ~l~expr yMATCHES ~r~expr { $<fl>$=$<fl>1; $$ = $1 + " matches " + $3; }
3267 //
3268 // // IEEE: expression_or_dist - here to avoid reduce problems
3269 // // "expr yDIST '{' dist_list '}'"
3270 | ~l~expr yDIST '{' dist_list '}' { $<fl>$=$<fl>1; $$ = $1 + " dist " + $3+"..."+$5; }
3271 ;
3272
3273 fexpr<str>: // For use as first part of statement (disambiguates <=)
3274 BISONPRE_COPY(expr,{s/~l~/f/g; s/~r~/f/g; s/~f__IGNORE~/__IGNORE/g;}) // {copied}
3275 ;
3276
3277 ev_expr<str>: // IEEE: event_expression
3278 // // for yOR/, see event_expression
3279 //
3280 // // IEEE: [ edge_identifier ] expression [ yIFF expression ]
3281 // // expr alone see below
3282 senitemEdge { }
3283 | ev_expr yIFF expr { }
3284 //
3285 // // IEEE: sequence_instance [ yIFF expression ]
3286 // // seq_inst is in expr, so matches senitem rule above
3287 //
3288 // // IEEE: event_expression yOR event_expression
3289 | ev_expr yOR ev_expr { }
3290 // // IEEE: event_expression ',' event_expression
3291 // // See real event_expression rule
3292 //
3293 //---------------------
3294 // // IEEE: expr
3295 | BISONPRE_COPY(expr,{s/~l~/ev_/g; s/~r~/ev_/g; s/~p~/ev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g;}) // {copied}
3296 //
3297 // // IEEE: '(' event_expression ')'
3298 // // expr:'(' x ')' conflicts with event_expression:'(' event_expression ')'
3299 // // so we use a special expression class
3300 | '(' event_expression ')' { $<fl>$=$<fl>1; $$ = "(...)"; }
3301 // // IEEE: From normal expr: '(' expr ':' expr ':' expr ')'
3302 // // But must avoid conflict
3303 | '(' event_expression ':' expr ':' expr ')' { $<fl>$=$<fl>1; $$ = "(...)"; }
3304 ;
3305
3306 //sexpr: See elsewhere
3307 //pexpr: See elsewhere
3308
3309 exprOkLvalue<str>: // expression that's also OK to use as a variable_lvalue
3310 ~l~exprScope { $<fl>$=$<fl>1; $$ = $1; }
3311 // // IEEE: concatenation/constant_concatenation
3312 | '{' cateList '}' { $<fl>$=$<fl>1; $$ = "{"+$2+"}"; }
3313 // // IEEE: concatenation/constant_concatenation+ constant_range_expression (1800-2009)
3314 | '{' cateList '}' '[' expr ']' { $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+"]"; NEED_S09($<fl>4,"{}[]"); }
3315 | '{' cateList '}' '[' expr ':' expr ']' { $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+$6+$7+"]"; NEED_S09($<fl>4,"{}[]"); }
3316 | '{' cateList '}' '[' expr yP_PLUSCOLON expr ']' { $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+$6+$7+"]"; NEED_S09($<fl>4,"{}[]"); }
3317 | '{' cateList '}' '[' expr yP_MINUSCOLON expr ']' { $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+$6+$7+"]"; NEED_S09($<fl>4,"{}[]"); }
3318 // // IEEE: assignment_pattern_expression
3319 // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
3320 // // We allow more here than the spec requires
3321 | ~l~exprScope assignment_pattern { $<fl>$=$<fl>1; $$=$1+$2; }
3322 | data_type assignment_pattern { $<fl>$=$<fl>1; $$=$1+$2; }
3323 | assignment_pattern { $<fl>$=$<fl>1; $$=$1; }
3324 //
3325 | streaming_concatenation { $<fl>$=$<fl>1; $$ = $1; }
3326 ;
3327
3328 fexprOkLvalue<str>: // exprOkLValue, For use as first part of statement (disambiguates <=)
3329 BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g}) // {copied}
3330 ;
3331
3332 sexprOkLvalue<str>: // exprOkLValue, For use by sequence_expr
3333 BISONPRE_COPY(exprOkLvalue,{s/~l~/s/g}) // {copied}
3334 ;
3335
3336 pexprOkLvalue<str>: // exprOkLValue, For use by property_expr
3337 BISONPRE_COPY(exprOkLvalue,{s/~l~/p/g}) // {copied}
3338 ;
3339
3340 ev_exprOkLvalue<str>: // exprOkLValue, For use by ev_expr
3341 BISONPRE_COPY(exprOkLvalue,{s/~l~/ev_/g}) // {copied}
3342 ;
3343
3344 pev_exprOkLvalue<str>: // exprOkLValue, For use by ev_expr
3345 BISONPRE_COPY(exprOkLvalue,{s/~l~/pev_/g}) // {copied}
3346 ;
3347
3348 exprLvalue<str>: // expression that should be a variable_lvalue
3349 ~f~exprOkLvalue { $<fl>$=$<fl>1; $$ = $1; }
3350 ;
3351
3352 fexprLvalue<str>: // For use as first part of statement (disambiguates <=)
3353 BISONPRE_COPY(exprLvalue,{s/~f~/f/g}) // {copied}
3354 ;
3355
3356 exprScope<str>: // scope and variable for use to inside an expression
3357 // // Here we've split method_call_root | implicit_class_handle | class_scope | package_scope
3358 // // from the object being called and let expr's "." deal with resolving it.
3359 // // (note method_call_root was simplified to require a primary in 1800-2009)
3360 //
3361 // // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
3362 // // Or method_call_body without parenthesis
3363 // // See also varRefClassBit, which is the non-expr version of most of this
3364 yTHIS { $<fl>$=$<fl>1; $$ = $1; }
3365 | idArrayed { $<fl>$=$<fl>1; $$ = $1; }
3366 | package_scopeIdFollows idArrayed { $<fl>$=$<fl>1; $$ = $1+$2; }
3367 | class_scopeIdFollows idArrayed { $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3368 | ~l~expr '.' idArrayed { $<fl>$=$<fl>1; $$ = $1+"."+$3; PORTNET($<fl>1, $$); }
3369 // // expr below must be a "yTHIS"
3370 | ~l~expr '.' ySUPER { $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3371 // // Part of implicit_class_handle
3372 | ySUPER { $<fl>$=$<fl>1; $$ = $1; }
3373 ;
3374
3375 fexprScope<str>: // exprScope, For use as first part of statement (disambiguates <=)
3376 BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied}
3377 ;
3378
3379 sexprScope<str>: // exprScope, For use by sequence_expr
3380 BISONPRE_COPY(exprScope,{s/~l~/s/g}) // {copied}
3381 ;
3382
3383 pexprScope<str>: // exprScope, For use by property_expr
3384 BISONPRE_COPY(exprScope,{s/~l~/p/g}) // {copied}
3385 ;
3386
3387 ev_exprScope<str>: // exprScope, For use by ev_expr
3388 BISONPRE_COPY(exprScope,{s/~l~/ev_/g}) // {copied}
3389 ;
3390
3391 pev_exprScope<str>: // exprScope, For use by ev_expr
3392 BISONPRE_COPY(exprScope,{s/~l~/pev_/g}) // {copied}
3393 ;
3394
3395 // Generic expressions
3396 exprOrDataType<str>: // expr | data_type: combined to prevent conflicts
3397 expr { $<fl>$=$<fl>1; $$ = $1; }
3398 // // data_type includes id that overlaps expr, so special flavor
3399 | data_type { $<fl>$=$<fl>1; $$ = $1; }
3400 // // not in spec, but needed for $past(sig,1,,@(posedge clk))
3401 | event_control { $$ = "event_control"; }
3402 ;
3403
3404 exprOrDataTypeOrMinTypMax<str>: // exprOrDataType or mintypmax_expression
3405 expr { $<fl>$=$<fl>1; $$ = $1; }
3406 | expr ':' expr ':' expr { $<fl>$=$<fl>1; $$ = $1+$2+$3+$4+$5; }
3407 // // data_type includes id that overlaps expr, so special flavor
3408 | data_type { $<fl>$=$<fl>1; $$ = $1; }
3409 // // not in spec, but needed for $past(sig,1,,@(posedge clk))
3410 | event_control { $$ = "event_control"; }
3411 ;
3412
3413
3414 cateList<str>:
3415 // // Not just 'expr' to prevent conflict via stream_concOrExprOrType
3416 stream_expression { $<fl>$=$<fl>1; $$ = $1; PIN_CONCAT_APPEND($1); }
3417 | cateList ',' stream_expression { $<fl>$=$<fl>1; $$ = $1+","+$3; PIN_CONCAT_APPEND($3); }
3418 ;
3419
3420 exprOrDataTypeList<str>:
3421 exprOrDataType { $<fl>$=$<fl>1; $$ = $1; }
3422 | exprOrDataTypeList ',' exprOrDataType { $<fl>$=$<fl>1; $$ = $1+","+$3; }
3423 | exprOrDataTypeList ',' { $<fl>$=$<fl>1; $$ = $1+","; } // Verilog::Parser only: ,, is ok
3424 ;
3425
3426 list_of_argumentsE<str>: // IEEE: [list_of_arguments]
3427 // // See comments under funcRef
3428 argsDottedList { $<fl>$=$<fl>1; $$=$1; }
3429 | argsExprListE { $<fl>$=$<fl>1; $$=$1; }
3430 | argsExprListE ',' argsDottedList { $<fl>$=$<fl>1; $$=$1+","+$3; }
3431 ;
3432
3433 pev_list_of_argumentsE<str>: // IEEE: [list_of_arguments] - pev_expr at bottom
3434 // // See comments under funcRef
3435 pev_argsDottedList { $<fl>$=$<fl>1; $$=$1; }
3436 | pev_argsExprListE { $<fl>$=$<fl>1; $$=$1; }
3437 | pev_argsExprListE ',' pev_argsDottedList { $<fl>$=$<fl>1; $$=$1+","+$3; }
3438 ;
3439
3440 argsExprList<str>: // IEEE: part of list_of_arguments (used where ,, isn't legal)
3441 expr { $<fl>$=$<fl>1; $$ = $1; }
3442 | argsExprList ',' expr { $<fl>$=$<fl>1; $$ = $1+","+$3; }
3443 ;
3444
3445 argsExprListE<str>: // IEEE: part of list_of_arguments
3446 argsExprOneE { $<fl>$=$<fl>1; $$ = $1; }
3447 | argsExprListE ',' argsExprOneE { $<fl>$=$<fl>1; $$ = $1+","+$3; }
3448 ;
3449
3450 pev_argsExprListE<str>: // IEEE: part of list_of_arguments - pev_expr at bottom
3451 pev_argsExprOneE { $<fl>$=$<fl>1; $$ = $1; }
3452 | pev_argsExprListE ',' pev_argsExprOneE { $<fl>$=$<fl>1; $$ = $1+","+$3; }
3453 ;
3454
3455 argsExprOneE<str>: // IEEE: part of list_of_arguments
3456 /*empty*/ { $$ = ""; } // ,, is legal in list_of_arguments
3457 | expr { $<fl>$=$<fl>1; $$ = $1; }
3458 ;
3459
3460 pev_argsExprOneE<str>: // IEEE: part of list_of_arguments - pev_expr at bottom
3461 /*empty*/ { $$ = ""; } // ,, is legal in list_of_arguments
3462 | pev_expr { $<fl>$=$<fl>1; $$ = $1; }
3463 ;
3464
3465 argsDottedList<str>: // IEEE: part of list_of_arguments
3466 argsDotted { $<fl>$=$<fl>1; $$=$1; }
3467 | argsDottedList ',' argsDotted { $<fl>$=$<fl>1; $$=$1+","+$3; }
3468 ;
3469
3470 pev_argsDottedList<str>: // IEEE: part of list_of_arguments - pev_expr at bottom
3471 pev_argsDotted { $<fl>$=$<fl>1; $$=$1; }
3472 | pev_argsDottedList ',' pev_argsDotted { $<fl>$=$<fl>1; $$=$1+","+$3; }
3473 ;
3474
3475 argsDotted<str>: // IEEE: part of list_of_arguments
3476 '.' idAny '(' ')' { $<fl>$=$<fl>1; $$=$1+$2+$3+$4; }
3477 | '.' idAny '(' expr ')' { $<fl>$=$<fl>1; $$=$1+$2+$3+$4+$5; }
3478 ;
3479
3480 pev_argsDotted<str>: // IEEE: part of list_of_arguments - pev_expr at bottom
3481 '.' idAny '(' ')' { $<fl>$=$<fl>1; $$=$1+$2+$3+$4; }
3482 | '.' idAny '(' pev_expr ')' { $<fl>$=$<fl>1; $$=$1+$2+$3+$4+$5; }
3483 ;
3484
3485 streaming_concatenation<str>: // ==IEEE: streaming_concatenation
3486 // // Need to disambiguate {<< expr-{ ... expr-} stream_concat }
3487 // // From {<< stream-{ ... stream-} }
3488 // // Likewise simple_type's idScoped from constExpr's idScope
3489 // // Thus we allow always any two operations. Sorry
3490 // // IEEE: "'{' yP_SL/R stream_concatenation '}'"
3491 // // IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'"
3492 // // IEEE: "'{' yP_SL/R constExpr stream_concatenation '}'"
3493 '{' yP_SLEFT stream_concOrExprOrType '}' { $<fl>$=$<fl>1; $$="{<<"+$3+"}"; }
3494 | '{' yP_SRIGHT stream_concOrExprOrType '}' { $<fl>$=$<fl>1; $$="{>>"+$3+"}"; }
3495 | '{' yP_SLEFT stream_concOrExprOrType stream_concatenation '}' { $<fl>$=$<fl>1; $$="{<<"+$3+" "+$4+"}"; }
3496 | '{' yP_SRIGHT stream_concOrExprOrType stream_concatenation '}' { $<fl>$=$<fl>1; $$="{>>"+$3+" "+$4+"}"; }
3497 ;
3498
3499 stream_concOrExprOrType<str>: // IEEE: stream_concatenation | slice_size:simple_type | slice_size:constExpr
3500 cateList { $<fl>$=$<fl>1; $$=$1; }
3501 | simple_type { $<fl>$=$<fl>1; $$=$1; }
3502 // // stream_concatenation found via cateList:stream_expr:'{-normal-concat'
3503 // // simple_typeRef found via cateList:stream_expr:expr:id
3504 // // constant_expression found via cateList:stream_expr:expr
3505 ;
3506
3507 stream_concatenation<str>: // ==IEEE: stream_concatenation
3508 '{' stream_expressionList '}' { $<fl>$=$<fl>1; $$="{"+$2+"}"; }
3509 ;
3510
3511 stream_expressionList<str>: // IEEE: part of stream_concatenation
3512 stream_expression { $<fl>$=$<fl>1; $$=$1; }
3513 | stream_expressionList ',' stream_expression { $<fl>$=$<fl>1; $$=$1+","+$3; }
3514 ;
3515
3516 stream_expression<str>: // ==IEEE: stream_expression
3517 // // IEEE: array_range_expression expanded below
3518 expr { $<fl>$=$<fl>1; $$=$1; }
3519 | expr yWITH__BRA '[' expr ']' { $<fl>$=$<fl>1; $$=$1; }
3520 | expr yWITH__BRA '[' expr ':' expr ']' { $<fl>$=$<fl>1; $$=$1; }
3521 | expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']' { $<fl>$=$<fl>1; $$=$1; }
3522 | expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']' { $<fl>$=$<fl>1; $$=$1; }
3523 ;
3524
3525 //************************************************
3526 // Gate declarations
3527
3528 // We can't tell between UDPs and modules as they aren't declared yet.
3529 // For simplicity, assume everything is a module, perhaps nameless,
3530 // and deal with it later.
3531
3532 // IEEE: cmos_switchtype + enable_gatetype + mos_switchtype
3533 // + n_input_gatetype + n_output_gatetype + pass_en_switchtype
3534 // + pass_switchtype
3535 gateKwd<str>:
3536 ygenGATE { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3537 | yAND { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3538 | yBUF { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3539 | yNAND { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3540 | yNOR { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3541 | yNOT { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3542 | yOR { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3543 | yXNOR { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3544 | yXOR { $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3545 ;
3546
3547 // This list is also hardcoded in VParseLex.l
3548 strength: // IEEE: strength0+strength1 - plus HIGHZ/SMALL/MEDIUM/LARGE
3549 ygenSTRENGTH { }
3550 | ySUPPLY0 { }
3551 | ySUPPLY1 { }
3552 ;
3553
3554 strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
3555 /* empty */ { }
3556 | strengthSpec { }
3557 ;
3558
3559 strengthSpec: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
3560 yP_PAR__STRENGTH strength ')' { }
3561 | yP_PAR__STRENGTH strength ',' strength ')' { }
3562 ;
3563
3564 //************************************************
3565 // Tables
3566
3567 combinational_body: // IEEE: combinational_body + sequential_body
3568 yTABLE tableJunkList yENDTABLE { }
3569 ;
3570
3571 tableJunkList:
3572 tableJunk { } /* ignored */
3573 | tableJunkList tableJunk { } /* ignored */
3574 ;
3575
3576 tableJunk:
BISONPRE_NOT(yTABLE,yENDTABLE)3577 BISONPRE_NOT(yTABLE,yENDTABLE) { }
3578 | yTABLE tableJunk yENDTABLE { }
3579 | error {}
3580 ;
3581
3582 //************************************************
3583 // Specify
3584
3585 specify_block: // ==IEEE: specify_block
3586 ySPECIFY specifyJunkList yENDSPECIFY { }
3587 | ySPECIFY yENDSPECIFY { }
3588 ;
3589
3590 specifyJunkList:
3591 specifyJunk { } /* ignored */
3592 | specifyJunkList specifyJunk { } /* ignored */
3593 ;
3594
3595 specifyJunk:
BISONPRE_NOT(ySPECIFY,yENDSPECIFY)3596 BISONPRE_NOT(ySPECIFY,yENDSPECIFY) { }
3597 | ySPECIFY specifyJunk yENDSPECIFY { }
3598 | error {}
3599 ;
3600
3601 specparam_declaration: // ==IEEE: specparam_declaration
3602 ySPECPARAM junkToSemiList ';' { }
3603 ;
3604
3605 junkToSemiList:
3606 junkToSemi { } /* ignored */
3607 | junkToSemiList junkToSemi { } /* ignored */
3608 ;
3609
3610 junkToSemi:
3611 BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { }
3612 | error {}
3613 ;
3614
3615 //************************************************
3616 // IDs
3617
3618 id<str>:
3619 yaID__ETC { $<fl>$=$<fl>1; $$=$1; }
3620 ;
3621
3622 idAny<str>: // Any kind of identifier
3623 yaID__aPACKAGE { $<fl>$=$<fl>1; $$=$1; }
3624 | yaID__aTYPE { $<fl>$=$<fl>1; $$=$1; }
3625 | yaID__ETC { $<fl>$=$<fl>1; $$=$1; }
3626 ;
3627
3628 idSVKwd<str>: // Warn about non-forward compatible Verilog 2001 code
3629 // // yBIT, yBYTE won't work here as causes conflicts
3630 yDO { $<fl>$=$<fl>1; $$=$1; ERRSVKWD($<fl>1,$$); }
3631 | yFINAL { $<fl>$=$<fl>1; $$=$1; ERRSVKWD($<fl>1,$$); }
3632 ;
3633
3634 variable_lvalue<str>: // IEEE: variable_lvalue or net_lvalue
3635 // // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist
3636 idClassSel { $<fl>$=$<fl>1; $$ = $1; }
3637 | '{' variable_lvalueConcList '}' { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3638 // // IEEE: [ assignment_pattern_expression_type ] assignment_pattern_variable_lvalue
3639 // // We allow more assignment_pattern_expression_types then strictly required
3640 | data_type yP_TICKBRA variable_lvalueList '}' { $<fl>$=$<fl>1; $$ = $1+" "+$2+$3+$4; }
3641 | idClassSel yP_TICKBRA variable_lvalueList '}' { $<fl>$=$<fl>1; $$ = $1+" "+$2+$3+$4; }
3642 | /**/ yP_TICKBRA variable_lvalueList '}' { $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3643 | streaming_concatenation { $<fl>$=$<fl>1; $$ = $1; }
3644 ;
3645
3646 variable_lvalueConcList<str>: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}'
3647 variable_lvalue { $<fl>$=$<fl>1; $$ = $1; }
3648 | variable_lvalueConcList ',' variable_lvalue { $<fl>$=$<fl>1; $$ = $1+","+$3; }
3649 ;
3650
3651 variable_lvalueList<str>: // IEEE: part of variable_lvalue: variable_lvalue { ',' variable_lvalue }
3652 variable_lvalue { $<fl>$=$<fl>1; $$ = $1; }
3653 | variable_lvalueList ',' variable_lvalue { $<fl>$=$<fl>1; $$ = $1+","+$3; }
3654 ;
3655
3656 idClassSel<str>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
3657 idDotted { $<fl>$=$<fl>1; $$ = $1; }
3658 // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
3659 | yTHIS '.' idDotted { $<fl>$=$<fl>1; $$ = "this."+$3; }
3660 | ySUPER '.' idDotted { $<fl>$=$<fl>1; $$ = "super."+$3; }
3661 | yTHIS '.' ySUPER '.' idDotted { $<fl>$=$<fl>1; $$ = "this.super."+$3; }
3662 // // Expanded: package_scope idDotted
3663 | class_scopeIdFollows idDotted { $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3664 | package_scopeIdFollows idDotted { $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3665 ;
3666
3667 idClassForeach<str>: // Misc Ref to dotted, and/or arrayed, no bit range for foreach statement
3668 // // We can't just use the more general idClassSel
3669 // // because ,'s are allowed in the []'s
3670 idDottedForeach { $<fl>$=$<fl>1; $$ = $1; }
3671 // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
3672 | yTHIS '.' idDottedForeach { $<fl>$=$<fl>1; $$ = "this."+$3; }
3673 | ySUPER '.' idDottedForeach { $<fl>$=$<fl>1; $$ = "super."+$3; }
3674 | yTHIS '.' ySUPER '.' idDottedForeach { $<fl>$=$<fl>1; $$ = "this.super."+$3; }
3675 // // Expanded: package_scope idDotted
3676 | class_scopeIdFollows idDottedForeach { $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3677 | package_scopeIdFollows idDottedForeach { $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3678 ;
3679
3680 hierarchical_identifierList: // IEEE: part of wait_statement
3681 hierarchical_identifier { }
3682 | hierarchical_identifierList ',' hierarchical_identifier { }
3683 ;
3684
3685 hierarchical_identifierBit: // IEEE: "hierarchical_identifier bit_select"
3686 // // Not in grammar but "this." believed legal here
3687 idClassSel { }
3688 ;
3689
3690 hierarchical_identifier<str>: // IEEE: hierarchical_identifier, including extra bit_select
3691 // // +hierarchical_parameter_identifier
3692 // // Not in grammar but "this." believed legal here
3693 idClassSel { $<fl>$=$<fl>1; $$ = $1; }
3694 ;
3695
3696 idDotted<str>:
3697 yD_ROOT '.' idDottedMore { $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3698 | idDottedMore { $<fl>$=$<fl>1; $$ = $1; }
3699 ;
3700
3701 idDottedForeach<str>:
3702 yD_ROOT '.' idDottedForeachMore { $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3703 | idDottedForeachMore { $<fl>$=$<fl>1; $$ = $1; }
3704 ;
3705
3706 idDottedMore<str>:
3707 idArrayed { $<fl>$=$<fl>1; $$ = $1; }
3708 | idDottedMore '.' idArrayed { $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3709 ;
3710
3711 idDottedForeachMore<str>:
3712 idForeach { $<fl>$=$<fl>1; $$ = $1; }
3713 | idDottedForeachMore '.' idForeach { $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3714 ;
3715
3716 // Single component of dotted path, maybe [#].
3717 // Due to lookahead constraints, we can't know if [:] or [+:] are valid (last dotted part),
3718 // we'll assume so and cleanup later.
3719 // id below includes:
3720 // enum_identifier
3721 idArrayed<str>: // IEEE: id + select
3722 id { $<fl>$=$<fl>1; $$ = $1; PORTNET($<fl>1, $1);}
3723 // // IEEE: part_select_range/constant_part_select_range
3724 | idArrayed '[' expr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+"]"; PORTRANGE($3, $3);}
3725 | idArrayed '[' constExpr ':' constExpr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+":"+$5+"]"; PORTRANGE($3, $5);}
3726 // // IEEE: indexed_range/constant_indexed_range
3727 | idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+"+:"+$5+"]"; }
3728 | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+"-:"+$5+"]"; }
3729 ;
3730
3731 idForeach<str>: // IEEE: id + select + [loop_variables]
3732 // // Merge of foreach and idArrayed to prevent conflict
3733 id { $<fl>$=$<fl>1; $$ = $1; }
3734 // // IEEE: part_select_range/constant_part_select_range
3735 | idForeach '[' expr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+"]"; }
3736 | idForeach '[' constExpr ':' constExpr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+":"+$5+"]"; }
3737 // // IEEE: indexed_range/constant_indexed_range
3738 | idForeach '[' expr yP_PLUSCOLON constExpr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+"+:"+$5+"]"; }
3739 | idForeach '[' expr yP_MINUSCOLON constExpr ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+"-:"+$5+"]"; }
3740 // // IEEE: part of foreach: [ loop_variables ]
3741 | idForeach '[' expr ',' loop_variables ']' { $<fl>$=$<fl>1; $$ = $1+"["+$3+","+$5+"]"; }
3742 ;
3743
3744 strAsInt<str>:
3745 yaSTRING { $<fl>$=$<fl>1; $$ = $1; }
3746 ;
3747
3748 endLabelE:
3749 /* empty */ { }
3750 | ':' idAny { }
3751 | ':' yNEW__ETC { }
3752 ;
3753
3754 //************************************************
3755 // Clocking
3756
3757 clocking_declaration: // IEEE: clocking_declaration
3758 clockingFront clocking_event ';'
3759 clocking_itemListE yENDCLOCKING endLabelE { PARSEP->symPopScope(VAstType::CLOCKING); }
3760 // // global clocking below - we allow item list, though not in grammar
3761 ;
3762
3763 clockingFront: // IEEE: part of class_declaration
3764 yCLOCKING { PARSEP->symPushNewAnon(VAstType::CLOCKING); }
3765 | yCLOCKING idAny/*clocking_identifier*/ { PARSEP->symPushNew(VAstType::CLOCKING,$2); }
3766 | yDEFAULT yCLOCKING { PARSEP->symPushNewAnon(VAstType::CLOCKING); }
3767 | yDEFAULT yCLOCKING idAny/*clocking_identifier*/ { PARSEP->symPushNew(VAstType::CLOCKING,$3); }
3768 | yGLOBAL__CLOCKING yCLOCKING { PARSEP->symPushNewAnon(VAstType::CLOCKING); }
3769 | yGLOBAL__CLOCKING yCLOCKING idAny/*clocking_identifier*/ { PARSEP->symPushNew(VAstType::CLOCKING,$3); }
3770 ;
3771
3772 clocking_event: // ==IEEE: clocking_event
3773 '@' id { }
3774 | '@' '(' event_expression ')' { }
3775 ;
3776
3777 clocking_itemListE:
3778 /* empty */ { }
3779 | clocking_itemList { }
3780 ;
3781
3782 clocking_itemList: // IEEE: [ clocking_item ]
3783 clocking_item { }
3784 | clocking_itemList clocking_item { }
3785 ;
3786
3787 clocking_item: // ==IEEE: clocking_item
3788 yDEFAULT default_skew ';' { }
3789 | clocking_direction list_of_clocking_decl_assign ';' { }
3790 | assertion_item_declaration { }
3791 ;
3792
3793 default_skew: // ==IEEE: default_skew
3794 yINPUT clocking_skew { }
3795 | yOUTPUT clocking_skew { }
3796 | yINPUT clocking_skew yOUTPUT clocking_skew { }
3797 ;
3798
3799 clocking_direction: // ==IEEE: clocking_direction
3800 yINPUT clocking_skewE { }
3801 | yOUTPUT clocking_skewE { }
3802 | yINPUT clocking_skewE yOUTPUT clocking_skewE { }
3803 | yINOUT { }
3804 ;
3805
3806 list_of_clocking_decl_assign: // ==IEEE: list_of_clocking_decl_assign
3807 clocking_decl_assign { }
3808 | list_of_clocking_decl_assign ',' clocking_decl_assign { }
3809 ;
3810
3811 clocking_decl_assign: // ==IEEE: clocking_decl_assign
3812 idAny/*new-signal_identifier*/ { }
3813 | idAny/*new-signal_identifier*/ '=' expr { }
3814 ;
3815
3816 clocking_skewE: // IEEE: [clocking_skew]
3817 /* empty */ { }
3818 | clocking_skew { }
3819 ;
3820
3821 clocking_skew: // ==IEEE: clocking_skew
3822 yPOSEDGE { }
3823 | yPOSEDGE delay_control { }
3824 | yNEGEDGE { }
3825 | yNEGEDGE delay_control { }
3826 | yEDGE { NEED_S09($<fl>1,"edge"); }
3827 | yEDGE delay_control { NEED_S09($<fl>1,"edge"); }
3828 | delay_control { }
3829 ;
3830
3831 cycle_delay: // ==IEEE: cycle_delay
3832 yP_POUNDPOUND yaINTNUM { }
3833 | yP_POUNDPOUND id { }
3834 | yP_POUNDPOUND '(' expr ')' { }
3835 ;
3836
3837 //************************************************
3838 // Asserts
3839
3840 assertion_item_declaration: // ==IEEE: assertion_item_declaration
3841 property_declaration { }
3842 | sequence_declaration { }
3843 | let_declaration { }
3844 ;
3845
3846 assertion_item: // ==IEEE: assertion_item
3847 concurrent_assertion_item { }
3848 | deferred_immediate_assertion_item { }
3849 ;
3850
3851 deferred_immediate_assertion_item: // ==IEEE: deferred_immediate_assertion_item
3852 deferred_immediate_assertion_statement { }
3853 | id/*block_identifier*/ ':' deferred_immediate_assertion_statement { }
3854 ;
3855
3856 procedural_assertion_statement: // ==IEEE: procedural_assertion_statement
3857 concurrent_assertion_statement { }
3858 | immediate_assertion_statement { }
3859 // // IEEE: checker_instantiation
3860 // // Unlike modules, checkers are the only "id id (...)" form in statements.
3861 | checker_instantiation { }
3862 ;
3863
3864 immediate_assertion_statement: // ==IEEE: immediate_assertion_statement
3865 simple_immediate_assertion_statement { }
3866 | deferred_immediate_assertion_statement { }
3867 ;
3868
3869 simple_immediate_assertion_statement: // ==IEEE: simple_immediate_assertion_statement
3870 // // IEEE: simple_immediate_assert_statement
3871 yASSERT '(' expr ')' action_block { }
3872 // // IEEE: simple_immediate_assume_statement
3873 | yASSUME '(' expr ')' action_block { }
3874 // // IEEE: simple_immediate_cover_statement
3875 | yCOVER '(' expr ')' stmt { }
3876 ;
3877
3878 final_zero: // IEEE: part of deferred_immediate_assertion_statement
3879 '#' yaINTNUM { } // yaINTNUM is always a '0'
3880 // // 1800-2012:
3881 | yFINAL { }
3882 ;
3883
3884 deferred_immediate_assertion_statement<nodep>: // ==IEEE: deferred_immediate_assertion_statement
3885 // // IEEE: deferred_immediate_assert_statement
3886 yASSERT final_zero '(' expr ')' action_block { }
3887 // // IEEE: deferred_immediate_assume_statement
3888 | yASSUME final_zero '(' expr ')' action_block { }
3889 // // IEEE: deferred_immediate_cover_statement
3890 | yCOVER final_zero '(' expr ')' stmt { }
3891 ;
3892
3893 expect_property_statement: // ==IEEE: expect_property_statement
3894 yEXPECT '(' property_spec ')' action_block { }
3895 ;
3896
3897 concurrent_assertion_item: // IEEE: concurrent_assertion_item
3898 concurrent_assertion_statement { }
3899 | id/*block_identifier*/ ':' concurrent_assertion_statement { }
3900 // // IEEE: checker_instantiation
3901 // // identical to module_instantiation; see etcInst
3902 ;
3903
3904 concurrent_assertion_statement: // ==IEEE: concurrent_assertion_statement
3905 // // IEEE: assert_property_statement
3906 yASSERT yPROPERTY '(' property_spec ')' action_block { }
3907 // // IEEE: assume_property_statement
3908 | yASSUME yPROPERTY '(' property_spec ')' action_block { }
3909 // // IEEE: cover_property_statement
3910 | yCOVER yPROPERTY '(' property_spec ')' stmtBlock { }
3911 // // IEEE: cover_sequence_statement
3912 | yCOVER ySEQUENCE '(' sexpr ')' stmt { }
3913 // // IEEE: yCOVER ySEQUENCE '(' clocking_event sexpr ')' stmt
3914 // // sexpr already includes "clocking_event sexpr"
3915 | yCOVER ySEQUENCE '(' clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt { }
3916 | yCOVER ySEQUENCE '(' yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt { }
3917 // // IEEE: restrict_property_statement
3918 | yRESTRICT yPROPERTY '(' property_spec ')' ';' { }
3919 ;
3920
3921 property_declaration: // ==IEEE: property_declaration
3922 property_declarationFront property_port_listE ';' property_declarationBody
3923 yENDPROPERTY endLabelE
3924 { PARSEP->symPopScope(VAstType::PROPERTY); }
3925 ;
3926
3927 property_declarationFront: // IEEE: part of property_declaration
3928 yPROPERTY idAny/*property_identifier*/
3929 { PARSEP->symPushNew(VAstType::PROPERTY,$2); }
3930 ;
3931
3932 property_port_listE: // IEEE: [ ( [ property_port_list ] ) ]
3933 /* empty */ { }
3934 | '(' {VARRESET_LIST(""); VARIO("input"); } property_port_list ')'
3935 { VARRESET_NONLIST(""); }
3936 ;
3937
3938 property_port_list: // ==IEEE: property_port_list
3939 property_port_item { }
3940 | property_port_list ',' property_port_item { }
3941 ;
3942
3943 property_port_item: // IEEE: property_port_item/sequence_port_item
3944 // // Merged in sequence_port_item
3945 // // IEEE: property_lvar_port_direction ::= yINPUT
3946 // // prop IEEE: [ yLOCAL [ yINPUT ] ] property_formal_type
3947 // // id {variable_dimension} [ '=' property_actual_arg ]
3948 // // seq IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
3949 // // id {variable_dimension} [ '=' sequence_actual_arg ]
3950 property_port_itemFront property_port_itemAssignment { }
3951 ;
3952
3953 property_port_itemFront: // IEEE: part of property_port_item/sequence_port_item
3954 //
3955 property_port_itemDirE property_formal_typeNoDt { VARDTYPE($2); }
3956 // // data_type_or_implicit
3957 | property_port_itemDirE data_type { VARDTYPE($2); }
3958 | property_port_itemDirE yVAR data_type { VARDTYPE($3); }
3959 | property_port_itemDirE yVAR implicit_typeE { VARDTYPE($3); }
3960 | property_port_itemDirE signingE rangeList { VARDTYPE(SPACED($2,$3)); }
3961 | property_port_itemDirE /*implicit*/ { /*VARDTYPE-same*/ }
3962 ;
3963
3964 property_port_itemAssignment: // IEEE: part of property_port_item/sequence_port_item/checker_port_direction
3965 portSig variable_dimensionListE { VARDONE($<fl>1, $1, $2, ""); PINNUMINC(); }
3966 | portSig variable_dimensionListE '=' property_actual_arg
3967 { VARDONE($<fl>1, $1, $2, $4); PINNUMINC(); }
3968 ;
3969
3970 property_port_itemDirE:
3971 /* empty */ { }
3972 | yLOCAL__ETC { }
3973 | yLOCAL__ETC port_direction { }
3974 ;
3975
3976 property_declarationBody: // IEEE: part of property_declaration
3977 assertion_variable_declarationList property_statement_spec { }
3978 // // IEEE-2012: Incorectly hasyCOVER ySEQUENCE then property_spec here.
3979 // // Fixed in IEEE 1800-2017
3980 | property_statement_spec { }
3981 ;
3982
3983 assertion_variable_declarationList: // IEEE: part of assertion_variable_declaration
3984 assertion_variable_declaration { }
3985 | assertion_variable_declarationList assertion_variable_declaration { }
3986 ;
3987
3988 sequence_declaration: // ==IEEE: sequence_declaration
3989 sequence_declarationFront sequence_port_listE ';' sequence_declarationBody
3990 yENDSEQUENCE endLabelE
3991 { PARSEP->symPopScope(VAstType::SEQUENCE); }
3992 ;
3993
3994 sequence_declarationFront: // IEEE: part of sequence_declaration
3995 ySEQUENCE idAny/*new_sequence*/
3996 { PARSEP->symPushNew(VAstType::SEQUENCE,$2); }
3997 ;
3998
3999 sequence_port_listE: // IEEE: [ ( [ sequence_port_list ] ) ]
4000 // // IEEE: sequence_lvar_port_direction ::= yINPUT | yINOUT | yOUTPUT
4001 // // IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
4002 // // id {variable_dimension} [ '=' sequence_actual_arg ]
4003 // // All this is almost identically the same as a property.
4004 // // Difference is only yINOUT/yOUTPUT (which might be added to 1800-2012)
4005 // // and yPROPERTY. So save some work.
4006 property_port_listE { }
4007 ;
4008
4009 property_formal_typeNoDt<str>: // IEEE: property_formal_type (w/o implicit)
4010 sequence_formal_typeNoDt { $$ = $1; }
4011 | yPROPERTY { $$ = "property"; }
4012 ;
4013
4014 sequence_formal_typeNoDt<str>: // ==IEEE: sequence_formal_type (w/o data_type_or_implicit)
4015 // // IEEE: data_type_or_implicit
4016 // // implicit expanded where used
4017 ySEQUENCE { $$ = "sequence"; }
4018 // // IEEE-2009: yEVENT
4019 // // already part of data_type. Removed in 1800-2012.
4020 | yUNTYPED { $$ = "untyped"; }
4021 ;
4022
4023 sequence_declarationBody: // IEEE: part of sequence_declaration
4024 // // 1800-2012 makes ';' optional
4025 assertion_variable_declarationList sexpr { }
4026 | assertion_variable_declarationList sexpr ';' { }
4027 | sexpr { }
4028 | sexpr ';' { }
4029 ;
4030
4031 property_spec: // IEEE: property_spec
4032 // // IEEE: [clocking_event ] [ yDISABLE yIFF '(' expression_or_dist ')' ] property_expr
4033 // // matches property_spec: "clocking_event property_expr" so we put it there
4034 yDISABLE yIFF '(' expr ')' pexpr { }
4035 | pexpr { }
4036 ;
4037
4038 property_statement_spec: // ==IEEE: property_statement_spec
4039 // // IEEE: [ clocking_event ] [ yDISABLE yIFF '(' expression_or_dist ')' ] property_statement
4040 property_statement { }
4041 | yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statement { }
4042 // // IEEE: clocking_event property_statement
4043 // // IEEE: clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statement
4044 // // Both overlap pexpr:"clocking_event pexpr" the difference is
4045 // // property_statement:property_statementCaseIf so replicate it
4046 | clocking_event property_statementCaseIf { }
4047 | clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statementCaseIf { }
4048 ;
4049
4050 property_statement: // ==IEEE: property_statement
4051 // // Doesn't make sense to have "pexpr ;" in pexpr rule itself, so we split out case/if
4052 pexpr ';' { }
4053 // // Note this term replicated in property_statement_spec
4054 // // If committee adds terms, they may need to be there too.
4055 | property_statementCaseIf { }
4056 ;
4057
4058 property_statementCaseIf: // IEEE: property_statement - minus pexpr
4059 yCASE '(' expr/*expression_or_dist*/ ')' property_case_itemList yENDCASE { }
4060 | yCASE '(' expr/*expression_or_dist*/ ')' yENDCASE { }
4061 | yIF '(' expr/*expression_or_dist*/ ')' pexpr %prec prLOWER_THAN_ELSE { }
4062 | yIF '(' expr/*expression_or_dist*/ ')' pexpr yELSE pexpr { }
4063 ;
4064
4065 property_case_itemList: // IEEE: {property_case_item}
4066 property_case_item { }
4067 | property_case_itemList ',' property_case_item { }
4068 ;
4069
4070 property_case_item: // ==IEEE: property_case_item
4071 // // IEEE: expression_or_dist { ',' expression_or_dist } ':' property_statement
4072 // // IEEE 1800-2012 changed from property_statement to property_expr
4073 // // IEEE 1800-2017 changed to require the semicolon
4074 caseCondList ':' pexpr { }
4075 | caseCondList ':' pexpr ';' { }
4076 | yDEFAULT pexpr { }
4077 | yDEFAULT ':' pexpr ';' { }
4078 ;
4079
4080 pev_expr<str>: // IEEE: property_actual_arg | expr
4081 // // which expands to pexpr | event_expression
4082 // // Used in port and function calls, when we can't know yet if something
4083 // // is a function/sequence/property or instance/checker pin.
4084 //
4085 // // '(' pev_expr ')'
4086 // // Already in pexpr
4087 // // IEEE: event_expression ',' event_expression
4088 // // ','s are legal in event_expressions, but parens required to avoid conflict with port-sep-,
4089 // // IEEE: event_expression yOR event_expression
4090 // // Already in pexpr - needs removal there
4091 // // IEEE: event_expression yIFF expr
4092 // // Already in pexpr - needs removal there
4093 //
4094 senitemEdge { $$=$1; }
4095 //
4096 //============= pexpr rules copied for pev_expr
4097 | BISONPRE_COPY_ONCE(pexpr,{s/~o~p/pev_/g; }) // {copied}
4098 //
4099 //============= sexpr rules copied for pev_expr
4100 | BISONPRE_COPY_ONCE(sexpr,{s/~p~s/pev_/g; }) // {copied}
4101 //
4102 //============= expr rules copied for pev_expr
4103 | BISONPRE_COPY_ONCE(expr,{s/~l~/pev_/g; s/~p~/pev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied}
4104 ;
4105
4106 pexpr<str>: // IEEE: property_expr (The name pexpr is important as regexps just add an "p" to expr.)
4107 //
4108 // // IEEE: sequence_expr
4109 // // Expanded below
4110 //
4111 // // IEEE: '(' pexpr ')'
4112 // // Expanded below
4113 //
4114 yNOT pexpr %prec prNEGATION { }
4115 | ySTRONG '(' sexpr ')' { }
4116 | yWEAK '(' sexpr ')' { }
4117 // // IEEE: pexpr yOR pexpr
4118 // // IEEE: pexpr yAND pexpr
4119 // // Under ~p~sexpr and/or ~p~sexpr
4120 //
4121 // // IEEE: "sequence_expr yP_ORMINUSGT pexpr"
4122 // // Instead we use pexpr to prevent conflicts
4123 | ~o~pexpr yP_ORMINUSGT pexpr { }
4124 | ~o~pexpr yP_OREQGT pexpr { }
4125 //
4126 // // IEEE-2009: property_statement
4127 // // IEEE-2012: yIF and yCASE
4128 | property_statementCaseIf { }
4129 //
4130 | ~o~pexpr/*sexpr*/ yP_POUNDMINUSPD pexpr { }
4131 | ~o~pexpr/*sexpr*/ yP_POUNDEQPD pexpr { }
4132 | yNEXTTIME pexpr { }
4133 | yS_NEXTTIME pexpr { }
4134 | yNEXTTIME '[' expr/*const*/ ']' pexpr %prec yNEXTTIME { }
4135 | yS_NEXTTIME '[' expr/*const*/ ']' pexpr %prec yS_NEXTTIME { }
4136 | yALWAYS pexpr { }
4137 | yALWAYS '[' cycle_delay_const_range_expression ']' pexpr %prec yALWAYS { }
4138 | yS_ALWAYS '[' constant_range ']' pexpr %prec yS_ALWAYS { }
4139 | yS_EVENTUALLY pexpr { }
4140 | yEVENTUALLY '[' constant_range ']' pexpr %prec yEVENTUALLY { }
4141 | yS_EVENTUALLY '[' cycle_delay_const_range_expression ']' pexpr %prec yS_EVENTUALLY { }
4142 | ~o~pexpr yUNTIL pexpr { }
4143 | ~o~pexpr yS_UNTIL pexpr { }
4144 | ~o~pexpr yUNTIL_WITH pexpr { }
4145 | ~o~pexpr yS_UNTIL_WITH pexpr { }
4146 | ~o~pexpr yIMPLIES pexpr { }
4147 // // yIFF also used by event_expression
4148 | ~o~pexpr yIFF ~o~pexpr { }
4149 | yACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec yACCEPT_ON { }
4150 | yREJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec yREJECT_ON { }
4151 | ySYNC_ACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_ACCEPT_ON { }
4152 | ySYNC_REJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_REJECT_ON { }
4153 //
4154 // // IEEE: "property_instance"
4155 // // Looks just like a function/method call
4156 //
4157 // // Note "clocking_event pexpr" overlaps property_statement_spec: clocking_event property_statement
4158 //
4159 // // Include property_specDisable to match property_spec rule
4160 | clocking_event yDISABLE yIFF '(' expr ')' pexpr %prec prSEQ_CLOCKING { }
4161 //
4162 //============= sexpr rules copied for property_expr
4163 | BISONPRE_COPY_ONCE(sexpr,{s/~p~s/p/g; }) // {copied}
4164 //
4165 //============= expr rules copied for property_expr
4166 | BISONPRE_COPY_ONCE(expr,{s/~l~/p/g; s/~p~/p/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied}
4167 ;
4168
4169
4170 sexpr<str>: // ==IEEE: sequence_expr (The name sexpr is important as regexps just add an "s" to expr.)
4171 // // ********* RULES COPIED IN sequence_exprProp
4172 // // For precedence, see IEEE 17.7.1
4173 //
4174 // // IEEE: "cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
4175 // // IEEE: "sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
4176 // // Both rules basically mean we can repeat sequences, so make it simpler:
4177 cycle_delay_range sexpr %prec yP_POUNDPOUND { }
4178 | ~p~sexpr cycle_delay_range sexpr %prec prPOUNDPOUND_MULTI { }
4179 //
4180 // // IEEE: expression_or_dist [ boolean_abbrev ]
4181 // // Note expression_or_dist includes "expr"!
4182 // // sexpr/*sexpression_or_dist*/ --- Hardcoded below
4183 | ~p~sexpr/*sexpression_or_dist*/ boolean_abbrev { }
4184 //
4185 // // IEEE: "sequence_instance [ sequence_abbrev ]"
4186 // // version without sequence_abbrev looks just like normal function call
4187 // // version w/sequence_abbrev matches above; expression_or_dist:expr:func boolean_abbrev:sequence_abbrev
4188 //
4189 // // IEEE: '(' expression_or_dist {',' sequence_match_item } ')' [ boolean_abbrev ]
4190 // // IEEE: '(' sexpr {',' sequence_match_item } ')' [ sequence_abbrev ]
4191 // // As sequence_expr includes expression_or_dist, and boolean_abbrev includes sequence_abbrev:
4192 // // '(' sequence_expr {',' sequence_match_item } ')' [ boolean_abbrev ]
4193 // // "'(' sexpr ')' boolean_abbrev" matches "[sexpr:'(' expr ')'] boolean_abbrev" so we can simply drop it
4194 | '(' ~p~sexpr ')' { $<fl>$=$<fl>1; $$=$1+$2+$3; }
4195 | '(' ~p~sexpr ',' sequence_match_itemList ')' { }
4196 //
4197 // // AND/OR are between pexprs OR sexprs
4198 | ~p~sexpr yAND ~p~sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
4199 | ~p~sexpr yOR ~p~sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
4200 // // Intersect always has an sexpr rhs
4201 | ~p~sexpr yINTERSECT sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
4202 //
4203 | yFIRST_MATCH '(' sexpr ')' { }
4204 | yFIRST_MATCH '(' sexpr ',' sequence_match_itemList ')' { }
4205 | ~p~sexpr/*sexpression_or_dist*/ yTHROUGHOUT sexpr { }
4206 // // Below pexpr's are really sequence_expr, but avoid conflict
4207 // // IEEE: sexpr yWITHIN sexpr
4208 | ~p~sexpr yWITHIN sexpr { $<fl>$=$<fl>1; $$=$1+$2+$3; }
4209 // // Note concurrent_assertion had duplicate rule for below
4210 | clocking_event ~p~sexpr %prec prSEQ_CLOCKING { }
4211 //
4212 //============= expr rules copied for sequence_expr
4213 | BISONPRE_COPY_ONCE(expr,{s/~l~/s/g; s/~p~/s/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; }) // {copied}
4214 ;
4215
4216 cycle_delay_range: // IEEE: ==cycle_delay_range
4217 // // These three terms in 1800-2005 ONLY
4218 yP_POUNDPOUND yaINTNUM { }
4219 | yP_POUNDPOUND id { }
4220 | yP_POUNDPOUND '(' constExpr ')' { }
4221 // // In 1800-2009 ONLY:
4222 // // IEEE: yP_POUNDPOUND constant_primary
4223 // // UNSUP: This causes a big grammer ambiguity
4224 // // as ()'s mismatch between primary and the following statement
4225 // // the sv-ac committee has been asked to clarify (Mantis 1901)
4226 | yP_POUNDPOUND '[' cycle_delay_const_range_expression ']' { }
4227 | yP_POUNDPOUND yP_BRASTAR ']' { }
4228 | yP_POUNDPOUND yP_BRAPLUSKET { }
4229 ;
4230
4231 sequence_match_itemList: // IEEE: [sequence_match_item] part of sequence_expr
4232 sequence_match_item { }
4233 | sequence_match_itemList ',' sequence_match_item { }
4234 ;
4235
4236 sequence_match_item: // ==IEEE: sequence_match_item
4237 // // IEEE says: operator_assignment
4238 // // IEEE says: inc_or_dec_expression
4239 // // IEEE says: subroutine_call
4240 // // This is the same list as...
4241 for_step_assignment { }
4242 ;
4243
4244 boolean_abbrev: // ==IEEE: boolean_abbrev
4245 // // IEEE: consecutive_repetition
4246 yP_BRASTAR const_or_range_expression ']' { }
4247 | yP_BRASTAR ']' { }
4248 | yP_BRAPLUSKET { }
4249 // // IEEE: non_consecutive_repetition
4250 | yP_BRAEQ const_or_range_expression ']' { }
4251 // // IEEE: goto_repetition
4252 | yP_BRAMINUSGT const_or_range_expression ']' { }
4253 ;
4254
4255 const_or_range_expression: // ==IEEE: const_or_range_expression
4256 constExpr { }
4257 | cycle_delay_const_range_expression { }
4258 ;
4259
4260
4261 constant_range: // ==IEEE: constant_range
4262 constExpr ':' constExpr { }
4263 ;
4264
4265 cycle_delay_const_range_expression: // ==IEEE: cycle_delay_const_range_expression
4266 // // Note '$' is part of constExpr
4267 constExpr ':' constExpr { }
4268 ;
4269
4270 //************************************************
4271 // Let
4272
4273 let_declaration: // ==IEEE: let_declaration
4274 let_declarationFront let_port_listE '=' expr ';'
4275 { PARSEP->symPopScope(VAstType::LET); }
4276 ;
4277
4278 let_declarationFront: // IEEE: part of let_declaration
4279 yLET idAny/*let_identifier*/
4280 { PARSEP->symPushNew(VAstType::LET,$2); }
4281 ;
4282
4283 let_port_listE: // ==IEEE: let_port_list
4284 /* empty */
4285 // // IEEE: let_port_list
4286 // // No significant difference from task ports
4287 | '(' tf_port_listE ')'
4288 { VARRESET_NONLIST(""); }
4289 ;
4290
4291 //************************************************
4292 // Covergroup
4293
4294 covergroup_declaration: // ==IEEE: covergroup_declaration
4295 covergroup_declarationFront coverage_eventE ';' coverage_spec_or_optionListE
4296 yENDGROUP endLabelE
4297 { PARSEP->endgroupCb($<fl>5,$5);
4298 PARSEP->symPopScope(VAstType::COVERGROUP); }
4299 | covergroup_declarationFront '(' tf_port_listE ')' coverage_eventE ';' coverage_spec_or_optionListE
4300 yENDGROUP endLabelE
4301 { PARSEP->endgroupCb($<fl>8,$8);
4302 PARSEP->symPopScope(VAstType::COVERGROUP); }
4303 ;
4304
4305 covergroup_declarationFront: // IEEE: part of covergroup_declaration
4306 yCOVERGROUP idAny
4307 { PARSEP->symPushNew(VAstType::COVERGROUP,$2);
4308 PARSEP->covergroupCb($<fl>1,$1,$2); }
4309 ;
4310
4311 cgexpr<str>: // IEEE-2012: covergroup_expression, before that just expression
4312 expr { $<fl>$=$<fl>1; $$ = $1; }
4313 ;
4314
4315 coverage_spec_or_optionListE: // IEEE: [{coverage_spec_or_option}]
4316 /* empty */ { }
4317 | coverage_spec_or_optionList { }
4318 ;
4319
4320 coverage_spec_or_optionList: // IEEE: {coverage_spec_or_option}
4321 coverage_spec_or_option { }
4322 | coverage_spec_or_optionList coverage_spec_or_option { }
4323 ;
4324
4325 coverage_spec_or_option: // ==IEEE: coverage_spec_or_option
4326 // // IEEE: coverage_spec
4327 cover_point { }
4328 | cover_cross { }
4329 | coverage_option ';' { }
4330 | error { }
4331 ;
4332
4333 coverage_option: // ==IEEE: coverage_option
4334 // // option/type_option aren't really keywords
4335 id/*yOPTION | yTYPE_OPTION*/ '.' idAny/*member_identifier*/ '=' expr { }
4336 ;
4337
4338 cover_point: // ==IEEE: cover_point
4339 /**/ yCOVERPOINT expr iffE bins_or_empty { }
4340 // // IEEE-2012: class_scope before an ID
4341 | /**/ /**/ /**/ id ':' yCOVERPOINT expr iffE bins_or_empty { }
4342 | class_scope_id ':' yCOVERPOINT expr iffE bins_or_empty { }
4343 | class_scope_id id data_type id ':' yCOVERPOINT expr iffE bins_or_empty { }
4344 | class_scope_id id /**/ id ':' yCOVERPOINT expr iffE bins_or_empty { }
4345 | /**/ id /**/ id ':' yCOVERPOINT expr iffE bins_or_empty { }
4346 // // IEEE-2012:
4347 | bins_or_empty { }
4348 ;
4349
4350 iffE: // IEEE: part of cover_point, others
4351 /* empty */ { }
4352 | yIFF '(' expr ')' { }
4353 ;
4354
4355 bins_or_empty: // ==IEEE: bins_or_empty
4356 '{' bins_or_optionsList '}' { }
4357 | '{' '}' { }
4358 | ';' { }
4359 ;
4360
4361 bins_or_optionsList: // IEEE: { bins_or_options ';' }
4362 bins_or_options ';' { }
4363 | bins_or_optionsList bins_or_options ';' { }
4364 ;
4365
4366 bins_or_options: // ==IEEE: bins_or_options
4367 // // Superset of IEEE - we allow []'s in more places
4368 coverage_option { }
4369 // // Can't use wildcardE as results in conflicts
4370 | /**/ bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' iffE { }
4371 | yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' iffE { }
4372 | /**/ bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' yWITH__CUR '{' cgexpr ')' iffE { }
4373 | yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' yWITH__CUR '{' cgexpr ')' iffE { }
4374 //
4375 // // cgexpr part of trans_list
4376 //
4377 | /**/ bins_keyword id/*bin_identifier*/ bins_orBraE '=' trans_list iffE { }
4378 | yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' trans_list iffE { }
4379 //
4380 | bins_keyword id/*bin_identifier*/ bins_orBraE '=' yDEFAULT iffE { }
4381 //
4382 | bins_keyword id/*bin_identifier*/ bins_orBraE '=' yDEFAULT ySEQUENCE iffE { }
4383 ;
4384
4385 bins_orBraE: // IEEE: part of bins_or_options:
4386 /* empty */ { }
4387 | '[' ']' { }
4388 | '[' cgexpr ']' { }
4389 ;
4390
4391 bins_keyword: // ==IEEE: bins_keyword
4392 yBINS { }
4393 | yILLEGAL_BINS { }
4394 | yIGNORE_BINS { }
4395 ;
4396
4397 covergroup_range_list: // ==IEEE: covergroup_range_list
4398 covergroup_value_range { }
4399 | covergroup_range_list ',' covergroup_value_range { }
4400 ;
4401
4402 trans_list: // ==IEEE: trans_list
4403 '(' trans_set ')' { }
4404 | trans_list ',' '(' trans_set ')' { }
4405 ;
4406
4407 trans_set: // ==IEEE: trans_set
4408 trans_range_list { }
4409 // // Note the { => } in the grammer, this is really a list
4410 | trans_set yP_EQGT trans_range_list { }
4411 ;
4412
4413 trans_range_list: // ==IEEE: trans_range_list
4414 trans_item { }
4415 | trans_item yP_BRASTAR repeat_range ']' { }
4416 | trans_item yP_BRAMINUSGT repeat_range ']' { }
4417 | trans_item yP_BRAEQ repeat_range ']' { }
4418 ;
4419
4420 trans_item: // ==IEEE: range_list
4421 covergroup_range_list { }
4422 ;
4423
4424 repeat_range: // ==IEEE: repeat_range
4425 cgexpr { }
4426 | cgexpr ':' cgexpr { }
4427 ;
4428
4429 cover_cross: // ==IEEE: cover_cross
4430 id/*cover_point_identifier*/ ':' yCROSS list_of_cross_items iffE cross_body { }
4431 | /**/ yCROSS list_of_cross_items iffE cross_body { }
4432 ;
4433
4434 list_of_cross_items: // ==IEEE: list_of_cross_items
4435 cross_item ',' cross_item { }
4436 | cross_item ',' cross_item ',' cross_itemList { }
4437 ;
4438
4439 cross_itemList: // IEEE: part of list_of_cross_items
4440 cross_item
4441 | cross_itemList ',' cross_item { }
4442 ;
4443
4444 cross_item: // ==IEEE: cross_item
4445 idAny/*cover_point_identifier or variable_identifier*/ { }
4446 ;
4447
4448 cross_body: // ==IEEE: cross_body
4449 '{' '}' { }
4450 // // IEEE-2012: No semicolon here, mistake in spec
4451 | '{' cross_body_itemSemiList '}' { }
4452 | ';' { }
4453 ;
4454
4455 cross_body_itemSemiList: // IEEE: part of cross_body
4456 cross_body_item ';' { }
4457 | cross_body_itemSemiList cross_body_item ';' { }
4458 ;
4459
4460 cross_body_item: // ==IEEE: cross_body_item
4461 // // IEEE: our semicolon is in the list
4462 bins_selection_or_option { }
4463 | function_declaration { }
4464 ;
4465
4466 bins_selection_or_option: // ==IEEE: bins_selection_or_option
4467 coverage_option { }
4468 | bins_selection { }
4469 ;
4470
4471 bins_selection: // ==IEEE: bins_selection
4472 bins_keyword idAny/*new-bin_identifier*/ '=' select_expression iffE { }
4473 ;
4474
4475 select_expression: // ==IEEE: select_expression
4476 // // IEEE: select_condition expanded here
4477 yBINSOF '(' bins_expression ')' { }
4478 | yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}' { }
4479 | yWITH__PAREN '(' cgexpr ')' { }
4480 // // IEEE-2012: Need clarification as to precedence
4481 //UNSUP yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr { }
4482 | '!' yBINSOF '(' bins_expression ')' { }
4483 | '!' yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}' { }
4484 | '!' yWITH__PAREN '(' cgexpr ')' { }
4485 // // IEEE-2012: Need clarification as to precedence
4486 //UNSUP '!' yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr { }
4487 | select_expression yP_ANDAND select_expression { }
4488 | select_expression yP_OROR select_expression { }
4489 | '(' select_expression ')' { }
4490 // // IEEE-2012: cross_identifier
4491 // // Part of covergroup_expression - generic identifier
4492 // // IEEE-2012: Need clarification as to precedence
4493 //UNSUP covergroup_expression [ yMATCHES covergroup_expression ]
4494 ;
4495
4496 bins_expression: // ==IEEE: bins_expression
4497 // // "cover_point_identifier" and "variable_identifier" look identical
4498 id/*variable_identifier or cover_point_identifier*/ { }
4499 | id/*cover_point_identifier*/ '.' idAny/*bins_identifier*/ { }
4500 ;
4501
4502 coverage_eventE: // IEEE: [ coverage_event ]
4503 /* empty */ { }
4504 | clocking_event { }
4505 | yWITH__ETC function idAny/*"sample"*/ '(' tf_port_listE ')' { }
4506 | yP_ATAT '(' block_event_expression ')' { }
4507 ;
4508
4509 block_event_expression: // ==IEEE: block_event_expression
4510 block_event_expressionTerm { }
4511 | block_event_expression yOR block_event_expressionTerm { }
4512 ;
4513
4514 block_event_expressionTerm: // IEEE: part of block_event_expression
4515 yBEGIN hierarchical_btf_identifier { }
4516 | yEND hierarchical_btf_identifier { }
4517 ;
4518
4519 hierarchical_btf_identifier: // ==IEEE: hierarchical_btf_identifier
4520 // // hierarchical_tf_identifier + hierarchical_block_identifier
4521 hierarchical_identifier/*tf_or_block*/ { }
4522 // // method_identifier
4523 | hierarchical_identifier class_scope_id { }
4524 | hierarchical_identifier id { }
4525 ;
4526
4527 //**********************************************************************
4528 // Randsequence
4529
4530 randsequence_statement: // ==IEEE: randsequence_statement
4531 yRANDSEQUENCE '(' ')' productionList yENDSEQUENCE { }
4532 | yRANDSEQUENCE '(' id/*production_identifier*/ ')' productionList yENDSEQUENCE { }
4533 ;
4534
4535 productionList: // IEEE: production+
4536 production { }
4537 | productionList production { }
4538 ;
4539
4540 production: // ==IEEE: production
4541 productionFront ':' rs_ruleList ';' { }
4542 ;
4543
4544 productionFront: // IEEE: part of production
4545 function_data_type id/*production_identifier*/ { }
4546 | /**/ id/*production_identifier*/ { }
4547 | function_data_type id/*production_identifier*/ '(' tf_port_listE ')' { }
4548 | /**/ id/*production_identifier*/ '(' tf_port_listE ')' { }
4549 ;
4550
4551 rs_ruleList: // IEEE: rs_rule+ part of production
4552 rs_rule { }
4553 | rs_ruleList '|' rs_rule { }
4554 ;
4555
4556 rs_rule: // ==IEEE: rs_rule
4557 rs_production_list { }
4558 | rs_production_list yP_COLONEQ weight_specification { }
4559 | rs_production_list yP_COLONEQ weight_specification rs_code_block { }
4560 ;
4561
4562 rs_production_list: // ==IEEE: rs_production_list
4563 rs_prodList { }
4564 | yRAND yJOIN /**/ production_item production_itemList { }
4565 | yRAND yJOIN '(' expr ')' production_item production_itemList { }
4566 ;
4567
4568 weight_specification: // ==IEEE: weight_specification
4569 yaINTNUM { }
4570 | idClassSel/*ps_identifier*/ { }
4571 | '(' expr ')' { }
4572 ;
4573
4574 rs_code_block: // ==IEEE: rs_code_block
4575 '{' '}' { }
4576 | '{' rs_code_blockItemList '}' { }
4577 ;
4578
4579 rs_code_blockItemList: // IEEE: part of rs_code_block
4580 rs_code_blockItem { }
4581 | rs_code_blockItemList rs_code_blockItem { }
4582 ;
4583
4584 rs_code_blockItem: // IEEE: part of rs_code_block
4585 data_declaration { }
4586 | stmt { }
4587 ;
4588
4589 rs_prodList: // IEEE: rs_prod+
4590 rs_prod { }
4591 | rs_prodList rs_prod { }
4592 ;
4593
4594 rs_prod: // ==IEEE: rs_prod
4595 production_item { }
4596 | rs_code_block { }
4597 // // IEEE: rs_if_else
4598 | yIF '(' expr ')' production_item %prec prLOWER_THAN_ELSE { }
4599 | yIF '(' expr ')' production_item yELSE production_item { }
4600 // // IEEE: rs_repeat
4601 | yREPEAT '(' expr ')' production_item { }
4602 // // IEEE: rs_case
4603 | yCASE '(' expr ')' rs_case_itemList yENDCASE { }
4604 ;
4605
4606 production_itemList: // IEEE: production_item+
4607 production_item { }
4608 | production_itemList production_item { }
4609 ;
4610
4611 production_item: // ==IEEE: production_item
4612 id/*production_identifier*/ { }
4613 | id/*production_identifier*/ '(' list_of_argumentsE ')' { }
4614 ;
4615
4616 rs_case_itemList: // IEEE: rs_case_item+
4617 rs_case_item { }
4618 | rs_case_itemList rs_case_item { }
4619 ;
4620
4621 rs_case_item: // ==IEEE: rs_case_item
4622 caseCondList ':' production_item ';' { }
4623 | yDEFAULT production_item ';' { }
4624 | yDEFAULT ':' production_item ';' { }
4625 ;
4626
4627 //**********************************************************************
4628 // Checker
4629
4630 checker_declaration: // ==IEEE: part of checker_declaration
4631 checkerFront checker_port_listE ';'
4632 checker_or_generate_itemListE yENDCHECKER endLabelE
4633 { PARSEP->symPopScope(VAstType::CHECKER); }
4634 ;
4635
4636 checkerFront: // IEEE: part of checker_declaration
4637 yCHECKER idAny/*checker_identifier*/
4638 { PARSEP->symPushNew(VAstType::CHECKER, $2); }
4639 ;
4640
4641 checker_port_listE: // IEEE: [ ( [ checker_port_list ] ) ]
4642 // // checker_port_item is basically the same as property_port_item, minus yLOCAL::
4643 // // Want to bet 1800-2012 adds local to checkers?
4644 property_port_listE { }
4645 ;
4646
4647 checker_or_generate_itemListE: // IEEE: [{ checker_or_generate_itemList }]
4648 /* empty */ { }
4649 | checker_or_generate_itemList { }
4650 ;
4651
4652 checker_or_generate_itemList: // IEEE: { checker_or_generate_itemList }
4653 checker_or_generate_item { }
4654 | checker_or_generate_itemList checker_or_generate_item { }
4655 ;
4656
4657 checker_or_generate_item: // ==IEEE: checker_or_generate_item
4658 checker_or_generate_item_declaration { }
4659 | initial_construct { }
4660 // // IEEE: checker_construct
4661 | yALWAYS stmtBlock { }
4662 | final_construct { }
4663 | assertion_item { }
4664 | continuous_assign { }
4665 | checker_generate_item { }
4666 ;
4667
4668 checker_or_generate_item_declaration: // ==IEEE: checker_or_generate_item_declaration
4669 data_declaration { }
4670 | yRAND data_declaration { }
4671 | function_declaration { }
4672 | checker_declaration { }
4673 | assertion_item_declaration { }
4674 | covergroup_declaration { }
4675 | overload_declaration { }
4676 | genvar_declaration { }
4677 | clocking_declaration { }
4678 | yDEFAULT yCLOCKING id/*clocking_identifier*/ ';' { }
4679 | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { }
4680 | ';' { }
4681 ;
4682
4683 checker_generate_item: // ==IEEE: checker_generate_item
4684 // // Specialized for checker so need "c_" prefixes here
4685 c_loop_generate_construct { }
4686 | c_conditional_generate_construct { }
4687 | c_generate_region { }
4688 //
4689 | elaboration_system_task { }
4690 ;
4691
4692 checker_instantiation:
4693 // // Only used for procedural_assertion_item's
4694 // // Version in concurrent_assertion_item looks like etcInst
4695 // // Thus instead of *_checker_port_connection we can use etcInst's cellpinList
4696 id/*checker_identifier*/ id '(' cellpinList ')' ';' { }
4697 ;
4698
4699 //**********************************************************************
4700 // Class
4701
4702 class_declaration: // ==IEEE: part of class_declaration
4703 // // IEEE-2012: using this also for interface_class_declaration
4704 // // The classExtendsE rule relys on classFront having the
4705 // // new class scope correct via classFront
4706 classFront parameter_port_listE classExtendsE classImplementsE ';'
4707 class_itemListE yENDCLASS endLabelE
4708 { PARSEP->endclassCb($<fl>7,$7);
4709 PARSEP->symPopScope(VAstType::CLASS); }
4710 ;
4711
4712 classFront: // IEEE: part of class_declaration
4713 classVirtualE yCLASS lifetimeE idAny/*class_identifier*/
4714 { PARSEP->symPushNew(VAstType::CLASS, $4);
4715 PARSEP->classCb($<fl>2,$2,$4,$1); }
4716 // // IEEE: part of interface_class_declaration
4717 | yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/
4718 { PARSEP->symPushNew(VAstType::CLASS, $4);
4719 PARSEP->classCb($<fl>2,$2,$4,$1); }
4720 ;
4721
4722 classVirtualE<str>:
4723 /* empty */ { $$=""; }
4724 | yVIRTUAL__CLASS { $<fl>$=$<fl>1; $$=$1; }
4725 ;
4726
4727 classExtendsE: // IEEE: part of class_declaration
4728 // // The classExtendsE rule relys on classFront having the
4729 // // new class scope correct via classFront
4730 /* empty */ { }
4731 | yEXTENDS class_typeWithoutId { PARSEP->syms().import($<fl>1,$<str>2,$<scp>2,"*"); }
4732 | yEXTENDS class_typeWithoutId '(' list_of_argumentsE ')' { PARSEP->syms().import($<fl>1,$<str>2,$<scp>2,"*"); }
4733 ;
4734
4735 classImplementsE: // IEEE: part of class_declaration
4736 // // All 1800-2012
4737 /* empty */ { }
4738 | yIMPLEMENTS classImplementsList { PARSEP->syms().import($<fl>1,$<str>2,$<scp>2,"*"); }
4739 ;
4740
4741 classImplementsList: // IEEE: part of class_declaration
4742 // // All 1800-2012
4743 class_typeWithoutId { }
4744 | classImplementsList ',' class_typeWithoutId { }
4745 ;
4746
4747 //=========
4748 // Package scoping - to traverse the symbol table properly, the final identifer
4749 // must be included in the rules below.
4750 // Each of these must end with {symsPackageDone | symsClassDone}
4751
4752 ps_id_etc<str>: // package_scope + general id
4753 package_scopeIdFollowsE id { $<fl>$=$<fl>1; $$=$1+$2; }
4754 ;
4755
4756 class_scope_id<str_scp>: // class_scope + id etc
4757 class_scopeIdFollows id { $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1+$<str>2; }
4758 ;
4759
4760 //=== Below rules assume special scoping per above
4761
4762 class_typeWithoutId<str_scp>: // as with class_typeWithoutId but allow yaID__aTYPE
4763 // // and we thus don't need to resolve it in specified package
4764 package_scopeIdFollowsE class_typeOneList { $<fl>$=$<fl>2; $<scp>$=$<scp>2; $<str>$=$1+$<str>2; }
4765 ;
4766
4767 class_scopeWithoutId<str_scp>: // class_type standalone without following id
4768 // // and we thus don't need to resolve it in specified package
4769 class_scopeIdFollows { $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1; PARSEP->symTableNextId(NULL); }
4770 ;
4771
4772 class_scopeIdFollows<str_scp>: // IEEE: class_scope + type
4773 // // IEEE: "class_type yP_COLONCOLON"
4774 // // IMPORTANT: The lexer will parse the following ID to be in the found package
4775 // // But class_type:'::' conflicts with class_scope:'::' so expand here
4776 package_scopeIdFollowsE class_typeOneListColonIdFollows { $<fl>$=$<fl>2; $<scp>$=$<scp>2; $<str>$=$1+$<str>2; }
4777 ;
4778
4779 class_typeOneListColonIdFollows<str_scp>: // IEEE: class_type :: but allow yaID__aTYPE
4780 class_typeOneList yP_COLONCOLON { $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1+$<str>2; PARSEP->symTableNextId($<scp>1); }
4781 ;
4782
4783 class_typeOneList<str_scp>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
4784 // // If you follow the rules down, class_type is really a list via ps_class_identifier
4785 // // Must propagate scp up for next id
4786 class_typeOne { $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1; }
4787 | class_typeOneListColonIdFollows class_typeOne { $<fl>$=$<fl>1; $<scp>$=$<scp>2; $<str>$=$<str>1+$<str>2; }
4788 ;
4789
4790 class_typeOne<str_scp>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
4791 // // If you follow the rules down, class_type is really a list via ps_class_identifier
4792 // // Not listed in IEEE, but see bug627 any parameter type maybe a class
4793 yaID__aTYPE parameter_value_assignmentE
4794 { $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1; }
4795 ;
4796
4797 package_scopeIdFollowsE<str>: // IEEE: [package_scope]
4798 // // IMPORTANT: The lexer will parse the following ID to be in the found package
4799 /* empty */ { $$=""; }
4800 | package_scopeIdFollows { $<fl>$=$<fl>1; $$=$1; }
4801 ;
4802
4803 package_scopeIdFollows<str>: // IEEE: package_scope
4804 // // IMPORTANT: The lexer will parse the following ID to be in the found package
4805 // // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' | class_scope ]
4806 // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token
4807 yD_UNIT { PARSEP->symTableNextId(PARSEP->syms().netlistSymp()); }
4808 /*cont*/ yP_COLONCOLON { $<fl>$=$<fl>1; $<str>$=$<str>1+$<str>3; }
4809 | yaID__aPACKAGE { PARSEP->symTableNextId($<scp>1); }
4810 /*cont*/ yP_COLONCOLON { $<fl>$=$<fl>1; $<str>$=$<str>1+$<str>3; }
4811 | yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
4812 /*cont*/ yP_COLONCOLON { $<fl>$=$<fl>1; $<str>$=$<str>1+$<str>3; }
4813 ;
4814
4815 //^^^=========
4816
4817 class_itemListE:
4818 /* empty */ { }
4819 | class_itemList { }
4820 ;
4821
4822 class_itemList:
4823 class_item { }
4824 | class_itemList class_item { }
4825 ;
4826
4827 class_item: // ==IEEE: class_item
4828 class_property { }
4829 | class_method { }
4830 | class_constraint { }
4831 //
4832 | class_declaration { }
4833 | timeunits_declaration { }
4834 | covergroup_declaration { }
4835 | local_parameter_declaration ';' { } // 1800-2009
4836 | parameter_declaration ';' { } // 1800-2009
4837 | ';' { }
4838 //
4839 | error ';' { }
4840 ;
4841
4842 class_method: // ==IEEE: class_method
4843 memberQualResetListE task_declaration { }
4844 | memberQualResetListE function_declaration { }
4845 // // 1800-2009 adds yPURE yVIRTUAL, already in memberQualResetListE
4846 | yEXTERN memberQualResetListE method_prototype ';' { }
4847 // // IEEE: "method_qualifierE class_constructor_declaration"
4848 // // part of function_declaration
4849 | yEXTERN memberQualResetListE class_constructor_prototype { }
4850 ;
4851
4852 // IEEE: class_constructor_prototype
4853 // See function_declaration
4854
4855 class_item_qualifier<str>: // IEEE: class_item_qualifier minus ySTATIC
4856 // // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
4857 yPROTECTED { $<fl>$=$<fl>1; $$=$1; }
4858 | yLOCAL__ETC { $<fl>$=$<fl>1; $$=$1; }
4859 | ySTATIC__ETC { $<fl>$=$<fl>1; $$=$1; }
4860 ;
4861
4862 memberQualResetListE: // Called from class_property for all qualifiers before yVAR
4863 // // Also before method declarations, to prevent grammar conflict
4864 // // Thus both types of qualifiers (method/property) are here
4865 /*empty*/ { VARRESET(); VARDTYPE(""); }
4866 | memberQualList { VARRESET(); VARDTYPE($1); }
4867 ;
4868
4869 memberQualList<str>:
4870 memberQualOne { $<fl>$=$<fl>1; $$=$1; }
4871 | memberQualList memberQualOne { $<fl>$=$<fl>1; $$=SPACED($1,$2); }
4872 ;
4873
4874 memberQualOne<str>: // IEEE: property_qualifier + method_qualifier
4875 // // Part of method_qualifier and property_qualifier
4876 class_item_qualifier { $<fl>$=$<fl>1; $$=$1; }
4877 // // Part of method_qualifier only
4878 | yVIRTUAL__ETC { $<fl>$=$<fl>1; $$=$1; }
4879 // // IMPORTANT: lexer looks for yPURE yVIRTUAL
4880 | yPURE yVIRTUAL__ETC { $<fl>$=$<fl>1; $$=$1+" "+$2; }
4881 // // Part of property_qualifier only
4882 | random_qualifier { $<fl>$=$<fl>1; $$=$1; }
4883 // // Part of lifetime, but here as ySTATIC can be in different positions
4884 | yAUTOMATIC { $<fl>$=$<fl>1; $$=$1; }
4885 // // Part of data_declaration, but not in data_declarationVarFrontClass
4886 | yCONST__ETC { $<fl>$=$<fl>1; $$=$1; }
4887 ;
4888
4889 //**********************************************************************
4890 // Constraints
4891
4892 class_constraint: // ==IEEE: class_constraint
4893 // // IEEE: constraint_declaration
4894 constraintStaticE yCONSTRAINT idAny constraint_block { }
4895 // // IEEE: constraint_prototype + constraint_prototype_qualifier
4896 | constraintStaticE yCONSTRAINT idAny ';' { }
4897 | yEXTERN constraintStaticE yCONSTRAINT idAny ';' { }
4898 | yPURE constraintStaticE yCONSTRAINT idAny ';' { }
4899 ;
4900
4901 constraint_block: // ==IEEE: constraint_block
4902 '{' constraint_block_itemList '}' { }
4903 ;
4904
4905 constraint_block_itemList: // IEEE: { constraint_block_item }
4906 constraint_block_item { }
4907 | constraint_block_itemList constraint_block_item { }
4908 ;
4909
4910 constraint_block_item: // ==IEEE: constraint_block_item
4911 ySOLVE solve_before_list yBEFORE solve_before_list ';' { }
4912 | constraint_expression { }
4913 ;
4914
4915 solve_before_list: // ==IEEE: solve_before_list
4916 constraint_primary { }
4917 | solve_before_list ',' constraint_primary { }
4918 ;
4919
4920 constraint_primary: // ==IEEE: constraint_primary
4921 // // exprScope more general than: [ implicit_class_handle '.' | class_scope ] hierarchical_identifier select
4922 exprScope { }
4923 ;
4924
4925 constraint_expressionList<str>: // ==IEEE: { constraint_expression }
4926 constraint_expression { $$=$1; }
4927 | constraint_expressionList constraint_expression { $$=$1+" "+$2; }
4928 ;
4929
4930 constraint_expression<str>: // ==IEEE: constraint_expression
4931 expr/*expression_or_dist*/ ';' { $$=$1; }
4932 // // 1800-2012:
4933 | ySOFT expr/*expression_or_dist*/ ';' { $$="soft "+$1; }
4934 // // 1800-2012:
4935 // // IEEE: uniqueness_constraint ';'
4936 | yUNIQUE '{' open_range_list '}' { $$="unique {...}"; }
4937 // // IEEE: expr yP_MINUSGT constraint_set
4938 // // Conflicts with expr:"expr yP_MINUSGT expr"; rule moved there
4939 //
4940 | yIF '(' expr ')' constraint_set %prec prLOWER_THAN_ELSE { $$=$1; }
4941 | yIF '(' expr ')' constraint_set yELSE constraint_set { $$=$1;}
4942 // // IEEE says array_identifier here, but dotted accepted in VMM + 1800-2009
4943 | yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' constraint_set { $$=$1; }
4944 // // soft is 1800-2012
4945 | yDISABLE ySOFT expr/*constraint_primary*/ ';' { $$="disable soft "+$1; }
4946 ;
4947
4948 constraint_set<str>: // ==IEEE: constraint_set
4949 constraint_expression { $$=$1; }
4950 | '{' constraint_expressionList '}' { $$=$1+$2+$3; }
4951 ;
4952
4953 dist_list: // ==IEEE: dist_list
4954 dist_item { }
4955 | dist_list ',' dist_item { }
4956 ;
4957
4958 dist_item: // ==IEEE: dist_item + dist_weight
4959 value_range { }
4960 | value_range yP_COLONEQ expr { }
4961 | value_range yP_COLONDIV expr { }
4962 ;
4963
4964 extern_constraint_declaration: // ==IEEE: extern_constraint_declaration
4965 constraintStaticE yCONSTRAINT class_scope_id constraint_block { }
4966 ;
4967
4968 constraintStaticE: // IEEE: part of extern_constraint_declaration
4969 /* empty */ { }
4970 | ySTATIC__CONSTRAINT { }
4971 ;
4972
4973 //**********************************************************************
4974 %%
4975
4976 int VParseGrammar::parse() {
4977 s_grammarp = this;
4978 return VParseBisonparse();
4979 }
debug(int level)4980 void VParseGrammar::debug(int level) {
4981 VParseBisondebug = level;
4982 }
tokenName(int token)4983 const char* VParseGrammar::tokenName(int token) {
4984 #if YYDEBUG || YYERROR_VERBOSE
4985 if (token >= 255) {
4986 switch (token) {
4987 /*BISONPRE_TOKEN_NAMES*/
4988 default: return yytname[token-255];
4989 }
4990 } else {
4991 static char ch[2]; ch[0]=token; ch[1]='\0';
4992 return ch;
4993 }
4994 #else
4995 return "";
4996 #endif
4997 }
4998
4999 //YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead
5000 // --report=lookahead
5001 // --report=itemset
5002 // --graph
5003 //
5004 // Local Variables:
5005 // compile-command: "cd .. ; make -j 8 && make test"
5006 // End:
5007