Branch data Line data Source code
1 : : // -*- mode: C++; c-file-style: "cc-mode" -*-
2 : : //*************************************************************************
3 : : // DESCRIPTION: Verilator: Bison grammar file
4 : : //
5 : : // Code available from: https://verilator.org
6 : : //
7 : : //*************************************************************************
8 : : //
9 : : // This program is free software; you can redistribute it and/or modify it
10 : : // under the terms of either the GNU Lesser General Public License Version 3
11 : : // or the Perl Artistic License Version 2.0.
12 : : // SPDX-FileCopyrightText: 2003-2026 Wilson Snyder
13 : : // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
14 : : //
15 : : //*************************************************************************
16 : : // Original code here by Paul Wasson and Duane Galbi
17 : : //*************************************************************************
18 : : // clang-format off
19 : :
20 : : %{
21 : : #ifdef NEVER_JUST_FOR_CLANG_FORMAT
22 : : }
23 : : #endif
24 : : // clang-format on
25 : : #include "V3ParseGrammar.h" // Defines YYTYPE; before including bison header
26 : :
27 : : #define YYERROR_VERBOSE 1 // For prior to Bison 3.6
28 : : #define YYINITDEPTH 10000 // Older bisons ignore YYMAXDEPTH
29 : : #define YYMAXDEPTH 10000
30 : : #define YYNEWLINE "\n"
31 : :
32 : : // Pick up new lexer
33 : : #define yylex PARSEP->tokenToBison
34 : :
35 : : #define BBCOVERIGN(fl, msg) (fl)->v3warn(COVERIGN, msg)
36 : : #define BBUNSUP(fl, msg) (fl)->v3warn(E_UNSUPPORTED, msg)
37 : : #define GATEUNSUP(fl, tok) \
38 : : { BBUNSUP((fl), "Unsupported: Verilog 1995 gate primitive: " << (tok)); }
39 : : #define RISEFALLDLYUNSUP(nodep) \
40 : : if (nodep->fileline()->timingOn() && v3Global.opt.timing().isSetTrue()) { \
41 : : nodep->v3warn(RISEFALLDLY, "Unsupported: turn-off delays. Ignoring the third delay"); \
42 : : }
43 : : #define MINTYPMAXDLYUNSUP(nodep) \
44 : : if (nodep->fileline()->timingOn() && v3Global.opt.timing().isSetTrue()) { \
45 : : nodep->v3warn( \
46 : : MINTYPMAXDLY, \
47 : : "Unsupported: minimum/typical/maximum delay expressions. Using the typical delay"); \
48 : : }
49 : : // Apply a delay to all continuous assignments under listp
50 : : static void DELAY_LIST(AstNode* listp, AstDelay* delayp) {
51 : : if (!delayp) return;
52 : : for (AstNode* nodep = listp; nodep; nodep = nodep->nextp()) {
53 : : if (VN_IS(nodep, Implicit)) continue;
54 : : AstAlways* const alwaysp = VN_AS(nodep, Always);
55 : : AstAssignW* const assignp = VN_AS(alwaysp->stmtsp(), AssignW);
56 : : assignp->timingControlp(delayp->backp() ? delayp->cloneTree(false) : delayp);
57 : : }
58 : : }
59 : : // Apply a strength to all continuous assignments under listp
60 : : static void STRENGTH_LIST(AstNode* listp, AstStrengthSpec* specp) {
61 : : if (!specp) return;
62 : : for (AstNode* nodep = listp; nodep; nodep = nodep->nextp()) {
63 : : if (VN_IS(nodep, Implicit)) continue;
64 : : AstAlways* const alwaysp = VN_AS(nodep, Always);
65 : : AstAssignW* const assignp = VN_AS(alwaysp->stmtsp(), AssignW);
66 : : assignp->strengthSpecp(specp->backp() ? specp->cloneTree(false) : specp);
67 : : }
68 : : }
69 : : static void STRENGTHUNSUP(AstStrengthSpec* nodep) {
70 : : if (!nodep) return;
71 : : BBUNSUP((nodep->fileline()), "Unsupported: Strength specifier on this gate type");
72 : : nodep->deleteTree();
73 : : }
74 : :
75 : : //======================================================================
76 : : // Statics (for here only)
77 : :
78 : : #define PARSEP V3ParseImp::parsep()
79 : : #define GRAMMARP V3ParseGrammar::singletonp()
80 : :
81 : : const VBasicDTypeKwd LOGIC = VBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
82 : : const VBasicDTypeKwd LOGIC_IMPLICIT = VBasicDTypeKwd::LOGIC_IMPLICIT;
83 : :
84 : : //======================================================================
85 : : // Macro functions
86 : :
87 : : // Only use in empty rules, so lines point at beginnings
88 : : #define CRELINE() (PARSEP->bisonLastFileline()->copyOrSameFileLineApplied())
89 : : #define FILELINE_OR_CRE(nodep) ((nodep) ? (nodep)->fileline() : CRELINE())
90 : :
91 : : #define VARRESET_LIST(decl) VARRESET__PVT(decl, 1) // Start of pinlist
92 : : #define VARRESET_NONLIST(decl) VARRESET__PVT(decl, 0); // Not in a pinlist
93 : : #define VARRESET__PVT(decl, pinNumStart) \
94 : : { \
95 : : VARDECL(decl); \
96 : : VARIO(NONE); \
97 : : VARDTYPE_NDECL(nullptr); \
98 : : GRAMMARP->m_pinNum = (pinNumStart); \
99 : : GRAMMARP->m_varLifetime = VLifetime::NONE; \
100 : : GRAMMARP->m_varDeclTyped = false; \
101 : : }
102 : : #define VARDECL(type) \
103 : : { GRAMMARP->m_varDecl = VVarType::type; }
104 : : #define VARIO(type) \
105 : : { GRAMMARP->m_varIO = VDirection::type; }
106 : : // Set direction to default-input when detect inside an ANSI port list
107 : : #define VARIOANSI() \
108 : : { \
109 : : if (GRAMMARP->m_varIO == VDirection::NONE) VARIO(INPUT); \
110 : : }
111 : : #define VARLIFE(flag) \
112 : : { GRAMMARP->m_varLifetime = flag; }
113 : : #define VARDTYPE(dtypep) \
114 : : { \
115 : : GRAMMARP->setDType(dtypep); \
116 : : GRAMMARP->m_varDeclTyped = true; \
117 : : }
118 : : #define VARDTYPE_NDECL(dtypep) \
119 : : { GRAMMARP->setDType(dtypep); } // Port that is range or signed only (not a decl)
120 : :
121 : : #define VARDONEA(fl, name, array, attrs) GRAMMARP->createVariable((fl), (name), (array), (attrs))
122 : : #define VARDONEP(portp, array, attrs) \
123 : : GRAMMARP->createVariable((portp)->fileline(), (portp)->name(), (array), (attrs))
124 : : #define PINNUMINC() (GRAMMARP->m_pinNum++)
125 : :
126 : : #define GATERANGE(rangep) \
127 : : { GRAMMARP->m_gateRangep = rangep; }
128 : :
129 : : #define INSTPREP(modfl, modname, paramsp) \
130 : : { \
131 : : GRAMMARP->m_impliedDecl = true; \
132 : : GRAMMARP->m_instModuleFl = modfl; \
133 : : GRAMMARP->m_instModule = modname; \
134 : : GRAMMARP->m_instParamp = paramsp; \
135 : : }
136 : :
137 : : #define DEL(...) \
138 : : { \
139 : : /* cppcheck-suppress constVariable */ \
140 : : AstNode* const nodeps[] = {__VA_ARGS__}; \
141 : : for (AstNode* const nodep : nodeps) \
142 : : if (nodep) nodep->deleteTree(); \
143 : : }
144 : :
145 : : static void ERRSVKWD(FileLine* fileline, const string& tokname) {
146 : : static int s_toldonce = 0;
147 : : fileline->v3error(
148 : : "Unexpected '"s + tokname + "': '" + tokname
149 : : + "' is a SystemVerilog keyword misused as an identifier."
150 : : + (!s_toldonce++ ? "\n" + fileline->warnMore()
151 : : + "... Suggest modify the Verilog-2001 code to avoid SV keywords,"
152 : : + " or use `begin_keywords or --language."
153 : : : ""));
154 : : }
155 : :
156 : : static void ASSIGNEQEXPR(FileLine* fileline) {
157 : : fileline->v3warn(ASSIGNEQEXPR,
158 : : "Assignment '=' inside expression\n"
159 : : << fileline->warnMore()
160 : : << "... Was a '==' intended, or suggest use a separate statement");
161 : : }
162 : :
163 : : static void UNSUPREAL(FileLine* fileline) {
164 : : fileline->v3warn(SHORTREAL,
165 : : "Unsupported: shortreal being promoted to real (suggest use real instead)");
166 : : }
167 : :
168 : : //======================================================================
169 : :
170 : : void yyerror(const char* errmsg) { PARSEP->bisonLastFileline()->v3error(errmsg); }
171 : :
172 : : template <typename T_Node, typename T_Next>
173 : : static T_Node* addNextNull(T_Node* nodep, T_Next* nextp) {
174 : : return AstNode::addNextNull<T_Node, T_Next>(nodep, nextp);
175 : : }
176 : :
177 : : //======================================================================
178 : :
179 : : class AstSenTree;
180 : : // clang-format off
181 : : %}
182 : :
183 : : // Bison 3.0 and newer
184 : : BISONPRE_VERSION(3.0,%define parse.error verbose)
185 : :
186 : : // We run bison with the -d argument. This tells it to generate a
187 : : // header file with token names. Old versions of bison pasted the
188 : : // contents of that file into the generated source as well; newer
189 : : // versions just include it.
190 : : //
191 : : // Since we run bison through ../bisonpre, it doesn't know the correct
192 : : // header file name, so we need to tell it.
193 : : BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
194 : :
195 : : // When writing Bison patterns we use yTOKEN instead of "token",
196 : : // so Bison will error out on unknown "token"s.
197 : :
198 : : // Generic lexer tokens, for example a number
199 : : // IEEE: real_number
200 : : %token<cdouble> yaFLOATNUM "FLOATING-POINT NUMBER"
201 : :
202 : : // IEEE: identifier, class_identifier, class_variable_identifier,
203 : : // covergroup_variable_identifier, dynamic_array_variable_identifier,
204 : : // enum_identifier, interface_identifier, interface_instance_identifier,
205 : : // package_identifier, type_identifier, variable_identifier,
206 : : %token<strp> yaID__ETC "IDENTIFIER"
207 : : %token<strp> yaID__CC "IDENTIFIER-::"
208 : : %token<strp> yaID__LEX "IDENTIFIER-in-lex"
209 : : %token<strp> yaID__PATHPULSE "IDENTIFIER-for-pathpulse"
210 : : %token<strp> yaID__aINST "IDENTIFIER-for-instance"
211 : : %token<strp> yaID__aTYPE "IDENTIFIER-for-type"
212 : : // Can't predecode aFUNCTION, can declare after use
213 : : // Can't predecode aINTERFACE, can declare after use
214 : : // Can't predecode aTASK, can declare after use
215 : :
216 : : // IEEE: integral_number
217 : : %token<nump> yaINTNUM "INTEGER NUMBER"
218 : : // IEEE: time_literal + time_unit
219 : : %token<cdouble> yaTIMENUM "TIME NUMBER"
220 : : // IEEE: string_literal
221 : : %token<strp> yaSTRING "STRING"
222 : : %token<strp> yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed
223 : : // IEEE: edge_descriptor
224 : : %token<nump> yaEDGEDESC "EDGE DESCRIPTOR"
225 : :
226 : : %token<fl> yaTIMINGSPEC "TIMING SPEC ELEMENT"
227 : :
228 : : %token<fl> ygenSTRENGTH "STRENGTH keyword (strong1/etc)"
229 : :
230 : : %token<strp> yaTABLE_FIELD "UDP table field"
231 : : %token<fl> yaTABLE_LRSEP ":"
232 : : %token<fl> yaTABLE_LINEEND "UDP table line end"
233 : :
234 : : %token<strp> yaSCCTOR "`systemc_ctor block"
235 : : %token<strp> yaSCDTOR "`systemc_dtor block"
236 : : %token<strp> yaSCHDR "`systemc_header block"
237 : : %token<strp> yaSCHDRP "`systemc_header_post block"
238 : : %token<strp> yaSCIMP "`systemc_implementation block"
239 : : %token<strp> yaSCIMPH "`systemc_imp_header block"
240 : : %token<strp> yaSCINT "`systemc_interface block"
241 : :
242 : : %token<fl> yVLT_CLOCKER "clocker"
243 : : %token<fl> yVLT_CLOCK_ENABLE "clock_enable"
244 : : %token<fl> yVLT_COVERAGE_BLOCK_OFF "coverage_block_off"
245 : : %token<fl> yVLT_COVERAGE_OFF "coverage_off"
246 : : %token<fl> yVLT_COVERAGE_ON "coverage_on"
247 : : %token<fl> yVLT_FORCEABLE "forceable"
248 : : %token<fl> yVLT_FULL_CASE "full_case"
249 : : %token<fl> yVLT_HIER_BLOCK "hier_block"
250 : : %token<fl> yVLT_HIER_PARAMS "hier_params"
251 : : %token<fl> yVLT_HIER_WORKERS "hier_workers"
252 : : %token<fl> yVLT_INLINE "inline"
253 : : %token<fl> yVLT_ISOLATE_ASSIGNMENTS "isolate_assignments"
254 : : %token<fl> yVLT_LINT_OFF "lint_off"
255 : : %token<fl> yVLT_LINT_ON "lint_on"
256 : : %token<fl> yVLT_NO_CLOCKER "no_clocker"
257 : : %token<fl> yVLT_NO_INLINE "no_inline"
258 : : %token<fl> yVLT_PARALLEL_CASE "parallel_case"
259 : : %token<fl> yVLT_PROFILE_DATA "profile_data"
260 : : %token<fl> yVLT_PUBLIC "public"
261 : : %token<fl> yVLT_PUBLIC_FLAT "public_flat"
262 : : %token<fl> yVLT_PUBLIC_FLAT_RD "public_flat_rd"
263 : : %token<fl> yVLT_PUBLIC_FLAT_RW "public_flat_rw"
264 : : %token<fl> yVLT_PUBLIC_MODULE "public_module"
265 : : %token<fl> yVLT_SC_BIGUINT "sc_biguint"
266 : : %token<fl> yVLT_SC_BV "sc_bv"
267 : : %token<fl> yVLT_SFORMAT "sformat"
268 : : %token<fl> yVLT_SPLIT_VAR "split_var"
269 : : %token<fl> yVLT_TIMING_OFF "timing_off"
270 : : %token<fl> yVLT_TIMING_ON "timing_on"
271 : : %token<fl> yVLT_TRACING_OFF "tracing_off"
272 : : %token<fl> yVLT_TRACING_ON "tracing_on"
273 : : %token<fl> yVLT_VERILATOR_LIB "verilator_lib"
274 : :
275 : : %token<fl> yVLT_D_BLOCK "--block"
276 : : %token<fl> yVLT_D_CONTENTS "--contents"
277 : : %token<fl> yVLT_D_COST "--cost"
278 : : %token<fl> yVLT_D_FILE "--file"
279 : : %token<fl> yVLT_D_FUNCTION "--function"
280 : : %token<fl> yVLT_D_HIER_DPI "--hier-dpi"
281 : : %token<fl> yVLT_D_LEVELS "--levels"
282 : : %token<fl> yVLT_D_LINES "--lines"
283 : : %token<fl> yVLT_D_MATCH "--match"
284 : : %token<fl> yVLT_D_MODEL "--model"
285 : : %token<fl> yVLT_D_MODULE "--module"
286 : : %token<fl> yVLT_D_MTASK "--mtask"
287 : : %token<fl> yVLT_D_PARAM "--param"
288 : : %token<fl> yVLT_D_PORT "--port"
289 : : %token<fl> yVLT_D_RULE "--rule"
290 : : %token<fl> yVLT_D_SCOPE "--scope"
291 : : %token<fl> yVLT_D_TASK "--task"
292 : : %token<fl> yVLT_D_VAR "--var"
293 : : %token<fl> yVLT_D_WORKERS "--workers"
294 : :
295 : : %token<strp> yaD_PLI "${pli-system}"
296 : :
297 : : %token<fl> yaT_NOUNCONNECTED "`nounconnecteddrive"
298 : : %token<fl> yaT_RESETALL "`resetall"
299 : : %token<fl> yaT_UNCONNECTED_PULL0 "`unconnected_drive pull0"
300 : : %token<fl> yaT_UNCONNECTED_PULL1 "`unconnected_drive pull1"
301 : :
302 : : // <fl> is the fileline, abbreviated to shorten "$<fl>1" references
303 : : %token<fl> '!'
304 : : %token<fl> '#'
305 : : %token<fl> '%'
306 : : %token<fl> '&'
307 : : %token<fl> '(' // See also yP_PAR__STRENGTH
308 : : %token<fl> ')'
309 : : %token<fl> '*'
310 : : %token<fl> '+'
311 : : %token<fl> ','
312 : : %token<fl> '-'
313 : : %token<fl> '.'
314 : : %token<fl> '/'
315 : : %token<fl> ':' // See also yP_COLON__BEGIN or yP_COLON__FORK
316 : : %token<fl> ';'
317 : : %token<fl> '<'
318 : : %token<fl> '=' // See also yP_EQ__NEW
319 : : %token<fl> '>'
320 : : %token<fl> '?'
321 : : %token<fl> '@'
322 : : %token<fl> '['
323 : : %token<fl> ']'
324 : : %token<fl> '^'
325 : : %token<fl> '{'
326 : : %token<fl> '|'
327 : : %token<fl> '}'
328 : : %token<fl> '~'
329 : :
330 : : // Specific keywords
331 : : // yKEYWORD means match "keyword"
332 : : // Other cases are yXX_KEYWORD where XX makes it unique,
333 : : // for example yP_ for punctuation based operators.
334 : : // Double underscores "yX__Y" means token X followed by Y,
335 : : // and "yX__ETC" means X folled by everything but Y(s).
336 : : %token<fl> y1STEP "1step"
337 : : %token<fl> yACCEPT_ON "accept_on"
338 : : %token<fl> yALIAS "alias"
339 : : %token<fl> yALWAYS "always"
340 : : %token<fl> yALWAYS_COMB "always_comb"
341 : : %token<fl> yALWAYS_FF "always_ff"
342 : : %token<fl> yALWAYS_LATCH "always_latch"
343 : : %token<fl> yAND "and"
344 : : %token<fl> yASSERT "assert"
345 : : %token<fl> yASSIGN "assign"
346 : : %token<fl> yASSUME "assume"
347 : : %token<fl> yAUTOMATIC "automatic"
348 : : %token<fl> yBEFORE "before"
349 : : %token<fl> yBEGIN "begin"
350 : : %token<fl> yBIND "bind"
351 : : %token<fl> yBINS "bins"
352 : : %token<fl> yBINSOF "binsof"
353 : : %token<fl> yBIT "bit"
354 : : %token<fl> yBREAK "break"
355 : : %token<fl> yBUF "buf"
356 : : %token<fl> yBUFIF0 "bufif0"
357 : : %token<fl> yBUFIF1 "bufif1"
358 : : %token<fl> yBYTE "byte"
359 : : %token<fl> yCASE "case"
360 : : %token<fl> yCASEX "casex"
361 : : %token<fl> yCASEZ "casez"
362 : : %token<fl> yCELL "cell"
363 : : %token<fl> yCHANDLE "chandle"
364 : : %token<fl> yCHECKER "checker"
365 : : %token<fl> yCLASS "class"
366 : : %token<fl> yCLOCKING "clocking"
367 : : %token<fl> yCMOS "cmos"
368 : : %token<fl> yCONFIG "config"
369 : : %token<fl> yCONSTRAINT "constraint"
370 : : %token<fl> yCONST__ETC "const"
371 : : %token<fl> yCONST__LEX "const-in-lex"
372 : : %token<fl> yCONST__REF "const-then-ref"
373 : : %token<fl> yCONTEXT "context"
374 : : %token<fl> yCONTINUE "continue"
375 : : %token<fl> yCOVER "cover"
376 : : %token<fl> yCOVERGROUP "covergroup"
377 : : %token<fl> yCOVERPOINT "coverpoint"
378 : : %token<fl> yCROSS "cross"
379 : : %token<fl> yDEASSIGN "deassign"
380 : : %token<fl> yDEFAULT "default"
381 : : %token<fl> yDEFPARAM "defparam"
382 : : %token<fl> yDESIGN "design"
383 : : %token<fl> yDISABLE "disable"
384 : : %token<fl> yDIST "dist"
385 : : %token<fl> yDO "do"
386 : : %token<fl> yEDGE "edge"
387 : : %token<fl> yELSE "else"
388 : : %token<fl> yEND "end"
389 : : %token<fl> yENDCASE "endcase"
390 : : %token<fl> yENDCHECKER "endchecker"
391 : : %token<fl> yENDCLASS "endclass"
392 : : %token<fl> yENDCLOCKING "endclocking"
393 : : %token<fl> yENDCONFIG "endconfig"
394 : : %token<fl> yENDFUNCTION "endfunction"
395 : : %token<fl> yENDGENERATE "endgenerate"
396 : : %token<fl> yENDGROUP "endgroup"
397 : : %token<fl> yENDINTERFACE "endinterface"
398 : : %token<fl> yENDMODULE "endmodule"
399 : : %token<fl> yENDPACKAGE "endpackage"
400 : : %token<fl> yENDPRIMITIVE "endprimitive"
401 : : %token<fl> yENDPROGRAM "endprogram"
402 : : %token<fl> yENDPROPERTY "endproperty"
403 : : %token<fl> yENDSEQUENCE "endsequence"
404 : : %token<fl> yENDSPECIFY "endspecify"
405 : : %token<fl> yENDTABLE "endtable"
406 : : %token<fl> yENDTASK "endtask"
407 : : %token<fl> yENUM "enum"
408 : : %token<fl> yEVENT "event"
409 : : %token<fl> yEVENTUALLY "eventually"
410 : : %token<fl> yEXPECT "expect"
411 : : %token<fl> yEXPORT "export"
412 : : %token<fl> yEXTENDS "extends"
413 : : %token<fl> yEXTERN "extern"
414 : : %token<fl> yFINAL "final"
415 : : %token<fl> yFIRST_MATCH "first_match"
416 : : %token<fl> yFOR "for"
417 : : %token<fl> yFORCE "force"
418 : : %token<fl> yFOREACH "foreach"
419 : : %token<fl> yFOREVER "forever"
420 : : %token<fl> yFORK "fork"
421 : : %token<fl> yFORKJOIN "forkjoin"
422 : : %token<fl> yFUNCTION "function"
423 : : %token<fl> yGENERATE "generate"
424 : : %token<fl> yGENVAR "genvar"
425 : : %token<fl> yGLOBAL__CLOCKING "global-then-clocking"
426 : : %token<fl> yGLOBAL__ETC "global"
427 : : %token<fl> yGLOBAL__LEX "global-in-lex"
428 : : %token<fl> yHIGHZ0 "highz0"
429 : : %token<fl> yHIGHZ1 "highz1"
430 : : %token<fl> yIF "if"
431 : : %token<fl> yIFF "iff"
432 : : %token<fl> yIGNORE_BINS "ignore_bins"
433 : : %token<fl> yILLEGAL_BINS "illegal_bins"
434 : : %token<fl> yIMPLEMENTS "implements"
435 : : %token<fl> yIMPLIES "implies"
436 : : %token<fl> yIMPORT "import"
437 : : %token<fl> yINCDIR "incdir"
438 : : %token<fl> yINCLUDE "include"
439 : : %token<fl> yINITIAL "initial"
440 : : %token<fl> yINOUT "inout"
441 : : %token<fl> yINPUT "input"
442 : : %token<fl> yINSIDE "inside"
443 : : %token<fl> yINSTANCE "instance"
444 : : %token<fl> yINT "int"
445 : : %token<fl> yINTEGER "integer"
446 : : %token<fl> yINTERCONNECT "interconnect"
447 : : %token<fl> yINTERFACE "interface"
448 : : %token<fl> yINTERSECT "intersect"
449 : : %token<fl> yJOIN "join"
450 : : %token<fl> yJOIN_ANY "join_any"
451 : : %token<fl> yJOIN_NONE "join_none"
452 : : %token<fl> yLET "let"
453 : : %token<fl> yLIBLIST "liblist"
454 : : %token<fl> yLIBRARY "library"
455 : : %token<fl> yLOCALPARAM "localparam"
456 : : %token<fl> yLOCAL__COLONCOLON "local-then-::"
457 : : %token<fl> yLOCAL__ETC "local"
458 : : %token<fl> yLOCAL__LEX "local-in-lex"
459 : : %token<fl> yLOGIC "logic"
460 : : %token<fl> yLONGINT "longint"
461 : : %token<fl> yMATCHES "matches"
462 : : %token<fl> yMODPORT "modport"
463 : : %token<fl> yMODULE "module"
464 : : %token<fl> yNAND "nand"
465 : : %token<fl> yNEGEDGE "negedge"
466 : : %token<fl> yNETTYPE "nettype"
467 : : %token<fl> yNEW__ETC "new"
468 : : %token<fl> yNEW__LEX "new-in-lex"
469 : : %token<fl> yNEW__PAREN "new-then-paren"
470 : : %token<fl> yNEXTTIME "nexttime"
471 : : %token<fl> yNMOS "nmos"
472 : : %token<fl> yNOR "nor"
473 : : %token<fl> yNOT "not"
474 : : %token<fl> yNOTIF0 "notif0"
475 : : %token<fl> yNOTIF1 "notif1"
476 : : %token<fl> yNULL "null"
477 : : %token<fl> yOR "or"
478 : : %token<fl> yOUTPUT "output"
479 : : %token<fl> yPACKAGE "package"
480 : : %token<fl> yPACKED "packed"
481 : : %token<fl> yPARAMETER "parameter"
482 : : %token<fl> yPMOS "pmos"
483 : : %token<fl> yPOSEDGE "posedge"
484 : : %token<fl> yPRIMITIVE "primitive"
485 : : %token<fl> yPRIORITY "priority"
486 : : %token<fl> yPROGRAM "program"
487 : : %token<fl> yPROPERTY "property"
488 : : %token<fl> yPROTECTED "protected"
489 : : %token<fl> yPULL0 "pull0"
490 : : %token<fl> yPULL1 "pull1"
491 : : %token<fl> yPULLDOWN "pulldown"
492 : : %token<fl> yPULLUP "pullup"
493 : : %token<fl> yPURE "pure"
494 : : %token<fl> yRAND "rand"
495 : : %token<fl> yRANDC "randc"
496 : : %token<fl> yRANDCASE "randcase"
497 : : %token<fl> yRANDOMIZE "randomize"
498 : : %token<fl> yRANDSEQUENCE "randsequence"
499 : : %token<fl> yRCMOS "rcmos"
500 : : %token<fl> yREAL "real"
501 : : %token<fl> yREALTIME "realtime"
502 : : %token<fl> yREF "ref"
503 : : %token<fl> yREG "reg"
504 : : %token<fl> yREJECT_ON "reject_on"
505 : : %token<fl> yRELEASE "release"
506 : : %token<fl> yREPEAT "repeat"
507 : : %token<fl> yRESTRICT "restrict"
508 : : %token<fl> yRETURN "return"
509 : : %token<fl> yRNMOS "rnmos"
510 : : %token<fl> yRPMOS "rpmos"
511 : : %token<fl> yRTRAN "rtran"
512 : : %token<fl> yRTRANIF0 "rtranif0"
513 : : %token<fl> yRTRANIF1 "rtranif1"
514 : : %token<fl> ySCALARED "scalared"
515 : : %token<fl> ySEQUENCE "sequence"
516 : : %token<fl> ySHORTINT "shortint"
517 : : %token<fl> ySHORTREAL "shortreal"
518 : : %token<fl> ySIGNED "signed"
519 : : %token<fl> ySOFT "soft"
520 : : %token<fl> ySOLVE "solve"
521 : : %token<fl> ySPECIFY "specify"
522 : : %token<fl> ySPECPARAM "specparam"
523 : : %token<fl> ySTATIC__CONSTRAINT "static-then-constraint"
524 : : %token<fl> ySTATIC__ETC "static"
525 : : %token<fl> ySTATIC__LEX "static-in-lex"
526 : : %token<fl> ySTRING "string"
527 : : %token<fl> ySTRONG "strong"
528 : : %token<fl> ySTRONG0 "strong0"
529 : : %token<fl> ySTRONG1 "strong1"
530 : : %token<fl> ySTRUCT "struct"
531 : : %token<fl> ySUPER "super"
532 : : %token<fl> ySUPPLY0 "supply0"
533 : : %token<fl> ySUPPLY1 "supply1"
534 : : %token<fl> ySYNC_ACCEPT_ON "sync_accept_on"
535 : : %token<fl> ySYNC_REJECT_ON "sync_reject_on"
536 : : %token<fl> yS_ALWAYS "s_always"
537 : : %token<fl> yS_EVENTUALLY "s_eventually"
538 : : %token<fl> yS_NEXTTIME "s_nexttime"
539 : : %token<fl> yS_UNTIL "s_until"
540 : : %token<fl> yS_UNTIL_WITH "s_until_with"
541 : : %token<fl> yTABLE "table"
542 : : %token<fl> yTAGGED "tagged"
543 : : %token<fl> yTAGGED__LEX "tagged-in-lex"
544 : : %token<fl> yTAGGED__NONPRIMARY "tagged-nonprimary"
545 : : %token<fl> yTASK "task"
546 : : %token<fl> yTHIS "this"
547 : : %token<fl> yTHROUGHOUT "throughout"
548 : : %token<fl> yTIME "time"
549 : : %token<fl> yTIMEPRECISION "timeprecision"
550 : : %token<fl> yTIMEUNIT "timeunit"
551 : : %token<fl> yTRAN "tran"
552 : : %token<fl> yTRANIF0 "tranif0"
553 : : %token<fl> yTRANIF1 "tranif1"
554 : : %token<fl> yTRI "tri"
555 : : %token<fl> yTRI0 "tri0"
556 : : %token<fl> yTRI1 "tri1"
557 : : %token<fl> yTRIAND "triand"
558 : : %token<fl> yTRIOR "trior"
559 : : %token<fl> yTRIREG "trireg"
560 : : %token<fl> yTRUE "true"
561 : : %token<fl> yTYPEDEF "typedef"
562 : : %token<fl> yTYPE__EQ "type-then-eqneq"
563 : : %token<fl> yTYPE__ETC "type"
564 : : %token<fl> yTYPE__LEX "type-in-lex"
565 : : %token<fl> yUNION "union"
566 : : %token<fl> yUNIQUE "unique"
567 : : %token<fl> yUNIQUE0 "unique0"
568 : : %token<fl> yUNSIGNED "unsigned"
569 : : %token<fl> yUNTIL "until"
570 : : %token<fl> yUNTIL_WITH "until_with"
571 : : %token<fl> yUNTYPED "untyped"
572 : : %token<fl> yUSE "use"
573 : : %token<fl> yVAR "var"
574 : : %token<fl> yVECTORED "vectored"
575 : : %token<fl> yVIRTUAL__CLASS "virtual-then-class"
576 : : %token<fl> yVIRTUAL__ETC "virtual"
577 : : %token<fl> yVIRTUAL__INTERFACE "virtual-then-interface"
578 : : %token<fl> yVIRTUAL__LEX "virtual-in-lex"
579 : : %token<fl> yVIRTUAL__anyID "virtual-then-identifier"
580 : : %token<fl> yVOID "void"
581 : : %token<fl> yWAIT "wait"
582 : : %token<fl> yWAIT_ORDER "wait_order"
583 : : %token<fl> yWAND "wand"
584 : : %token<fl> yWEAK "weak"
585 : : %token<fl> yWEAK0 "weak0"
586 : : %token<fl> yWEAK1 "weak1"
587 : : %token<fl> yWHILE "while"
588 : : %token<fl> yWILDCARD "wildcard"
589 : : %token<fl> yWIRE "wire"
590 : : %token<fl> yWITHIN "within"
591 : : %token<fl> yWITH__BRA "with-then-["
592 : : %token<fl> yWITH__CUR "with-then-{"
593 : : %token<fl> yWITH__ETC "with"
594 : : %token<fl> yWITH__LEX "with-in-lex"
595 : : %token<fl> yWITH__PAREN "with-then-("
596 : : %token<fl> yWITH__PAREN_CUR "with-then-(-then-{"
597 : : %token<fl> yWOR "wor"
598 : : %token<fl> yWREAL "wreal"
599 : : %token<fl> yXNOR "xnor"
600 : : %token<fl> yXOR "xor"
601 : :
602 : : %token<fl> yD_ACOS "$acos"
603 : : %token<fl> yD_ACOSH "$acosh"
604 : : %token<fl> yD_ASIN "$asin"
605 : : %token<fl> yD_ASINH "$asinh"
606 : : %token<fl> yD_ASSERTCTL "$assertcontrol"
607 : : %token<fl> yD_ASSERTFAILOFF "$assertfailoff"
608 : : %token<fl> yD_ASSERTFAILON "$assertfailon"
609 : : %token<fl> yD_ASSERTKILL "$assertkill"
610 : : %token<fl> yD_ASSERTNONVACUOUSON "$assertnonvacuouson"
611 : : %token<fl> yD_ASSERTOFF "$assertoff"
612 : : %token<fl> yD_ASSERTON "$asserton"
613 : : %token<fl> yD_ASSERTPASSOFF "$assertpassoff"
614 : : %token<fl> yD_ASSERTPASSON "$assertpasson"
615 : : %token<fl> yD_ASSERTVACUOUSOFF "$assertvacuousoff"
616 : : %token<fl> yD_ATAN "$atan"
617 : : %token<fl> yD_ATAN2 "$atan2"
618 : : %token<fl> yD_ATANH "$atanh"
619 : : %token<fl> yD_BITS "$bits"
620 : : %token<fl> yD_BITSTOREAL "$bitstoreal"
621 : : %token<fl> yD_BITSTOSHORTREAL "$bitstoshortreal"
622 : : %token<fl> yD_C "$c"
623 : : %token<fl> yD_CPURE "$cpure"
624 : : %token<fl> yD_CAST "$cast"
625 : : %token<fl> yD_CEIL "$ceil"
626 : : %token<fl> yD_CHANGED "$changed"
627 : : %token<fl> yD_CHANGED_GCLK "$changed_gclk"
628 : : %token<fl> yD_CHANGING_GCLK "$changing_gclk"
629 : : %token<fl> yD_CLOG2 "$clog2"
630 : : %token<fl> yD_COS "$cos"
631 : : %token<fl> yD_COSH "$cosh"
632 : : %token<fl> yD_COUNTBITS "$countbits"
633 : : %token<fl> yD_COUNTONES "$countones"
634 : : %token<fl> yD_DIMENSIONS "$dimensions"
635 : : %token<fl> yD_DISPLAY "$display"
636 : : %token<fl> yD_DISPLAYB "$displayb"
637 : : %token<fl> yD_DISPLAYH "$displayh"
638 : : %token<fl> yD_DISPLAYO "$displayo"
639 : : %token<fl> yD_DIST_CHI_SQUARE "$dist_chi_square"
640 : : %token<fl> yD_DIST_ERLANG "$dist_erlang"
641 : : %token<fl> yD_DIST_EXPONENTIAL "$dist_exponential"
642 : : %token<fl> yD_DIST_NORMAL "$dist_normal"
643 : : %token<fl> yD_DIST_POISSON "$dist_poisson"
644 : : %token<fl> yD_DIST_T "$dist_t"
645 : : %token<fl> yD_DIST_UNIFORM "$dist_uniform"
646 : : %token<fl> yD_DUMPALL "$dumpall"
647 : : %token<fl> yD_DUMPFILE "$dumpfile"
648 : : %token<fl> yD_DUMPFLUSH "$dumpflush"
649 : : %token<fl> yD_DUMPLIMIT "$dumplimit"
650 : : %token<fl> yD_DUMPOFF "$dumpoff"
651 : : %token<fl> yD_DUMPON "$dumpon"
652 : : %token<fl> yD_DUMPPORTS "$dumpports"
653 : : %token<fl> yD_DUMPVARS "$dumpvars"
654 : : %token<fl> yD_ERROR "$error"
655 : : %token<fl> yD_EXIT "$exit"
656 : : %token<fl> yD_EXP "$exp"
657 : : %token<fl> yD_FALLING_GCLK "$falling_gclk"
658 : : %token<fl> yD_FATAL "$fatal"
659 : : %token<fl> yD_FCLOSE "$fclose"
660 : : %token<fl> yD_FDISPLAY "$fdisplay"
661 : : %token<fl> yD_FDISPLAYB "$fdisplayb"
662 : : %token<fl> yD_FDISPLAYH "$fdisplayh"
663 : : %token<fl> yD_FDISPLAYO "$fdisplayo"
664 : : %token<fl> yD_FELL "$fell"
665 : : %token<fl> yD_FELL_GCLK "$fell_gclk"
666 : : %token<fl> yD_FEOF "$feof"
667 : : %token<fl> yD_FERROR "$ferror"
668 : : %token<fl> yD_FFLUSH "$fflush"
669 : : %token<fl> yD_FGETC "$fgetc"
670 : : %token<fl> yD_FGETS "$fgets"
671 : : %token<fl> yD_FINISH "$finish"
672 : : %token<fl> yD_FLOOR "$floor"
673 : : %token<fl> yD_FMONITOR "$fmonitor"
674 : : %token<fl> yD_FMONITORB "$fmonitorb"
675 : : %token<fl> yD_FMONITORH "$fmonitorh"
676 : : %token<fl> yD_FMONITORO "$fmonitoro"
677 : : %token<fl> yD_FOPEN "$fopen"
678 : : %token<fl> yD_FREAD "$fread"
679 : : %token<fl> yD_FREWIND "$frewind"
680 : : %token<fl> yD_FSCANF "$fscanf"
681 : : %token<fl> yD_FSEEK "$fseek"
682 : : %token<fl> yD_FSTROBE "$fstrobe"
683 : : %token<fl> yD_FSTROBEB "$fstrobeb"
684 : : %token<fl> yD_FSTROBEH "$fstrobeh"
685 : : %token<fl> yD_FSTROBEO "$fstrobeo"
686 : : %token<fl> yD_FTELL "$ftell"
687 : : %token<fl> yD_FUTURE_GCLK "$future_gclk"
688 : : %token<fl> yD_FWRITE "$fwrite"
689 : : %token<fl> yD_FWRITEB "$fwriteb"
690 : : %token<fl> yD_FWRITEH "$fwriteh"
691 : : %token<fl> yD_FWRITEO "$fwriteo"
692 : : %token<fl> yD_GET_INITIAL_RANDOM_SEED "$get_initial_random_seed"
693 : : %token<fl> yD_GLOBAL_CLOCK "$global_clock"
694 : : %token<fl> yD_HIGH "$high"
695 : : %token<fl> yD_HYPOT "$hypot"
696 : : %token<fl> yD_INCREMENT "$increment"
697 : : %token<fl> yD_INFERRED_DISABLE "$inferred_disable"
698 : : %token<fl> yD_INFO "$info"
699 : : %token<fl> yD_ISUNBOUNDED "$isunbounded"
700 : : %token<fl> yD_ISUNKNOWN "$isunknown"
701 : : %token<fl> yD_ITOR "$itor"
702 : : %token<fl> yD_LEFT "$left"
703 : : %token<fl> yD_LN "$ln"
704 : : %token<fl> yD_LOG10 "$log10"
705 : : %token<fl> yD_LOW "$low"
706 : : %token<fl> yD_MONITOR "$monitor"
707 : : %token<fl> yD_MONITORB "$monitorb"
708 : : %token<fl> yD_MONITORH "$monitorh"
709 : : %token<fl> yD_MONITORO "$monitoro"
710 : : %token<fl> yD_MONITOROFF "$monitoroff"
711 : : %token<fl> yD_MONITORON "$monitoron"
712 : : %token<fl> yD_ONEHOT "$onehot"
713 : : %token<fl> yD_ONEHOT0 "$onehot0"
714 : : %token<fl> yD_PAST "$past"
715 : : %token<fl> yD_PAST_GCLK "$past_gclk"
716 : : %token<fl> yD_POW "$pow"
717 : : %token<fl> yD_PRINTTIMESCALE "$printtimescale"
718 : : %token<fl> yD_RANDOM "$random"
719 : : %token<fl> yD_READMEMB "$readmemb"
720 : : %token<fl> yD_READMEMH "$readmemh"
721 : : %token<fl> yD_REALTIME "$realtime"
722 : : %token<fl> yD_REALTOBITS "$realtobits"
723 : : %token<fl> yD_REWIND "$rewind"
724 : : %token<fl> yD_RIGHT "$right"
725 : : %token<fl> yD_RISING_GCLK "$rising_gclk"
726 : : %token<fl> yD_ROOT "$root"
727 : : %token<fl> yD_ROSE "$rose"
728 : : %token<fl> yD_ROSE_GCLK "$rose_gclk"
729 : : %token<fl> yD_RTOI "$rtoi"
730 : : %token<fl> yD_SAMPLED "$sampled"
731 : : %token<fl> yD_SDF_ANNOTATE "$sdf_annotate"
732 : : %token<fl> yD_SETUPHOLD "$setuphold"
733 : : %token<fl> yD_SFORMAT "$sformat"
734 : : %token<fl> yD_SFORMATF "$sformatf"
735 : : %token<fl> yD_SHORTREALTOBITS "$shortrealtobits"
736 : : %token<fl> yD_SIGNED "$signed"
737 : : %token<fl> yD_SIN "$sin"
738 : : %token<fl> yD_SINH "$sinh"
739 : : %token<fl> yD_SIZE "$size"
740 : : %token<fl> yD_SQRT "$sqrt"
741 : : %token<fl> yD_SSCANF "$sscanf"
742 : : %token<fl> yD_STABLE "$stable"
743 : : %token<fl> yD_STABLE_GCLK "$stable_gclk"
744 : : %token<fl> yD_STACKTRACE "$stacktrace"
745 : : %token<fl> yD_STEADY_GCLK "$steady_gclk"
746 : : %token<fl> yD_STIME "$stime"
747 : : %token<fl> yD_STOP "$stop"
748 : : %token<fl> yD_STROBE "$strobe"
749 : : %token<fl> yD_STROBEB "$strobeb"
750 : : %token<fl> yD_STROBEH "$strobeh"
751 : : %token<fl> yD_STROBEO "$strobeo"
752 : : %token<fl> yD_SWRITE "$swrite"
753 : : %token<fl> yD_SWRITEB "$swriteb"
754 : : %token<fl> yD_SWRITEH "$swriteh"
755 : : %token<fl> yD_SWRITEO "$swriteo"
756 : : %token<fl> yD_SYSTEM "$system"
757 : : %token<fl> yD_TAN "$tan"
758 : : %token<fl> yD_TANH "$tanh"
759 : : %token<fl> yD_TESTPLUSARGS "$test$plusargs"
760 : : %token<fl> yD_TIME "$time"
761 : : %token<fl> yD_TIMEFORMAT "$timeformat"
762 : : %token<fl> yD_TIMEPRECISION "$timeprecision"
763 : : %token<fl> yD_TIMEUNIT "$timeunit"
764 : : %token<fl> yD_TYPENAME "$typename"
765 : : %token<fl> yD_UNGETC "$ungetc"
766 : : %token<fl> yD_UNIT "$unit"
767 : : %token<fl> yD_UNPACKED_DIMENSIONS "$unpacked_dimensions"
768 : : %token<fl> yD_UNSIGNED "$unsigned"
769 : : %token<fl> yD_URANDOM "$urandom"
770 : : %token<fl> yD_URANDOM_RANGE "$urandom_range"
771 : : %token<fl> yD_VALUEPLUSARGS "$value$plusargs"
772 : : %token<fl> yD_WARNING "$warning"
773 : : %token<fl> yD_WRITE "$write"
774 : : %token<fl> yD_WRITEB "$writeb"
775 : : %token<fl> yD_WRITEH "$writeh"
776 : : %token<fl> yD_WRITEMEMB "$writememb"
777 : : %token<fl> yD_WRITEMEMH "$writememh"
778 : : %token<fl> yD_WRITEO "$writeo"
779 : :
780 : : %token<fl> yVL_CLOCKER "/*verilator clocker*/"
781 : : %token<fl> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
782 : : %token<fl> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
783 : : %token<fl> yVL_FORCEABLE "/*verilator forceable*/"
784 : : %token<fl> yVL_FULL_CASE "/*verilator full_case*/"
785 : : %token<fl> yVL_HIER_BLOCK "/*verilator hier_block*/"
786 : : %token<fl> yVL_INLINE_MODULE "/*verilator inline_module*/"
787 : : %token<fl> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
788 : : %token<fl> yVL_NO_CLOCKER "/*verilator no_clocker*/"
789 : : %token<fl> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
790 : : %token<fl> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
791 : : %token<fl> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
792 : : %token<fl> yVL_PUBLIC "/*verilator public*/"
793 : : %token<fl> yVL_PUBLIC_FLAT "/*verilator public_flat*/"
794 : : %token<fl> yVL_PUBLIC_FLAT_ON "/*verilator public_flat_on*/"
795 : : %token<fl> yVL_PUBLIC_FLAT_RD "/*verilator public_flat_rd*/"
796 : : %token<fl> yVL_PUBLIC_FLAT_RD_ON "/*verilator public_flat_rd_on*/"
797 : : %token<fl> yVL_PUBLIC_FLAT_RW "/*verilator public_flat_rw*/"
798 : : %token<fl> yVL_PUBLIC_FLAT_RW_ON "/*verilator public_flat_rw_on*/"
799 : : %token<fl> yVL_PUBLIC_FLAT_RW_ON_SNS "/*verilator public_flat_rw_on_sns*/"
800 : : %token<fl> yVL_PUBLIC_ON "/*verilator public_on*/"
801 : : %token<fl> yVL_PUBLIC_OFF "/*verilator public_off*/"
802 : : %token<fl> yVL_PUBLIC_MODULE "/*verilator public_module*/"
803 : : %token<fl> yVL_SC_BIGUINT "/*verilator sc_biguint*/"
804 : : %token<fl> yVL_SC_BV "/*verilator sc_bv*/"
805 : : %token<fl> yVL_SFORMAT "/*verilator sformat*/"
806 : : %token<fl> yVL_SPLIT_VAR "/*verilator split_var*/"
807 : : %token<fl> yVL_FSM_ARC_INCL_COND "/*verilator fsm_arc_include_cond*/"
808 : : %token<fl> yVL_FSM_RESET_ARC "/*verilator fsm_reset_arc*/"
809 : : %token<fl> yVL_FSM_STATE "/*verilator fsm_state*/"
810 : : %token<strp> yVL_TAG "/*verilator tag*/"
811 : : %token<fl> yVL_UNROLL_DISABLE "/*verilator unroll_disable*/"
812 : : %token<fl> yVL_UNROLL_FULL "/*verilator unroll_full*/"
813 : :
814 : : %token<fl> yP_TICK "'"
815 : : %token<fl> yP_TICKBRA "'{"
816 : : %token<fl> yP_OROR "||"
817 : : %token<fl> yP_ANDAND "&&"
818 : : %token<fl> yP_NOR "~|"
819 : : %token<fl> yP_XNOR "^~"
820 : : %token<fl> yP_NAND "~&"
821 : : %token<fl> yP_EQUAL "=="
822 : : %token<fl> yP_NOTEQUAL "!="
823 : : %token<fl> yP_CASEEQUAL "==="
824 : : %token<fl> yP_CASENOTEQUAL "!=="
825 : : %token<fl> yP_WILDEQUAL "==?"
826 : : %token<fl> yP_WILDNOTEQUAL "!=?"
827 : : %token<fl> yP_GTE ">="
828 : : %token<fl> yP_LTE "<="
829 : : %token<fl> yP_LTE__IGNORE "<=-ignored" // Used when expr:<= means assignment
830 : : %token<fl> yP_SLEFT "<<"
831 : : %token<fl> yP_SRIGHT ">>"
832 : : %token<fl> yP_SSRIGHT ">>>"
833 : : %token<fl> yP_POW "**"
834 : :
835 : : %token<fl> yP_COLON__BEGIN ":-then-begin"
836 : : %token<fl> yP_COLON__FORK ":-then-fork"
837 : : %token<fl> yP_EQ__NEW "=-then-new"
838 : : %token<fl> yP_PAR__IGNORE "(-ignored" // Used when sequence_expr:expr:( is ignored
839 : : %token<fl> yP_PAR__STRENGTH "(-for-strength"
840 : :
841 : : %token<fl> yP_LTMINUSGT "<->"
842 : : %token<fl> yP_PLUSCOLON "+:"
843 : : %token<fl> yP_MINUSCOLON "-:"
844 : : %token<fl> yP_MINUSGT "->"
845 : : %token<fl> yP_MINUSGTGT "->>"
846 : : %token<fl> yP_EQGT "=>"
847 : : %token<fl> yP_ASTGT "*>"
848 : : %token<fl> yP_ANDANDAND "&&&"
849 : : %token<fl> yP_POUNDPOUND "##"
850 : : %token<fl> yP_POUNDMINUSPD "#-#"
851 : : %token<fl> yP_POUNDEQPD "#=#"
852 : : %token<fl> yP_DOTSTAR ".*"
853 : :
854 : : %token<fl> yP_ATAT "@@"
855 : : %token<fl> yP_COLONCOLON "::"
856 : : %token<fl> yP_COLONEQ ":="
857 : : %token<fl> yP_COLONDIV ":/"
858 : : %token<fl> yP_ORMINUSGT "|->"
859 : : %token<fl> yP_OREQGT "|=>"
860 : : %token<fl> yP_BRASTAR "[*"
861 : : %token<fl> yP_BRAEQ "[="
862 : : %token<fl> yP_BRAMINUSGT "[->"
863 : : %token<fl> yP_BRAPLUSKET "[+]"
864 : :
865 : : %token<fl> yP_PLUSPLUS "++"
866 : : %token<fl> yP_MINUSMINUS "--"
867 : : %token<fl> yP_PLUSEQ "+="
868 : : %token<fl> yP_MINUSEQ "-="
869 : : %token<fl> yP_TIMESEQ "*="
870 : : %token<fl> yP_DIVEQ "/="
871 : : %token<fl> yP_MODEQ "%="
872 : : %token<fl> yP_ANDEQ "&="
873 : : %token<fl> yP_OREQ "|="
874 : : %token<fl> yP_XOREQ "^="
875 : : %token<fl> yP_SLEFTEQ "<<="
876 : : %token<fl> yP_SRIGHTEQ ">>="
877 : : %token<fl> yP_SSRIGHTEQ ">>>="
878 : :
879 : : %token<fl> yP_PLUSSLASHMINUS "+/-"
880 : : %token<fl> yP_PLUSPCTMINUS "+%-"
881 : :
882 : : // [* is not an operator, as "[ * ]" is legal
883 : : // [= and [-> could be repetition operators, but to match [* we don't add them.
884 : : // '( is not an operator, as "' (" is legal
885 : :
886 : : //********************
887 : : // Verilog op precedence
888 : : //UNSUP %token<fl> prUNARYARITH
889 : : //UNSUP %token<fl> prREDUCTION
890 : : //UNSUP %token<fl> prNEGATION
891 : : //UNSUP %token<fl> prEVENTBEGIN
892 : : %token<fl> prTAGGED
893 : :
894 : : // These prevent other conflicts
895 : : %left yP_ANDANDAND
896 : : %left yMATCHES
897 : : %left prTAGGED
898 : : //UNSUP %left prSEQ_CLOCKING
899 : :
900 : : // PSL op precedence
901 : :
902 : : // Lowest precedence
903 : : // These are in IEEE 17.7.1
904 : : %nonassoc yALWAYS yS_ALWAYS yEVENTUALLY yS_EVENTUALLY yACCEPT_ON yREJECT_ON ySYNC_ACCEPT_ON ySYNC_REJECT_ON
905 : :
906 : : %right yP_ORMINUSGT yP_OREQGT yP_POUNDMINUSPD yP_POUNDEQPD
907 : : %right yUNTIL yS_UNTIL yUNTIL_WITH yS_UNTIL_WITH yIMPLIES
908 : : %right yIFF
909 : : %left yOR
910 : : %left yAND
911 : : %nonassoc yNOT yNEXTTIME yS_NEXTTIME
912 : : %left yINTERSECT
913 : : %left yWITHIN
914 : : %right yTHROUGHOUT
915 : : %left prPOUNDPOUND_MULTI
916 : : %left yP_POUNDPOUND
917 : : %left yP_BRASTAR yP_BRAEQ yP_BRAMINUSGT yP_BRAPLUSKET
918 : :
919 : : // Not specified, but needed higher than yOR, lower than normal non-pexpr expressions
920 : : //UNSUP %left yPOSEDGE yNEGEDGE yEDGE
921 : :
922 : : //UNSUP %left '{' '}'
923 : :
924 : : // Verilog op precedence
925 : : %right yP_MINUSGT yP_LTMINUSGT
926 : : %right '?' ':' yP_COLON__BEGIN yP_COLON__FORK
927 : : %left yP_OROR
928 : : %left yP_ANDAND
929 : : %left '|' yP_NOR
930 : : %left '^' yP_XNOR
931 : : %left '&' yP_NAND
932 : : %left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
933 : : %left '>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE yDIST
934 : : %left yP_SLEFT yP_SRIGHT yP_SSRIGHT
935 : : %left '+' '-'
936 : : %left '*' '/' '%'
937 : : %left yP_POW
938 : : %left prUNARYARITH yP_MINUSMINUS yP_PLUSPLUS prREDUCTION prNEGATION
939 : : %left '.'
940 : : // Not in IEEE, but need to avoid conflicts; TICK should bind tightly just lower than COLONCOLON
941 : : %left yP_TICK
942 : : //%left '(' ')' '[' ']' yP_COLONCOLON '.'
943 : :
944 : : %nonassoc prLOWER_THAN_ELSE
945 : : %nonassoc yELSE
946 : :
947 : : //BISONPRE_TYPES
948 : : // Blank lines for type insertion
949 : : // Blank lines for type insertion
950 : : // Blank lines for type insertion
951 : : // Blank lines for type insertion
952 : : // Blank lines for type insertion
953 : : // Blank lines for type insertion
954 : : // Blank lines for type insertion
955 : : // Blank lines for type insertion
956 : : // Blank lines for type insertion
957 : : // Blank lines for type insertion
958 : : // Blank lines for type insertion
959 : : // Blank lines for type insertion
960 : : // Blank lines for type insertion
961 : : // Blank lines for type insertion
962 : : // Blank lines for type insertion
963 : : // Blank lines for type insertion
964 : : // Blank lines for type insertion
965 : : // Blank lines for type insertion
966 : : // Blank lines for type insertion
967 : : // Blank lines for type insertion
968 : : // Blank lines for type insertion
969 : : // Blank lines for type insertion
970 : : // Blank lines for type insertion
971 : : // Blank lines for type insertion
972 : : // Blank lines for type insertion
973 : : // Blank lines for type insertion
974 : : // Blank lines for type insertion
975 : : // Blank lines for type insertion
976 : : // Blank lines for type insertion
977 : : // Blank lines for type insertion
978 : : // Blank lines for type insertion
979 : : // Blank lines for type insertion
980 : : // Blank lines for type insertion
981 : : // Blank lines for type insertion
982 : : // Blank lines for type insertion
983 : : // Blank lines for type insertion
984 : : // Blank lines for type insertion
985 : : // Blank lines for type insertion
986 : : // Blank lines for type insertion
987 : : // Blank lines for type insertion
988 : : // Blank lines for type insertion
989 : : // Blank lines for type insertion
990 : : // Blank lines for type insertion
991 : : // Blank lines for type insertion
992 : : // Blank lines for type insertion
993 : : // Blank lines for type insertion
994 : : // Blank lines for type insertion
995 : : // Blank lines for type insertion
996 : : // Blank lines for type insertion
997 : : // Blank lines for type insertion
998 : : // Blank lines for type insertion
999 : : // Blank lines for type insertion
1000 : : // Blank lines for type insertion
1001 : : // Blank lines for type insertion
1002 : : // Blank lines for type insertion
1003 : : // Blank lines for type insertion
1004 : : // Blank lines for type insertion
1005 : : // Blank lines for type insertion
1006 : : // Blank lines for type insertion
1007 : : // Blank lines for type insertion
1008 : : // Blank lines for type insertion
1009 : : // Blank lines for type insertion
1010 : : // Blank lines for type insertion
1011 : : // Blank lines for type insertion
1012 : : // Blank lines for type insertion
1013 : : // Blank lines for type insertion
1014 : : // Blank lines for type insertion
1015 : : // Blank lines for type insertion
1016 : : // Blank lines for type insertion
1017 : : // Blank lines for type insertion
1018 : : // Blank lines for type insertion
1019 : : // Blank lines for type insertion
1020 : :
1021 : : %start source_text
1022 : :
1023 : : %%
1024 : : //**********************************************************************
1025 : : // Files
1026 : :
1027 : : source_text: // ==IEEE: source_text
1028 : : /* empty */ { }
1029 : : // // timeunits_declaration moved into description:package_item
1030 : : | descriptionList { }
1031 : : ;
1032 : :
1033 : : descriptionList: // IEEE: part of source_text
1034 : : description { }
1035 : : | descriptionList description { }
1036 : : ;
1037 : :
1038 : : description: // ==IEEE: description
1039 : : module_declaration { }
1040 : : // // udp_declaration moved into module_declaration
1041 : : // // library_declaration and include_statement moved from library_description
1042 : : | library_declaration { PARSEP->rootp()->addMiscsp($1); }
1043 : : | include_statement { }
1044 : : | interface_declaration { }
1045 : : | program_declaration { }
1046 : : | package_declaration { }
1047 : : | package_itemTop { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
1048 : : | bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
1049 : : | config_declaration { }
1050 : : // // Verilator only
1051 : : | yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3
1052 : : | yaT_NOUNCONNECTED { PARSEP->unconnectedDrive(VOptionBool::OPT_DEFAULT_FALSE); }
1053 : : | yaT_UNCONNECTED_PULL0 { PARSEP->unconnectedDrive(VOptionBool::OPT_FALSE); }
1054 : : | yaT_UNCONNECTED_PULL1 { PARSEP->unconnectedDrive(VOptionBool::OPT_TRUE); }
1055 : : | vltItem { }
1056 : : | error { } // LCOV_EXCL_LINE
1057 : : ;
1058 : :
1059 : : timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
1060 : : yTIMEUNIT yaTIMENUM ';'
1061 : : { $$ = PARSEP->createTimescale($<fl>2, true, $2, false, 0); }
1062 : : | yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';'
1063 : : { $$ = PARSEP->createTimescale($<fl>2, true, $2, true, $4); }
1064 : : | yTIMEPRECISION yaTIMENUM ';'
1065 : : { $$ = PARSEP->createTimescale($<fl>2, false, 0, true, $2); }
1066 : : ;
1067 : :
1068 : : //**********************************************************************
1069 : : // Packages
1070 : :
1071 : : package_declaration: // ==IEEE: package_declaration
1072 : : packageFront package_itemListE yENDPACKAGE endLabelE
1073 : : { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
1074 : : if ($2) $1->addStmtsp($2);
1075 : : GRAMMARP->endLabel($<fl>4, $1, $4); }
1076 : : ;
1077 : :
1078 : : packageFront<nodeModulep>:
1079 : : yPACKAGE lifetimeE idAny ';'
1080 : : { $$ = new AstPackage{$<fl>3, *$3, PARSEP->libname()};
1081 : : if ($$->name() == "std") {
1082 : : if ($$->fileline()->filename() != V3Options::getStdPackagePath()) {
1083 : : $$->v3error("Redeclaring the 'std' package is not allowed");
1084 : : } else {
1085 : : PARSEP->rootp()->stdPackagep(VN_AS($$, Package));
1086 : : }
1087 : : }
1088 : : $$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
1089 : : $$->lifetime($2);
1090 : : $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
1091 : : $$->timeunit(PARSEP->timeLastUnit());
1092 : : PARSEP->rootp()->timeprecisionMerge($$->fileline(),
1093 : : PARSEP->timeLastPrec());
1094 : : PARSEP->rootp()->addModulesp($$); }
1095 : : ;
1096 : :
1097 : : package_itemListE<nodep>: // IEEE: [{ package_item }]
1098 : : /* empty */ { $$ = nullptr; }
1099 : : | package_itemList { $$ = $1; }
1100 : : ;
1101 : :
1102 : : package_itemList<nodep>: // IEEE: { package_item }
1103 : : package_item { $$ = $1; }
1104 : : | package_itemList package_item { $$ = addNextNull($1, $2); }
1105 : : ;
1106 : :
1107 : : package_item<nodep>: // ==IEEE: package_item
1108 : : package_or_generate_item_declaration { $$ = $1; }
1109 : : | anonymous_program { $$ = $1; }
1110 : : | package_export_declaration { $$ = $1; }
1111 : : | timeunits_declaration { $$ = $1; }
1112 : : | sigAttrScope { $$ = nullptr; }
1113 : : ;
1114 : :
1115 : : package_itemTop<nodep>: // ==IEEE: package_item
1116 : :
1117 : : package_or_generate_item_declNoChecker { $$ = $1; }
1118 : : | checker_declaration
1119 : : { PARSEP->rootp()->addModulesp($1);
1120 : : $$ = nullptr; }
1121 : : | anonymous_program { $$ = $1; }
1122 : : | package_export_declaration { $$ = $1; }
1123 : : | timeunits_declaration { $$ = $1; }
1124 : : | sigAttrScope { $$ = nullptr; }
1125 : : ;
1126 : :
1127 : : package_or_generate_item_declaration<nodep>: // ==IEEE: package_or_generate_item_declaration
1128 : : package_or_generate_item_declNoChecker { $$ = $1; }
1129 : : | checker_declaration
1130 : : { $1->v3warn(E_UNSUPPORTED, "Unsupported: 'checker' below unit-level");
1131 : : PARSEP->rootp()->addModulesp($1);
1132 : : $$ = nullptr; }
1133 : : ;
1134 : :
1135 : : package_or_generate_item_declNoChecker<nodep>:
1136 : : net_declaration { $$ = $1; }
1137 : : | data_declaration { $$ = $1; }
1138 : : | task_declaration { $$ = $1; }
1139 : : | function_declaration { $$ = $1; }
1140 : : // // IEEE checker_declaration excluded, to handle Top, see other rules
1141 : : // // checker_declaration
1142 : : | dpi_import_export { $$ = $1; }
1143 : : | extern_constraint_declaration { $$ = $1; }
1144 : : | class_declaration { $$ = $1; }
1145 : : // // IEEE-2023: Added: interface_class_declaration
1146 : : // // interface_class_declaration is part of class_declaration
1147 : : // // class_constructor_declaration is part of function_declaration
1148 : : // // local_parameter_declaration under parameter_declaration
1149 : : | parameter_declaration ';' { $$ = $1; }
1150 : : | covergroup_declaration { $$ = $1; }
1151 : : | assertion_item_declaration { $$ = $1; }
1152 : : | ';' { $$ = nullptr; }
1153 : : ;
1154 : :
1155 : : package_import_declarationList<nodep>:
1156 : : package_import_declaration { $$ = $1; }
1157 : : | package_import_declarationList package_import_declaration
1158 : : { $$ = addNextNull($1, $2); }
1159 : : ;
1160 : :
1161 : : package_import_declaration<nodep>: // ==IEEE: package_import_declaration
1162 : : yIMPORT package_import_itemList ';' { $$ = $2; }
1163 : : ;
1164 : :
1165 : : package_import_itemList<nodep>:
1166 : : package_import_item { $$ = $1; }
1167 : : | package_import_itemList ',' package_import_item { $$ = addNextNull($1, $3); }
1168 : : ;
1169 : :
1170 : : package_import_item<nodep>: // ==IEEE: package_import_item
1171 : : idCC/*package_identifier*/ yP_COLONCOLON package_import_itemObj
1172 : : { $$ = new AstPackageImport{$<fl>1, *$<strp>1, *$3}; }
1173 : : ;
1174 : :
1175 : : package_import_itemObj<strp>: // IEEE: part of package_import_item
1176 : : idAny/*package_identifier*/ { $<fl>$ = $<fl>1; $$ = $1; }
1177 : : | '*' { $<fl>$ = $<fl>1; static string star = "*"; $$ = ☆ }
1178 : : ;
1179 : :
1180 : : package_export_declaration<nodep>: // IEEE: package_export_declaration
1181 : : yEXPORT '*' yP_COLONCOLON '*' ';'
1182 : : { $$ = new AstPackageExportStarStar{$<fl>2}; }
1183 : : | yEXPORT package_export_itemList ';' { $$ = $2; }
1184 : : ;
1185 : :
1186 : : package_export_itemList<nodep>:
1187 : : package_export_item { $$ = $1; }
1188 : : | package_export_itemList ',' package_export_item { $$ = addNextNull($1, $3); }
1189 : : ;
1190 : :
1191 : : package_export_item<nodep>: // ==IEEE: package_export_item
1192 : : idCC yP_COLONCOLON package_import_itemObj
1193 : : { $$ = new AstPackageExport{$<fl>3, *$<strp>1, *$3}; }
1194 : : ;
1195 : :
1196 : : //**********************************************************************
1197 : : // Module headers
1198 : :
1199 : : module_declaration: // ==IEEE: module_declaration
1200 : : // // timeunits_declaration instead in module_item
1201 : : // // IEEE: module_nonansi_header + module_ansi_header
1202 : : modFront importsAndParametersE portsStarE ';'
1203 : : /*cont*/ module_itemListE yENDMODULE endLabelE
1204 : : { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
1205 : : $1->hasParameterList($<flag>2);
1206 : : if ($2) $1->addStmtsp($2);
1207 : : if ($3) $1->addStmtsp($3);
1208 : : if ($5) $1->addStmtsp($5);
1209 : : GRAMMARP->endLabel($<fl>7, $1, $7); }
1210 : : | udpFront portsStarE ';'
1211 : : /*cont*/ module_itemListE yENDPRIMITIVE endLabelE
1212 : : { $1->modTrace(false); // Stash for implicit wires, etc
1213 : : if ($2) $1->addStmtsp($2);
1214 : : if ($4) $1->addStmtsp($4);
1215 : : GRAMMARP->m_tracingParse = true;
1216 : : GRAMMARP->endLabel($<fl>6, $1, $6); }
1217 : : //
1218 : : | yEXTERN modFront parameter_port_listE portsStarE ';'
1219 : : { DEL($2->unlinkFrBack()); }
1220 : : // We allow modules to be declared after instantiations, so harmless
1221 : : ;
1222 : :
1223 : : modFront<nodeModulep>:
1224 : : // // General note: all *Front functions must call symPushNew before
1225 : : // // any formal arguments, as the arguments must land in the new scope.
1226 : : yMODULE lifetimeE idAny
1227 : : { $$ = new AstModule{$<fl>3, *$3, PARSEP->libname()};
1228 : : $$->lifetime($2);
1229 : : $$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn());
1230 : : $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
1231 : : $$->timeunit(PARSEP->timeLastUnit());
1232 : : PARSEP->rootp()->timeprecisionMerge($$->fileline(),
1233 : : PARSEP->timeLastPrec());
1234 : : $$->unconnectedDrive(PARSEP->unconnectedDrive());
1235 : : PARSEP->rootp()->addModulesp($$); }
1236 : : | modFront sigAttrScope { $$ = $1; }
1237 : : ;
1238 : :
1239 : : importsAndParametersE<nodep>: // IEEE: common part of module_declaration, interface_declaration, program_declaration
1240 : : // // { package_import_declaration } [ parameter_port_list ]
1241 : : parameter_port_listE
1242 : : { $$ = $1; $<flag>$ = $<flag>1; } // hasParameterList
1243 : : | package_import_declarationList parameter_port_listE
1244 : : { $$ = addNextNull($1, $2);
1245 : : $<flag>$ = $<flag>2; } // hasParameterList
1246 : : ;
1247 : :
1248 : : udpFront<nodeModulep>:
1249 : : yPRIMITIVE lifetimeE idAny
1250 : : { $$ = new AstPrimitive{$<fl>3, *$3, PARSEP->libname()};
1251 : : $$->inLibrary(true);
1252 : : $$->lifetime($2);
1253 : : $$->modTrace(false);
1254 : : $$->addStmtsp(new AstPragma{$<fl>3, VPragmaType::INLINE_MODULE});
1255 : : GRAMMARP->m_tracingParse = false;
1256 : : PARSEP->rootp()->addModulesp($$); }
1257 : : ;
1258 : :
1259 : : parameter_value_assignmentInstE<pinp>: // IEEE: [ parameter_value_assignment ] for instance
1260 : : /* empty */ { $$ = nullptr; }
1261 : : | parameter_value_assignmentInst { $$ = $1; }
1262 : : ;
1263 : :
1264 : : parameter_value_assignmentClassE<pinp>: // IEEE: [ parameter_value_assignment ] for classes
1265 : : /* empty */ { $$ = nullptr; }
1266 : : | parameter_value_assignmentClass { $$ = $1; }
1267 : : ;
1268 : :
1269 : : parameter_value_assignmentInst<pinp>: // IEEE: parameter_value_assignment for instance
1270 : : '#' '(' instParamListE ')' { $$ = $3; }
1271 : : // // Parentheses are optional around a single parameter
1272 : : // // IMPORTANT: Below hardcoded in tokenPipeScanParam
1273 : : | '#' yaINTNUM { $$ = new AstPin{$<fl>2, 1, "", new AstConst{$<fl>2, *$2}}; }
1274 : : | '#' yaFLOATNUM { $$ = new AstPin{$<fl>2, 1, "",
1275 : : new AstConst{$<fl>2, AstConst::RealDouble{}, $2}}; }
1276 : : | '#' timeNumAdjusted { $$ = new AstPin{$<fl>2, 1, "", $2}; }
1277 : : | '#' idClassSel { $$ = new AstPin{$<fl>2, 1, "", $2}; }
1278 : : // // Not needed in Verilator:
1279 : : // // Side effect of combining *_instantiations
1280 : : // // '#' delay_value { UNSUP }
1281 : : ;
1282 : :
1283 : : parameter_value_assignmentClass<pinp>: // IEEE: parameter_value_assignment (for classes)
1284 : : // // Like parameter_value_assignment, but for classes only, which always have #()
1285 : : '#' '(' instParamListE ')' { $$ = $3; }
1286 : : ;
1287 : :
1288 : : parameter_port_listE<nodep>: // IEEE: parameter_port_list + empty == parameter_value_assignment
1289 : : /* empty */ { $$ = nullptr; $<flag>$ = false; } // hasParameterList
1290 : : | '#' '(' ')' { $$ = nullptr;
1291 : : $<flag>$ = true; } // hasParameterList
1292 : : // // IEEE: '#' '(' list_of_param_assignments { ',' parameter_port_declaration } ')'
1293 : : // // IEEE: '#' '(' parameter_port_declaration { ',' parameter_port_declaration } ')'
1294 : : // // Can't just do that as "," conflicts with between vars and between stmts, so
1295 : : // // split into pre-comma and post-comma parts
1296 : : | '#' '(' { VARRESET_LIST(GPARAM);
1297 : : GRAMMARP->m_pinAnsi = true; }
1298 : : /*cont*/ paramPortDeclOrArgList ')' { $$ = $4;
1299 : : $<flag>$ = true; // hasParameterList
1300 : : VARRESET_NONLIST(UNKNOWN);
1301 : : GRAMMARP->m_pinAnsi = false; }
1302 : : // // Note legal to start with "a=b" with no parameter statement
1303 : : ;
1304 : :
1305 : : paramPortDeclOrArgList<nodep>: // IEEE: list_of_param_assignments + { parameter_port_declaration }
1306 : : paramPortDeclOrArg { $$ = $1; }
1307 : : | paramPortDeclOrArgList ',' paramPortDeclOrArg { $$ = $1->addNext($3); }
1308 : : | paramPortDeclOrArgList sigAttrScope { $$ = $1; }
1309 : : ;
1310 : :
1311 : : paramPortDeclOrArg<nodep>: // IEEE: param_assignment + parameter_port_declaration
1312 : : // // We combine the two as we can't tell which follows a comma
1313 : : paramPortDeclOrArgSub { $$ = $1; }
1314 : : | vlTag { $$ = nullptr; }
1315 : : ;
1316 : :
1317 : : paramPortDeclOrArgSub<nodep>:
1318 : : parameter_port_declarationFrontE param_assignment { $$ = $2; }
1319 : : | parameter_port_declarationTypeFrontE type_assignment { $$ = $2; }
1320 : : | sigAttrScope paramPortDeclOrArgSub { $$ = $2; }
1321 : : ;
1322 : :
1323 : : portsStarE<nodep>: // IEEE: .* + list_of_ports + list_of_port_declarations + empty
1324 : : /* empty */ { $$ = nullptr; }
1325 : : | '(' ')' { $$ = nullptr; }
1326 : : // // .* expanded from module_declaration
1327 : : //UNSUP '(' yP_DOTSTAR ')' { UNSUP }
1328 : : | '('
1329 : : /*mid*/ { VARRESET_LIST(PORT); GRAMMARP->m_pinAnsi = true; }
1330 : : /*cont*/ list_of_ports ')'
1331 : : { $$ = $3; VARRESET_NONLIST(UNKNOWN); GRAMMARP->m_pinAnsi = false; }
1332 : : ;
1333 : :
1334 : : list_of_portsE<nodep>: // IEEE: [ list_of_ports + list_of_port_declarations ]
1335 : : portAndTagE { $$ = $1; }
1336 : : | list_of_portsE ',' portAndTagE { $$ = addNextNull($1, $3); }
1337 : : ;
1338 : :
1339 : : list_of_ports<nodep>: // IEEE: list_of_ports + list_of_port_declarations
1340 : : portAndTag { $$ = $1; }
1341 : : | list_of_portsE ',' portAndTagE { $$ = addNextNull($1, $3); }
1342 : : ;
1343 : :
1344 : : portAndTagE<nodep>:
1345 : : /* empty */
1346 : : { const int p = PINNUMINC();
1347 : : const string name = "__pinNumber" + cvtToStr(p);
1348 : : $$ = new AstPort{CRELINE(), p, name};
1349 : : AstVar* varp = new AstVar{CRELINE(), VVarType::WIRE, name, VFlagChildDType{},
1350 : : new AstBasicDType{CRELINE(), LOGIC_IMPLICIT}};
1351 : : varp->declDirection(VDirection::INPUT);
1352 : : varp->direction(VDirection::INPUT);
1353 : : varp->ansi(false);
1354 : : varp->declTyped(true);
1355 : : varp->trace(false);
1356 : : $$ = $$->addNext(varp);
1357 : : $$->v3warn(NULLPORT, "Null port on module (perhaps extraneous comma)"); }
1358 : : | portAndTag { $$ = $1; }
1359 : : | portAndTag sigAttrScope { $$ = $1; }
1360 : : ;
1361 : :
1362 : : portAndTag<nodep>:
1363 : : port { $$ = $1; }
1364 : : | vlTag port { $$ = $2; } // Tag will associate with previous port
1365 : : | sigAttrScope portAndTag { $$ = $2; }
1366 : : ;
1367 : :
1368 : : port<nodep>: // ==IEEE: port
1369 : : // // SEE ALSO port_declaration, tf_port_declaration,
1370 : : // // data_declarationVarFront
1371 : : //
1372 : : // // Though not type for interfaces, we factor out the port direction and type
1373 : : // // so we can handle it in one place
1374 : : //
1375 : : // // IEEE: interface_port_header port_identifier { unpacked_dimension }
1376 : : // // Expanded interface_port_header
1377 : : // // We use instantCb here because the non-port form looks just like a module instantiation
1378 : : //
1379 : : // // Looks identical to variable_declaration, so V3LinkDot must resolve when ID known
1380 : : // // NO: portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE
1381 : : //
1382 : : portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE
1383 : : { // VAR for now, but V3LinkCells may call setIfcaeRef on it later
1384 : : $$ = $5; VARDECL(VAR); VARIO(NONE);
1385 : : AstNodeDType* const dtp = new AstIfaceRefDType{$<fl>2, $<fl>4, "", *$2, *$4};
1386 : : VARDTYPE(dtp); VARIOANSI();
1387 : : addNextNull($$, VARDONEP($$, $6, $7)); }
1388 : : | portDirNetE yINTERFACE portSig rangeListE sigAttrListE
1389 : : { $$ = $3; GRAMMARP->createGenericIface($3, $4, $5); }
1390 : : | portDirNetE yINTERFACE '.' idAny/*modport*/ portSig rangeListE sigAttrListE
1391 : : { $$ = $5; GRAMMARP->createGenericIface($5, $6, $7, $<fl>4, *$4); }
1392 : : //
1393 : : | portDirNetE yINTERCONNECT signingE rangeListE portSig variable_dimensionListE sigAttrListE
1394 : : { $$ = $5;
1395 : : BBUNSUP($<fl>2, "Unsupported: interconnect");
1396 : : AstNodeDType* const dtp = GRAMMARP->addRange(
1397 : : new AstBasicDType{$2, LOGIC_IMPLICIT, $3}, $4, true);
1398 : : VARDTYPE(dtp); VARIOANSI();
1399 : : addNextNull($$, VARDONEP($$, $6, $7)); }
1400 : : //
1401 : : // // IEEE: ansi_port_declaration, with [port_direction] removed
1402 : : // // IEEE: [ net_port_header | interface_port_header ]
1403 : : // // port_identifier { unpacked_dimension } [ '=' constant_expression ]
1404 : : // // IEEE: [ variable_port_header ] port_identifier
1405 : : // // { variable_dimension } [ '=' constant_expression ]
1406 : : // // IEEE: '.' port_identifier '(' [ expression ] ')'
1407 : : // // Substitute net_port_header = [ port_direction ] net_port_type
1408 : : // // Substitute variable_port_header = [ port_direction ] variable_port_type
1409 : : // // Substitute net_port_type = [ net_type ] data_type_or_implicit
1410 : : // // Substitute variable_port_type = var_data_type
1411 : : // // Substitute var_data_type = data_type | yVAR data_type_or_implicit
1412 : : // // [ [ port_direction ] net_port_type | interface_port_header]
1413 : : // // port_identifier { unpacked_dimension }
1414 : : // // [ [ port_direction ] var_data_type ]
1415 : : // // port_identifier variable_dimensionListE [ '=' constant_expression ]
1416 : : // // [ [ port_direction ] net_port_type | [ port_direction ] var_data_type ]
1417 : : // // '.' port_identifier '(' [ expression ] ')'
1418 : : //
1419 : : // // Remove optional '[...] id' is in portAssignment
1420 : : // // Remove optional '[port_direction]' is in port
1421 : : // // net_port_type | interface_port_header
1422 : : // // port_identifier { unpacked_dimension }
1423 : : // // net_port_type | interface_port_header
1424 : : // // port_identifier { unpacked_dimension }
1425 : : // // var_data_type
1426 : : // // port_identifier variable_dimensionListE [ '=' constExpr ]
1427 : : // // net_port_type | [ port_direction ] var_data_type '.' port_identifier '(' [ expr ] ')'
1428 : : // // Expand implicit_type
1429 : : //
1430 : : // // variable_dimensionListE instead of rangeListE to avoid conflicts
1431 : : //
1432 : : // // Note implicit rules looks just line declaring additional followon port
1433 : : // // No VARDECL("port") for implicit, as we don't want to declare variables for them
1434 : : // // IEEE: portDirNetE data_type '.' portSig -> handled with AstDot in expr.
1435 : : //
1436 : : | portDirNetE data_type portSig variable_dimensionListE sigAttrListE
1437 : : { $$ = $3; VARDTYPE($2); VARIOANSI();
1438 : : addNextNull($$, VARDONEP($$, $4, $5)); }
1439 : : | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
1440 : : { $$ = $3; VARDTYPE($2); VARIOANSI();
1441 : : if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } }
1442 : : | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE
1443 : : { $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
1444 : : addNextNull($$, VARDONEP($$, $5, $6)); }
1445 : : | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
1446 : : { $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
1447 : : if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
1448 : : | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
1449 : : { $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
1450 : : addNextNull($$, VARDONEP($$, $5, $6)); }
1451 : : | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
1452 : : { $$ = $4; VARDECL(VAR); VARDTYPE($3); VARIOANSI();
1453 : : if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
1454 : : | portDirNetE signing portSig variable_dimensionListE sigAttrListE
1455 : : { $$ = $3;
1456 : : AstNodeDType* const dtp = new AstBasicDType{$3->fileline(), LOGIC_IMPLICIT, $2};
1457 : : VARDTYPE_NDECL(dtp); VARIOANSI();
1458 : : addNextNull($$, VARDONEP($$, $4, $5)); }
1459 : : | portDirNetE signing portSig variable_dimensionListE sigAttrListE '=' constExpr
1460 : : { $$ = $3;
1461 : : AstNodeDType* const dtp = new AstBasicDType{$3->fileline(), LOGIC_IMPLICIT, $2};
1462 : : VARDTYPE_NDECL(dtp); VARIOANSI();
1463 : : if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } }
1464 : : | portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE
1465 : : { $$ = $4;
1466 : : AstNodeDType* const dtp = GRAMMARP->addRange(
1467 : : new AstBasicDType{$3->fileline(), LOGIC_IMPLICIT, $2}, $3, true);
1468 : : VARDTYPE_NDECL(dtp);
1469 : : addNextNull($$, VARDONEP($$, $5, $6)); }
1470 : : | portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE '=' constExpr
1471 : : { $$ = $4;
1472 : : AstNodeDType* const dtp = GRAMMARP->addRange(
1473 : : new AstBasicDType{$3->fileline(), LOGIC_IMPLICIT, $2}, $3, true);
1474 : : VARDTYPE_NDECL(dtp);
1475 : : if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
1476 : : | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE
1477 : : { $$ = $2; /*VARDTYPE-same*/ addNextNull($$, VARDONEP($$, $3, $4)); }
1478 : : | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
1479 : : { $$ = $2; /*VARDTYPE-same*/
1480 : : if (AstVar* vp = VARDONEP($$, $3, $4)) { addNextNull($$, vp); vp->valuep($6); } }
1481 : : // // IEEE: '.' port_identifier '(' [ expression ] ')'
1482 : : | portDirNetE /*implicit*/ '.' portSig '(' expr ')'
1483 : : { $$ = $3; DEL($5);
1484 : : BBUNSUP($<fl>2, "Unsupported: complex ports (IEEE 1800-2023 23.2.2.1/2)"); }
1485 : : // // IEEE: part of (non-ansi) port_reference
1486 : : | '{' port_expressionList '}'
1487 : : { $$ = $2; }
1488 : : ;
1489 : :
1490 : : portDirNetE: // IEEE: part of port, optional net type and/or direction
1491 : : /* empty */ { }
1492 : : // // Per spec, if direction given default the nettype.
1493 : : // // The higher level rule may override this VARDTYPE with one later in the parse.
1494 : : | port_direction { VARDECL(PORT); VARDTYPE_NDECL(nullptr); }
1495 : : | port_direction { VARDECL(PORT); } net_type { VARDTYPE_NDECL(nullptr); } // net_type calls VARDECL
1496 : : | net_type { VARDTYPE_NDECL(nullptr); } // net_type calls VARDECL
1497 : : ;
1498 : :
1499 : : port_declNetE: // IEEE: part of port_declaration, optional net type
1500 : : /* empty */ { }
1501 : : | net_type { } // net_type calls VARDECL
1502 : : ;
1503 : :
1504 : : portSig<nodep>:
1505 : : id/*port*/
1506 : : { $$ = new AstPort{$<fl>1, PINNUMINC(), *$1}; }
1507 : : | idSVKwd
1508 : : { $$ = new AstPort{$<fl>1, PINNUMINC(), *$1}; }
1509 : : ;
1510 : :
1511 : : port_expressionList<nodep>: // IEEE: part of (non-ansi) port_reference
1512 : : port_reference { $$ = $1; }
1513 : : | port_expressionList ',' port_reference { $$ = addNextNull($1, $3); }
1514 : : ;
1515 : :
1516 : : port_reference<nodep>: // IEEE: (non-ansi) port-reference
1517 : : // // IEEE: port_identifier constant_select
1518 : : // // constant_select ::= [ '[' constant_part_select_range ']' ]
1519 : : id/*port_identifier*/ { $$ = nullptr; } // UNSUP above here
1520 : : | id/*port_identifier*/ part_select_range { $$ = nullptr; DEL($2); } // UNSUP above here
1521 : : ;
1522 : :
1523 : : //**********************************************************************
1524 : : // Interface headers
1525 : :
1526 : : interface_declaration: // IEEE: interface_declaration + interface_nonansi_header + interface_ansi_header:
1527 : : // // timeunits_declarationE is instead in interface_item
1528 : : intFront importsAndParametersE portsStarE ';'
1529 : : interface_itemListE yENDINTERFACE endLabelE
1530 : : { if ($2) $1->addStmtsp($2);
1531 : : if ($3) $1->addStmtsp($3);
1532 : : if ($5) $1->addStmtsp($5);
1533 : : $1->hasParameterList($<flag>2); }
1534 : : | yEXTERN intFront parameter_port_listE portsStarE ';'
1535 : : { DEL($2->unlinkFrBack()); }
1536 : : // We allow interfaces to be declared after instantiations, so harmless
1537 : : ;
1538 : :
1539 : : intFront<nodeModulep>:
1540 : : yINTERFACE lifetimeE idAny/*new_interface*/
1541 : : { $$ = new AstIface{$<fl>3, *$3, PARSEP->libname()};
1542 : : $$->inLibrary(true);
1543 : : $$->lifetime($2);
1544 : : PARSEP->rootp()->addModulesp($$); }
1545 : : | intFront sigAttrScope { $$ = $1; }
1546 : : ;
1547 : :
1548 : : interface_itemListE<nodep>:
1549 : : /* empty */ { $$ = nullptr; }
1550 : : | interface_itemList { $$ = $1; }
1551 : : ;
1552 : :
1553 : : interface_itemList<nodep>:
1554 : : interface_item { $$ = $1; }
1555 : : | interface_itemList interface_item { $$ = addNextNull($1, $2); }
1556 : : ;
1557 : :
1558 : : interface_item<nodep>: // IEEE: interface_item + non_port_interface_item
1559 : : port_declaration ';' { $$ = $1; }
1560 : : // // IEEE: non_port_interface_item
1561 : : // // IEEE: generate_region
1562 : : | i_generate_region { $$ = $1; }
1563 : : | interface_or_generate_item { $$ = $1; }
1564 : : | program_declaration
1565 : : { $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: program decls within interface decls"); }
1566 : : // // IEEE 1800-2017: modport_item
1567 : : // // See instead old 2012 position in interface_or_generate_item
1568 : : | interface_declaration
1569 : : { $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: interface decls within interface decls"); }
1570 : : | timeunits_declaration { $$ = $1; }
1571 : : // // See note in interface_or_generate item
1572 : : | module_common_item { $$ = $1; }
1573 : : ;
1574 : :
1575 : : interface_or_generate_item<nodep>: // ==IEEE: interface_or_generate_item
1576 : : // // module_common_item in interface_item, as otherwise duplicated
1577 : : // // with module_or_generate_item's module_common_item
1578 : : modport_declaration { $$ = $1; }
1579 : : | extern_tf_declaration { $$ = $1; }
1580 : : ;
1581 : :
1582 : : //**********************************************************************
1583 : : // Program headers
1584 : :
1585 : : anonymous_program<nodep>: // ==IEEE: anonymous_program
1586 : : // // See the spec - this doesn't change the scope, items still go up "top"
1587 : : yPROGRAM ';' anonymous_program_itemListE yENDPROGRAM
1588 : : { $$ = nullptr;
1589 : : BBUNSUP($<fl>1, "Unsupported: Anonymous programs");
1590 : : VARDTYPE_NDECL(nullptr);
1591 : : DEL($3); }
1592 : : ;
1593 : :
1594 : : anonymous_program_itemListE<nodep>: // IEEE: { anonymous_program_item }
1595 : : /* empty */ { $$ = nullptr; }
1596 : : | anonymous_program_itemList { $$ = $1; }
1597 : : ;
1598 : :
1599 : : anonymous_program_itemList<nodep>: // IEEE: { anonymous_program_item }
1600 : : anonymous_program_item { $$ = $1; }
1601 : : | anonymous_program_itemList anonymous_program_item { $$ = addNextNull($1, $2); }
1602 : : ;
1603 : :
1604 : : anonymous_program_item<nodep>: // ==IEEE: anonymous_program_item
1605 : : task_declaration { $$ = $1; }
1606 : : | function_declaration { $$ = $1; }
1607 : : | class_declaration { $$ = $1; }
1608 : : // // IEEE-2023: Added: interface_class_declaration
1609 : : // // interface_class_declaration is part of class_declaration
1610 : : | covergroup_declaration { $$ = $1; }
1611 : : // // class_constructor_declaration is part of function_declaration
1612 : : | ';' { $$ = nullptr; }
1613 : : ;
1614 : :
1615 : : program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header:
1616 : : // // timeunits_declarationE is instead in program_item
1617 : : pgmFront parameter_port_listE portsStarE ';'
1618 : : /*cont*/ program_itemListE yENDPROGRAM endLabelE
1619 : : { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
1620 : : $1->hasParameterList($<flag>2);
1621 : : if ($2) $1->addStmtsp($2);
1622 : : if ($3) $1->addStmtsp($3);
1623 : : if ($5) $1->addStmtsp($5);
1624 : : GRAMMARP->endLabel($<fl>7, $1, $7); }
1625 : : | yEXTERN pgmFront parameter_port_listE portsStarE ';'
1626 : : { DEL($2->unlinkFrBack()); }
1627 : : // We allow programs to be declared after instantiations, so harmless
1628 : : ;
1629 : :
1630 : : pgmFront<nodeModulep>:
1631 : : yPROGRAM lifetimeE idAny/*new_program*/
1632 : : { $$ = new AstModule{$<fl>3, *$3, PARSEP->libname(), AstModule::Program{}};
1633 : : $$->lifetime($2);
1634 : : $$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn());
1635 : : $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
1636 : : $$->timeunit(PARSEP->timeLastUnit());
1637 : : PARSEP->rootp()->timeprecisionMerge($$->fileline(),
1638 : : PARSEP->timeLastPrec());
1639 : : PARSEP->rootp()->addModulesp($$); }
1640 : : ;
1641 : :
1642 : : program_itemListE<nodep>: // ==IEEE: [{ program_item }]
1643 : : /* empty */ { $$ = nullptr; }
1644 : : | program_itemList { $$ = $1; }
1645 : : ;
1646 : :
1647 : : program_itemList<nodep>: // ==IEEE: { program_item }
1648 : : program_item { $$ = $1; }
1649 : : | program_itemList program_item { $$ = addNextNull($1, $2); }
1650 : : ;
1651 : :
1652 : : program_item<nodep>: // ==IEEE: program_item
1653 : : port_declaration ';' { $$ = $1; }
1654 : : | non_port_program_item { $$ = $1; }
1655 : : ;
1656 : :
1657 : : non_port_program_item<nodep>: // ==IEEE: non_port_program_item
1658 : : continuous_assign { $$ = $1; }
1659 : : | module_or_generate_item_declaration { $$ = $1; }
1660 : : | initial_construct { $$ = $1; }
1661 : : | final_construct { $$ = $1; }
1662 : : | concurrent_assertion_item { $$ = $1; }
1663 : : | timeunits_declaration { $$ = $1; }
1664 : : | program_generate_item { $$ = $1; }
1665 : : ;
1666 : :
1667 : : program_generate_item<nodep>: // ==IEEE: program_generate_item
1668 : : loop_generate_construct { $$ = $1; }
1669 : : | conditional_generate_construct { $$ = $1; }
1670 : : | generate_region { $$ = $1; }
1671 : : // not in IEEE, but presumed so can do yBEGIN ... yEND
1672 : : | genItemBegin { $$ = $1; }
1673 : : | severity_system_task { $$ = $1; }
1674 : : ;
1675 : :
1676 : : extern_tf_declaration<nodep>: // ==IEEE: extern_tf_declaration
1677 : : yEXTERN task_prototype ';'
1678 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: extern task"); DEL($2); }
1679 : : | yEXTERN function_prototype ';'
1680 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: extern function"); DEL($2); }
1681 : : | yEXTERN yFORKJOIN task_prototype ';'
1682 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: extern forkjoin"); DEL($3); }
1683 : : ;
1684 : :
1685 : : modport_declaration<nodep>: // ==IEEE: modport_declaration
1686 : : yMODPORT modport_itemList ';' { $$ = $2; }
1687 : : ;
1688 : :
1689 : : modport_itemList<nodep>: // IEEE: part of modport_declaration
1690 : : modport_item { $$ = $1; }
1691 : : | modport_itemList ',' modport_item { $$ = addNextNull($1, $3); }
1692 : : ;
1693 : :
1694 : : modport_item<nodep>: // ==IEEE: modport_item
1695 : : idAny/*new-modport*/ '('
1696 : : /*mid*/ { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT);
1697 : : GRAMMARP->m_modportProtoTasksp = nullptr; }
1698 : : /*cont*/ modportPortsDeclList ')'
1699 : : { $$ = new AstModport{$<fl>1, *$1, $4};
1700 : : // Append any prototype tasks from import/export as interface siblings
1701 : : if (GRAMMARP->m_modportProtoTasksp) {
1702 : : $$ = AstNode::addNextNull(
1703 : : GRAMMARP->m_modportProtoTasksp, $$);
1704 : : GRAMMARP->m_modportProtoTasksp = nullptr;
1705 : : } }
1706 : : ;
1707 : :
1708 : : modportPortsDeclList<nodep>:
1709 : : modportPortsDecl { $$ = $1; }
1710 : : | modportPortsDeclList ',' modportPortsDecl { $$ = addNextNull($1, $3); }
1711 : : ;
1712 : :
1713 : : // IEEE: modport_ports_declaration + modport_simple_ports_declaration
1714 : : // + (modport_tf_ports_declaration+import_export) + modport_clocking_declaration
1715 : : // We've expanded the lists each take to instead just have standalone ID ports.
1716 : : // We track the type as with the V2k series of defines, then create as each ID is seen.
1717 : : modportPortsDecl<nodep>:
1718 : : // // IEEE: modport_simple_ports_declaration
1719 : : port_direction { GRAMMARP->m_modportImpExpActive = false; } modportSimplePortOrTFPort { $$ = $3; }
1720 : : // // IEEE: modport_clocking_declaration
1721 : : | yCLOCKING idAny/*clocking_identifier*/ { $$ = new AstModportClockingRef{$1, *$2}; }
1722 : : // // IEEE: yIMPORT modport_tf_port
1723 : : // // IEEE: yEXPORT modport_tf_port
1724 : : // // modport_tf_port expanded here
1725 : : | yIMPORT idAny/*tf_identifier*/
1726 : : { $$ = new AstModportFTaskRef{$<fl>2, *$2, false};
1727 : : GRAMMARP->m_modportImpExpActive = true;
1728 : : GRAMMARP->m_modportImpExpLastIsExport = false; }
1729 : : | yEXPORT idAny/*tf_identifier*/
1730 : : { $$ = new AstModportFTaskRef{$<fl>2, *$2, true};
1731 : : GRAMMARP->m_modportImpExpActive = true;
1732 : : GRAMMARP->m_modportImpExpLastIsExport = true; }
1733 : : | yIMPORT method_prototype
1734 : : { $$ = new AstModportFTaskRef{$<fl>2, $2->name(), false};
1735 : : GRAMMARP->m_modportImpExpActive = true;
1736 : : GRAMMARP->m_modportImpExpLastIsExport = false;
1737 : : // Import prototype: task should already exist in interface
1738 : : // (from export or direct declaration). Delete the prototype.
1739 : : DEL($2); }
1740 : : | yEXPORT method_prototype
1741 : : { $$ = new AstModportFTaskRef{$<fl>2, $2->name(), true};
1742 : : GRAMMARP->m_modportImpExpActive = true;
1743 : : GRAMMARP->m_modportImpExpLastIsExport = true;
1744 : : // Export: add prototype task to interface (as sibling of modport)
1745 : : GRAMMARP->m_modportProtoTasksp
1746 : : = AstNode::addNextNull(GRAMMARP->m_modportProtoTasksp, $2); }
1747 : : // Continuations of above after a comma.
1748 : : // // IEEE: modport_simple_ports_declaration
1749 : : | modportSimplePortOrTFPort { $$ = $1; }
1750 : : ;
1751 : :
1752 : : modportSimplePortOrTFPort<nodep>:// IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
1753 : : idAny { $$ = GRAMMARP->m_modportImpExpActive ?
1754 : : static_cast<AstNode*>(
1755 : : new AstModportFTaskRef{
1756 : : $<fl>1, *$1, GRAMMARP->m_modportImpExpLastIsExport} ) :
1757 : : static_cast<AstNode*>(
1758 : : new AstModportVarRef{
1759 : : $<fl>1, *$1, GRAMMARP->m_varIO} ); }
1760 : : | '.' idAny '(' ')' { $$ = new AstModportVarRef{$<fl>2, *$2, GRAMMARP->m_varIO};
1761 : : BBUNSUP($<fl>4, "Unsupported: Modport empty expression"); }
1762 : : | '.' idAny '(' expr ')' { $$ = new AstModportVarRef{$<fl>2, *$2, $4, GRAMMARP->m_varIO}; }
1763 : : ;
1764 : :
1765 : : //************************************************
1766 : : // Variable Declarations
1767 : :
1768 : : genvar_declaration<nodep>: // ==IEEE: genvar_declaration
1769 : : yGENVAR list_of_genvar_identifiers ';' { $$ = $2; }
1770 : : ;
1771 : :
1772 : : list_of_genvar_identifiers<nodep>: // IEEE: list_of_genvar_identifiers (for declaration)
1773 : : genvar_identifierDecl { $$ = $1; }
1774 : : | list_of_genvar_identifiers ',' genvar_identifierDecl { $$ = $1->addNext($3); }
1775 : : ;
1776 : :
1777 : : genvar_identifierDecl<varp>: // IEEE: genvar_identifier (for declaration)
1778 : : idAny/*new-genvar_identifier*/ sigAttrListE
1779 : : { VARRESET_NONLIST(GENVAR);
1780 : : AstNodeDType* const dtp = new AstBasicDType{$<fl>1, VBasicDTypeKwd::INTEGER};
1781 : : VARDTYPE(dtp);
1782 : : $$ = VARDONEA($<fl>1, *$1, nullptr, $2); }
1783 : : ;
1784 : :
1785 : : parameter_declaration<nodep>: // IEEE: local_ or parameter_declaration and type_parameter_declaration
1786 : : // // IEEE: yPARAMETER yTYPE list_of_type_assignments ';'
1787 : : // // Instead of list_of_type_assignments
1788 : : // // we use list_of_param_assignments because for port handling
1789 : : // // it already must accept types, so simpler to have code only one place
1790 : : // // Front must execute first so VARDTYPE is ready before list of vars
1791 : : parameter_declarationFront list_of_param_assignments { $$ = $2; }
1792 : : | parameter_declarationTypeFront list_of_type_assignments { $$ = $2; }
1793 : : ;
1794 : :
1795 : : parameter_declarationFront: // IEEE: local_ or parameter_declaration w/o assignment
1796 : : // // Front must execute first so VARDTYPE is ready before list of vars
1797 : : varParamReset implicit_typeE { /*VARRESET-in-varParam*/ VARDTYPE($2); }
1798 : : | varParamReset data_type { /*VARRESET-in-varParam*/ VARDTYPE($2); }
1799 : : ;
1800 : :
1801 : : parameter_declarationTypeFront: // IEEE: local_ or parameter_declaration w/o assignment
1802 : : // // Front must execute first so VARDTYPE is ready before list of vars
1803 : : varParamReset yTYPE__ETC
1804 : : { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$2}); }
1805 : : | varParamReset yTYPE__ETC forward_type
1806 : : { /*VARRESET-in-varParam*/
1807 : : AstNodeDType* const dtp = new AstParseTypeDType{$2, $3}; VARDTYPE(dtp); }
1808 : : ;
1809 : :
1810 : : parameter_port_declarationFrontE: // IEEE: local_ or parameter_port_declaration w/o assignment
1811 : : // // IEEE: parameter_declaration (minus assignment)
1812 : : // // IEEE: local_parameter_declaration (minus assignment)
1813 : : // // Front must execute first so VARDTYPE is ready before list of vars
1814 : : varParamReset implicit_typeE { /*VARRESET-in-varParam*/ VARDTYPE($2); }
1815 : : | varParamReset data_type { /*VARRESET-in-varParam*/ VARDTYPE($2); }
1816 : : | implicit_typeE
1817 : : { /*VARRESET-in-varParam*/
1818 : : // Keep previous type to handle subsequent declarations.
1819 : : // This rule is also used when the previous parameter is a type parameter
1820 : : if ($1) $1->v3error("parameter port declarations require 'parameter'"
1821 : : " keyword before implicit data types"
1822 : : " (IEEE 1800-2023 6.20.1/A.2.1.1)\n"
1823 : : + $1->warnMore()
1824 : : + "... Suggest add 'parameter' before here");
1825 : : }
1826 : : | data_type { /*VARRESET-in-varParam*/ VARDTYPE($1); }
1827 : : ;
1828 : :
1829 : : parameter_port_declarationTypeFrontE: // IEEE: parameter_port_declaration w/o assignment
1830 : : // // IEEE: parameter_declaration (minus assignment)
1831 : : // // IEEE: local_parameter_declaration (minus assignment)
1832 : : // // Front must execute first so VARDTYPE is ready before list of vars
1833 : : varParamReset yTYPE__ETC
1834 : : { /*VARRESET-in-varParam*/
1835 : : AstNodeDType* const dtp = new AstParseTypeDType{$2}; VARDTYPE(dtp); }
1836 : : | varParamReset yTYPE__ETC forward_type
1837 : : { /*VARRESET-in-varParam*/
1838 : : AstNodeDType* const dtp = new AstParseTypeDType{$2, $3}; VARDTYPE(dtp); }
1839 : : | yTYPE__ETC
1840 : : { /*VARRESET-in-varParam*/
1841 : : AstNodeDType* const dtp = new AstParseTypeDType{$1}; VARDTYPE(dtp); }
1842 : : | yTYPE__ETC forward_type
1843 : : { /*VARRESET-in-varParam*/
1844 : : AstNodeDType* const dtp = new AstParseTypeDType{$1, $2}; VARDTYPE(dtp); }
1845 : : ;
1846 : :
1847 : : forward_type<fwdtype>: // ==IEEE: forward_type
1848 : : yENUM { $$ = VFwdType::ENUM; }
1849 : : | ySTRUCT { $$ = VFwdType::STRUCT; }
1850 : : | yUNION { $$ = VFwdType::UNION; }
1851 : : | yCLASS { $$ = VFwdType::CLASS; }
1852 : : | yINTERFACE yCLASS { $$ = VFwdType::INTERFACE_CLASS; }
1853 : : ;
1854 : :
1855 : : net_declaration<nodep>: // IEEE: net_declaration - excluding implict
1856 : : net_declarationFront netSigList ';'
1857 : : { $$ = $2;
1858 : : if (GRAMMARP->m_netStrengthp) {
1859 : : VL_DO_CLEAR(delete GRAMMARP->m_netStrengthp, GRAMMARP->m_netStrengthp = nullptr);
1860 : : }
1861 : : GRAMMARP->setNetDelay(nullptr); }
1862 : : ;
1863 : :
1864 : : net_declarationFront: // IEEE: beginning of net_declaration
1865 : : net_declRESET net_type driveStrengthE net_scalaredE net_dataTypeE
1866 : : { VARDTYPE_NDECL($5);
1867 : : GRAMMARP->setNetStrength($3); }
1868 : : | net_declRESET yINTERCONNECT signingE rangeListE
1869 : : { BBUNSUP($<fl>2, "Unsupported: interconnect");
1870 : : VARDECL(WIRE);
1871 : : AstNodeDType* const dtp = GRAMMARP->addRange(
1872 : : new AstBasicDType{$2, LOGIC_IMPLICIT, $3}, $4, true);
1873 : : VARDTYPE_NDECL(dtp); }
1874 : : ;
1875 : :
1876 : : net_declRESET:
1877 : : /* empty */ { VARRESET_NONLIST(UNKNOWN); }
1878 : : ;
1879 : :
1880 : : net_scalaredE:
1881 : : /* empty */ { }
1882 : : // //UNSUP: ySCALARED/yVECTORED ignored
1883 : : | ySCALARED { }
1884 : : | yVECTORED { }
1885 : : ;
1886 : :
1887 : : net_dataTypeE<nodeDTypep>:
1888 : : // // If there's a SV data type there shouldn't be a delay on this wire
1889 : : // // Otherwise #(...) can't be determined to be a delay or parameters
1890 : : // // Submit this as a footnote to the committee
1891 : : var_data_type { $$ = $1; }
1892 : : | signingE rangeList delay_controlE
1893 : : { $$ = GRAMMARP->addRange(new AstBasicDType{$2->fileline(), LOGIC, $1},
1894 : : $2, true);
1895 : : GRAMMARP->setNetDelay($3); } // not implicit
1896 : : | signing
1897 : : { $$ = new AstBasicDType{$<fl>1, LOGIC, $1}; } // not implicit
1898 : : | /*implicit*/ delay_controlE
1899 : : { $$ = new AstBasicDType{CRELINE(), LOGIC};
1900 : : GRAMMARP->setNetDelay($1); } // not implicit
1901 : : ;
1902 : :
1903 : : net_type: // ==IEEE: net_type
1904 : : ySUPPLY0 { VARDECL(SUPPLY0); }
1905 : : | ySUPPLY1 { VARDECL(SUPPLY1); }
1906 : : | yTRI { VARDECL(TRIWIRE); }
1907 : : | yTRI0 { VARDECL(TRI0); }
1908 : : | yTRI1 { VARDECL(TRI1); }
1909 : : | yTRIAND { VARDECL(TRIAND); }
1910 : : | yTRIOR { VARDECL(TRIOR); }
1911 : : | yTRIREG { VARDECL(WIRE); BBUNSUP($1, "Unsupported: trireg"); }
1912 : : | yWAND { VARDECL(TRIAND); }
1913 : : | yWIRE { VARDECL(WIRE); }
1914 : : | yWOR { VARDECL(TRIOR); }
1915 : : // // VAMS - somewhat hackish
1916 : : | yWREAL { VARDECL(WREAL); }
1917 : : ;
1918 : :
1919 : : varParamReset:
1920 : : yPARAMETER { VARRESET_NONLIST(GPARAM); }
1921 : : | yLOCALPARAM { VARRESET_NONLIST(LPARAM); }
1922 : : // Note that the type of these params could be modified later according to context (see V3LinkParse)
1923 : : ;
1924 : :
1925 : : port_direction: // ==IEEE: port_direction + tf_port_direction
1926 : : // // IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here
1927 : : // // Only used for ANSI declarations
1928 : : yINPUT { VARIO(INPUT); }
1929 : : | yOUTPUT { VARIO(OUTPUT); }
1930 : : | yINOUT { VARIO(INOUT); }
1931 : : | yREF { VARIO(REF); }
1932 : : // // IEEE 1800-2023: Added 'ref static' and 'const ref static'
1933 : : | yREF ySTATIC__ETC { VARIO(REF);
1934 : : BBUNSUP($1, "Unsupported: 'ref static' ports"); }
1935 : : | yCONST__REF yREF { VARIO(CONSTREF); }
1936 : : | yCONST__REF yREF ySTATIC__ETC { VARIO(CONSTREF);
1937 : : BBUNSUP($1, "Unsupported: 'ref static' ports"); }
1938 : : ;
1939 : :
1940 : : port_directionReset: // IEEE: port_direction that starts a port_declaraiton
1941 : : // // Used only for declarations outside the port list
1942 : : yINPUT { VARRESET_NONLIST(UNKNOWN); VARIO(INPUT); }
1943 : : | yOUTPUT { VARRESET_NONLIST(UNKNOWN); VARIO(OUTPUT); }
1944 : : | yINOUT { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); }
1945 : : | yREF { VARRESET_NONLIST(UNKNOWN); VARIO(REF); }
1946 : : | yCONST__REF yREF { VARRESET_NONLIST(UNKNOWN); VARIO(CONSTREF); }
1947 : : ;
1948 : :
1949 : : port_declaration<nodep>: // ==IEEE: port_declaration
1950 : : // // Non-ANSI; used inside block followed by ';'
1951 : : // // SEE ALSO port, tf_port_declaration, data_declarationVarFront
1952 : : //
1953 : : // // IEEE: inout_declaration
1954 : : // // IEEE: input_declaration
1955 : : // // IEEE: output_declaration
1956 : : // // IEEE: ref_declaration
1957 : : port_directionReset port_declNetE data_type
1958 : : /*mid*/ { VARDTYPE($3); }
1959 : : /*cont*/ list_of_variable_decl_assignments { $$ = $5; }
1960 : : | port_directionReset port_declNetE yVAR data_type
1961 : : /*mid*/ { VARDECL(VAR); VARDTYPE($4); }
1962 : : /*cont*/ list_of_variable_decl_assignments { $$ = $6; }
1963 : : | port_directionReset port_declNetE yVAR implicit_typeE
1964 : : /*mid*/ { VARDECL(VAR); VARDTYPE($4); }
1965 : : /*cont*/ list_of_variable_decl_assignments { $$ = $6; }
1966 : : | port_directionReset port_declNetE signingE rangeList
1967 : : /*mid*/ { AstNodeDType* const dtp = GRAMMARP->addRange(
1968 : : new AstBasicDType{$4->fileline(), LOGIC_IMPLICIT, $3}, $4, true);
1969 : : VARDTYPE_NDECL(dtp); }
1970 : : /*cont*/ list_of_variable_decl_assignments { $$ = $6; }
1971 : : | port_directionReset port_declNetE signing
1972 : : /*mid*/ { AstNodeDType* const dtp = new AstBasicDType{$<fl>3, LOGIC_IMPLICIT, $3};
1973 : : VARDTYPE_NDECL(dtp); }
1974 : : /*cont*/ list_of_variable_decl_assignments { $$ = $5; }
1975 : : | port_directionReset port_declNetE /*implicit*/
1976 : : /*mid*/ { VARDTYPE_NDECL(nullptr); /*default_nettype*/ }
1977 : : /*cont*/ list_of_variable_decl_assignments { $$ = $4; }
1978 : : //
1979 : : // // IEEE: interface_port_declaration
1980 : : // // IEEE: interface_identifier list_of_interface_identifiers
1981 : : //
1982 : : // // Identical to variable_declaration, resolve in V3LinkDot when id known
1983 : : // // NO: id/*interface*/ mpInstnameList
1984 : : //
1985 : : // // IEEE: interface_port_declaration
1986 : : // // IEEE: interface_identifier '.' modport_identifier list_of_interface_identifiers
1987 : : | id/*interface*/ '.' idAny/*modport*/
1988 : : /*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF);
1989 : : AstIfaceRefDType* const dtp = new AstIfaceRefDType{$<fl>1, $<fl>3, "", *$1, *$3};
1990 : : dtp->isPortDecl(true);
1991 : : VARDTYPE(dtp); }
1992 : : /*cont*/ mpInstnameList
1993 : : { $$ = VARDONEP($5, nullptr, nullptr); DEL($5); }
1994 : : //UNSUP: strengthSpecE for udp_instantiations
1995 : : ;
1996 : :
1997 : : tf_port_declaration<nodep>: // ==IEEE: tf_port_declaration
1998 : : // // Used inside function; followed by ';'
1999 : : // // SEE ALSO port_declaration, port, data_declarationVarFront
2000 : : //
2001 : : port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';'
2002 : : { $$ = $4; }
2003 : : | port_directionReset implicit_typeE { VARDTYPE_NDECL($2); } list_of_tf_variable_identifiers ';'
2004 : : { $$ = $4; }
2005 : : | port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';'
2006 : : { $$ = $5; }
2007 : : | port_directionReset yVAR implicit_typeE { VARDTYPE($3); } list_of_tf_variable_identifiers ';'
2008 : : { $$ = $5; }
2009 : : ;
2010 : :
2011 : : integer_atom_type<basicDTypep>: // ==IEEE: integer_atom_type
2012 : : yBYTE { $$ = new AstBasicDType{$1, VBasicDTypeKwd::BYTE}; }
2013 : : | ySHORTINT { $$ = new AstBasicDType{$1, VBasicDTypeKwd::SHORTINT}; }
2014 : : | yINT { $$ = new AstBasicDType{$1, VBasicDTypeKwd::INT}; }
2015 : : | yLONGINT { $$ = new AstBasicDType{$1, VBasicDTypeKwd::LONGINT}; }
2016 : : | yINTEGER { $$ = new AstBasicDType{$1, VBasicDTypeKwd::INTEGER}; }
2017 : : | yTIME { $$ = new AstBasicDType{$1, VBasicDTypeKwd::TIME}; }
2018 : : ;
2019 : :
2020 : : integer_vector_type<basicDTypep>: // ==IEEE: integer_atom_type
2021 : : yBIT { $$ = new AstBasicDType{$1, VBasicDTypeKwd::BIT}; }
2022 : : | yLOGIC { $$ = new AstBasicDType{$1, VBasicDTypeKwd::LOGIC}; }
2023 : : | yREG { $$ = new AstBasicDType{$1, VBasicDTypeKwd::LOGIC}; } // logic==reg
2024 : : ;
2025 : :
2026 : : non_integer_type<basicDTypep>: // ==IEEE: non_integer_type
2027 : : yREAL { $$ = new AstBasicDType{$1, VBasicDTypeKwd::DOUBLE}; }
2028 : : | yREALTIME { $$ = new AstBasicDType{$1, VBasicDTypeKwd::DOUBLE}; }
2029 : : | ySHORTREAL { $$ = new AstBasicDType{$1, VBasicDTypeKwd::DOUBLE}; UNSUPREAL($1); }
2030 : : ;
2031 : :
2032 : : signingE<signstate>: // IEEE: signing - plus empty
2033 : : /*empty*/ { $$ = VSigning::NOSIGN; }
2034 : : | signing { $$ = $1; }
2035 : : ;
2036 : :
2037 : : signing<signstate>: // ==IEEE: signing
2038 : : ySIGNED { $<fl>$ = $<fl>1; $$ = VSigning::SIGNED; }
2039 : : | yUNSIGNED { $<fl>$ = $<fl>1; $$ = VSigning::UNSIGNED; }
2040 : : ;
2041 : :
2042 : : //************************************************
2043 : : // Data Types
2044 : :
2045 : : simple_typeNoRef<nodeDTypep>: // IEEE: simple_type without idType
2046 : : // // IEEE: integer_type
2047 : : integer_atom_type { $$ = $1; }
2048 : : | integer_vector_type { $$ = $1; }
2049 : : | non_integer_type { $$ = $1; }
2050 : : //
2051 : : // // { generate_block_identifer ... } '.'
2052 : : // // Need to determine if generate_block_identifier can be lex-detected
2053 : : ;
2054 : :
2055 : : data_type<nodeDTypep>: // ==IEEE: data_type
2056 : : // // IEEE: data_type_or_incomplete_class_scoped_type parses same as this
2057 : : // // as can't tell them apart until link
2058 : : // // This expansion also replicated elsewhere, IE data_type__AndID
2059 : : data_typeNoRef { $$ = $1; }
2060 : : //
2061 : : // // REFERENCES
2062 : : //
2063 : : // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
2064 : : // // IEEE: class_type
2065 : : // // IEEE: ps_covergroup_identifier
2066 : : // // Don't distinguish between types and classes so all these combined
2067 : : | packageClassScopeE idType packed_dimensionListE
2068 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, nullptr};
2069 : : $$ = GRAMMARP->createArray(refp, $3, true); }
2070 : : | packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE
2071 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3};
2072 : : $$ = GRAMMARP->createArray(refp, $4, true); }
2073 : : ;
2074 : :
2075 : : data_typeAny<nodeDTypep>: // ==IEEE: data_type (accepting idAny)
2076 : : // // IEEE: data_type_or_incomplete_class_scoped_type parses same as this
2077 : : // // as can't tell them apart until link
2078 : : // // This expansion also replicated elsewhere, IE data_type__AndID
2079 : : data_typeNoRef { $$ = $1; }
2080 : : //
2081 : : // // REFERENCES
2082 : : //
2083 : : // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
2084 : : // // IEEE: class_type
2085 : : // // IEEE: ps_covergroup_identifier
2086 : : // // Don't distinguish between types and classes so all these combined
2087 : : | packageClassScopeE idAny packed_dimensionListE
2088 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, nullptr};
2089 : : $$ = GRAMMARP->createArray(refp, $3, true); }
2090 : : | packageClassScopeE idAny parameter_value_assignmentClass packed_dimensionListE
2091 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3};
2092 : : $$ = GRAMMARP->createArray(refp, $4, true); }
2093 : : ;
2094 : :
2095 : : data_typeBasic<nodeDTypep>: // IEEE: part of data_type
2096 : : integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1, $3, true); }
2097 : : | integer_atom_type signingE { $1->setSignedState($2); $$ = $1; }
2098 : : | non_integer_type { $$ = $1; }
2099 : : ;
2100 : :
2101 : : data_typeNoRef<nodeDTypep>: // ==IEEE: data_type, excluding class_type etc references
2102 : : data_typeBasic { $$ = $1; }
2103 : : | struct_unionDecl packed_dimensionListE
2104 : : { $$ = GRAMMARP->createArray(
2105 : : new AstDefImplicitDType{$1->fileline(),
2106 : : "__typeimpsu" + cvtToStr(GRAMMARP->s_typeImpNum++),
2107 : : VFlagChildDType{}, $1}, $2, true); }
2108 : : | enumDecl packed_dimensionListE
2109 : : { $$ = GRAMMARP->createArray(
2110 : : new AstDefImplicitDType{$1->fileline(),
2111 : : "__typeimpenum" + cvtToStr(GRAMMARP->s_typeImpNum++),
2112 : : VFlagChildDType{}, $1}, $2, true); }
2113 : : | ySTRING
2114 : : { $$ = new AstBasicDType{$1, VBasicDTypeKwd::STRING}; }
2115 : : | yCHANDLE
2116 : : { $$ = new AstBasicDType{$1, VBasicDTypeKwd::CHANDLE}; }
2117 : : | yEVENT
2118 : : { $$ = new AstBasicDType{$1, VBasicDTypeKwd::EVENT}; v3Global.setHasEvents(); }
2119 : : | type_referenceDecl { $$ = $1; }
2120 : : // // IEEE: class_scope: see data_type above
2121 : : // // IEEE: class_type: see data_type above
2122 : : // // IEEE: ps_covergroup: see data_type above
2123 : : // // Rules overlap virtual_interface_declaration
2124 : : | yVIRTUAL__INTERFACE yINTERFACE data_typeVirtual
2125 : : { $$ = $3; }
2126 : : | yVIRTUAL__anyID data_typeVirtual
2127 : : { $$ = $2; }
2128 : : ;
2129 : :
2130 : : data_typeVirtual<nodeDTypep>: // ==IEEE: data_type after yVIRTUAL [ yINTERFACE ]
2131 : : // // Parameters here are SV2009
2132 : : idAny/*interface*/
2133 : : { AstIfaceRefDType* const ifrefp = new AstIfaceRefDType{$<fl>1, "", *$1};
2134 : : ifrefp->isVirtual(true);
2135 : : $$ = ifrefp; }
2136 : : | idAny/*interface*/ '.' idAny/*modport*/
2137 : : { AstIfaceRefDType* const ifrefp = new AstIfaceRefDType{$<fl>1, $<fl>3, "", *$1, *$3};
2138 : : ifrefp->isVirtual(true);
2139 : : $$ = ifrefp; }
2140 : : | idAny/*interface*/ parameter_value_assignmentClass
2141 : : { AstIfaceRefDType* const ifrefp = new AstIfaceRefDType{$<fl>1, nullptr, "", *$1, "", $2};
2142 : : ifrefp->isVirtual(true);
2143 : : $$ = ifrefp; }
2144 : : | idAny/*interface*/ parameter_value_assignmentClass '.' idAny/*modport*/
2145 : : { AstIfaceRefDType* const ifrefp = new AstIfaceRefDType{$<fl>1, $<fl>4, "", *$1, *$4, $2};
2146 : : ifrefp->isVirtual(true);
2147 : : $$ = ifrefp; }
2148 : : ;
2149 : :
2150 : : data_type_or_void<nodeDTypep>: // ==IEEE: data_type_or_void
2151 : : data_typeAny { $$ = $1; }
2152 : : | yVOID
2153 : : { $$ = new AstBasicDType{$1, VBasicDTypeKwd::CVOID}; }
2154 : : ;
2155 : :
2156 : : var_data_type<nodeDTypep>: // ==IEEE: var_data_type
2157 : : data_type { $$ = $1; }
2158 : : | yVAR data_type { $$ = $2; }
2159 : : | yVAR implicit_typeE { $$ = $2; }
2160 : : ;
2161 : :
2162 : : type_referenceBoth<nodeExprp>: // IEEE: type_reference
2163 : : yTYPE__ETC '(' exprOrDataType ')'
2164 : : { $$ = new AstAttrOf{$1, VAttrType::TYPEID, $3}; }
2165 : : ;
2166 : :
2167 : : type_referenceDecl<nodeDTypep>: // IEEE: type_reference (as a data type for declaration)
2168 : : yTYPE__ETC '(' exprOrDataType ')'
2169 : : { $$ = new AstRefDType{$1, AstRefDType::FlagTypeOfExpr{}, $3}; }
2170 : : ;
2171 : :
2172 : : type_referenceEq<nodeExprp>: // IEEE: type_reference (as an ==/!== expression)
2173 : : yTYPE__EQ '(' exprOrDataType ')'
2174 : : { $$ = new AstAttrOf{$1, VAttrType::TYPEID, $3}; }
2175 : : ;
2176 : :
2177 : : struct_unionDecl<nodeUOrStructDTypep>: // IEEE: part of data_type
2178 : : // // packedSigningE is NOP for unpacked
2179 : : ySTRUCT packedSigningE '{'
2180 : : /*mid*/ { $<nodeUOrStructDTypep>$ = new AstStructDType{$1, $2}; }
2181 : : /*cont*/ struct_union_memberListEnd
2182 : : { $$ = $<nodeUOrStructDTypep>4; $$->addMembersp($5); }
2183 : : | yUNION taggedSoftE packedSigningE '{'
2184 : : /*mid*/ { $<nodeUOrStructDTypep>$ = new AstUnionDType{$1, $2 == tagged_SOFT, $2 == tagged_TAGGED, $3}; }
2185 : : /*cont*/ struct_union_memberListEnd
2186 : : { $$ = $<nodeUOrStructDTypep>5; $$->addMembersp($6); }
2187 : : ;
2188 : :
2189 : : struct_union_memberListEnd<memberDTypep>: // IEEE: { struct_union_member } '}'
2190 : : struct_union_memberList '}' { $$ = $1; }
2191 : : //
2192 : : | struct_union_memberList error '}' { $$ = $1; } // LCOV_EXCL_LINE
2193 : : | error '}' { $$ = nullptr; } // LCOV_EXCL_LINE
2194 : : ;
2195 : :
2196 : : struct_union_memberList<memberDTypep>: // IEEE: { struct_union_member }
2197 : : struct_union_member { $$ = $1; }
2198 : :
2199 : : | struct_union_memberList struct_union_member { $$ = addNextNull($1, $2); }
2200 : : //
2201 : : | struct_union_memberList error ';' { $$ = $1; } // LCOV_EXCL_LINE
2202 : : | error ';' { $$ = nullptr; } // LCOV_EXCL_LINE
2203 : : ;
2204 : :
2205 : : struct_union_member<memberDTypep>: // ==IEEE: struct_union_member
2206 : : // // UNSUP random_qualifer not propagated until have randomize support
2207 : : random_qualifierE data_type_or_void
2208 : : /*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member.
2209 : : /*cont*/ list_of_member_decl_assignments ';'
2210 : : { $$ = $4; DEL(GRAMMARP->m_memDTypep); GRAMMARP->m_memDTypep = nullptr; }
2211 : : | vlTag { $$ = nullptr; }
2212 : : ;
2213 : :
2214 : : list_of_member_decl_assignments<memberDTypep>: // Derived from IEEE: list_of_variable_decl_assignments
2215 : : member_decl_assignment { $$ = $1; }
2216 : : | list_of_member_decl_assignments ',' member_decl_assignment { $$ = addNextNull($1, $3); }
2217 : : ;
2218 : :
2219 : : member_decl_assignment<memberDTypep>: // Derived from IEEE: variable_decl_assignment
2220 : : // // At present we allow only packed structures/unions.
2221 : : // // So this is different from variable_decl_assignment
2222 : : idAny variable_dimensionListE
2223 : : { $$ = new AstMemberDType{$<fl>1, *$1, VFlagChildDType{},
2224 : : GRAMMARP->createArray((GRAMMARP->m_memDTypep
2225 : : ? GRAMMARP->m_memDTypep->cloneTree(true) : nullptr),
2226 : : $2, false),
2227 : : nullptr};
2228 : : PARSEP->tagNodep($$);
2229 : : }
2230 : : | idAny variable_dimensionListE '=' variable_declExpr
2231 : : { $$ = new AstMemberDType{$<fl>1, *$1, VFlagChildDType{},
2232 : : GRAMMARP->createArray((GRAMMARP->m_memDTypep
2233 : : ? GRAMMARP->m_memDTypep->cloneTree(true) : nullptr),
2234 : : $2, false),
2235 : : $4};
2236 : : PARSEP->tagNodep($$);
2237 : : }
2238 : : | idSVKwd { $$ = nullptr; }
2239 : : //
2240 : : // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
2241 : : // // Matches above with variable_dimensionE = "[]"
2242 : : // // IEEE: "class_variable_identifier [ '=' class_new ]"
2243 : : // // variable_dimensionE must be empty
2244 : : // // Pushed into variable_declExpr:dynamic_array_new
2245 : : ;
2246 : :
2247 : : list_of_variable_decl_assignments<varp>: // ==IEEE: list_of_variable_decl_assignments
2248 : : variable_decl_assignment { $$ = $1; }
2249 : : | list_of_variable_decl_assignments ',' variable_decl_assignment { $$ = addNextNull($1, $3); }
2250 : : ;
2251 : :
2252 : : variable_decl_assignment<varp>: // ==IEEE: variable_decl_assignment
2253 : : id variable_dimensionListE sigAttrListE
2254 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3); }
2255 : : | id variable_dimensionListE sigAttrListE '=' variable_declExpr
2256 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3); $$->valuep($5); }
2257 : : | idSVKwd { $$ = nullptr; }
2258 : : //
2259 : : // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
2260 : : | id variable_dimensionListE sigAttrListE yP_EQ__NEW dynamic_array_new
2261 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3); $$->valuep($5); }
2262 : : // // IEEE: "class_variable_identifier [ '=' class_new ]"
2263 : : // // variable_dimensionE must be empty
2264 : : | id variable_dimensionListE sigAttrListE yP_EQ__NEW class_new
2265 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3); $$->valuep($5); }
2266 : : ;
2267 : :
2268 : : list_of_tf_variable_identifiers<nodep>: // ==IEEE: list_of_tf_variable_identifiers
2269 : : tf_variable_identifier { $$ = $1; }
2270 : : | list_of_tf_variable_identifiers ',' tf_variable_identifier { $$ = $1->addNext($3); }
2271 : : ;
2272 : :
2273 : : tf_variable_identifier<varp>: // IEEE: part of list_of_tf_variable_identifiers
2274 : : id variable_dimensionListE sigAttrListE exprEqE
2275 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3);
2276 : : if ($4) AstNode::addNext<AstNode, AstNode>(
2277 : : $$, new AstAssign{$4->fileline(), new AstParseRef{$<fl>1, *$1}, $4}); }
2278 : : ;
2279 : :
2280 : : variable_declExpr<nodep>: // IEEE: part of variable_decl_assignment - rhs of expr
2281 : : expr { $$ = $1; }
2282 : : | dynamic_array_new { $$ = $1; }
2283 : : | class_newNoScope { $$ = $1; }
2284 : : ;
2285 : :
2286 : : variable_dimensionListE<nodeRangep>: // IEEE: variable_dimension + empty
2287 : : /*empty*/ { $$ = nullptr; }
2288 : : | variable_dimensionList { $$ = $1; }
2289 : : ;
2290 : :
2291 : : variable_dimensionList<nodeRangep>: // IEEE: variable_dimension + empty
2292 : : variable_dimension { $$ = $1; }
2293 : : | variable_dimensionList variable_dimension { $$ = $1->addNext($2); }
2294 : : ;
2295 : :
2296 : : variable_dimension<nodeRangep>: // ==IEEE: variable_dimension
2297 : : // // IEEE: unsized_dimension
2298 : : '[' ']' { $$ = new AstUnsizedRange{$1}; }
2299 : : // // IEEE: unpacked_dimension
2300 : : | anyrange { $$ = $1; }
2301 : : // // IEEE: unpacked_dimension (if const_expr)
2302 : : // // IEEE: associative_dimension (if data_type)
2303 : : // // Can't tell which until see if expr is data type or not
2304 : : | '[' exprOrDataType ']' { $$ = new AstBracketRange{$1, $2}; }
2305 : : | yP_BRASTAR ']' { $$ = new AstWildcardRange{$1}; }
2306 : : | '[' '*' ']' { $$ = new AstWildcardRange{$1}; }
2307 : : // // IEEE: queue_dimension
2308 : : // // '[' '$' ']' -- $ is part of expr, see '[' constExpr ']'
2309 : : // // '[' '$' ':' expr ']' -- anyrange:expr:$
2310 : : ;
2311 : :
2312 : : random_qualifierE<qualifiers>: // IEEE: random_qualifier + empty
2313 : : /*empty*/ { $$ = VMemberQualifiers::none(); }
2314 : : | random_qualifier { $$ = $1; }
2315 : : ;
2316 : :
2317 : : random_qualifier<qualifiers>: // ==IEEE: random_qualifier
2318 : : yRAND { $$ = VMemberQualifiers::none(); $$.m_rand = true; }
2319 : : | yRANDC { $$ = VMemberQualifiers::none(); $$.m_randc = true; }
2320 : : ;
2321 : :
2322 : : taggedSoftE<taggedstate>:
2323 : : /*empty*/ { $$ = tagged_NONE; }
2324 : : | ySOFT { $$ = tagged_SOFT; }
2325 : : | yTAGGED { $$ = tagged_TAGGED; }
2326 : : ;
2327 : :
2328 : : packedSigningE<signstate>:
2329 : : // // VSigning::NOSIGN overloaded to indicate not packed
2330 : : /*empty*/ { $$ = VSigning::NOSIGN; }
2331 : : | yPACKED signingE { $$ = $2; if ($$ == VSigning::NOSIGN) $$ = VSigning::UNSIGNED; }
2332 : : ;
2333 : :
2334 : : //************************************************
2335 : : // enum
2336 : :
2337 : : // IEEE: part of data_type
2338 : : enumDecl<nodeDTypep>:
2339 : : yENUM enum_base_typeE '{' enum_nameList '}'
2340 : : { $$ = new AstEnumDType{$1, VFlagChildDType{}, $2, $4}; }
2341 : : ;
2342 : :
2343 : : enum_base_typeE<nodeDTypep>: // IEEE: enum_base_type
2344 : : /* empty */
2345 : : { $$ = new AstBasicDType{CRELINE(), VBasicDTypeKwd::INT}; }
2346 : : // // Not in spec, but obviously "enum [1:0]" should work
2347 : : // // implicit_type expanded, without empty
2348 : : // // Note enum base types are always packed data types
2349 : : | signingE rangeList
2350 : : { $$ = GRAMMARP->addRange(new AstBasicDType{$2->fileline(), LOGIC_IMPLICIT, $1}, $2, true); }
2351 : : | signing
2352 : : { $$ = new AstBasicDType{$<fl>1, LOGIC_IMPLICIT, $1}; }
2353 : : //
2354 : : | integer_atom_type signingE
2355 : : { $1->setSignedState($2); $$ = $1; }
2356 : : | integer_vector_type signingE rangeListE
2357 : : { $1->setSignedState($2); $$ = GRAMMARP->addRange($1, $3, true); }
2358 : : // // below can be idAny or yaID__aTYPE
2359 : : // // IEEE requires a type, though no shift conflict if idAny
2360 : : // // IEEE: type_identifier [ packed_dimension ]
2361 : : // // however other simulators allow [ class_scope | package_scope ] type_identifier
2362 : : | idAny rangeListE
2363 : : { $$ = GRAMMARP->createArray(new AstRefDType{$<fl>1, *$1}, $2, true); }
2364 : : | packageClassScope idAny rangeListE
2365 : : { AstRefDType* refp = new AstRefDType{$<fl>2, *$2, $1, nullptr};
2366 : : $$ = GRAMMARP->createArray(refp, $3, true); }
2367 : : ;
2368 : :
2369 : : enum_nameList<enumItemp>:
2370 : : enum_name_declaration { $$ = $1; }
2371 : : | enum_nameList ',' enum_name_declaration { $$ = addNextNull($1, $3); }
2372 : : ;
2373 : :
2374 : : enum_name_declaration<enumItemp>: // ==IEEE: enum_name_declaration
2375 : : idAny/*enum_identifier*/ enumNameRangeE enumNameStartE
2376 : : { $$ = new AstEnumItem{$<fl>1, *$1, $2, $3}; }
2377 : : ;
2378 : :
2379 : : enumNameRangeE<rangep>: // IEEE: second part of enum_name_declaration
2380 : : /* empty */
2381 : : { $$ = nullptr; }
2382 : : | '[' intnumAsConst ']'
2383 : : { $$ = new AstRange{$1, new AstConst{$1, 0}, new AstConst($1, $2->toSInt() - 1)}; DEL($2); }
2384 : : | '[' intnumAsConst ':' intnumAsConst ']'
2385 : : { $$ = new AstRange{$1, $2, $4}; }
2386 : : ;
2387 : :
2388 : : enumNameStartE<nodeExprp>: // IEEE: third part of enum_name_declaration
2389 : : /* empty */ { $$ = nullptr; }
2390 : : | '=' constExpr { $$ = $2; }
2391 : : ;
2392 : :
2393 : : intnumAsConst<constp>:
2394 : : yaINTNUM { $$ = new AstConst{$<fl>1, *$1}; }
2395 : : ;
2396 : :
2397 : : //************************************************
2398 : : // Typedef
2399 : :
2400 : : data_declaration<nodep>: // ==IEEE: data_declaration
2401 : : // // VARRESET can't be called here - conflicts
2402 : : data_declarationVar { $$ = $1; }
2403 : : | type_declaration { $$ = $1; }
2404 : : | package_import_declaration { $$ = $1; }
2405 : : // // IEEE: virtual_interface_declaration
2406 : : // // "yVIRTUAL yID yID" looks just like a data_declaration
2407 : : // // Therefore the virtual_interface_declaration term isn't used
2408 : : // // 1800-2009:
2409 : : | nettype_declaration { $$ = $1; }
2410 : : | vlTag { $$ = nullptr; }
2411 : : ;
2412 : :
2413 : : class_property<nodep>: // ==IEEE: class_property, which is {property_qualifier} data_declaration
2414 : : memberQualListE data_declarationVarClass
2415 : : { $$ = $2; $1.applyToNodes($2); }
2416 : : | memberQualListE type_declaration
2417 : : { $$ = $2; if (VN_IS($2, Typedef)) $1.applyToNodes(VN_AS($2, Typedef)); }
2418 : : // // UNSUP: Import needs to apply local/protected from memberQualList, and error on others
2419 : : | memberQualListE package_import_declaration
2420 : : { $$ = $2; }
2421 : : // // IEEE: virtual_interface_declaration
2422 : : // // "yVIRTUAL yID yID" looks just like a data_declaration
2423 : : // // Therefore the virtual_interface_declaration term isn't used
2424 : : ;
2425 : :
2426 : : data_declarationVar<varp>: // IEEE: part of data_declaration
2427 : : // // The first declaration has complications between assuming what's
2428 : : // // the type vs ID declaring
2429 : : data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; }
2430 : : ;
2431 : :
2432 : : data_declarationVarClass<varp>: // IEEE: part of data_declaration (for class_property)
2433 : : // // The first declaration has complications between assuming what's
2434 : : // // the type vs ID declaring
2435 : : data_declarationVarFrontClass list_of_variable_decl_assignments ';' { $$ = $2; }
2436 : : ;
2437 : :
2438 : : data_declarationVarFront: // IEEE: part of data_declaration
2439 : : // // Non-ANSI; used inside block followed by ';'
2440 : : // // SEE ALSO port_declaration, tf_port_declaration, port
2441 : : //
2442 : : // // Expanded: "constE yVAR lifetimeE data_type"
2443 : : // // implicit_type expanded into /*empty*/ or "signingE rangeList"
2444 : : yVAR lifetimeE data_type
2445 : : { VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); }
2446 : : | yVAR lifetimeE
2447 : : { VARRESET_NONLIST(VAR); VARLIFE($2);
2448 : : AstNodeDType* const dtp = new AstBasicDType{$<fl>1, LOGIC_IMPLICIT};
2449 : : VARDTYPE(dtp); }
2450 : : | yVAR lifetimeE signingE rangeList
2451 : : { /*VARRESET-in-ddVar*/ VARLIFE($2);
2452 : : AstNodeDType* const dtp = GRAMMARP->addRange(
2453 : : new AstBasicDType{$<fl>1, LOGIC_IMPLICIT, $3}, $4, true);
2454 : : VARDTYPE(dtp); }
2455 : : //
2456 : : // // implicit_type expanded into /*empty*/ or "signingE rangeList"
2457 : : | yCONST__ETC yVAR lifetimeE data_type
2458 : : { VARRESET_NONLIST(VAR); VARLIFE($3);
2459 : : AstNodeDType* const dtp = new AstConstDType{$<fl>2, VFlagChildDType{}, $4};
2460 : : VARDTYPE(dtp); }
2461 : : | yCONST__ETC yVAR lifetimeE
2462 : : { VARRESET_NONLIST(VAR); VARLIFE($3);
2463 : : AstNodeDType* const dtp = new AstConstDType{$<fl>2, VFlagChildDType{},
2464 : : new AstBasicDType{$<fl>2, LOGIC_IMPLICIT}};
2465 : : VARDTYPE(dtp); }
2466 : : | yCONST__ETC yVAR lifetimeE signingE rangeList
2467 : : { VARRESET_NONLIST(VAR); VARLIFE($3);
2468 : : AstNodeDType* const dtp = new AstConstDType{$<fl>2, VFlagChildDType{},
2469 : : GRAMMARP->addRange(new AstBasicDType{$<fl>2, LOGIC_IMPLICIT, $4}, $5, true)};
2470 : : VARDTYPE(dtp); }
2471 : : //
2472 : : // // Expanded: "constE lifetimeE data_type"
2473 : : | /**/ data_type
2474 : : { VARRESET_NONLIST(VAR); VARDTYPE($1); }
2475 : : | /**/ lifetime data_type
2476 : : { VARRESET_NONLIST(VAR); VARLIFE($1); VARDTYPE($2); }
2477 : : | yCONST__ETC lifetimeE data_type
2478 : : { VARRESET_NONLIST(VAR); VARLIFE($2);
2479 : : AstNodeDType* const dtp = new AstConstDType{$<fl>1, VFlagChildDType{}, $3};
2480 : : VARDTYPE(dtp); }
2481 : : // // = class_new is in variable_decl_assignment
2482 : : ;
2483 : :
2484 : : data_declarationVarFrontClass: // IEEE: part of data_declaration (for class_property)
2485 : : // // VARRESET called before this rule
2486 : : // // yCONST is removed, added to memberQual rules
2487 : : // // implicit_type expanded into /*empty*/ or "signingE rangeList"
2488 : : yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); }
2489 : : | yVAR lifetimeE { VARRESET_NONLIST(VAR); VARLIFE($2); }
2490 : : | yVAR lifetimeE signingE rangeList
2491 : : { /*VARRESET-in-ddVar*/
2492 : : AstNodeDType* const dtp = GRAMMARP->addRange(new AstBasicDType{$<fl>1, LOGIC_IMPLICIT, $3}, $4, true);
2493 : : VARDTYPE(dtp);
2494 : : VARLIFE($2); }
2495 : : //
2496 : : // // Expanded: "constE lifetimeE data_type"
2497 : : | data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
2498 : : // // lifetime is removed, added to memberQual rules to avoid conflict
2499 : : // // yCONST is removed, added to memberQual rules to avoid conflict
2500 : : // // = class_new is in variable_decl_assignment
2501 : : ;
2502 : :
2503 : : nettype_declaration<nodep>: // IEEE: nettype_declaration/net_type_declaration
2504 : : // // Union of data_typeAny and nettype_identifier matching
2505 : : yNETTYPE data_typeNoRef
2506 : : /*cont*/ idAny/*nettype_identifier*/ ';'
2507 : : { $$ = GRAMMARP->createNettype($<fl>3, *$3); BBUNSUP($<fl>1, "Unsupported: nettype"); }
2508 : : | yNETTYPE data_typeNoRef
2509 : : /*cont*/ idAny/*nettype_identifier*/
2510 : : /*cont*/ yWITH__ETC packageClassScopeE id/*tf_identifier*/ ';'
2511 : : { $$ = GRAMMARP->createNettype($<fl>3, *$3); BBUNSUP($<fl>1, "Unsupported: nettype with"); }
2512 : : | yNETTYPE packageClassScopeE idAny packed_dimensionListE
2513 : : /*cont*/ idAny/*nettype_identifier*/ ';'
2514 : : { $$ = GRAMMARP->createNettype($<fl>5, *$5); BBUNSUP($<fl>1, "Unsupported: nettype"); }
2515 : : | yNETTYPE packageClassScopeE idAny packed_dimensionListE
2516 : : /*cont*/ idAny/*nettype_identifier*/
2517 : : /*cont*/ yWITH__ETC packageClassScopeE id/*tf_identifier*/ ';'
2518 : : { $$ = GRAMMARP->createNettype($<fl>5, *$5); BBUNSUP($<fl>1, "Unsupported: nettype with"); }
2519 : : | yNETTYPE packageClassScopeE idAny parameter_value_assignmentClass packed_dimensionListE
2520 : : /*cont*/ idAny/*nettype_identifier*/ ';'
2521 : : { $$ = GRAMMARP->createNettype($<fl>6, *$6); BBUNSUP($<fl>1, "Unsupported: nettype"); }
2522 : : | yNETTYPE packageClassScopeE idAny parameter_value_assignmentClass packed_dimensionListE
2523 : : /*cont*/ idAny/*nettype_identifier*/
2524 : : /*cont*/ yWITH__ETC packageClassScopeE id/*tf_identifier*/ ';'
2525 : : { $$ = GRAMMARP->createNettype($<fl>6, *$6); BBUNSUP($<fl>1, "Unsupported: nettype with"); }
2526 : : ;
2527 : :
2528 : : implicit_typeE<nodeDTypep>: // IEEE: part of *data_type_or_implicit
2529 : : // // Also expanded in data_declaration
2530 : : /* empty */
2531 : : { $$ = nullptr; }
2532 : : | signingE rangeList
2533 : : { $$ = GRAMMARP->addRange(new AstBasicDType{$2->fileline(), LOGIC_IMPLICIT, $1}, $2, true); }
2534 : : | signing
2535 : : { $$ = new AstBasicDType{$<fl>1, LOGIC_IMPLICIT, $1}; }
2536 : : ;
2537 : :
2538 : : assertion_variable_declaration<nodep>: // IEEE: assertion_variable_declaration
2539 : : // // IEEE: var_data_type expanded
2540 : : var_data_type { VARRESET_NONLIST(VAR); VARDTYPE_NDECL($1); }
2541 : : /*cont*/ list_of_variable_decl_assignments ';' { $$ = $3; }
2542 : : ;
2543 : :
2544 : : type_declaration<nodep>: // ==IEEE: type_declaration
2545 : : // Data_type expanded
2546 : : yTYPEDEF data_typeNoRef
2547 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2548 : : { AstNodeDType* const dtp = $2;
2549 : : $$ = GRAMMARP->createTypedef($<fl>3, *$3, $5, dtp, $4); }
2550 : :
2551 : : // IEEE 1800-2023 6.18 typedef: dotted or arrayed type identifier
2552 : : // Handles interface typedef references like if0.rq_t and if0[0].rq_t (arrays allowed after first component)
2553 : : | yTYPEDEF idDottedOrArrayed
2554 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2555 : : { VARRESET_NONLIST(LPARAM);
2556 : : AstParseTypeDType* const ptypep = new AstParseTypeDType{$<fl>2, VFwdType::NONE};
2557 : : VARDTYPE(ptypep);
2558 : : AstVar* const varp = VARDONEA($<fl>3, *$3, $4, $5);
2559 : : // idDottedOrArrayed produces Dot/SelBit tree for hierarchical refs like if0[0].rq_t
2560 : : varp->valuep($2);
2561 : : $$ = varp; }
2562 : :
2563 : : // IEEE 1800-2023 6.18 typedef with hierarchical type identifier
2564 : : // Special-case array on first component requiring a '.' after ']' to disambiguate from packed dims
2565 : : // Examples: typedef if0[0].rq_t my_t; typedef if0[0].x_if.rq_t my_t;
2566 : : | yTYPEDEF id '[' expr ']' '.' idDottedSelMore
2567 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2568 : : { VARRESET_NONLIST(LPARAM);
2569 : : AstParseTypeDType* const ptypep = new AstParseTypeDType{$<fl>2, VFwdType::NONE};
2570 : : VARDTYPE(ptypep);
2571 : : AstVar* const varp = VARDONEA($<fl>8, *$8, $9, $10);
2572 : : AstNodeExpr* const arrp = new AstSelBit{$3, new AstParseRef{$<fl>2, *$2, nullptr, nullptr}, $4};
2573 : : varp->valuep(new AstDot{$6, false, arrp, $7});
2574 : : $$ = varp; }
2575 : :
2576 : : | yTYPEDEF packageClassScope idAny packed_dimensionListE
2577 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2578 : : { AstRefDType* const refp = new AstRefDType{$<fl>3, *$3, $2, nullptr};
2579 : : AstNodeDType* const dtp = GRAMMARP->createArray(refp, $4, true);
2580 : : $$ = GRAMMARP->createTypedef($<fl>5, *$5, $7, dtp, $6); }
2581 : : | yTYPEDEF packageClassScope idAny parameter_value_assignmentClass packed_dimensionListE
2582 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2583 : : { AstRefDType* const refp = new AstRefDType{$<fl>3, *$3, $2, $4};
2584 : : AstNodeDType* const dtp = GRAMMARP->createArray(refp, $5, true);
2585 : : $$ = GRAMMARP->createTypedef($<fl>6, *$6, $8, dtp, $7); }
2586 : :
2587 : : // Type alias without packed dimensions: typedef existing_t new_t;
2588 : : | yTYPEDEF idAny idAny variable_dimensionListE dtypeAttrListE ';'
2589 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, nullptr};
2590 : : $$ = GRAMMARP->createTypedef($<fl>3, *$3, $5, refp, $4); }
2591 : :
2592 : : // IEEE 1800-2023 6.18.2 typedef with packed dimensions on an existing type identifier
2593 : : // Disambiguated from interface array access by requiring ':' inside the brackets
2594 : : // (applies to both plain identifiers and type identifiers)
2595 : : | yTYPEDEF id '[' constExpr ':' constExpr ']' packed_dimensionListE
2596 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2597 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, nullptr};
2598 : : AstNodeRange* const rangep = new AstRange{$3, $4, $6};
2599 : : AstNodeDType* const dtp = GRAMMARP->createArray(refp, addNextNull(rangep, $8), true);
2600 : : $$ = GRAMMARP->createTypedef($<fl>9, *$9, $11, dtp, $10); }
2601 : :
2602 : : // Same as above but for type identifiers (parameter types, etc.)
2603 : : | yTYPEDEF idType '[' constExpr ':' constExpr ']' packed_dimensionListE
2604 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2605 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, nullptr};
2606 : : AstNodeRange* const rangep = new AstRange{$3, $4, $6};
2607 : : AstNodeDType* const dtp = GRAMMARP->createArray(refp, addNextNull(rangep, $8), true);
2608 : : $$ = GRAMMARP->createTypedef($<fl>9, *$9, $11, dtp, $10); }
2609 : :
2610 : : | yTYPEDEF idAny parameter_value_assignmentClass packed_dimensionListE
2611 : : /*cont*/ idAny variable_dimensionListE dtypeAttrListE ';'
2612 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, nullptr, $3};
2613 : : AstNodeDType* const dtp = GRAMMARP->createArray(refp, $4, true);
2614 : : $$ = GRAMMARP->createTypedef($<fl>5, *$5, $7, dtp, $6); }
2615 : :
2616 : : // // idAny as also allows redeclaring same typedef again
2617 : : | yTYPEDEF idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>2, *$2, VFwdType::NONE); }
2618 : : // // IEEE: expanded forward_type to prevent conflict
2619 : : | yTYPEDEF yENUM idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>3, *$3, VFwdType::ENUM); }
2620 : : | yTYPEDEF ySTRUCT idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>3, *$3, VFwdType::STRUCT); }
2621 : : | yTYPEDEF yUNION idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>3, *$3, VFwdType::UNION); }
2622 : : | yTYPEDEF yCLASS idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>3, *$3, VFwdType::CLASS); }
2623 : : | yTYPEDEF yINTERFACE yCLASS idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>4, *$4, VFwdType::INTERFACE_CLASS); }
2624 : : //
2625 : : | yTYPEDEF error idAny ';' { $$ = GRAMMARP->createTypedefFwd($<fl>3, *$3, VFwdType::NONE); } // LCOV_EXCL_LINE
2626 : : ;
2627 : :
2628 : : dtypeAttrListE<nodep>:
2629 : : /* empty */ { $$ = nullptr; }
2630 : : | dtypeAttrList { $$ = $1; }
2631 : : ;
2632 : :
2633 : : dtypeAttrList<nodep>:
2634 : : dtypeAttr { $$ = $1; }
2635 : : | dtypeAttrList dtypeAttr { $$ = addNextNull($1, $2); }
2636 : : ;
2637 : :
2638 : : dtypeAttr<nodep>:
2639 : : yVL_PUBLIC { $$ = new AstAttrOf{$1, VAttrType::DT_PUBLIC}; }
2640 : : ;
2641 : :
2642 : : vlTag: // verilator tag handling
2643 : : yVL_TAG { if (PARSEP->tagNodep()) PARSEP->tagNodep()->tag(*$1); }
2644 : : ;
2645 : :
2646 : : //************************************************
2647 : : // Module Items
2648 : :
2649 : : module_itemListE<nodep>: // IEEE: Part of module_declaration
2650 : : /* empty */ { $$ = nullptr; }
2651 : : | module_itemList { $$ = $1; }
2652 : : ;
2653 : :
2654 : : module_itemList<nodep>: // IEEE: Part of module_declaration
2655 : : module_item { $$ = $1; }
2656 : : | module_itemList module_item { $$ = addNextNull($1, $2); }
2657 : : ;
2658 : :
2659 : : module_item<nodep>: // ==IEEE: module_item
2660 : : port_declaration ';' { $$ = $1; }
2661 : : | non_port_module_item { $$ = $1; }
2662 : : ;
2663 : :
2664 : : non_port_module_item<nodep>: // ==IEEE: non_port_module_item
2665 : : generate_region { $$ = $1; }
2666 : : // not in IEEE, but presumed so can do yBEGIN ... yEND
2667 : : | genItemBegin { $$ = $1; }
2668 : : | module_or_generate_item { $$ = $1; }
2669 : : | specify_block { $$ = $1; }
2670 : : | specparam_declaration { $$ = $1; }
2671 : : | program_declaration
2672 : : { $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: program decls within module decls"); }
2673 : : | module_declaration
2674 : : { $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: module decls within module decls"); }
2675 : : | interface_declaration
2676 : : { $$ = nullptr; BBUNSUP(CRELINE(), "Unsupported: interface decls within module decls"); }
2677 : : | timeunits_declaration { $$ = $1; }
2678 : : // // Verilator specific
2679 : : | vlScBlock { $$ = $1; }
2680 : : | yVL_HIER_BLOCK { $$ = new AstPragma{$1, VPragmaType::HIER_BLOCK}; }
2681 : : | yVL_INLINE_MODULE { $$ = new AstPragma{$1, VPragmaType::INLINE_MODULE}; }
2682 : : | yVL_NO_INLINE_MODULE { $$ = new AstPragma{$1, VPragmaType::NO_INLINE_MODULE}; }
2683 : : | yVL_PUBLIC_MODULE { $$ = new AstPragma{$1, VPragmaType::PUBLIC_MODULE}; v3Global.dpi(true); }
2684 : : ;
2685 : :
2686 : : vlScBlock<nodep>: // Verilator-specific `systemc_* blocks
2687 : : yaSCHDR { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::HDR, *$1}; }
2688 : : | yaSCHDRP { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::HDR_POST, *$1}; }
2689 : : | yaSCINT { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::INT, *$1}; }
2690 : : | yaSCIMP { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::IMP, *$1}; }
2691 : : | yaSCIMPH { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::IMP_HDR, *$1}; }
2692 : : | yaSCCTOR { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::CTOR, *$1}; }
2693 : : | yaSCDTOR { $$ = new AstSystemCSection{$<fl>1, VSystemCSectionType::DTOR, *$1}; }
2694 : : ;
2695 : :
2696 : :
2697 : : module_or_generate_item<nodep>: // ==IEEE: module_or_generate_item
2698 : : // // IEEE: parameter_override
2699 : : yDEFPARAM list_of_defparam_assignments ';' { $$ = $2; }
2700 : : // // IEEE: gate_instantiation + udp_instantiation + module_instantiation
2701 : : // // not here, see etcInst in module_common_item
2702 : : // // We joined udp & module definitions, so this goes here
2703 : : | combinational_body { $$ = $1; }
2704 : : // // This module_common_item shared with
2705 : : // // interface_or_generate_item:module_common_item
2706 : : | module_common_item { $$ = $1; }
2707 : : ;
2708 : :
2709 : : module_common_item<nodep>: // ==IEEE: module_common_item
2710 : : module_or_generate_item_declaration { $$ = $1; }
2711 : : // // IEEE: interface_instantiation
2712 : : // // + IEEE: program_instantiation
2713 : : // // + module_instantiation from module_or_generate_item
2714 : : | etcInst { $$ = $1; }
2715 : : | assertion_item { $$ = $1; }
2716 : : | bind_directive { $$ = $1; }
2717 : : | continuous_assign { $$ = $1; }
2718 : : | net_alias { $$ = $1; }
2719 : : | initial_construct { $$ = $1; }
2720 : : | final_construct { $$ = $1; }
2721 : : | always_construct { $$ = $1; }
2722 : : | loop_generate_construct { $$ = $1; }
2723 : : | conditional_generate_construct { $$ = $1; }
2724 : : | severity_system_task { $$ = $1; }
2725 : : | sigAttrScope { $$ = nullptr; }
2726 : : //
2727 : : | error ';' { $$ = nullptr; } // LCOV_EXCL_LINE
2728 : : ;
2729 : :
2730 : : always_construct<nodep>: // IEEE: == always_construct
2731 : : yALWAYS stmt { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS, nullptr, $2}; }
2732 : : | yALWAYS_FF stmt { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_FF, nullptr, $2}; }
2733 : : | yALWAYS_LATCH stmt { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_LATCH, nullptr, $2}; }
2734 : : | yALWAYS_COMB stmt { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_COMB, nullptr, $2}; }
2735 : : ;
2736 : :
2737 : : continuous_assign<nodep>: // IEEE: continuous_assign
2738 : : yASSIGN driveStrengthE delay_controlE assignList ';'
2739 : : { $$ = $4;
2740 : : STRENGTH_LIST($4, $2);
2741 : : DELAY_LIST($4, $3); }
2742 : : ;
2743 : :
2744 : : initial_construct<nodep>: // IEEE: initial_construct
2745 : : yINITIAL stmt { $$ = new AstInitial{$1, $2}; }
2746 : : ;
2747 : :
2748 : :
2749 : : net_alias<nodep>: // IEEE: net_alias
2750 : : yALIAS variable_lvalue aliasEqList ';'
2751 : : { $2->addNext($3);
2752 : : $$ = new AstAlias{$1, $2}; }
2753 : : ;
2754 : :
2755 : : aliasEqList<nodeExprp>: // IEEE: part of net_alias
2756 : : '=' variable_lvalue { $$ = $2; }
2757 : : | aliasEqList '=' variable_lvalue { $$ = $1->addNext($3); }
2758 : : ;
2759 : :
2760 : : final_construct<nodep>: // IEEE: final_construct
2761 : : yFINAL stmt { $$ = new AstFinal{$1, $2}; }
2762 : : ;
2763 : :
2764 : : module_or_generate_item_declaration<nodep>: // ==IEEE: module_or_generate_item_declaration
2765 : : package_or_generate_item_declaration { $$ = $1; }
2766 : : | genvar_declaration { $$ = $1; }
2767 : : | clocking_declaration { $$ = $1; }
2768 : : | modDefaultClocking { $$ = $1; }
2769 : : | defaultDisable { $$ = $1; }
2770 : : ;
2771 : :
2772 : : modDefaultClocking<nodep>: // IEEE: part of module_or_generate_item_declaration/checker_or_...
2773 : : yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';'
2774 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: default clocking identifier"); }
2775 : : ;
2776 : :
2777 : : defaultDisable<nodep>: // IEEE: part of module_/checker_or_generate_item_declaration
2778 : : yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';'
2779 : : { $$ = new AstDefaultDisable{$1, $4}; }
2780 : : ;
2781 : :
2782 : : bind_directive<nodep>: // ==IEEE: bind_directive + bind_target_scope
2783 : : // // ';' - Note IEEE grammar is wrong, includes extra ';'
2784 : : // // - it's already in module_instantiation
2785 : : // // We merged the rules - id may be a bind_target_instance or
2786 : : // // module_identifier or interface_identifier
2787 : : yBIND bind_target_instance bind_instantiation { $$ = new AstBind{$<fl>2, *$2, $3}; }
2788 : : | yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation
2789 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: Bind with instance list"); DEL($5); }
2790 : : ;
2791 : :
2792 : : bind_target_instance_list: // ==IEEE: bind_target_instance_list
2793 : : bind_target_instance { }
2794 : : | bind_target_instance_list ',' bind_target_instance { }
2795 : : ;
2796 : :
2797 : : bind_target_instance<strp>: // ==IEEE: bind_target_instance
2798 : : //UNSUP hierarchical_identifierBit { }
2799 : : idAny { $$ = $1; }
2800 : : ;
2801 : :
2802 : : bind_instantiation<nodep>: // ==IEEE: bind_instantiation
2803 : : // // IEEE: program_instantiation
2804 : : // // IEEE: + module_instantiation
2805 : : // // IEEE: + interface_instantiation
2806 : : // // Need to get an AstBind instead of AstCell, so have special rules
2807 : : instDecl { $$ = $1; }
2808 : : ;
2809 : :
2810 : : //************************************************
2811 : : // Generates
2812 : : //
2813 : : // Way down in generate_item is speced a difference between module,
2814 : : // interface and checker generates. modules and interfaces are almost
2815 : : // identical (minus DEFPARAMs) so we overlap them. Checkers are too
2816 : : // different, so we copy all rules for checkers.
2817 : :
2818 : : generate_region<nodep>: // ==IEEE: generate_region
2819 : : yGENERATE ~c~genItemList yENDGENERATE { $$ = $2; }
2820 : : | yGENERATE yENDGENERATE { $$ = nullptr; }
2821 : : ;
2822 : :
2823 : : c_generate_region<nodep>: // IEEE: generate_region (for checkers)
2824 : : BISONPRE_COPY(generate_region,{s/~c~/c_/g}) // {copied}
2825 : : ;
2826 : :
2827 : : i_generate_region<nodep>: // IEEE: generate_region (for interface)
2828 : : BISONPRE_COPY(generate_region,{s/~c~/i_/g}) // {copied}
2829 : : ;
2830 : :
2831 : : generate_block_or_null<nodep>: // IEEE: generate_block_or_null (called from gencase/genif/genfor)
2832 : : // ';' // is included in
2833 : : // // IEEE: generate_block
2834 : : // // Must always return a BEGIN node, or nullptr - see GenFor construction
2835 : : ~c~generate_item
2836 : : { $$ = $1 ? (new AstGenBlock{$1->fileline(), "", $1, true}) : nullptr; }
2837 : : | ~c~genItemBegin { $$ = $1; }
2838 : : ;
2839 : :
2840 : : c_generate_block_or_null<nodep>: // IEEE: generate_block_or_null (for checkers)
2841 : : BISONPRE_COPY(generate_block_or_null,{s/~c~/c_/g}) // {copied}
2842 : : ;
2843 : :
2844 : : genItemBegin<nodep>: // IEEE: part of generate_block
2845 : : yBEGIN ~c~genItemList yEND { $$ = new AstGenBlock{$1, "", $2, false}; }
2846 : : | yBEGIN yEND { $$ = nullptr; }
2847 : : | id yP_COLON__BEGIN yBEGIN ~c~genItemList yEND endLabelE
2848 : : { $$ = new AstGenBlock{$<fl>1, *$1, $4, false};
2849 : : GRAMMARP->endLabel($<fl>6, *$1, $6); }
2850 : : | id yP_COLON__BEGIN yBEGIN yEND endLabelE
2851 : : { $$ = new AstGenBlock{$<fl>1, *$1, nullptr, false};
2852 : : GRAMMARP->endLabel($<fl>5, *$1, $5); }
2853 : : | yBEGIN ':' idAny ~c~genItemList yEND endLabelE
2854 : : { $$ = new AstGenBlock{$<fl>3, *$3, $4, false};
2855 : : GRAMMARP->endLabel($<fl>6, *$3, $6); }
2856 : : | yBEGIN ':' idAny yEND endLabelE
2857 : : { $$ = new AstGenBlock{$<fl>3, *$3, nullptr, false};
2858 : : GRAMMARP->endLabel($<fl>5, *$3, $5); }
2859 : : ;
2860 : :
2861 : : c_genItemBegin<nodep>: // IEEE: part of generate_block (for checkers)
2862 : : BISONPRE_COPY(genItemBegin,{s/~c~/c_/g}) // {copied}
2863 : : ;
2864 : :
2865 : : i_genItemBegin<nodep>: // IEEE: part of generate_block (for interfaces)
2866 : : BISONPRE_COPY(genItemBegin,{s/~c~/i_/g}) // {copied}
2867 : : ;
2868 : :
2869 : : genItemOrBegin<nodep>: // Not in IEEE, but our begin isn't under generate_item
2870 : : ~c~generate_item { $$ = $1; }
2871 : : | ~c~genItemBegin { $$ = $1; }
2872 : : ;
2873 : :
2874 : : c_genItemOrBegin<nodep>: // (for checkers)
2875 : : BISONPRE_COPY(genItemOrBegin,{s/~c~/c_/g}) // {copied}
2876 : : ;
2877 : :
2878 : : i_genItemOrBegin<nodep>: // (for interfaces)
2879 : : interface_item { $$ = $1; }
2880 : : | i_genItemBegin { $$ = $1; }
2881 : : ;
2882 : :
2883 : : genItemList<nodep>:
2884 : : ~c~genItemOrBegin { $$ = $1; }
2885 : : | ~c~genItemList ~c~genItemOrBegin { $$ = addNextNull($1, $2); }
2886 : : ;
2887 : :
2888 : : c_genItemList<nodep>: // (for checkers)
2889 : : BISONPRE_COPY(genItemList,{s/~c~/c_/g}) // {copied}
2890 : : ;
2891 : :
2892 : : i_genItemList<nodep>: // (for interfaces)
2893 : : BISONPRE_COPY(genItemList,{s/~c~/i_/g}) // {copied}
2894 : : ;
2895 : :
2896 : : generate_item<nodep>: // IEEE: module_or_interface_or_generate_item
2897 : : // // Only legal when in a generate under a module (or interface under a module)
2898 : : module_or_generate_item { $$ = $1; }
2899 : : // // Only legal when in a generate under an interface
2900 : : //UNSUP interface_or_generate_item { $$ = $1; }
2901 : : // // IEEE: checker_or_generate_item
2902 : : // // Only legal when in a generate under a checker
2903 : : // // so below in c_generate_item
2904 : : ;
2905 : :
2906 : : c_generate_item<nodep>: // IEEE: generate_item (for checkers)
2907 : : checker_or_generate_item { $$ = $1; }
2908 : : ;
2909 : :
2910 : : conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
2911 : : yCASE '(' exprTypeCompare ')' ~c~case_generate_itemList yENDCASE
2912 : : { $$ = new AstGenCase{$1, $3, $5}; }
2913 : : | yIF '(' exprTypeCompare ')' ~c~generate_block_or_null %prec prLOWER_THAN_ELSE
2914 : : { $$ = new AstGenIf{$1, $3, $5, nullptr}; }
2915 : : | yIF '(' exprTypeCompare ')' ~c~generate_block_or_null yELSE ~c~generate_block_or_null
2916 : : { $$ = new AstGenIf{$1, $3, $5, $7}; }
2917 : : ;
2918 : :
2919 : : c_conditional_generate_construct<nodep>: // IEEE: conditional_generate_construct (for checkers)
2920 : : BISONPRE_COPY(conditional_generate_construct,{s/~c~/c_/g}) // {copied}
2921 : : ;
2922 : :
2923 : : loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
2924 : : yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null
2925 : : { // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
2926 : : AstGenBlock* lowerp = VN_CAST($9, GenBlock);
2927 : : UASSERT_OBJ(!$9 || lowerp, $9, "Child of GENFOR should have been begin");
2928 : : AstNode* const itemsp = lowerp && lowerp->itemsp() ? lowerp->itemsp()->unlinkFrBackWithNext() : nullptr;
2929 : : AstGenBlock* const blkp = new AstGenBlock{$1, lowerp ? lowerp->name() : "", nullptr, true};
2930 : : // V3LinkDot detects BEGIN(GENFOR(...)) as a special case
2931 : : AstNode* initp = $3;
2932 : : AstNode* const varp = $3;
2933 : : if (VN_IS(varp, Var)) { // Genvar
2934 : : initp = varp->nextp();
2935 : : initp->unlinkFrBackWithNext(); // Detach 2nd from varp, make 1st init
2936 : : blkp->addItemsp(varp);
2937 : : }
2938 : : // Statements are under 'genforp' as instances under this
2939 : : // for loop won't get an extra layer of hierarchy tacked on
2940 : : blkp->genforp(new AstGenFor{$1, initp, $5, $7, itemsp});
2941 : : $$ = blkp;
2942 : : DEL(lowerp);
2943 : : }
2944 : : ;
2945 : :
2946 : : c_loop_generate_construct<nodep>: // IEEE: loop_generate_construct (for checkers)
2947 : : BISONPRE_COPY(loop_generate_construct,{s/~c~/c_/g}) // {copied}
2948 : : ;
2949 : :
2950 : : genvar_initialization<nodep>: // ==IEEE: genvar_initialization
2951 : : parseRefBase '=' expr { $$ = new AstAssign{$2, $1, $3}; }
2952 : : | yGENVAR genvar_identifierDecl '=' constExpr
2953 : : { $$ = $2; AstNode::addNext<AstNode, AstNode>($$,
2954 : : new AstAssign{$3, new AstVarRef{$2->fileline(), $2, VAccess::WRITE}, $4}); }
2955 : : ;
2956 : :
2957 : : genvar_iteration<nodep>: // ==IEEE: genvar_iteration
2958 : : parseRefBase '=' expr
2959 : : { $$ = new AstAssign{$2, $1, $3}; }
2960 : : | parseRefBase yP_PLUSEQ expr
2961 : : { $$ = new AstAssign{$2, $1, new AstAdd{$2, $1->cloneTreePure(true), $3}}; }
2962 : : | parseRefBase yP_MINUSEQ expr
2963 : : { $$ = new AstAssign{$2, $1, new AstSub{$2, $1->cloneTreePure(true), $3}}; }
2964 : : | parseRefBase yP_TIMESEQ expr
2965 : : { $$ = new AstAssign{$2, $1, new AstMul{$2, $1->cloneTreePure(true), $3}}; }
2966 : : | parseRefBase yP_DIVEQ expr
2967 : : { $$ = new AstAssign{$2, $1, new AstDiv{$2, $1->cloneTreePure(true), $3}}; }
2968 : : | parseRefBase yP_MODEQ expr
2969 : : { $$ = new AstAssign{$2, $1, new AstModDiv{$2, $1->cloneTreePure(true), $3}}; }
2970 : : | parseRefBase yP_ANDEQ expr
2971 : : { $$ = new AstAssign{$2, $1, new AstAnd{$2, $1->cloneTreePure(true), $3}}; }
2972 : : | parseRefBase yP_OREQ expr
2973 : : { $$ = new AstAssign{$2, $1, new AstOr{$2, $1->cloneTreePure(true), $3}}; }
2974 : : | parseRefBase yP_XOREQ expr
2975 : : { $$ = new AstAssign{$2, $1, new AstXor{$2, $1->cloneTreePure(true), $3}}; }
2976 : : | parseRefBase yP_SLEFTEQ expr
2977 : : { $$ = new AstAssign{$2, $1, new AstShiftL{$2, $1->cloneTreePure(true), $3}}; }
2978 : : | parseRefBase yP_SRIGHTEQ expr
2979 : : { $$ = new AstAssign{$2, $1, new AstShiftR{$2, $1->cloneTreePure(true), $3}}; }
2980 : : | parseRefBase yP_SSRIGHTEQ expr
2981 : : { $$ = new AstAssign{$2, $1, new AstShiftRS{$2, $1->cloneTreePure(true), $3}}; }
2982 : : // // inc_or_dec_operator
2983 : : | yP_PLUSPLUS parseRefBase
2984 : : { $$ = new AstAssign{$1, $2, new AstAdd{$1, $2->cloneTreePure(true),
2985 : : new AstConst{$1, AstConst::StringToParse{}, "'b1"}}}; }
2986 : : | yP_MINUSMINUS parseRefBase
2987 : : { $$ = new AstAssign{$1, $2, new AstSub{$1, $2->cloneTreePure(true),
2988 : : new AstConst{$1, AstConst::StringToParse{}, "'b1"}}}; }
2989 : : | parseRefBase yP_PLUSPLUS
2990 : : { $$ = new AstAssign{$2, $1, new AstAdd{$2, $1->cloneTreePure(true),
2991 : : new AstConst{$2, AstConst::StringToParse{}, "'b1"}}}; }
2992 : : | parseRefBase yP_MINUSMINUS
2993 : : { $$ = new AstAssign{$2, $1, new AstSub{$2, $1->cloneTreePure(true),
2994 : : new AstConst{$2, AstConst::StringToParse{}, "'b1"}}}; }
2995 : : ;
2996 : :
2997 : : case_generate_itemList<genCaseItemp>: // IEEE: { case_generate_itemList }
2998 : : ~c~case_generate_item { $$ = $1; }
2999 : : | ~c~case_generate_itemList ~c~case_generate_item { $$ = $1; $1->addNext($2); }
3000 : : ;
3001 : :
3002 : : c_case_generate_itemList<genCaseItemp>: // IEEE: { case_generate_item } (for checkers)
3003 : : BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied}
3004 : : ;
3005 : :
3006 : : case_generate_item<genCaseItemp>: // ==IEEE: case_generate_item
3007 : : caseCondList colon ~c~generate_block_or_null { $$ = new AstGenCaseItem{$2, $1, $3}; }
3008 : : | yDEFAULT colon ~c~generate_block_or_null { $$ = new AstGenCaseItem{$1, nullptr, $3}; }
3009 : : | yDEFAULT ~c~generate_block_or_null { $$ = new AstGenCaseItem{$1, nullptr, $2}; }
3010 : : ;
3011 : :
3012 : : c_case_generate_item<genCaseItemp>: // IEEE: case_generate_item (for checkers)
3013 : : BISONPRE_COPY(case_generate_item,{s/~c~/c_/g}) // {copied}
3014 : : ;
3015 : :
3016 : : //************************************************
3017 : : // Assignments and register declarations
3018 : :
3019 : : assignList<alwaysp>:
3020 : : assignOne { $$ = $1; }
3021 : : | assignList ',' assignOne { $$ = $1->addNext($3); }
3022 : : ;
3023 : :
3024 : : assignOne<alwaysp>:
3025 : : variable_lvalue '=' expr { AstAssignW* const ap = new AstAssignW{$2, $1, $3};
3026 : : $$ = new AstAlways{ap}; }
3027 : : ;
3028 : :
3029 : : delay_or_event_controlE<nodep>: // IEEE: delay_or_event_control plus empty
3030 : : /* empty */ { $$ = nullptr; }
3031 : : | delay_control { $$ = $1; }
3032 : : | event_control { $$ = $1; }
3033 : : | yREPEAT '(' expr ')' event_control
3034 : : { $$ = $5; BBUNSUP($1, "Unsupported: repeat event control"); }
3035 : : ;
3036 : :
3037 : : delay_controlE<delayp>:
3038 : : /* empty */ { $$ = nullptr; }
3039 : : | delay_control { $$ = $1; }
3040 : : ;
3041 : :
3042 : : delay_control<delayp>: //== IEEE: delay_control
3043 : : '#' delay_value
3044 : : { $$ = new AstDelay{$<fl>1, $2, false}; }
3045 : : | '#' '(' minTypMax ')'
3046 : : { $$ = new AstDelay{$<fl>1, $3, false}; }
3047 : : | '#' '(' minTypMax ',' minTypMax ')'
3048 : : { $$ = new AstDelay{$<fl>1, $3, false};
3049 : : $$->fallDelay($5); }
3050 : : | '#' '(' minTypMax ',' minTypMax ',' minTypMax ')'
3051 : : { $$ = new AstDelay{$<fl>1, $3, false}; $$->fallDelay($5); RISEFALLDLYUNSUP($7); DEL($7); }
3052 : : ;
3053 : :
3054 : : delay_value<nodeExprp>: // ==IEEE:delay_value
3055 : : // // IEEE: ps_identifier
3056 : : idClass { $$ = $1; }
3057 : : | yaINTNUM { $$ = new AstConst{$<fl>1, *$1}; }
3058 : : | yaFLOATNUM { $$ = new AstConst{$<fl>1, AstConst::RealDouble{}, $1}; }
3059 : : | timeNumAdjusted { $$ = $1; }
3060 : : | y1STEP { $$ = new AstConst{$<fl>1, AstConst::OneStep{}}; }
3061 : : ;
3062 : :
3063 : : minTypMax<nodeExprp>: // IEEE: mintypmax_expression and constant_mintypmax_expression
3064 : : expr { $$ = $1; }
3065 : : | expr ':' expr ':' expr { $$ = $3; MINTYPMAXDLYUNSUP($3); DEL($1); DEL($5); }
3066 : : ;
3067 : :
3068 : : minTypMaxE<nodeExprp>:
3069 : : /*empty*/ { $$ = nullptr; }
3070 : : | minTypMax { $$ = $1; }
3071 : : ;
3072 : :
3073 : : netSigList<varp>: // IEEE: list_of_port_identifiers
3074 : : netSig { $$ = $1; }
3075 : : | netSigList ',' netSig { $$ = $1; $1->addNext($3); }
3076 : : ;
3077 : :
3078 : : netSig<varp>: // IEEE: net_decl_assignment - one element from list_of_port_identifiers
3079 : : netId variable_dimensionListE sigAttrListE
3080 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3); }
3081 : : | netId variable_dimensionListE sigAttrListE '=' expr
3082 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3);
3083 : : AstDelay* const delayp = $$->delayp() ? $$->delayp()->unlinkFrBack() : nullptr;
3084 : : AstAssignW* const assignp = new AstAssignW{$4, new AstParseRef{$<fl>1, *$1}, $5, delayp};
3085 : : if (GRAMMARP->m_netStrengthp) assignp->strengthSpecp(GRAMMARP->m_netStrengthp->cloneTree(false));
3086 : : AstNode::addNext<AstNode, AstNode>($$, new AstAlways{assignp}); }
3087 : : ;
3088 : :
3089 : : netId<strp>:
3090 : : id/*new-net*/ { $$ = $1; $<fl>$ = $<fl>1; }
3091 : : | idSVKwd { $$ = $1; $<fl>$ = $<fl>1; }
3092 : : ;
3093 : :
3094 : : sigAttrScope:
3095 : : yVL_PUBLIC_FLAT_RW_ON_SNS attr_event_control
3096 : : { GRAMMARP->createScopedSigAttr(VAttrType::VAR_PUBLIC_FLAT_RW);
3097 : : v3Global.dpi(true); DEL($2); }
3098 : : | yVL_PUBLIC_ON { GRAMMARP->createScopedSigAttr(VAttrType::VAR_PUBLIC); }
3099 : : | yVL_PUBLIC_FLAT_ON { GRAMMARP->createScopedSigAttr(VAttrType::VAR_PUBLIC_FLAT); }
3100 : : | yVL_PUBLIC_FLAT_RD_ON { GRAMMARP->createScopedSigAttr(VAttrType::VAR_PUBLIC_FLAT_RD); }
3101 : : | yVL_PUBLIC_FLAT_RW_ON { GRAMMARP->createScopedSigAttr(VAttrType::VAR_PUBLIC_FLAT_RW); }
3102 : : | yVL_PUBLIC_OFF { GRAMMARP->setScopedSigAttr(nullptr); }
3103 : : ;
3104 : :
3105 : : sigAttrListE<nodep>: // Scoped Attributes are added to explicit attributes
3106 : : /* empty */ { $$ = nullptr; }
3107 : : | sigAttrList { $$ = $1; }
3108 : : ;
3109 : :
3110 : : sigAttrList<nodep>:
3111 : : sigAttr { $$ = $1; }
3112 : : | sigAttrList sigAttr { $$ = addNextNull($1, $2); }
3113 : : ;
3114 : :
3115 : : sigAttr<nodep>:
3116 : : yVL_CLOCKER { $$ = nullptr; /* Historical, now has no effect */ }
3117 : : | yVL_NO_CLOCKER { $$ = nullptr; /* Historical, now has no effect */ }
3118 : : | yVL_CLOCK_ENABLE { $$ = nullptr; /* Historical, now has no effect */ }
3119 : : | yVL_FORCEABLE { $$ = new AstAttrOf{$1, VAttrType::VAR_FORCEABLE}; }
3120 : : | yVL_PUBLIC { $$ = new AstAttrOf{$1, VAttrType::VAR_PUBLIC}; v3Global.dpi(true); }
3121 : : | yVL_PUBLIC_FLAT { $$ = new AstAttrOf{$1, VAttrType::VAR_PUBLIC_FLAT}; v3Global.dpi(true); }
3122 : : | yVL_PUBLIC_FLAT_RD { $$ = new AstAttrOf{$1, VAttrType::VAR_PUBLIC_FLAT_RD}; v3Global.dpi(true); }
3123 : : | yVL_PUBLIC_FLAT_RW attr_event_controlE { $$ = new AstAttrOf{$1, VAttrType::VAR_PUBLIC_FLAT_RW}; v3Global.dpi(true); DEL($2); }
3124 : : | yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf{$1, VAttrType::VAR_ISOLATE_ASSIGNMENTS}; }
3125 : : | yVL_SC_BIGUINT { $$ = new AstAttrOf{$1, VAttrType::VAR_SC_BIGUINT}; }
3126 : : | yVL_SC_BV { $$ = new AstAttrOf{$1, VAttrType::VAR_SC_BV}; }
3127 : : | yVL_SFORMAT { $$ = new AstAttrOf{$1, VAttrType::VAR_SFORMAT}; }
3128 : : | yVL_SPLIT_VAR { $$ = new AstAttrOf{$1, VAttrType::VAR_SPLIT_VAR}; }
3129 : : | yVL_FSM_ARC_INCL_COND { $$ = new AstAttrOf{$1, VAttrType::VAR_FSM_ARC_INCLUDE_COND}; }
3130 : : | yVL_FSM_RESET_ARC { $$ = new AstAttrOf{$1, VAttrType::VAR_FSM_RESET_ARC}; }
3131 : : | yVL_FSM_STATE { $$ = new AstAttrOf{$1, VAttrType::VAR_FSM_STATE}; }
3132 : : ;
3133 : :
3134 : : rangeListE<nodeRangep>: // IEEE: [{packed_dimension}]
3135 : : /* empty */ { $$ = nullptr; }
3136 : : | rangeList { $$ = $1; }
3137 : : ;
3138 : :
3139 : : rangeList<nodeRangep>: // IEEE: {packed_dimension}
3140 : : anyrange { $$ = $1; }
3141 : : | rangeList anyrange { $$ = $1->addNext($2); }
3142 : : ;
3143 : :
3144 : : anyrange<nodeRangep>:
3145 : : '[' constExpr ':' constExpr ']' { $$ = new AstRange{$1, $2, $4}; }
3146 : : ;
3147 : :
3148 : : part_select_rangeList<nodePreSelp>: // IEEE: part_select_range (as used after function calls)
3149 : : part_select_range { $$ = $1; }
3150 : : | part_select_rangeList part_select_range { $$ = GRAMMARP->scrubSel($1, $2); }
3151 : : ;
3152 : :
3153 : : part_select_range<nodePreSelp>:
3154 : : '[' expr ']'
3155 : : { $$ = new AstSelBit{$1, new AstParseHolder{$1}, $2}; }
3156 : : | '[' constExpr ':' constExpr ']'
3157 : : { $$ = new AstSelExtract{$1, new AstParseHolder{$1}, $2, $4}; }
3158 : : | '[' expr yP_PLUSCOLON constExpr ']'
3159 : : { $$ = new AstSelPlus{$1, new AstParseHolder{$1}, $2, $4}; }
3160 : : | '[' expr yP_MINUSCOLON constExpr ']'
3161 : : { $$ = new AstSelMinus{$1, new AstParseHolder{$1}, $2, $4}; }
3162 : : ;
3163 : :
3164 : : packed_dimensionListE<nodeRangep>: // IEEE: [{ packed_dimension }]
3165 : : /* empty */ { $$ = nullptr; }
3166 : : | packed_dimensionList { $$ = $1; }
3167 : : ;
3168 : :
3169 : : packed_dimensionList<nodeRangep>: // IEEE: { packed_dimension }
3170 : : packed_dimension { $$ = $1; }
3171 : : | packed_dimensionList packed_dimension { $$ = $1->addNext($2); }
3172 : : ;
3173 : :
3174 : : packed_dimension<nodeRangep>: // ==IEEE: packed_dimension
3175 : : anyrange { $$ = $1; }
3176 : : | '[' ']'
3177 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: [] dimensions"); }
3178 : : ;
3179 : :
3180 : : //************************************************
3181 : : // Parameters
3182 : :
3183 : : param_assignment<varp>: // ==IEEE: param_assignment
3184 : : // // IEEE: constant_param_expression
3185 : : // // constant_param_expression: '$' is in expr
3186 : : id/*new-parameter*/ variable_dimensionListE sigAttrListE exprOrDataTypeEqE
3187 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3);
3188 : : if ($4) $$->valuep($4);
3189 : : else if (!GRAMMARP->m_pinAnsi)
3190 : : $$->v3warn(PARAMNODEFAULT, "Parameter without default requires"
3191 : : " ANSI-style parameter list (IEEE 1800-2023 6.20.1): "
3192 : : << $$->prettyNameQ()); }
3193 : : ;
3194 : :
3195 : : list_of_param_assignments<varp>: // ==IEEE: list_of_param_assignments
3196 : : param_assignment { $$ = $1; }
3197 : : | list_of_param_assignments ',' param_assignment { $$ = $1->addNext($3); }
3198 : : ;
3199 : :
3200 : : type_assignment<varp>: // ==IEEE: type_assignment
3201 : : // // note exprOrDataType being a data_type is only for yPARAMETER yTYPE
3202 : : // // Using exprOrDataType allows hierarchical refs like if0.rq_t
3203 : : // // which get resolved to types during linking
3204 : : idAny/*new-parameter*/ sigAttrListE
3205 : : { $$ = VARDONEA($<fl>1, *$1, nullptr, $2); }
3206 : : | idAny/*new-parameter*/ sigAttrListE '=' exprOrDataType
3207 : : { $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
3208 : : // V3LinkParse will wrap this in RequireDType when creating ParamTypeDType
3209 : : $$->valuep($4); }
3210 : : ;
3211 : :
3212 : : list_of_type_assignments<varp>: // ==IEEE: list_of_type_assignments
3213 : : type_assignment { $$ = $1; }
3214 : : | list_of_type_assignments ',' type_assignment
3215 : : { $$ = addNextNull($1, $3); }
3216 : : ;
3217 : :
3218 : : list_of_defparam_assignments<nodep>: //== IEEE: list_of_defparam_assignments
3219 : : defparam_assignment { $$ = $1; }
3220 : : | list_of_defparam_assignments ',' defparam_assignment
3221 : : { $$ = addNextNull($1, $3); }
3222 : : ;
3223 : :
3224 : : defparam_assignment<nodep>: // ==IEEE: defparam_assignment
3225 : : defparamIdRangeList '.' defparamIdRange '=' expr
3226 : : { $$ = new AstDefParam{$4, $1, *$3, $5}; }
3227 : : | defparamIdRange '=' expr
3228 : : { $$ = nullptr; BBUNSUP($2, "Unsupported: defparam with no dot");
3229 : : DEL($3); }
3230 : : ;
3231 : :
3232 : : defparamIdRangeList<nodeExprp>: // IEEE: part of defparam_assignment
3233 : : defparamIdRangeExpr { $$ = $1; }
3234 : : | defparamIdRangeList '.' defparamIdRangeExpr
3235 : : { $$ = new AstDot{$2, false, $1, $3}; }
3236 : : ;
3237 : :
3238 : : defparamIdRangeExpr<nodeExprp>: // IEEE: part of defparam_assignment
3239 : : idAny
3240 : : { $$ = new AstParseRef{$<fl>1, *$1, nullptr, nullptr}; }
3241 : : | idAny part_select_rangeList
3242 : : { $$ = new AstParseRef{$<fl>1, *$1, nullptr, nullptr};
3243 : : BBUNSUP($2, "Unsupported: defparam with arrayed instance");
3244 : : DEL($2); }
3245 : : ;
3246 : :
3247 : : defparamIdRange<strp>: // IEEE: part of defparam_assignment
3248 : : idAny
3249 : : { $$ = $1; }
3250 : : | idAny part_select_rangeList
3251 : : { $$ = $1; BBUNSUP($2, "Unsupported: defparam with arrayed instance");
3252 : : DEL($2); }
3253 : : ;
3254 : :
3255 : : //************************************************
3256 : : // Instances
3257 : : // We don't know identifier types, so this matches all module,udp,etc instantiation
3258 : : // module_id [#(params)] name (pins) [, name ...] ; // module_instantiation
3259 : : // gate (strong0) [#(delay)] [name] (pins) [, (pins)...] ; // gate_instantiation
3260 : : // program_id [#(params}] name ; // program_instantiation
3261 : : // interface_id [#(params}] name ; // interface_instantiation
3262 : : // checker_id name (pins) ; // checker_instantiation
3263 : :
3264 : : etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_instantiation
3265 : : instDecl { $$ = $1; }
3266 : : | gateDecl { $$ = $1; }
3267 : : ;
3268 : :
3269 : : instDecl<nodep>:
3270 : : // // Disambigurated from data_declaration based on
3271 : : // // idInst which is found as IEEE requires a later '('
3272 : : idInst parameter_value_assignmentInstE
3273 : : /*mid*/ { INSTPREP($<fl>1, *$1, $2); }
3274 : : /*cont*/ instnameList ';'
3275 : : { $$ = $4;
3276 : : GRAMMARP->m_impliedDecl = false;
3277 : : if (GRAMMARP->m_instParamp) {
3278 : : VL_DO_CLEAR(GRAMMARP->m_instParamp->deleteTree(),
3279 : : GRAMMARP->m_instParamp = nullptr);
3280 : : } }
3281 : : //
3282 : : // // IEEE: part of udp_instance when no name_of_instance
3283 : : // // Note no unpacked dimension nor list of instances
3284 : : | id
3285 : : /*mid*/ { INSTPREP($<fl>1, *$1, nullptr); }
3286 : : /*cont*/ instnameParenUdpn ';'
3287 : : { $$ = $3; GRAMMARP->m_impliedDecl = false; }
3288 : : ;
3289 : :
3290 : : mpInstnameList<nodep>: // Similar to instnameList, but for modport instantiations which have no parenthesis
3291 : : mpInstnameParen { $$ = $1; }
3292 : : | mpInstnameList ',' mpInstnameParen { $$ = $1->addNext($3); }
3293 : : ;
3294 : :
3295 : : mpInstnameParen<nodep>: // Similar to instnameParen, but for modport instantiations which have no parenthesis
3296 : : id instRangeListE sigAttrListE { $$ = VARDONEA($<fl>1, *$1, $2, $3); }
3297 : : ;
3298 : :
3299 : : instnameList<nodep>:
3300 : : instnameParen { $$ = $1; }
3301 : : | instnameList ',' instnameParen { $$ = $1->addNext($3); }
3302 : : ;
3303 : :
3304 : : instnameParen<nodep>:
3305 : : id instRangeListE '(' instPinListE ')'
3306 : : { $$ = GRAMMARP->createCell($<fl>1, *$1, $4, $2); }
3307 : : ;
3308 : :
3309 : : instnameParenUdpn<nodep>: // IEEE: part of udp_instance when no name_of_instance
3310 : : '(' instPinListE ')' // When UDP has empty name, unpacked dimensions must not be used
3311 : : { $$ = GRAMMARP->createCell($<fl>1, "", $2, nullptr); }
3312 : : ;
3313 : :
3314 : : instRangeListE<nodeRangep>:
3315 : : /* empty */ { $$ = nullptr; }
3316 : : | instRangeList { $$ = $1; }
3317 : : ;
3318 : :
3319 : : instRangeList<nodeRangep>:
3320 : : instRange { $$ = $1; }
3321 : : | instRangeList instRange { $$ = addNextNull($1, $2); }
3322 : : ;
3323 : :
3324 : : instRange<nodeRangep>:
3325 : : '[' constExpr ']'
3326 : : { $$ = new AstRange{$1, new AstConst{$1, 0}, new AstSub{$1, $2, new AstConst{$1, 1}}, true}; }
3327 : : | '[' constExpr ':' constExpr ']'
3328 : : { $$ = new AstRange{$1, $2, $4}; }
3329 : : ;
3330 : :
3331 : : instParamListE<pinp>:
3332 : : { GRAMMARP->pinPush(); } instParamItListE { $$ = $2; GRAMMARP->pinPop(CRELINE()); }
3333 : : ;
3334 : :
3335 : : instPinListE<pinp>:
3336 : : { VARRESET_LIST(UNKNOWN); } instPinItListE { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
3337 : : ;
3338 : :
3339 : : instParamItListE<pinp>: // IEEE: list_of_parameter_value_assignments/list_of_parameter_assignments
3340 : : // // Empty gets a node, to track class reference of #()
3341 : : /*empty*/ { $$ = new AstPin{CRELINE(), PINNUMINC(), "", nullptr}; }
3342 : : | instParamItList { $$ = $1; }
3343 : : ;
3344 : :
3345 : : instParamItList<pinp>: // IEEE: list_of_parameter_value_assignments/list_of_parameter_assignments
3346 : : instParamItem { $$ = $1; }
3347 : : | instParamItList ',' instParamItem { $$ = addNextNull($1, $3); }
3348 : : ;
3349 : :
3350 : : instPinItListE<pinp>: // IEEE: list_of_port_connections
3351 : : instPinItemE { $$ = $1; }
3352 : : | instPinItListE ',' instPinItemE { $$ = addNextNull($1, $3); }
3353 : : ;
3354 : :
3355 : : instParamItem<pinp>: // IEEE: named_parameter_assignment + empty
3356 : : // // Note empty is not allowed in parameter lists
3357 : : yP_DOTSTAR { $$ = new AstPin{$1, PINNUMINC(), ".*", nullptr}; }
3358 : : | '.' idAny '(' ')'
3359 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2, nullptr};
3360 : : $$->svDotName(true); }
3361 : : | '.' idSVKwd
3362 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2,
3363 : : new AstParseRef{$<fl>2, *$2, nullptr, nullptr}};
3364 : : $$->svDotName(true); $$->svImplicit(true); }
3365 : : | '.' idAny
3366 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2,
3367 : : new AstParseRef{$<fl>2, *$2, nullptr, nullptr}};
3368 : : $$->svDotName(true); $$->svImplicit(true); }
3369 : : // // mintypmax is expanded here, as it might be a UDP or gate primitive
3370 : : // // data_type for 'parameter type' hookups
3371 : : | '.' idAny '(' exprOrDataType ')'
3372 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2, $4};
3373 : : $$->svDotName(true); }
3374 : : //UNSUP | '.' idAny '(' exprOrDataType/*expr*/ ':' expr ')'
3375 : : //UNSUP { MINTYPMAXDLYUNSUP($4); DEL($4);
3376 : : //UNSUP $$ = new AstPin{$<fl>2, PINNUMINC(), *$2, $6};
3377 : : //UNSUP $$->svDotName(true); }
3378 : : //UNSUP | '.' idAny '(' exprOrDataType/*expr*/ ':' expr ':' expr ')'
3379 : : //UNSUP { MINTYPMAXDLYUNSUP($4); DEL($4); DEL($8);
3380 : : //UNSUP $$ = new AstPin{$<fl>2, PINNUMINC(), *$2, $6};
3381 : : //UNSUP $$->svDotName(true); }
3382 : : // // data_type for 'parameter type' hookups
3383 : : | exprOrDataType
3384 : : { $$ = new AstPin{FILELINE_OR_CRE($1), PINNUMINC(), "", $1}; }
3385 : : //UNSUP | exprOrDataType/*expr*/ ':' expr
3386 : : //UNSUP { MINTYPMAXDLYUNSUP($1); DEL($1);
3387 : : //UNSUP $$ = new AstPin{FILELINE_OR_CRE($3), PINNUMINC(), "", $3}; }
3388 : : //UNSUP | exprOrDataType/*expr*/ ':' expr ':' expr
3389 : : //UNSUP { MINTYPMAXDLYUNSUP($1); DEL($1); DEL($5);
3390 : : //UNSUP $$ = new AstPin{FILELINE_OR_CRE($3), PINNUMINC(), "", $3}; }
3391 : : ;
3392 : :
3393 : : instPinItemE<pinp>: // IEEE: named_port_connection + empty
3394 : : // // Note empty can match either () or (,); V3LinkCells cleans up ()
3395 : : /* empty: ',,' is legal */ { $$ = new AstPin{CRELINE(), PINNUMINC(), "", nullptr}; }
3396 : : | yP_DOTSTAR { $$ = new AstPin{$1, PINNUMINC(), ".*", nullptr}; }
3397 : : | '.' idAny '(' ')'
3398 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2, nullptr};
3399 : : $$->svDotName(true); }
3400 : : | '.' idSVKwd
3401 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2,
3402 : : new AstParseRef{$<fl>2, *$2, nullptr, nullptr}};
3403 : : $$->svDotName(true); $$->svImplicit(true); }
3404 : : | '.' idAny
3405 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2,
3406 : : new AstParseRef{$<fl>2, *$2, nullptr, nullptr}};
3407 : : $$->svDotName(true); $$->svImplicit(true); }
3408 : : // // mintypmax is expanded here, as it might be a UDP or gate primitive
3409 : : //UNSUP pev_expr below
3410 : : | '.' idAny '(' expr ')'
3411 : : { $$ = new AstPin{$<fl>2, PINNUMINC(), *$2, $4};
3412 : : $$->svDotName(true); }
3413 : : //UNSUP '.' idAny '(' pev_expr ':' expr ')' { }
3414 : : //UNSUP '.' idAny '(' pev_expr ':' expr ':' expr ')' { }
3415 : : //
3416 : : | expr { $$ = new AstPin{FILELINE_OR_CRE($1), PINNUMINC(), "", $1}; }
3417 : : //UNSUP expr ':' expr { }
3418 : : //UNSUP expr ':' expr ':' expr { }
3419 : : ;
3420 : :
3421 : : //************************************************
3422 : : // EventControl lists
3423 : :
3424 : : attr_event_controlE<senTreep>:
3425 : : /* empty */ { $$ = nullptr; }
3426 : : | attr_event_control { $$ = $1; }
3427 : : ;
3428 : :
3429 : : attr_event_control<senTreep>: // ==IEEE: event_control
3430 : : '@' '(' event_expression ')' { $$ = new AstSenTree{$1, $3}; }
3431 : : | '@' '(' '*' ')' { $$ = GRAMMARP->createSenTreeDotStar($1); }
3432 : : | '@' '*' { $$ = GRAMMARP->createSenTreeDotStar($1); }
3433 : : ;
3434 : :
3435 : : event_control<senTreep>: // ==IEEE: event_control
3436 : : // UNSUP: Needs alignment with IEEE event_control and clocking_event
3437 : : '@' '(' '*' ')' { $$ = GRAMMARP->createSenTreeDotStar($1); }
3438 : : | '@' '*' { $$ = GRAMMARP->createSenTreeDotStar($1); }
3439 : : // // IEEE: clocking_event
3440 : : | '@' '(' event_expression ')' { $$ = new AstSenTree{$1, $3}; }
3441 : : // // IEEE: hierarchical_event_identifier
3442 : : // // UNSUP below should be idClassSel
3443 : : | '@' senitemVar { $$ = new AstSenTree{$1, $2}; } /* For events only */
3444 : : // // IEEE: sequence_instance
3445 : : // // sequence_instance without parens matches idClassSel above.
3446 : : // // Ambiguity: "'@' sequence (-for-sequence" versus
3447 : : // // expr:delay_or_event_controlE "'@' id (-for-expr
3448 : : // // For now we avoid this, as it's very unlikely someone would mix
3449 : : // // 1995 delay with a sequence with parameters.
3450 : : // // Alternatively split this out of event_control, and delay_or_event_controlE
3451 : : // // and anywhere delay_or_event_controlE is called allow two expressions
3452 : : //UNSUP '@' idClassSel '(' list_of_argumentsE ')' { }
3453 : : ;
3454 : :
3455 : : event_expression<senItemp>: // IEEE: event_expression - split over several
3456 : : //UNSUP // Below are all removed
3457 : : senitem { $$ = $1; }
3458 : : | event_expression yOR senitem { $$ = addNextNull($1, $3); }
3459 : : | event_expression ',' senitem { $$ = addNextNull($1, $3); } /* Verilog 2001 */
3460 : : //UNSUP // Above are all removed, replace with:
3461 : : //UNSUP ev_expr { $$ = $1; }
3462 : : //UNSUP event_expression ',' ev_expr %prec yOR { $$ = addNextNull($1, $3); }
3463 : : ;
3464 : :
3465 : : senitem<senItemp>: // IEEE: part of event_expression, non-'OR' ',' terms
3466 : : senitemEdge { $$ = $1; }
3467 : : | expr
3468 : : { $$ = new AstSenItem{$<fl>1, VEdgeType::ET_CHANGED, $1}; }
3469 : : | expr yIFF expr
3470 : : { $$ = new AstSenItem{$<fl>1, VEdgeType::ET_CHANGED, $1, $3}; }
3471 : : ;
3472 : :
3473 : : senitemVar<senItemp>:
3474 : : idClassSel
3475 : : { $$ = new AstSenItem{$1->fileline(), VEdgeType::ET_CHANGED, $1}; }
3476 : : ;
3477 : :
3478 : : senitemEdge<senItemp>: // IEEE: part of event_expression
3479 : : yPOSEDGE expr
3480 : : { $$ = new AstSenItem{$1, VEdgeType::ET_POSEDGE, $2}; }
3481 : : | yNEGEDGE expr
3482 : : { $$ = new AstSenItem{$1, VEdgeType::ET_NEGEDGE, $2}; }
3483 : : | yEDGE expr
3484 : : { $$ = new AstSenItem{$1, VEdgeType::ET_BOTHEDGE, $2}; }
3485 : : | yPOSEDGE expr yIFF expr
3486 : : { $$ = new AstSenItem{$1, VEdgeType::ET_POSEDGE, $2, $4}; }
3487 : : | yNEGEDGE expr yIFF expr
3488 : : { $$ = new AstSenItem{$1, VEdgeType::ET_NEGEDGE, $2, $4}; }
3489 : : | yEDGE expr yIFF expr
3490 : : { $$ = new AstSenItem{$1, VEdgeType::ET_BOTHEDGE, $2, $4}; }
3491 : : ;
3492 : :
3493 : : //************************************************
3494 : : // Statements
3495 : :
3496 : : seq_block<beginp>: // ==IEEE: seq_block
3497 : : // // IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
3498 : : // // So need AstBegin's even if unnamed to scope variables down
3499 : : yBEGIN startLabelE blockDeclListE stmtListE yEND endLabelE
3500 : : {
3501 : : $$ = new AstBegin{$1, $2 ? *$2 : "", nullptr, false};
3502 : : GRAMMARP->endLabel($<fl>6, $$, $6);
3503 : : $$->addDeclsp($3);
3504 : : $$->addStmtsp($4);
3505 : : }
3506 : : ;
3507 : :
3508 : : seq_blockPreId<beginp>: // IEEE: seq_block, but called with leading ID
3509 : : id yP_COLON__BEGIN yBEGIN blockDeclListE stmtListE yEND endLabelE
3510 : : {
3511 : : $$ = new AstBegin{$3, *$1, nullptr, false};
3512 : : GRAMMARP->endLabel($<fl>7, $$, $7);
3513 : : $$->addDeclsp($4);
3514 : : $$->addStmtsp($5);
3515 : : }
3516 : : ;
3517 : :
3518 : : par_blockJoin<joinType>:
3519 : : yJOIN { $$ = VJoinType::JOIN; }
3520 : : | yJOIN_ANY { $$ = VJoinType::JOIN_ANY; }
3521 : : | yJOIN_NONE { $$ = VJoinType::JOIN_NONE; }
3522 : : ;
3523 : :
3524 : : par_block<forkp>: // ==IEEE: par_block
3525 : : yFORK startLabelE blockDeclListE stmtListE par_blockJoin endLabelE
3526 : : {
3527 : : $$ = new AstFork{$1, $5, $2 ? *$2 : ""};
3528 : : GRAMMARP->endLabel($<fl>6, $$, $6);
3529 : : $$->addDeclsp($3);
3530 : : $$->addForksp(V3ParseGrammar::wrapInBegin($4));
3531 : : }
3532 : : ;
3533 : :
3534 : : par_blockPreId<forkp>: // ==IEEE: par_block but called with leading ID
3535 : : id yP_COLON__FORK yFORK blockDeclListE stmtListE par_blockJoin endLabelE
3536 : : {
3537 : : $$ = new AstFork{$3, $6, *$1};
3538 : : GRAMMARP->endLabel($<fl>7, $$, $7);
3539 : : $$->addDeclsp($4);
3540 : : $$->addForksp(V3ParseGrammar::wrapInBegin($5));
3541 : : }
3542 : : ;
3543 : :
3544 : : blockDeclListE<nodep>: // IEEE: [ block_item_declaration ]
3545 : : /*empty*/ { $$ = nullptr; }
3546 : : | blockDeclListE block_item_declaration { $$ = addNextNull($1, $2); }
3547 : : | error ';' { $$ = nullptr; } // LCOV_EXCL_LINE
3548 : : ;
3549 : :
3550 : : block_item_declaration<nodep>: // ==IEEE: block_item_declaration
3551 : : data_declaration { $$ = $1; }
3552 : : | parameter_declaration ';' { $$ = $1; }
3553 : : | let_declaration { $$ = $1; }
3554 : : ;
3555 : :
3556 : : stmtListE<nodeStmtp>:
3557 : : /*empty*/ { $$ = nullptr; }
3558 : : | stmtList { $$ = $1; }
3559 : : ;
3560 : :
3561 : : stmtList<nodeStmtp>:
3562 : : stmt { $$ = $1; }
3563 : : | stmtList stmt { $$ = addNextNull($1, $2); }
3564 : : //
3565 : : | stmtList error ';' { $$ = $1; } // LCOV_EXCL_LINE
3566 : : ;
3567 : :
3568 : : stmt<nodeStmtp>: // IEEE: statement + statement_or_null + seq_block + par_block
3569 : : statement_item { $$ = $1; }
3570 : : // // S05 block creation rule
3571 : : | id/*block_identifier*/ ':' statement_item { $$ = new AstBegin{$<fl>1, *$1, $3, false}; }
3572 : : // // from _or_null
3573 : : | ';' { $$ = nullptr; }
3574 : : // // labeled par_block/seq_block with leading ':'
3575 : : | seq_blockPreId { $$ = $1; }
3576 : : | par_blockPreId { $$ = $1; }
3577 : : ;
3578 : :
3579 : : statement_item<nodeStmtp>: // IEEE: statement_item
3580 : : // // IEEE: operator_assignment
3581 : : foperator_assignment ';' { $$ = $1; }
3582 : : //
3583 : : // // IEEE: blocking_assignment
3584 : : // // 1800-2009 restricts LHS of assignment to new to not have a range
3585 : : // // This is ignored to avoid conflicts
3586 : : | fexprLvalue yP_EQ__NEW dynamic_array_new ';' { $$ = new AstAssign{$2, $1, $3}; }
3587 : : | fexprLvalue yP_EQ__NEW class_new ';' { $$ = new AstAssign{$2, $1, $3}; }
3588 : : // // IEEE: inc_or_dec_expression
3589 : : | finc_or_dec_expression ';' { $$ = new AstStmtExpr{$<fl>1, $1}; }
3590 : : //
3591 : : // // IEEE: nonblocking_assignment
3592 : : | fexprLvalue yP_LTE delay_or_event_controlE expr ';'
3593 : : { $$ = new AstAssignDly{$2, $1, $4, $3}; }
3594 : : // // IEEE: clocking_drive ';'
3595 : : | fexprLvalue yP_LTE cycle_delay expr ';'
3596 : : { $$ = new AstAssignDly{$2, $1, $4, $3}; }
3597 : : //UNSUP cycle_delay fexprLvalue yP_LTE ';' { UNSUP }
3598 : : | yASSIGN idClassSel '=' delay_or_event_controlE expr ';'
3599 : : { $$ = new AstAssignCont{$1, $2, $5, $4}; }
3600 : : | yDEASSIGN variable_lvalue ';'
3601 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: Verilog 1995 deassign"); DEL($2); }
3602 : : | yFORCE variable_lvalue '=' expr ';'
3603 : : { $$ = new AstAssignForce{$1, $2, $4}; v3Global.setHasForceableSignals(); }
3604 : : | yRELEASE variable_lvalue ';'
3605 : : { $$ = new AstRelease{$1, $2}; v3Global.setHasForceableSignals(); }
3606 : : //
3607 : : // // IEEE: case_statement
3608 : : | unique_priorityE caseStart caseAttrE case_itemList yENDCASE
3609 : : { $$ = $2; if ($4) $2->addItemsp($4);
3610 : : if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
3611 : : if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
3612 : : if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
3613 : : // case matches uses patterns, not expressions
3614 : : | unique_priorityE caseStart caseAttrE yMATCHES case_matches_itemList yENDCASE
3615 : : { $$ = $2; if ($5) $2->addItemsp($5);
3616 : : $2->caseMatchesSet();
3617 : : if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
3618 : : if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
3619 : : if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
3620 : : | unique_priorityE caseStart caseAttrE yINSIDE case_inside_itemList yENDCASE
3621 : : { $$ = $2; if ($5) $2->addItemsp($5);
3622 : : if (!$2->caseSimple()) $4->v3error("Illegal to have inside on a casex/casez");
3623 : : $2->caseInsideSet();
3624 : : if ($1 == uniq_UNIQUE) $2->uniquePragma(true);
3625 : : if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true);
3626 : : if ($1 == uniq_PRIORITY) $2->priorityPragma(true); }
3627 : : //
3628 : : // // IEEE: conditional_statement
3629 : : | unique_priorityE yIF '(' expr ')' stmt %prec prLOWER_THAN_ELSE
3630 : : { AstIf* const newp = new AstIf{$2, $4,
3631 : : PARSEP->newBlock($2, $6)};
3632 : : $$ = newp;
3633 : : if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
3634 : : if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
3635 : : if ($1 == uniq_PRIORITY) newp->priorityPragma(true); }
3636 : : | unique_priorityE yIF '(' expr ')' stmt yELSE stmt
3637 : : { AstIf* const newp = new AstIf{$2, $4,
3638 : : PARSEP->newBlock($2, $6),
3639 : : PARSEP->newBlock($2, $8)};
3640 : : $$ = newp;
3641 : : if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
3642 : : if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
3643 : : if ($1 == uniq_PRIORITY) newp->priorityPragma(true); }
3644 : : //
3645 : : // // IEEE: subroutine_call_statement
3646 : : // // IEEE says we then expect a function call
3647 : : // // (function_subroutine_callNoMethod), but rest of
3648 : : // // the code expects an AstTask when used as a statement,
3649 : : // // so parse as if task
3650 : : // // Alternative would be shim with new AstVoidStmt.
3651 : : | yVOID yP_TICK '(' task_subroutine_callNoMethod ')' ';'
3652 : : { AstNodeExpr* const exprp = $4;
3653 : : AstNode* callp = exprp;
3654 : : while (AstDot* const dotp = VN_CAST(callp, Dot)) callp = dotp->rhsp();
3655 : : FileLine* const newfl = new FileLine{callp->fileline()};
3656 : : newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
3657 : : callp->fileline(newfl);
3658 : : $$ = exprp->makeStmt(); }
3659 : : | yVOID yP_TICK '(' expr '.' task_subroutine_callNoMethod ')' ';'
3660 : : { AstNodeExpr* const exprp = new AstDot{$5, false, $4, $6};
3661 : : FileLine* const newfl = new FileLine{$6->fileline()};
3662 : : newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
3663 : : $6->fileline(newfl);
3664 : : $$ = exprp->makeStmt(); }
3665 : : | yVOID yP_TICK '(' system_f_only_expr_call ')' ';'
3666 : : { $$ = new AstStmtExpr{$<fl>4, $4};
3667 : : FileLine* const newfl = new FileLine{$$->fileline()};
3668 : : newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
3669 : : $$->fileline(newfl); }
3670 : : // // Any system function as a task
3671 : : | yVOID yP_TICK '(' system_f_or_t_expr_call ')' ';'
3672 : : { $$ = new AstStmtExpr{$<fl>4, $4};
3673 : : FileLine* const newfl = new FileLine{$$->fileline()};
3674 : : newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
3675 : : $$->fileline(newfl); }
3676 : : //
3677 : : | task_subroutine_callNoSemi ';' { $$ = $1; }
3678 : : //
3679 : : | statementVerilatorPragmas { $$ = new AstStmtPragma{$<fl>1, $1}; }
3680 : : //
3681 : : // // IEEE: disable_statement
3682 : : | yDISABLE yFORK ';' { $$ = new AstDisableFork{$1}; }
3683 : : | yDISABLE idDottedSel ';'
3684 : : { $$ = new AstDisable{$1, $2};
3685 : : PARSEP->importIfInStd($1, "process", true);
3686 : : }
3687 : : // // IEEE: event_trigger
3688 : : | yP_MINUSGT expr ';'
3689 : : { $$ = new AstFireEvent{$1, $2, false}; }
3690 : : | yP_MINUSGTGT delay_or_event_controlE expr ';'
3691 : : { $$ = new AstFireEvent{$1, $3, true}; }
3692 : : //
3693 : : // do/for/forever/while loops all modelled as AstLoop
3694 : : | yDO stmt yWHILE '(' expr ')' ';'
3695 : : { AstLoop* const loopp = new AstLoop{$1, $2};
3696 : : loopp->addContsp(new AstLoopTest{$<fl>5, loopp, $5});
3697 : : $$ = loopp; }
3698 : : | yFOR '(' { VARRESET_NONLIST(UNKNOWN); } for_initializationE ';' exprE ';' for_stepE ')' stmt
3699 : : { AstBegin* const blockp = new AstBegin{$1, "", $4, true};
3700 : : AstLoop* const loopp = new AstLoop{$1};
3701 : : if ($6) loopp->addStmtsp(new AstLoopTest{$<fl>6, loopp, $6});
3702 : : loopp->addStmtsp($10);
3703 : : loopp->addContsp($8);
3704 : : blockp->addStmtsp(loopp);
3705 : : $$ = blockp; }
3706 : : | yFOREVER stmt
3707 : : { AstLoop* const loopp = new AstLoop{$1, $2};
3708 : : $$ = loopp; }
3709 : : | yWHILE '(' expr ')' stmt
3710 : : { AstLoop* const loopp = new AstLoop{$1};
3711 : : loopp->addStmtsp(new AstLoopTest{$<fl>3, loopp, $3});
3712 : : loopp->addStmtsp($5);
3713 : : $$ = loopp; }
3714 : : // Other loop statements
3715 : : | yREPEAT '(' expr ')' stmt { $$ = new AstRepeat{$1, $3, $5}; }
3716 : : // // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
3717 : : | yFOREACH '(' idClassSelForeach ')' stmt
3718 : : { $$ = new AstBegin{$1, "", new AstForeach{$1, $3, $5}, true}; }
3719 : : //
3720 : : // // IEEE: jump_statement
3721 : : | yRETURN ';' { $$ = new AstReturn{$1}; }
3722 : : | yRETURN expr ';' { $$ = new AstReturn{$1, $2}; }
3723 : : | yBREAK ';' { $$ = new AstBreak{$1}; }
3724 : : | yCONTINUE ';' { $$ = new AstContinue{$1}; }
3725 : : //
3726 : : | par_block { $$ = $1; }
3727 : : // // IEEE: procedural_timing_control_statement + procedural_timing_control
3728 : : | delay_control stmt
3729 : : { AstNodeStmt* nextp = nullptr;
3730 : : if ($2) {
3731 : : if ($2->nextp()) nextp = VN_AS($2->nextp()->unlinkFrBackWithNext(), NodeStmt);
3732 : : $1->addStmtsp($2);
3733 : : }
3734 : : $$ = $1;
3735 : : addNextNull($$, nextp); }
3736 : : | event_control stmt
3737 : : { AstNodeStmt* nextp = nullptr;
3738 : : if ($2 && $2->nextp()) nextp = VN_AS($2->nextp()->unlinkFrBackWithNext(), NodeStmt);
3739 : : $$ = new AstEventControl{FILELINE_OR_CRE($1), $1, $2};
3740 : : addNextNull($$, nextp); }
3741 : : | cycle_delay stmt
3742 : : { AstNodeStmt* nextp = nullptr;
3743 : : if ($2) {
3744 : : if ($2->nextp()) nextp = VN_AS($2->nextp()->unlinkFrBackWithNext(), NodeStmt);
3745 : : $1->addStmtsp($2);
3746 : : }
3747 : : $$ = $1;
3748 : : addNextNull($$, nextp); }
3749 : : | seq_block { $$ = $1; }
3750 : : //
3751 : : // // IEEE: wait_statement
3752 : : | yWAIT '(' expr ')' stmt { $$ = new AstWait{$1, $3, $5}; }
3753 : : | yWAIT yFORK ';' { $$ = new AstWaitFork{$1}; }
3754 : : // // action_block expanded here
3755 : : | yWAIT_ORDER '(' vrdList ')' stmt %prec prLOWER_THAN_ELSE
3756 : : { $$ = nullptr; BBUNSUP($4, "Unsupported: wait_order"); DEL($3, $5); }
3757 : : | yWAIT_ORDER '(' vrdList ')' stmt yELSE stmt
3758 : : { $$ = nullptr; BBUNSUP($4, "Unsupported: wait_order"); DEL($3, $5, $7);}
3759 : : | yWAIT_ORDER '(' vrdList ')' yELSE stmt
3760 : : { $$ = nullptr; BBUNSUP($4, "Unsupported: wait_order"); DEL($3, $6); }
3761 : : //
3762 : : // // IEEE: procedural_assertion_statement
3763 : : | procedural_assertion_statement { $$ = $1; }
3764 : : //
3765 : : | randsequence_statement { $$ = $1; }
3766 : : //
3767 : : // // IEEE: randcase_statement
3768 : : | yRANDCASE rand_case_itemList yENDCASE { $$ = new AstRandCase{$1, $2}; }
3769 : : //
3770 : : // // IEEE: expect_property_statement
3771 : : // // action_block expanded here
3772 : : | yEXPECT '(' property_spec ')' stmt %prec prLOWER_THAN_ELSE
3773 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: expect"); DEL($3, $5); }
3774 : : | yEXPECT '(' property_spec ')' stmt yELSE stmt
3775 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: expect"); DEL($3, $5, $7); }
3776 : : | yEXPECT '(' property_spec ')' yELSE stmt
3777 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: expect"); DEL($3, $6); }
3778 : : ;
3779 : :
3780 : : statementVerilatorPragmas<pragmap>:
3781 : : yVL_COVERAGE_BLOCK_OFF
3782 : : { $$ = new AstPragma{$1, VPragmaType::COVERAGE_BLOCK_OFF}; }
3783 : : | yVL_UNROLL_DISABLE
3784 : : { $$ = new AstPragma{$1, VPragmaType::UNROLL_DISABLE}; }
3785 : : | yVL_UNROLL_FULL
3786 : : { $$ = new AstPragma{$1, VPragmaType::UNROLL_FULL}; }
3787 : : ;
3788 : :
3789 : : foperator_assignment<nodeStmtp>: // IEEE: operator_assignment (for first part of expression)
3790 : : fexprLvalue '=' delay_or_event_controlE expr { $$ = new AstAssign{$2, $1, $4, $3}; }
3791 : : //
3792 : : | fexprLvalue yP_PLUSEQ expr
3793 : : { $$ = new AstAssign{$2, $1, new AstAdd{$2, $1->cloneTreePure(true), $3}}; }
3794 : : | fexprLvalue yP_MINUSEQ expr
3795 : : { $$ = new AstAssign{$2, $1, new AstSub{$2, $1->cloneTreePure(true), $3}}; }
3796 : : | fexprLvalue yP_TIMESEQ expr
3797 : : { $$ = new AstAssign{$2, $1, new AstMul{$2, $1->cloneTreePure(true), $3}}; }
3798 : : | fexprLvalue yP_DIVEQ expr
3799 : : { $$ = new AstAssign{$2, $1, new AstDiv{$2, $1->cloneTreePure(true), $3}}; }
3800 : : | fexprLvalue yP_MODEQ expr
3801 : : { $$ = new AstAssign{$2, $1, new AstModDiv{$2, $1->cloneTreePure(true), $3}}; }
3802 : : | fexprLvalue yP_ANDEQ expr
3803 : : { $$ = new AstAssign{$2, $1, new AstAnd{$2, $1->cloneTreePure(true), $3}}; }
3804 : : | fexprLvalue yP_OREQ expr
3805 : : { $$ = new AstAssign{$2, $1, new AstOr{$2, $1->cloneTreePure(true), $3}}; }
3806 : : | fexprLvalue yP_XOREQ expr
3807 : : { $$ = new AstAssign{$2, $1, new AstXor{$2, $1->cloneTreePure(true), $3}}; }
3808 : : | fexprLvalue yP_SLEFTEQ expr
3809 : : { $$ = new AstAssign{$2, $1, new AstShiftL{$2, $1->cloneTreePure(true), $3}}; }
3810 : : | fexprLvalue yP_SRIGHTEQ expr
3811 : : { $$ = new AstAssign{$2, $1, new AstShiftR{$2, $1->cloneTreePure(true), $3}}; }
3812 : : | fexprLvalue yP_SSRIGHTEQ expr
3813 : : { $$ = new AstAssign{$2, $1, new AstShiftRS{$2, $1->cloneTreePure(true), $3}}; }
3814 : : ;
3815 : :
3816 : : inc_or_dec_expression<nodeExprp>: // ==IEEE: inc_or_dec_expression
3817 : : // // Need fexprScope instead of variable_lvalue to prevent conflict
3818 : : ~l~exprScope yP_PLUSPLUS
3819 : : { $<fl>$ = $<fl>1; $$ = new AstPostAdd{$2, new AstConst{$2, AstConst::StringToParse{}, "'b1"},
3820 : : // Purity checked in V3LinkInc
3821 : : $1, $1->cloneTree(true)}; }
3822 : : | ~l~exprScope yP_MINUSMINUS
3823 : : { $<fl>$ = $<fl>1; $$ = new AstPostSub{$2, new AstConst{$2, AstConst::StringToParse{}, "'b1"},
3824 : : // Purity checked in V3LinkInc
3825 : : $1, $1->cloneTree(true)}; }
3826 : : // // Need expr instead of variable_lvalue to prevent conflict
3827 : : | yP_PLUSPLUS expr
3828 : : { $<fl>$ = $<fl>1; $$ = new AstPreAdd{$1, new AstConst{$1, AstConst::StringToParse{}, "'b1"},
3829 : : // Purity checked in V3LinkInc
3830 : : $2, $2->cloneTree(true)}; }
3831 : : | yP_MINUSMINUS expr
3832 : : { $<fl>$ = $<fl>1; $$ = new AstPreSub{$1, new AstConst{$1, AstConst::StringToParse{}, "'b1"},
3833 : : // Purity checked in V3LinkInc
3834 : : $2, $2->cloneTree(true)}; }
3835 : : ;
3836 : :
3837 : : finc_or_dec_expression<nodeExprp>: // ==IEEE: inc_or_dec_expression
3838 : : BISONPRE_COPY(inc_or_dec_expression,{s/~l~/f/g}) // {copied}
3839 : : ;
3840 : :
3841 : : sinc_or_dec_expression<nodeExprp>: // IEEE: inc_or_dec_expression (for sequence_expression)
3842 : : BISONPRE_COPY(inc_or_dec_expression,{s/~l~/s/g}) // {copied}
3843 : : ;
3844 : :
3845 : : pinc_or_dec_expression<nodeExprp>: // IEEE: inc_or_dec_expression (for property_expression)
3846 : : BISONPRE_COPY(inc_or_dec_expression,{s/~l~/p/g}) // {copied}
3847 : : ;
3848 : :
3849 : : //UNSUPev_inc_or_dec_expression<nodeExprp>: // IEEE: inc_or_dec_expression (for ev_expr)
3850 : : //UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/ev_/g}) // {copied}
3851 : : //UNSUP ;
3852 : :
3853 : : //UNSUPpev_inc_or_dec_expression<nodeExprp>: // IEEE: inc_or_dec_expression (for pev_expr)
3854 : : //UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/pev_/g}) // {copied}
3855 : : //UNSUP ;
3856 : :
3857 : : class_new<nodeExprp>: // IEEE: class_new
3858 : : // // See V3ParseImp::tokenPipeScanEqNew that searches for '=' ... yNEW__LEX
3859 : : class_newNoScope
3860 : : { $$ = $1; }
3861 : : // // Special precedence so (...) doesn't match expr
3862 : : // // A scope is not legal in front of a AstNewCopy
3863 : : | packageClassScopeNoId yNEW__ETC
3864 : : { $$ = AstDot::newIfPkg($<fl>2, $1, new AstNew{$2, nullptr, true}); }
3865 : : | packageClassScopeNoId yNEW__PAREN '(' list_of_argumentsE ')'
3866 : : { $$ = AstDot::newIfPkg($<fl>2, $1, new AstNew{$2, $4, true}); }
3867 : : ;
3868 : :
3869 : : class_newNoScope<nodeExprp>: // IEEE: class_new but no packageClassScope
3870 : : // // Special precedence so (...) doesn't match expr
3871 : : yNEW__ETC { $$ = new AstNew{$1}; }
3872 : : | yNEW__ETC expr { $$ = new AstNewCopy{$1, $2}; }
3873 : : | yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew{$1, $3}; }
3874 : : ;
3875 : :
3876 : : dynamic_array_new<nodeExprp>: // ==IEEE: dynamic_array_new
3877 : : yNEW__ETC '[' expr ']' { $$ = new AstNewDynamic{$1, $3, nullptr}; }
3878 : : | yNEW__ETC '[' expr ']' '(' expr ')' { $$ = new AstNewDynamic{$1, $3, $6}; }
3879 : : ;
3880 : :
3881 : : //************************************************
3882 : : // Case/If
3883 : :
3884 : : unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
3885 : : /*empty*/ { $$ = uniq_NONE; }
3886 : : | yPRIORITY { $$ = uniq_PRIORITY; }
3887 : : | yUNIQUE { $$ = uniq_UNIQUE; }
3888 : : | yUNIQUE0 { $$ = uniq_UNIQUE0; }
3889 : : ;
3890 : :
3891 : : caseStart<casep>: // IEEE: part of case_statement
3892 : : yCASE '(' exprTypeCompare ')'
3893 : : { $$ = GRAMMARP->m_caseAttrp = new AstCase{$1, VCaseType::CT_CASE, $3, nullptr}; }
3894 : : | yCASEX '(' exprTypeCompare ')'
3895 : : { $$ = GRAMMARP->m_caseAttrp = new AstCase{$1, VCaseType::CT_CASEX, $3, nullptr}; }
3896 : : | yCASEZ '(' exprTypeCompare ')'
3897 : : { $$ = GRAMMARP->m_caseAttrp = new AstCase{$1, VCaseType::CT_CASEZ, $3, nullptr}; }
3898 : : ;
3899 : :
3900 : : caseAttrE:
3901 : : /*empty*/ { }
3902 : : | caseAttrE yVL_FULL_CASE { GRAMMARP->m_caseAttrp->fullPragma(true); }
3903 : : | caseAttrE yVL_PARALLEL_CASE { GRAMMARP->m_caseAttrp->parallelPragma(true); }
3904 : : ;
3905 : :
3906 : : case_itemList<caseItemp>: // IEEE: { case_item + ... }
3907 : : caseCondList colon stmt { $$ = new AstCaseItem{$2, $1, $3}; }
3908 : : | yDEFAULT colon stmt { $$ = new AstCaseItem{$1, nullptr, $3}; }
3909 : : | yDEFAULT stmt { $$ = new AstCaseItem{$1, nullptr, $2}; }
3910 : : | case_itemList caseCondList colon stmt { $$ = $1->addNext(new AstCaseItem{$3, $2, $4}); }
3911 : : | case_itemList yDEFAULT stmt { $$ = $1->addNext(new AstCaseItem{$2, nullptr, $3}); }
3912 : : | case_itemList yDEFAULT colon stmt { $$ = $1->addNext(new AstCaseItem{$2, nullptr, $4}); }
3913 : : ;
3914 : :
3915 : : case_inside_itemList<caseItemp>: // IEEE: { case_inside_item + range_list ... }
3916 : : range_list colon stmt { $$ = new AstCaseItem{$2, $1, $3}; }
3917 : : | yDEFAULT colon stmt { $$ = new AstCaseItem{$1, nullptr, $3}; }
3918 : : | yDEFAULT stmt { $$ = new AstCaseItem{$1, nullptr, $2}; }
3919 : : | case_inside_itemList range_list colon stmt { $$ = $1->addNext(new AstCaseItem{$3, $2, $4}); }
3920 : : | case_inside_itemList yDEFAULT stmt { $$ = $1->addNext(new AstCaseItem{$2, nullptr, $3}); }
3921 : : | case_inside_itemList yDEFAULT colon stmt { $$ = $1->addNext(new AstCaseItem{$2, nullptr, $4}); }
3922 : : ;
3923 : :
3924 : : case_matches_itemList<caseItemp>: // IEEE: { case_pattern_item + ... }
3925 : : // // IEEE: case_pattern_item ::= pattern [&&& expr] : stmt
3926 : : // // pattern includes expr for tagged void members (tagged id)
3927 : : patternNoExpr colon stmt { $$ = new AstCaseItem{$2, $1, $3}; }
3928 : : | expr colon stmt { $$ = new AstCaseItem{$2, $1, $3}; }
3929 : : | yDEFAULT colon stmt { $$ = new AstCaseItem{$1, nullptr, $3}; }
3930 : : | yDEFAULT stmt { $$ = new AstCaseItem{$1, nullptr, $2}; }
3931 : : | case_matches_itemList patternNoExpr colon stmt
3932 : : { $$ = $1->addNext(new AstCaseItem{$3, $2, $4}); }
3933 : : | case_matches_itemList expr colon stmt
3934 : : { $$ = $1->addNext(new AstCaseItem{$3, $2, $4}); }
3935 : : | case_matches_itemList yDEFAULT stmt { $$ = $1->addNext(new AstCaseItem{$2, nullptr, $3}); }
3936 : : | case_matches_itemList yDEFAULT colon stmt { $$ = $1->addNext(new AstCaseItem{$2, nullptr, $4}); }
3937 : : ;
3938 : :
3939 : : rand_case_itemList<caseItemp>: // IEEE: { rand_case_item + ... }
3940 : : // // Randcase syntax doesn't have default, or expression lists
3941 : : expr colon stmt { $$ = new AstCaseItem{$2, $1, $3}; }
3942 : : | rand_case_itemList expr colon stmt { $$ = $1->addNext(new AstCaseItem{$3, $2, $4}); }
3943 : : ;
3944 : :
3945 : : range_list<nodeExprp>: // ==IEEE: range_list/open_range_list + value_range/open_value_range
3946 : : value_range { $$ = $1; }
3947 : : | range_list ',' value_range { $$ = $1->addNext($3); }
3948 : : ;
3949 : :
3950 : : value_range<nodeExprp>: // ==IEEE: value_range/open_value_range
3951 : : expr { $$ = $1; }
3952 : : | '[' expr ':' expr ']' { $$ = new AstInsideRange{$1, $2, $4}; }
3953 : : // // IEEE-2023: added all four:
3954 : : // // Skipped as '$' is part of our expr
3955 : : // // IEEE-2023: '[' '$' ':' expr ']'
3956 : : // // Skipped as '$' is part of our expr
3957 : : // // IEEE-2023: '[' expr ':' '$' ']'
3958 : : | '[' expr yP_PLUSSLASHMINUS expr ']'
3959 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: +/- range"); DEL($2, $4); }
3960 : : | '[' expr yP_PLUSPCTMINUS expr ']'
3961 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: +%- range"); DEL($2, $4); }
3962 : : ;
3963 : :
3964 : : covergroup_value_range<nodeExprp>: // ==IEEE-2012: covergroup_value_range
3965 : : cgexpr { $$ = $1; }
3966 : : | '[' cgexpr ':' cgexpr ']'
3967 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: covergroup value range"); DEL($2, $4); }
3968 : : // // IEEE-2023: added all four:
3969 : : // // Skipped as '$' is part of our expr
3970 : : // // IEEE-2023: '[' '$' ':' cgexpr ']'
3971 : : // // Skipped as '$' is part of our expr
3972 : : // // IEEE-2023: '[' cgexpr ':' '$' ']'
3973 : : | '[' cgexpr yP_PLUSSLASHMINUS cgexpr ']'
3974 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: covergroup value range"); DEL($2, $4); }
3975 : : | '[' cgexpr yP_PLUSPCTMINUS cgexpr ']'
3976 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: covergroup value range"); DEL($2, $4); }
3977 : : ;
3978 : :
3979 : : caseCondList<nodeExprp>: // IEEE: part of case_item
3980 : : exprTypeCompare { $$ = $1; }
3981 : : | caseCondList ',' exprTypeCompare { $$ = $1->addNext($3); }
3982 : : ;
3983 : :
3984 : : patternNoExpr<nodeExprp>: // IEEE: pattern **Excluding Expr*
3985 : : '.' idAny/*variable*/
3986 : : { $$ = new AstPatternVar{$1, *$2}; }
3987 : : | yP_DOTSTAR
3988 : : { $$ = new AstPatternStar{$1}; }
3989 : : // // IEEE: "expr" excluded; expand in callers
3990 : : // // IEEE: tagged member_identifier [ pattern ]
3991 : : // // Standalone "yTAGGED__NONPRIMARY idAny" is handled via expr in patternOne
3992 : : // // Here, we need to treat yTAGGED and yTAGGED__NONPRIMARY identically.
3993 : : | yTAGGED idAny/*member_identifier*/ patternNoExpr
3994 : : { $$ = new AstTaggedPattern{$1, *$2, $3}; }
3995 : : | yTAGGED__NONPRIMARY idAny/*member_identifier*/ patternNoExpr
3996 : : { $$ = new AstTaggedPattern{$1, *$2, $3}; }
3997 : : // // "yP_TICKBRA patternList '}'" part of expr under assignment_pattern
3998 : : ;
3999 : :
4000 : : patternList<nodep>: // IEEE: part of pattern
4001 : : patternOne { $$ = $1; }
4002 : : | patternList ',' patternOne { $$ = addNextNull($1, $3); }
4003 : : ;
4004 : :
4005 : : patternOne<nodep>: // IEEE: part of pattern
4006 : : expr
4007 : : { if ($1) $$ = new AstPatMember{$1->fileline(), $1, nullptr, nullptr}; else $$ = nullptr; }
4008 : : | expr '{' argsExprList '}' { $$ = new AstPatMember{$2, $3, nullptr, $1}; }
4009 : : | patternNoExpr { $$ = $1; }
4010 : : ;
4011 : :
4012 : : patternMemberList<nodep>: // IEEE: part of pattern and assignment_pattern
4013 : : patternMemberOne { $$ = $1; }
4014 : : | patternMemberList ',' patternMemberOne { $$ = addNextNull($1, $3); }
4015 : : ;
4016 : :
4017 : : patternMemberOne<patMemberp>: // IEEE: part of pattern and assignment_pattern
4018 : : patternKey ':' expr { $$ = new AstPatMember{$1->fileline(), $3, $1, nullptr}; }
4019 : : | patternKey ':' patternNoExpr { $$ = new AstPatMember{$1->fileline(), $3, $1, nullptr}; }
4020 : : // // From assignment_pattern_key
4021 : : | yDEFAULT ':' expr { $$ = new AstPatMember{$1, $3, nullptr, nullptr}; $$->isDefault(true); }
4022 : : | yDEFAULT ':' patternNoExpr { AstPatMember* const patp = new AstPatMember{$1, $3, nullptr, nullptr}; patp->isDefault(true); $$ = patp; }
4023 : : ;
4024 : :
4025 : : patternKey<nodep>: // IEEE: merge structure_pattern_key, array_pattern_key, assignment_pattern_key
4026 : : // // IEEE: structure_pattern_key
4027 : : // // id/*member*/ is part of constExpr below
4028 : : //UNSUP constExpr { $$ = $1; }
4029 : : // // IEEE: assignment_pattern_key
4030 : : // // Verilator:
4031 : : // // The above expressions cause problems because "foo" may be
4032 : : // // a constant identifier (if array) or a reference to the
4033 : : // // "foo"member (if structure)
4034 : : // // So for now we only allow a true constant number, or an
4035 : : // // identifier which we treat as a structure member name
4036 : : yaINTNUM
4037 : : { $$ = new AstConst{$<fl>1, *$1}; }
4038 : : | '-' yaINTNUM
4039 : : { V3Number neg{*$2}; neg.opNegate(*$2); $$ = new AstConst{$<fl>2, neg}; }
4040 : : | yaFLOATNUM
4041 : : { $$ = new AstConst{$<fl>1, AstConst::RealDouble{}, $1}; }
4042 : : | id
4043 : : { $$ = new AstText{$<fl>1, *$1}; }
4044 : : | strAsInt
4045 : : { $$ = $1; }
4046 : : | simple_typeNoRef
4047 : : { $$ = $1; }
4048 : : // // expanded from simple_type ps_type_identifier (part of simple_type)
4049 : : // // expanded from simple_type ps_parameter_identifier (part of simple_type)
4050 : : | packageClassScope id
4051 : : { $$ = AstDot::newIfPkg($<fl>1, $1,
4052 : : new AstParseRef{$<fl>2, *$2, nullptr, nullptr}); }
4053 : : | packageClassScopeE idType
4054 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, nullptr};
4055 : : $$ = refp; }
4056 : : ;
4057 : :
4058 : : assignment_pattern<patternp>: // ==IEEE: assignment_pattern
4059 : : // This doesn't match the text of the spec. I think a : is missing, or example code needed
4060 : : // yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; }
4061 : : // // "'{ const_expression }" is same as patternList with one entry
4062 : : // // From patternNoExpr
4063 : : // // also IEEE: "''{' expression { ',' expression } '}'"
4064 : : // // matches since patternList includes expr
4065 : : yP_TICKBRA patternList '}' { $$ = new AstPattern{$1, $2}; }
4066 : : // // From patternNoExpr
4067 : : // // also IEEE "''{' structure_pattern_key ':' ...
4068 : : // // also IEEE "''{' array_pattern_key ':' ...
4069 : : | yP_TICKBRA patternMemberList '}' { $$ = new AstPattern{$1, $2}; }
4070 : : // // IEEE: Not in grammar, but in VMM
4071 : : | yP_TICKBRA '}' { $$ = new AstPattern{$1, nullptr}; }
4072 : : ;
4073 : :
4074 : : // "datatype id = x {, id = x }" | "yaId = x {, id=x}" is legal
4075 : : for_initializationE<nodep>: // ==IEEE: for_initialization + for_variable_declaration
4076 : : /* empty */ { $$ = nullptr; }
4077 : : | for_initializationItemList { $$ = $1; }
4078 : : ;
4079 : :
4080 : : for_initializationItemList<nodep>: // IEEE: [for_variable_declaration...]
4081 : : for_initializationItem { $$ = $1; }
4082 : : | for_initializationItemList ',' for_initializationItem { $$ = addNextNull($1, $3); }
4083 : : ;
4084 : :
4085 : : for_initializationItem<nodep>: // IEEE: variable_assignment + for_variable_declaration
4086 : : // // IEEE: for_variable_declaration
4087 : : data_type idAny/*new*/ '=' expr
4088 : : { VARRESET_NONLIST(VAR); VARDTYPE($1);
4089 : : AstVar* const varp = VARDONEA($<fl>2, *$2, nullptr, nullptr);
4090 : : varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
4091 : : $$ = varp;
4092 : : $$->addNext(new AstAssign{$3, new AstParseRef{$<fl>2, *$2}, $4}); }
4093 : : // // IEEE-2012:
4094 : : | yVAR data_type idAny/*new*/ '=' expr
4095 : : { VARRESET_NONLIST(VAR); VARDTYPE($2);
4096 : : AstVar* const varp = VARDONEA($<fl>3, *$3, nullptr, nullptr);
4097 : : varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
4098 : : $$ = varp;
4099 : : $$->addNext(new AstAssign{$4, new AstParseRef{$<fl>3, *$3}, $5}); }
4100 : : // // IEEE: variable_assignment
4101 : : // // UNSUP variable_lvalue below
4102 : : | id/*newOrExisting*/ '=' expr
4103 : : { if (GRAMMARP->m_varDecl) {
4104 : : AstVar* const varp = VARDONEA($<fl>1, *$1, nullptr, nullptr);
4105 : : varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
4106 : : $$ = varp;
4107 : : $$->addNext(new AstAssign{$2, new AstParseRef{$<fl>1, *$1}, $3});
4108 : : } else {
4109 : : $$ = new AstAssign{$2, new AstParseRef{$<fl>1, *$1}, $3};
4110 : : }
4111 : : }
4112 : : ;
4113 : :
4114 : : for_stepE<nodep>: // IEEE: for_step + empty
4115 : : /* empty */ { $$ = nullptr; }
4116 : : | for_step { $$ = $1; }
4117 : : ;
4118 : :
4119 : : for_step<nodep>: // IEEE: for_step
4120 : : for_step_assignment { $$ = $1; }
4121 : : | for_step ',' for_step_assignment { $$ = addNextNull($1, $3); }
4122 : : ;
4123 : :
4124 : : for_step_assignment<nodep>: // ==IEEE: for_step_assignment
4125 : : foperator_assignment { $$ = $1; }
4126 : : | finc_or_dec_expression { $$ = new AstStmtExpr{$<fl>1, $1}; }
4127 : : // // IEEE: function_subroutine_call
4128 : : | task_subroutine_callNoSemi { $$ = $1; }
4129 : : ;
4130 : :
4131 : : loop_variables<nodep>: // IEEE: loop_variables
4132 : : loop_variableE { $$ = $1; }
4133 : : | loop_variables ',' loop_variableE { $$ = $1->addNext($3); }
4134 : : ;
4135 : :
4136 : : loop_variableE<nodep>: // IEEE: part of loop_variables
4137 : : /* empty */ { $$ = new AstEmpty{CRELINE()}; }
4138 : : | parseRefBase { $$ = $1; }
4139 : : ;
4140 : :
4141 : : //************************************************
4142 : : // Functions/tasks
4143 : :
4144 : : taskRef<nodeExprp>: // IEEE: part of tf_call
4145 : : id { $$ = new AstTaskRef{$<fl>1, *$1}; }
4146 : : | id '(' list_of_argumentsE ')' { $$ = new AstTaskRef{$<fl>1, *$1, $3}; }
4147 : : | packageClassScope id '(' list_of_argumentsE ')'
4148 : : { $$ = AstDot::newIfPkg($<fl>2, $1, new AstTaskRef{$<fl>2, *$2, $4}); }
4149 : : ;
4150 : :
4151 : : funcRef<nodeExprp>: // IEEE: part of tf_call
4152 : : // // package_scope/hierarchical_... is part of expr, so just need ID
4153 : : // // making-a id-is-a
4154 : : // // ----------------- ------------------
4155 : : // // tf_call tf_identifier expr (list_of_arguments)
4156 : : // // method_call(post .) function_identifier expr (list_of_arguments)
4157 : : // // property_instance property_identifier property_actual_arg
4158 : : // // sequence_instance sequence_identifier sequence_actual_arg
4159 : : // // let_expression let_identifier let_actual_arg
4160 : : //
4161 : : id '(' list_of_argumentsE ')'
4162 : : { $$ = new AstFuncRef{$<fl>1, *$1, $3}; }
4163 : : | packageClassScope id '(' list_of_argumentsE ')'
4164 : : { $$ = AstDot::newIfPkg($<fl>2, $1, new AstFuncRef{$<fl>2, *$2, $4}); }
4165 : : //UNSUP list_of_argumentE should be pev_list_of_argumentE
4166 : : //UNSUP: idDottedSel is really just id to allow dotted method calls
4167 : : ;
4168 : :
4169 : : task_subroutine_callNoSemi<nodeStmtp>: // similar to IEEE task_subroutine_call but without ';'
4170 : : // // Expr included here to resolve our not knowing what is a method call
4171 : : // // Expr here must result in a subroutine_call
4172 : : task_subroutine_callNoMethod { $$ = $1->makeStmt(); }
4173 : : | fexpr '.' task_subroutine_callNoMethod { $$ = (new AstDot{$<fl>2, false, $1, $3})->makeStmt(); }
4174 : : | system_t_stmt_call { $$ = $1; }
4175 : : // // Any system function as a task
4176 : : | system_f_or_t_expr_call { $$ = new AstStmtExpr{$<fl>1, $1}; }
4177 : : // // Not here in IEEE; from class_constructor_declaration
4178 : : // // Because we've joined class_constructor_declaration into generic functions
4179 : : // // Way over-permissive;
4180 : : // // IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ]
4181 : : | fexpr '.' class_newNoScope { $$ = (new AstDot{$<fl>2, false, $1, $3})->makeStmt(); }
4182 : : ;
4183 : :
4184 : : task_subroutine_callNoMethod<nodeExprp>: // function_subroutine_callNoMethod (as task)
4185 : : // // IEEE: tf_call
4186 : : taskRef { $$ = $1; }
4187 : : // // funcref below not task ref to avoid conflict, must later handle either
4188 : : | funcRef yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$2, $1, $4}; }
4189 : : // // can call as method and yWITH without parenthesis
4190 : : | id yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$2, new AstFuncRef{$<fl>1, *$1}, $4}; }
4191 : : // // IEEE: method_call requires a "." so is in expr
4192 : : // // IEEE: ['std::'] not needed, as normal std package resolution will find it
4193 : : // // IEEE: randomize_call
4194 : : // // We implement randomize as a normal funcRef, since randomize isn't a keyword
4195 : : // // Note yNULL is already part of expressions, so they come for free
4196 : : | funcRef yWITH__CUR constraint_block { $$ = new AstWithParse{$2, $1, nullptr, $3}; }
4197 : : | funcRef yWITH__PAREN_CUR '(' expr ')' constraint_block { $$ = new AstWithParse{$2, $1, $4, $6}; }
4198 : : ;
4199 : :
4200 : : function_subroutine_callNoMethod<nodeExprp>: // IEEE: function_subroutine_call (as function)
4201 : : // // IEEE: tf_call
4202 : : funcRef { $$ = $1; }
4203 : : | funcRef yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$2, $1, $4}; }
4204 : : // // can call as method and yWITH without parenthesis
4205 : : | id yWITH__PAREN '(' expr ')' { $$ = new AstWithParse{$2, new AstFuncRef{$<fl>1, *$1}, $4}; }
4206 : : | system_f_only_expr_call { $$ = $1; }
4207 : : | system_f_or_t_expr_call { $$ = $1; }
4208 : : // // IEEE: method_call requires a "." so is in expr
4209 : : // // IEEE: ['std::'] not needed, as normal std package resolution will find it
4210 : : // // IEEE: randomize_call
4211 : : // // We implement randomize as a normal funcRef, since randomize isn't a keyword
4212 : : // // Note yNULL is already part of expressions, so they come for free
4213 : : | funcRef yWITH__CUR constraint_block { $$ = new AstWithParse{$2, $1, nullptr, $3}; }
4214 : : | funcRef yWITH__PAREN_CUR '(' expr ')' constraint_block { $$ = new AstWithParse{$2, $1, $4, $6}; }
4215 : : ;
4216 : :
4217 : : system_t_stmt_call<nodeStmtp>: // IEEE: part of system_tf_call (as task returning statement)
4218 : : //
4219 : : yaD_PLI systemDpiArgsE { AstTaskRef* const refp = new AstTaskRef{$<fl>1, *$1, $2};
4220 : : refp->pli(true);
4221 : : $$ = refp->makeStmt(); }
4222 : : //
4223 : : | yD_DUMPPORTS '(' idDottedSel ',' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FILE, $5}; DEL($3);
4224 : : $$->addNext(new AstDumpCtl{$<fl>1, VDumpCtlType::VARS,
4225 : : new AstConst{$<fl>1, 1}}); }
4226 : : | yD_DUMPPORTS '(' ',' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FILE, $4};
4227 : : $$->addNext(new AstDumpCtl{$<fl>1, VDumpCtlType::VARS,
4228 : : new AstConst{$<fl>1, 1}}); }
4229 : : | yD_DUMPFILE '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FILE, $3}; }
4230 : : | yD_DUMPVARS parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS,
4231 : : new AstConst{$<fl>1, 0}}; }
4232 : : | yD_DUMPVARS '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS, $3}; }
4233 : : | yD_DUMPVARS '(' expr ',' exprList ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS, $3}; DEL($5); }
4234 : : | yD_DUMPALL parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ALL}; }
4235 : : | yD_DUMPALL '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ALL}; DEL($3); }
4236 : : | yD_DUMPFLUSH parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FLUSH}; }
4237 : : | yD_DUMPFLUSH '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FLUSH}; DEL($3); }
4238 : : | yD_DUMPLIMIT '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::LIMIT, $3}; }
4239 : : | yD_DUMPLIMIT '(' expr ',' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::LIMIT, $3}; DEL($5); }
4240 : : | yD_DUMPOFF parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::OFF}; }
4241 : : | yD_DUMPOFF '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::OFF}; DEL($3); }
4242 : : | yD_DUMPON parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ON}; }
4243 : : | yD_DUMPON '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ON}; DEL($3); }
4244 : : //
4245 : : | yD_C '(' cStrList ')' {
4246 : : AstCStmtUser* cstmtp = nullptr;
4247 : : if (!v3Global.opt.ignc()) {
4248 : : cstmtp = new AstCStmtUser{$1, true};
4249 : : cstmtp->add($3);
4250 : : }
4251 : : $$ = cstmtp;
4252 : : }
4253 : : | yD_SDF_ANNOTATE '(' exprEListE ')' { $$ = nullptr; $1->v3warn(SPECIFYIGN, "Ignoring unsupported: $sdf_annotate"); DEL($3); }
4254 : : | yD_STACKTRACE parenE { $$ = new AstStackTraceT{$1}; }
4255 : : | yD_SYSTEM '(' expr ')' { $$ = new AstSystemT{$1, $3}; }
4256 : : //
4257 : : | yD_EXIT parenE { $$ = new AstFinish{$1}; }
4258 : : //
4259 : : | yD_FCLOSE '(' expr ')' { $$ = new AstFClose{$1, $3}; }
4260 : : | yD_FFLUSH parenE { $$ = new AstFFlush{$1, nullptr}; }
4261 : : | yD_FFLUSH '(' expr ')' { $$ = new AstFFlush{$1, $3}; }
4262 : : | yD_FINISH parenE { $$ = new AstFinish{$1}; }
4263 : : | yD_FINISH '(' expr ')' { $$ = new AstFinish{$1}; DEL($3); }
4264 : : | yD_STOP parenE { $$ = new AstStop{$1, false}; }
4265 : : | yD_STOP '(' expr ')' { $$ = new AstStop{$1, false}; DEL($3); }
4266 : : //
4267 : : | yD_SFORMAT '(' expr ',' exprDispList ')' { $$ = new AstSFormat{$1, false, $3, $5}; }
4268 : : | yD_SWRITE '(' expr ',' exprDispList ')' { $$ = new AstSFormat{$1, true, $3, $5, 'd'}; }
4269 : : | yD_SWRITEB '(' expr ',' exprDispList ')' { $$ = new AstSFormat{$1, true, $3, $5, 'b'}; }
4270 : : | yD_SWRITEH '(' expr ',' exprDispList ')' { $$ = new AstSFormat{$1, true, $3, $5, 'h'}; }
4271 : : | yD_SWRITEO '(' expr ',' exprDispList ')' { $$ = new AstSFormat{$1, true, $3, $5, 'o'}; }
4272 : : //
4273 : : | yD_DISPLAY parenE { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, nullptr}; }
4274 : : | yD_DISPLAY '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, $4}; }
4275 : : | yD_DISPLAYB parenE { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, nullptr, 'b'}; }
4276 : : | yD_DISPLAYB '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, $4, 'b'}; }
4277 : : | yD_DISPLAYH parenE { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, nullptr, 'h'}; }
4278 : : | yD_DISPLAYH '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, $4, 'h'}; }
4279 : : | yD_DISPLAYO parenE { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, nullptr, 'o'}; }
4280 : : | yD_DISPLAYO '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, nullptr, $4, 'o'}; }
4281 : : | yD_MONITOR '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, nullptr, $4}; }
4282 : : | yD_MONITORB '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, nullptr, $4, 'b'}; }
4283 : : | yD_MONITORH '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, nullptr, $4, 'h'}; }
4284 : : | yD_MONITORO '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, nullptr, $4, 'o'}; }
4285 : : | yD_STROBE '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, nullptr, $4}; }
4286 : : | yD_STROBEB '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, nullptr, $4, 'b'}; }
4287 : : | yD_STROBEH '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, nullptr, $4, 'h'}; }
4288 : : | yD_STROBEO '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, nullptr, $4, 'o'}; }
4289 : : | yD_WRITE parenE { $$ = nullptr; } // NOP
4290 : : | yD_WRITE '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, nullptr, $4}; }
4291 : : | yD_WRITEB parenE { $$ = nullptr; } // NOP
4292 : : | yD_WRITEB '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, nullptr, $4, 'b'}; }
4293 : : | yD_WRITEH parenE { $$ = nullptr; } // NOP
4294 : : | yD_WRITEH '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, nullptr, $4, 'h'}; }
4295 : : | yD_WRITEO parenE { $$ = nullptr; } // NOP
4296 : : | yD_WRITEO '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, nullptr, $4, 'o'}; }
4297 : : | yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, nullptr}; }
4298 : : | yD_FDISPLAY '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, $5}; }
4299 : : | yD_FDISPLAYB '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, nullptr, 'b'}; }
4300 : : | yD_FDISPLAYB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, $5, 'b'}; }
4301 : : | yD_FDISPLAYH '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, nullptr, 'h'}; }
4302 : : | yD_FDISPLAYH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, $5, 'h'}; }
4303 : : | yD_FDISPLAYO '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, nullptr, 'o'}; }
4304 : : | yD_FDISPLAYO '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_DISPLAY, $3, $5, 'o'}; }
4305 : : | yD_FMONITOR '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5}; }
4306 : : | yD_FMONITORB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5, 'b'}; }
4307 : : | yD_FMONITORH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5, 'h'}; }
4308 : : | yD_FMONITORO '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5, 'o'}; }
4309 : : | yD_FSTROBE '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, nullptr}; }
4310 : : | yD_FSTROBE '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5}; }
4311 : : | yD_FSTROBEB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5, 'b'}; }
4312 : : | yD_FSTROBEH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5, 'h'}; }
4313 : : | yD_FSTROBEO '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5, 'o'}; }
4314 : : | yD_FWRITE '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, nullptr}; }
4315 : : | yD_FWRITE '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5}; }
4316 : : | yD_FWRITEB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5, 'b'}; }
4317 : : | yD_FWRITEH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5, 'h'}; }
4318 : : | yD_FWRITEO '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5, 'o'}; }
4319 : : | yD_INFO parenE { $$ = new AstDisplay{$1, VDisplayType::DT_INFO, nullptr, nullptr}; }
4320 : : | yD_INFO '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_INFO, nullptr, $4}; }
4321 : : | yD_WARNING parenE { $$ = new AstDisplay{$1, VDisplayType::DT_WARNING, nullptr, nullptr}; }
4322 : : | yD_WARNING '(' commasE exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WARNING, nullptr, $4}; }
4323 : : | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); }
4324 : : | yD_ERROR '(' commasE exprDispList ')'
4325 : : { $$ = new AstDisplay{$1, VDisplayType::DT_ERROR, nullptr, $4};
4326 : : $$->addNext(new AstStop{$1, false}); }
4327 : : | yD_FATAL parenE
4328 : : { $$ = new AstDisplay{$1, VDisplayType::DT_FATAL, nullptr, nullptr};
4329 : : $$->addNext(new AstStop{$1, true}); }
4330 : : | yD_FATAL '(' expr ')'
4331 : : { $$ = new AstDisplay{$1, VDisplayType::DT_FATAL, nullptr, nullptr};
4332 : : $$->addNext(new AstStop{$1, true}); DEL($3); }
4333 : : | yD_FATAL '(' expr ',' exprDispList ')'
4334 : : { $$ = new AstDisplay{$1, VDisplayType::DT_FATAL, nullptr, $5};
4335 : : $$->addNext(new AstStop{$1, true}); DEL($3); }
4336 : : //
4337 : : | yD_ASSERTCTL '(' expr ')' { $$ = new AstAssertCtl{$1, $3}; }
4338 : : | yD_ASSERTCTL '(' expr ',' exprE ')' { $$ = new AstAssertCtl{$1, $3, $5}; }
4339 : : | yD_ASSERTCTL '(' expr ',' exprE ',' exprE ')' { $$ = new AstAssertCtl{$1, $3, $5, $7}; }
4340 : : | yD_ASSERTCTL '(' expr ',' exprE ',' exprE ',' exprE ')' { $$ = new AstAssertCtl{$1, $3, $5, $7, $9}; }
4341 : : | yD_ASSERTCTL '(' expr ',' exprE ',' exprE ',' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, $3, $5, $7, $9, $11}; }
4342 : : | yD_ASSERTFAILOFF '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::FAIL_OFF, 31, 7, $3}; }
4343 : : | yD_ASSERTFAILOFF '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::FAIL_OFF, 31, 7, $3, $5}; }
4344 : : | yD_ASSERTFAILOFF parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::FAIL_OFF, 31, 7}; }
4345 : : | yD_ASSERTFAILON '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::FAIL_ON, 31, 7, $3}; }
4346 : : | yD_ASSERTFAILON '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::FAIL_ON, 31, 7, $3, $5}; }
4347 : : | yD_ASSERTFAILON parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::FAIL_ON, 31, 7}; }
4348 : : | yD_ASSERTKILL '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::KILL, 15, 7, $3}; }
4349 : : | yD_ASSERTKILL '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::KILL, 15, 7, $3, $5}; }
4350 : : | yD_ASSERTKILL parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::KILL, 15, 7}; }
4351 : : | yD_ASSERTNONVACUOUSON '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::NONVACUOUS_ON, 31, 7, $3}; }
4352 : : | yD_ASSERTNONVACUOUSON '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::NONVACUOUS_ON, 31, 7, $3, $5}; }
4353 : : | yD_ASSERTNONVACUOUSON parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::NONVACUOUS_ON, 31, 7}; }
4354 : : | yD_ASSERTOFF '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::OFF, 15, 7, $3}; }
4355 : : | yD_ASSERTOFF '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::OFF, 15, 7, $3, $5}; }
4356 : : | yD_ASSERTOFF parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::OFF, 15, 7}; }
4357 : : | yD_ASSERTON '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::ON, 15, 7, $3}; }
4358 : : | yD_ASSERTON '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::ON, 15, 7, $3, $5}; }
4359 : : | yD_ASSERTON parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::ON, 15, 7}; }
4360 : : | yD_ASSERTPASSOFF '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::PASS_OFF, 31, 7, $3}; }
4361 : : | yD_ASSERTPASSOFF '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::PASS_OFF, 31, 7, $3, $5}; }
4362 : : | yD_ASSERTPASSOFF parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::PASS_OFF, 31, 7}; }
4363 : : | yD_ASSERTPASSON '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::PASS_ON, 31, 7, $3}; }
4364 : : | yD_ASSERTPASSON '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::PASS_ON, 31, 7, $3, $5}; }
4365 : : | yD_ASSERTPASSON parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::PASS_ON, 31, 7}; }
4366 : : | yD_ASSERTVACUOUSOFF '(' expr ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::VACUOUS_OFF, 31, 7, $3}; }
4367 : : | yD_ASSERTVACUOUSOFF '(' exprE ',' exprList ')' { $$ = new AstAssertCtl{$1, VAssertCtlType::VACUOUS_OFF, 31, 7, $3, $5}; }
4368 : : | yD_ASSERTVACUOUSOFF parenE { $$ = new AstAssertCtl{$1, VAssertCtlType::VACUOUS_OFF, 31, 7}; }
4369 : : //
4370 : : | yD_MONITOROFF parenE { $$ = new AstMonitorOff{$1, true}; }
4371 : : | yD_MONITORON parenE { $$ = new AstMonitorOff{$1, false}; }
4372 : : //
4373 : : | yD_PRINTTIMESCALE { $$ = new AstPrintTimeScale{$1}; }
4374 : : | yD_PRINTTIMESCALE '(' ')' { $$ = new AstPrintTimeScale{$1}; }
4375 : : | yD_PRINTTIMESCALE '(' idClassSel ')' { $$ = new AstPrintTimeScale{$1}; DEL($3); }
4376 : : | yD_TIMEFORMAT '(' exprE ',' exprE ',' exprE ',' exprE ')'
4377 : : { $$ = new AstTimeFormat{$1, $3, $5, $7, $9}; }
4378 : : | yD_TIMEFORMAT '(' exprE ',' exprE ',' exprE ')'
4379 : : { $$ = new AstTimeFormat{$1, $3, $5, $7, nullptr}; }
4380 : : | yD_TIMEFORMAT '(' exprE ',' exprE ')'
4381 : : { $$ = new AstTimeFormat{$1, $3, $5, nullptr, nullptr}; }
4382 : : | yD_TIMEFORMAT '(' exprE ')'
4383 : : { $$ = new AstTimeFormat{$1, $3, nullptr, nullptr, nullptr}; }
4384 : : //
4385 : : | yD_READMEMB '(' expr ',' idClassSel ')' { $$ = new AstReadMem{$1, false, $3, $5, nullptr, nullptr}; }
4386 : : | yD_READMEMB '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem{$1, false, $3, $5, $7, nullptr}; }
4387 : : | yD_READMEMB '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem{$1, false, $3, $5, $7, $9}; }
4388 : : | yD_READMEMH '(' expr ',' idClassSel ')' { $$ = new AstReadMem{$1, true, $3, $5, nullptr, nullptr}; }
4389 : : | yD_READMEMH '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem{$1, true, $3, $5, $7, nullptr}; }
4390 : : | yD_READMEMH '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem{$1, true, $3, $5, $7, $9}; }
4391 : : //
4392 : : | yD_WRITEMEMB '(' expr ',' idClassSel ')' { $$ = new AstWriteMem{$1, false, $3, $5, nullptr, nullptr}; }
4393 : : | yD_WRITEMEMB '(' expr ',' idClassSel ',' expr ')' { $$ = new AstWriteMem{$1, false, $3, $5, $7, nullptr}; }
4394 : : | yD_WRITEMEMB '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstWriteMem{$1, false, $3, $5, $7, $9}; }
4395 : : | yD_WRITEMEMH '(' expr ',' idClassSel ')' { $$ = new AstWriteMem{$1, true, $3, $5, nullptr, nullptr}; }
4396 : : | yD_WRITEMEMH '(' expr ',' idClassSel ',' expr ')' { $$ = new AstWriteMem{$1, true, $3, $5, $7, nullptr}; }
4397 : : | yD_WRITEMEMH '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstWriteMem{$1, true, $3, $5, $7, $9}; }
4398 : : //
4399 : : | yD_CAST '(' expr ',' expr ')'
4400 : : { FileLine* const fl_nowarn = new FileLine{$1};
4401 : : fl_nowarn->warnOff(V3ErrorCode::WIDTH, true);
4402 : : $$ = new AstAssertIntrinsic{fl_nowarn, new AstCastDynamic{fl_nowarn, $5, $3},
4403 : : nullptr, nullptr}; }
4404 : : ;
4405 : :
4406 : : system_f_only_expr_call<nodeExprp>: // IEEE: part of system_tf_call (for functions returning expressions)
4407 : : yaD_PLI systemDpiArgsE { $$ = new AstFuncRef{$<fl>1, *$1, $2}; VN_CAST($$, FuncRef)->pli(true); }
4408 : : //
4409 : : | yD_C '(' cStrList ')' {
4410 : : AstCExprUser* cexprp = nullptr;
4411 : : if (!v3Global.opt.ignc()) {
4412 : : cexprp = new AstCExprUser{$1};
4413 : : cexprp->add($3);
4414 : : }
4415 : : $$ = cexprp;
4416 : : }
4417 : : | yD_CPURE '(' cStrList ')' {
4418 : : AstCExprUser* cexprp = nullptr;
4419 : : if (!v3Global.opt.ignc()) {
4420 : : cexprp = new AstCExprUser{$1, AstCExprUser::Pure{}};
4421 : : cexprp->add($3);
4422 : : }
4423 : : $$ = cexprp;
4424 : : }
4425 : : | yD_CAST '(' expr ',' expr ')' { $$ = new AstCastDynamic{$1, $5, $3}; }
4426 : : | yD_STACKTRACE parenE { $$ = new AstStackTraceF{$1}; }
4427 : : | yD_SYSTEM '(' expr ')' { $$ = new AstSystemF{$1, $3}; }
4428 : : ;
4429 : :
4430 : : system_f_or_t_expr_call<nodeExprp>: // IEEE: part of system_tf_call (can be task or func)
4431 : : yD_ACOS '(' expr ')' { $$ = new AstAcosD{$1, $3}; }
4432 : : | yD_ACOSH '(' expr ')' { $$ = new AstAcoshD{$1, $3}; }
4433 : : | yD_ASIN '(' expr ')' { $$ = new AstAsinD{$1, $3}; }
4434 : : | yD_ASINH '(' expr ')' { $$ = new AstAsinhD{$1, $3}; }
4435 : : | yD_ATAN '(' expr ')' { $$ = new AstAtanD{$1, $3}; }
4436 : : | yD_ATAN2 '(' expr ',' expr ')' { $$ = new AstAtan2D{$1, $3, $5}; }
4437 : : | yD_ATANH '(' expr ')' { $$ = new AstAtanhD{$1, $3}; }
4438 : : | yD_BITS '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_BITS, $3}; }
4439 : : | yD_BITS '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_BITS, $3, $5}; }
4440 : : | yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD{$1, $3}; }
4441 : : | yD_BITSTOSHORTREAL '(' expr ')' { $$ = new AstBitsToRealD{$1, $3}; UNSUPREAL($1); }
4442 : : | yD_CEIL '(' expr ')' { $$ = new AstCeilD{$1, $3}; }
4443 : : | yD_CHANGED '(' expr ')' { $$ = new AstLogNot{$1, new AstStable{$1, $3, nullptr}}; }
4444 : : | yD_CHANGED '(' expr ',' expr ')'
4445 : : { $$ = new AstLogNot{$1, new AstStable{$1, $3, GRAMMARP->createSenTreeChanged($1, $5)}}; }
4446 : : | yD_CHANGED_GCLK '(' expr ')'
4447 : : { $$ = new AstLogNot{$1, new AstStable{$1, $3, GRAMMARP->createGlobalClockSenTree($1)}}; }
4448 : : | yD_CHANGING_GCLK '(' expr ')'
4449 : : { $$ = new AstLogNot{$1, new AstSteady{$1, $3}}; }
4450 : : | yD_CLOG2 '(' expr ')' { $$ = new AstCLog2{$1, $3}; }
4451 : : | yD_COS '(' expr ')' { $$ = new AstCosD{$1, $3}; }
4452 : : | yD_COSH '(' expr ')' { $$ = new AstCoshD{$1, $3}; }
4453 : : | yD_COUNTBITS '(' expr ',' expr ')' { $$ = new AstCountBits{$1, $3, $5}; }
4454 : : | yD_COUNTBITS '(' expr ',' expr ',' expr ')' { $$ = new AstCountBits{$1, $3, $5, $7}; }
4455 : : | yD_COUNTBITS '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstCountBits{$1, $3, $5, $7, $9}; }
4456 : : | yD_COUNTBITS '(' expr ',' expr ',' expr ',' expr ',' exprList ')'
4457 : : { $$ = new AstCountBits{$1, $3, $5, $7, $9};
4458 : : BBUNSUP($11, "Unsupported: $countbits with more than 3 control fields"); }
4459 : : | yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes{$1, $3}; }
4460 : : | yD_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_DIMENSIONS, $3}; }
4461 : : | yD_DIST_CHI_SQUARE '(' expr ',' expr ')' { $$ = new AstDistChiSquare{$1, $3, $5}; }
4462 : : | yD_DIST_ERLANG '(' expr ',' expr ',' expr ')' { $$ = new AstDistErlang{$1, $3, $5, $7}; }
4463 : : | yD_DIST_EXPONENTIAL '(' expr ',' expr ')' { $$ = new AstDistExponential{$1, $3, $5}; }
4464 : : | yD_DIST_NORMAL '(' expr ',' expr ',' expr ')' { $$ = new AstDistNormal{$1, $3, $5, $7}; }
4465 : : | yD_DIST_POISSON '(' expr ',' expr ')' { $$ = new AstDistPoisson{$1, $3, $5}; }
4466 : : | yD_DIST_T '(' expr ',' expr ')' { $$ = new AstDistT{$1, $3, $5}; }
4467 : : | yD_DIST_UNIFORM '(' expr ',' expr ',' expr ')' { $$ = new AstDistUniform{$1, $3, $5, $7}; }
4468 : : | yD_EXP '(' expr ')' { $$ = new AstExpD{$1, $3}; }
4469 : : | yD_FALLING_GCLK '(' expr ')' { $$ = new AstFalling{$1, $3}; }
4470 : : | yD_FELL '(' expr ')' { $$ = new AstFell{$1, $3, nullptr}; }
4471 : : | yD_FELL '(' expr ',' expr ')' { $$ = new AstFell{$1, $3, GRAMMARP->createSenTreeChanged($1, $5)}; }
4472 : : | yD_FELL_GCLK '(' expr ')' { $$ = new AstFell{$1, $3, GRAMMARP->createGlobalClockSenTree($1)}; }
4473 : : | yD_FEOF '(' expr ')' { $$ = new AstFEof{$1, $3}; }
4474 : : | yD_FERROR '(' expr ',' idClassSel ')' { $$ = new AstFError{$1, $3, $5}; }
4475 : : | yD_FGETC '(' expr ')' { $$ = new AstFGetC{$1, $3}; }
4476 : : | yD_FGETS '(' expr ',' expr ')' { $$ = new AstFGetS{$1, $3, $5}; }
4477 : : | yD_FOPEN '(' expr ')' { $$ = new AstFOpenMcd{$1, $3}; }
4478 : : | yD_FOPEN '(' expr ',' expr ')' { $$ = new AstFOpen{$1, $3, $5}; }
4479 : : | yD_FREAD '(' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, nullptr, nullptr}; }
4480 : : | yD_FREAD '(' expr ',' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, $7, nullptr}; }
4481 : : | yD_FREAD '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, $7, $9}; }
4482 : : | yD_FREAD '(' expr ',' expr ',' ',' expr ')' { $$ = new AstFRead{$1, $3, $5, nullptr, $8}; }
4483 : : | yD_FREWIND '(' expr ')' { $$ = new AstFRewind{$1, $3}; }
4484 : : | yD_FUTURE_GCLK '(' expr ')' { $$ = new AstFuture{$1, $3, nullptr}; }
4485 : : | yD_FLOOR '(' expr ')' { $$ = new AstFloorD{$1, $3}; }
4486 : : | yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF{$1, *$5, $3, $6}; }
4487 : : | yD_FSEEK '(' expr ',' expr ',' expr ')' { $$ = new AstFSeek{$1, $3, $5, $7}; }
4488 : : | yD_FTELL '(' expr ')' { $$ = new AstFTell{$1, $3}; }
4489 : : | yD_GET_INITIAL_RANDOM_SEED parenE { $$ = new AstGetInitialRandomSeed{$1}; }
4490 : : | yD_GLOBAL_CLOCK parenE { $$ = GRAMMARP->createGlobalClockParseRef($1); }
4491 : : | yD_HIGH '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_HIGH, $3, nullptr}; }
4492 : : | yD_HIGH '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_HIGH, $3, $5}; }
4493 : : | yD_HYPOT '(' expr ',' expr ')' { $$ = new AstHypotD{$1, $3, $5}; }
4494 : : | yD_INCREMENT '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_INCREMENT, $3, nullptr}; }
4495 : : | yD_INCREMENT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_INCREMENT, $3, $5}; }
4496 : : | yD_INFERRED_DISABLE parenE { $$ = new AstInferredDisable{$1}; }
4497 : : | yD_ISUNBOUNDED '(' expr ')' { $$ = new AstIsUnbounded{$1, $3}; }
4498 : : | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown{$1, $3}; }
4499 : : | yD_ITOR '(' expr ')' { $$ = new AstIToRD{$1, $3}; }
4500 : : | yD_LEFT '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_LEFT, $3, nullptr}; }
4501 : : | yD_LEFT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_LEFT, $3, $5}; }
4502 : : | yD_LN '(' expr ')' { $$ = new AstLogD{$1, $3}; }
4503 : : | yD_LOG10 '(' expr ')' { $$ = new AstLog10D{$1, $3}; }
4504 : : | yD_LOW '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_LOW, $3, nullptr}; }
4505 : : | yD_LOW '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_LOW, $3, $5}; }
4506 : : | yD_ONEHOT '(' expr ')' { $$ = new AstOneHot{$1, $3}; }
4507 : : | yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0{$1, $3}; }
4508 : : | yD_PAST '(' expr ')' { $$ = new AstPast{$1, $3}; }
4509 : : | yD_PAST '(' expr ',' exprE ')' { $$ = new AstPast{$1, $3, $5}; }
4510 : : | yD_PAST '(' expr ',' exprE ',' exprE ')'
4511 : : { if ($7) BBUNSUP($1, "Unsupported: $past expr2 and/or clock arguments");
4512 : : DEL($7);
4513 : : $$ = new AstPast{$1, $3, $5}; }
4514 : : | yD_PAST '(' expr ',' exprE ',' exprE ',' clocking_eventE ')'
4515 : : { if ($7 || $9) BBUNSUP($1, "Unsupported: $past expr2 and/or clock arguments");
4516 : : DEL($7, $9);
4517 : : $$ = new AstPast{$1, $3, $5}; }
4518 : : | yD_PAST_GCLK '(' expr ')' { $$ = new AstPast{$1, $3, nullptr, GRAMMARP->createGlobalClockSenTree($1)}; }
4519 : : | yD_POW '(' expr ',' expr ')' { $$ = new AstPowD{$1, $3, $5}; }
4520 : : | yD_RANDOM '(' expr ')' { $$ = new AstRand{$1, $3, false}; }
4521 : : | yD_RANDOM parenE { $$ = new AstRand{$1, nullptr, false}; }
4522 : : | yD_REALTIME parenE { $$ = new AstTimeD{$1, VTimescale{VTimescale::NONE}}; }
4523 : : | yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits{$1, $3}; }
4524 : : | yD_REWIND '(' expr ')' { $$ = new AstFSeek{$1, $3, new AstConst{$1, 0}, new AstConst{$1, 0}}; }
4525 : : | yD_RIGHT '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_RIGHT, $3, nullptr}; }
4526 : : | yD_RIGHT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_RIGHT, $3, $5}; }
4527 : : | yD_RISING_GCLK '(' expr ')' { $$ = new AstRising{$1, $3}; }
4528 : : | yD_ROSE '(' expr ')' { $$ = new AstRose{$1, $3, nullptr}; }
4529 : : | yD_ROSE '(' expr ',' expr ')' { $$ = new AstRose{$1, $3, GRAMMARP->createSenTreeChanged($1, $5)}; }
4530 : : | yD_ROSE_GCLK '(' expr ')' { $$ = new AstRose{$1, $3, GRAMMARP->createGlobalClockSenTree($1)}; }
4531 : : | yD_RTOI '(' expr ')' { $$ = new AstRToIS{$1, $3}; }
4532 : : | yD_SAMPLED '(' expr ')' { $$ = new AstSampled{$1, $3}; }
4533 : : | yD_SFORMATF '(' exprDispList ')' { $$ = new AstSFormatF{$1, AstSFormatF::ExprFormat{}, $3, 'd', false}; }
4534 : : | yD_SHORTREALTOBITS '(' expr ')' { $$ = new AstRealToBits{$1, $3}; UNSUPREAL($1); }
4535 : : | yD_SIGNED '(' expr ')' { $$ = new AstSigned{$1, $3}; }
4536 : : | yD_SIN '(' expr ')' { $$ = new AstSinD{$1, $3}; }
4537 : : | yD_SINH '(' expr ')' { $$ = new AstSinhD{$1, $3}; }
4538 : : | yD_SIZE '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_SIZE, $3, nullptr}; }
4539 : : | yD_SIZE '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_SIZE, $3, $5}; }
4540 : : | yD_SQRT '(' expr ')' { $$ = new AstSqrtD{$1, $3}; }
4541 : : | yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF{$1, *$5, $3, $6}; }
4542 : : | yD_STABLE '(' expr ')' { $$ = new AstStable{$1, $3, nullptr}; }
4543 : : | yD_STABLE '(' expr ',' expr ')' { $$ = new AstStable{$1, $3, GRAMMARP->createSenTreeChanged($1, $5)}; }
4544 : : | yD_STABLE_GCLK '(' expr ')' { $$ = new AstStable{$1, $3, GRAMMARP->createGlobalClockSenTree($1)}; }
4545 : : | yD_STEADY_GCLK '(' expr ')' { $$ = new AstSteady{$1, $3}; }
4546 : : | yD_STIME parenE
4547 : : { $$ = new AstSel{$1, new AstTime{$1, VTimescale{VTimescale::NONE}}, 0, 32}; }
4548 : : | yD_TAN '(' expr ')' { $$ = new AstTanD{$1, $3}; }
4549 : : | yD_TANH '(' expr ')' { $$ = new AstTanhD{$1, $3}; }
4550 : : | yD_TESTPLUSARGS '(' expr ')' { $$ = new AstTestPlusArgs{$1, $3}; }
4551 : : | yD_TIME parenE { $$ = new AstTime{$1, VTimescale{VTimescale::NONE}}; }
4552 : : | yD_TIMEPRECISION { $$ = new AstTimePrecision{$1}; }
4553 : : | yD_TIMEPRECISION '(' ')' { $$ = new AstTimePrecision{$1}; }
4554 : : | yD_TIMEPRECISION '(' idClassSel ')' { $$ = new AstTimePrecision{$1}; DEL($3); }
4555 : : | yD_TIMEUNIT { $$ = new AstTimeUnit{$1}; }
4556 : : | yD_TIMEUNIT '(' ')' { $$ = new AstTimeUnit{$1}; }
4557 : : | yD_TIMEUNIT '(' idClassSel ')' { $$ = new AstTimeUnit{$1}; DEL($3); }
4558 : : | yD_TYPENAME '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::TYPENAME, $3}; }
4559 : : | yD_UNGETC '(' expr ',' expr ')' { $$ = new AstFUngetC{$1, $5, $3}; } // Arg swap to file first
4560 : : | yD_UNPACKED_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_UNPK_DIMENSIONS, $3}; }
4561 : : | yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned{$1, $3}; }
4562 : : | yD_URANDOM '(' expr ')' { $$ = new AstRand{$1, $3, true}; }
4563 : : | yD_URANDOM parenE { $$ = new AstRand{$1, nullptr, true}; }
4564 : : | yD_URANDOM_RANGE '(' expr ')' { $$ = new AstURandomRange{$1, $3, new AstConst{$1, 0}}; }
4565 : : | yD_URANDOM_RANGE '(' expr ',' expr ')' { $$ = new AstURandomRange{$1, $3, $5}; }
4566 : : | yD_VALUEPLUSARGS '(' expr ',' expr ')' { $$ = new AstValuePlusArgs{$1, $3, $5}; }
4567 : : ;
4568 : :
4569 : : severity_system_task<nodep>: // IEEE: severity_system_task/elaboration_severity_system_task (1800-2009)
4570 : : // // TODO: These currently just make initial statements, should instead give runtime error
4571 : : severity_system_task_guts ';' { $$ = new AstInitial{$<fl>1, $1}; }
4572 : : ;
4573 : :
4574 : : severity_system_task_guts<nodep>: // IEEE: part of severity_system_task (1800-2009)
4575 : : // // $fatal first argument is exit number, must be constant
4576 : : yD_INFO parenE { $$ = new AstElabDisplay{$1, VDisplayType::DT_INFO, nullptr}; }
4577 : : | yD_INFO '(' exprList ')' { $$ = new AstElabDisplay{$1, VDisplayType::DT_INFO, $3}; }
4578 : : | yD_WARNING parenE { $$ = new AstElabDisplay{$1, VDisplayType::DT_WARNING, nullptr}; }
4579 : : | yD_WARNING '(' exprList ')' { $$ = new AstElabDisplay{$1, VDisplayType::DT_WARNING, $3}; }
4580 : : | yD_ERROR parenE { $$ = new AstElabDisplay{$1, VDisplayType::DT_ERROR, nullptr}; }
4581 : : | yD_ERROR '(' exprList ')' { $$ = new AstElabDisplay{$1, VDisplayType::DT_ERROR, $3}; }
4582 : : | yD_FATAL parenE { $$ = new AstElabDisplay{$1, VDisplayType::DT_FATAL, nullptr}; }
4583 : : | yD_FATAL '(' expr ')' { $$ = new AstElabDisplay{$1, VDisplayType::DT_FATAL, nullptr}; DEL($3); }
4584 : : | yD_FATAL '(' expr ',' exprListE ')' { $$ = new AstElabDisplay{$1, VDisplayType::DT_FATAL, $5}; DEL($3); }
4585 : : ;
4586 : :
4587 : : systemDpiArgsE<argp>: // IEEE: part of system_if_call for arguments of $dpi call
4588 : : parenE { $$ = nullptr; }
4589 : : | '(' exprList ')' { $$ = GRAMMARP->argWrapList($2); }
4590 : : ;
4591 : :
4592 : : property_actual_arg<nodeExprp>: // ==IEEE: property_actual_arg
4593 : : // // IEEE: property_expr
4594 : : // // IEEE: sequence_actual_arg
4595 : : //UNSUP pev_expr { $$ = $1; }
4596 : : //UNSUP remove below:
4597 : : pexpr { $$ = $1; }
4598 : : // // IEEE: sequence_expr
4599 : : // // property_expr already includes sequence_expr
4600 : : ;
4601 : :
4602 : : exprOrDataType<nodep>: // expr | data_type: combined to prevent conflicts
4603 : : expr { $$ = $1; }
4604 : : // // data_type includes id that overlaps expr, so special flavor
4605 : : // // data_type expanded:
4606 : : | data_typeNoRef { $$ = $1; }
4607 : : //
4608 : : // // Conflicts with non-type id, resolved in V3LinkDot
4609 : : // // NO: packageClassScopeE idType packed_dimensionListE
4610 : : //
4611 : : | packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE
4612 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3};
4613 : : $$ = GRAMMARP->createArray(refp, $4, true); }
4614 : : // // not in spec, but needed for $past(sig,1,,@(posedge clk))
4615 : : //UNSUP event_control { }
4616 : : ;
4617 : :
4618 : : //UNSUPexprOrDataTypeOrMinTypMax<nodep>: // exprOrDataType or mintypmax_expression
4619 : : //UNSUP expr { $$ = $1; }
4620 : : //UNSUP | expr ':' expr ':' expr { $$ = $3; }
4621 : : //UNSUP // // data_type includes id that overlaps expr, so special flavor
4622 : : //UNSUP | data_type { $$ = $1; }
4623 : : //UNSUP // // not in spec, but needed for $past(sig,1,,@(posedge clk))
4624 : : //UNSUP | event_control { $$ = $1; }
4625 : : //UNSUP ;
4626 : :
4627 : : //UNSUPexprOrDataTypeList<nodep>:
4628 : : //UNSUP exprOrDataType { $$ = $1; }
4629 : : //UNSUP | exprOrDataTypeList ',' exprOrDataType { $$ = addNextNull($1, $3); }
4630 : : //UNSUP ;
4631 : :
4632 : : list_of_argumentsE<argp>: // IEEE: [list_of_arguments]
4633 : : argsDottedList { $$ = $1; }
4634 : : | argsExprListE
4635 : : { if ($1->emptyConnectNoNext()) {
4636 : : $1->deleteTree(); $$ = nullptr; // Mis-created when have 'func()'
4637 : : } else { $$ = $1; } }
4638 : : | argsExprListE ',' argsDottedList { $$ = addNextNull($1, $3); }
4639 : : ;
4640 : :
4641 : : task_declaration<nodeFTaskp>: // ==IEEE: task_declaration
4642 : : yTASK dynamic_override_specifiersE lifetimeE taskId tfGuts yENDTASK endLabelE
4643 : : { $$ = $4; $$->addStmtsp($5);
4644 : : $$->baseOverride($2);
4645 : : $$->lifetime($3);
4646 : : GRAMMARP->endLabel($<fl>7, $$, $7); }
4647 : : ;
4648 : :
4649 : : task_prototype<nodeFTaskp>: // ==IEEE: task_prototype
4650 : : yTASK dynamic_override_specifiersE taskId '(' tf_port_listE ')'
4651 : : { $$ = $3; $$->addStmtsp($5); $$->prototype(true); }
4652 : : | yTASK dynamic_override_specifiersE taskId
4653 : : { $$ = $3; $$->prototype(true); }
4654 : : ;
4655 : :
4656 : : function_declaration<nodeFTaskp>: // IEEE: function_declaration + function_body_declaration
4657 : : yFUNCTION dynamic_override_specifiersE lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE
4658 : : { $$ = $4; $4->attrIsolateAssign($5); $$->addStmtsp($6);
4659 : : $$->baseOverride($2);
4660 : : $$->lifetime($3);
4661 : : GRAMMARP->endLabel($<fl>8, $$, $8); }
4662 : : | yFUNCTION dynamic_override_specifiersE lifetimeE funcIdNew funcIsolateE tfNewGuts yENDFUNCTION endLabelE
4663 : : { $$ = $4; $4->attrIsolateAssign($5); $$->addStmtsp($6);
4664 : : $$->baseOverride($2);
4665 : : $$->lifetime($3);
4666 : : GRAMMARP->endLabel($<fl>8, $$, $8); }
4667 : : ;
4668 : :
4669 : : function_prototype<nodeFTaskp>: // IEEE: function_prototype
4670 : : yFUNCTION dynamic_override_specifiersE funcId '(' tf_port_listE ')'
4671 : : { $$ = $3; $$->addStmtsp($5); $$->prototype(true); }
4672 : : | yFUNCTION dynamic_override_specifiersE funcId
4673 : : { $$ = $3; $$->prototype(true); }
4674 : : ;
4675 : :
4676 : : class_constructor_prototype<nodeFTaskp>: // ==IEEE: class_constructor_prototype
4677 : : // // IEEE has no dynamic_override_specifiersE,
4678 : : // // but required to avoid conflicts, so we must check after parsing
4679 : : yFUNCTION dynamic_override_specifiersE funcIdNew '(' class_constructor_arg_listE ')' ';'
4680 : : { $$ = $3; $$->addStmtsp($5); $$->prototype(true); }
4681 : : | yFUNCTION dynamic_override_specifiersE funcIdNew ';'
4682 : : { $$ = $3; $$->prototype(true); }
4683 : : ;
4684 : :
4685 : : funcIsolateE<cint>:
4686 : : /* empty */ { $$ = 0; }
4687 : : | yVL_ISOLATE_ASSIGNMENTS { $$ = 1; }
4688 : : ;
4689 : :
4690 : : method_prototype<nodeFTaskp>:
4691 : : task_prototype { $$ = $1; }
4692 : : | function_prototype { $$ = $1; }
4693 : : ;
4694 : :
4695 : : lifetimeE<lifetime>: // IEEE: [lifetime]
4696 : : /* empty */ { $$ = VLifetime::NONE; }
4697 : : | lifetime { $$ = $1; }
4698 : : ;
4699 : :
4700 : : lifetime<lifetime>: // ==IEEE: lifetime
4701 : : // // Note lifetime used by members is instead under memberQual
4702 : : ySTATIC__ETC { $$ = VLifetime::STATIC_EXPLICIT; }
4703 : : | yAUTOMATIC { $$ = VLifetime::AUTOMATIC_EXPLICIT; }
4704 : : ;
4705 : :
4706 : : taskId<nodeFTaskp>:
4707 : : id
4708 : : { $$ = new AstTask{$<fl>$, *$1, nullptr};
4709 : : $$->verilogTask(true); }
4710 : : //
4711 : : | id/*interface_identifier*/ '.' idAny
4712 : : { $$ = new AstTask{$<fl>$, *$3, nullptr};
4713 : : $$->verilogTask(true);
4714 : : $$->ifacePortName(*$1); }
4715 : : //
4716 : : | packageClassScope id
4717 : : { $$ = new AstTask{$<fl>$, *$2, nullptr};
4718 : : $$->verilogTask(true);
4719 : : $$->classOrPackagep($1);
4720 : : $$->classMethod(true); }
4721 : : ;
4722 : :
4723 : : funcId<nodeFTaskp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
4724 : : // // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
4725 : : // // function_data_type expanded here to prevent conflicts with
4726 : : // // implicit_type:empty vs data_type:ID
4727 : : /**/ fIdScoped
4728 : : { $$ = $1;
4729 : : $$->fvarp(new AstBasicDType{$<fl>1, LOGIC_IMPLICIT}); }
4730 : : | signingE rangeList fIdScoped
4731 : : { $$ = $3;
4732 : : $$->fvarp(GRAMMARP->addRange(new AstBasicDType{$<fl>3, LOGIC_IMPLICIT, $1}, $2, true)); }
4733 : : | signing fIdScoped
4734 : : { $$ = $2;
4735 : : $$->fvarp(new AstBasicDType{$<fl>2, LOGIC_IMPLICIT, $1}); }
4736 : : | data_typeNoRef fIdScoped
4737 : : { $$ = $2;
4738 : : $$->fvarp($1); }
4739 : : | packageClassScopeE idInstType packed_dimensionListE fIdScoped
4740 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, nullptr};
4741 : : $$ = $4;
4742 : : $$->fvarp(GRAMMARP->createArray(refp, $3, true)); }
4743 : : | packageClassScopeE idInstType parameter_value_assignmentClass packed_dimensionListE fIdScoped
4744 : : { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3};
4745 : : $$ = $5;
4746 : : $$->fvarp(GRAMMARP->createArray(refp, $4, true)); }
4747 : : // // To verilator tasks are the same as void functions (we separately detect time passing)
4748 : : | yVOID taskId
4749 : : { $$ = $2; // Internals represent it as a task, not a function (TODO cleanup)
4750 : : $$->verilogTask(false);
4751 : : $$->verilogFunction(true); }
4752 : : ;
4753 : :
4754 : : funcIdNew<nodeFTaskp>: // IEEE: from class_constructor_declaration
4755 : : yNEW__ETC
4756 : : { $$ = new AstFunc{$<fl>1, "new", nullptr, nullptr};
4757 : : $$->verilogFunction(true);
4758 : : $$->isConstructor(true); }
4759 : : | yNEW__PAREN
4760 : : { $$ = new AstFunc{$<fl>1, "new", nullptr, nullptr};
4761 : : $$->verilogFunction(true);
4762 : : $$->isConstructor(true); }
4763 : : | packageClassScopeNoId yNEW__PAREN
4764 : : { $$ = new AstFunc{$<fl>2, "new", nullptr, nullptr};
4765 : : $$->verilogFunction(true);
4766 : : $$->classOrPackagep($1);
4767 : : $$->isConstructor(true);
4768 : : $$->classMethod(true); }
4769 : : ;
4770 : :
4771 : : fIdScoped<funcp>: // IEEE: part of function_body_declaration/task_body_declaration
4772 : : // // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
4773 : : id
4774 : : { $<fl>$ = $<fl>1;
4775 : : $$ = new AstFunc{$<fl>$, *$1, nullptr, nullptr};
4776 : : $$->verilogFunction(true); }
4777 : : //
4778 : : | id/*interface_identifier*/ '.' idAny
4779 : : { $<fl>$ = $<fl>1;
4780 : : $$ = new AstFunc{$<fl>$, *$3, nullptr, nullptr};
4781 : : $$->verilogFunction(true);
4782 : : $$->ifacePortName(*$1); }
4783 : : //
4784 : : | packageClassScope id
4785 : : { $<fl>$ = $<fl>1;
4786 : : $$ = new AstFunc{$<fl>$, *$2, nullptr, nullptr};
4787 : : $$->verilogFunction(true);
4788 : : $$->classMethod(true);
4789 : : $$->classOrPackagep($1); }
4790 : : ;
4791 : :
4792 : : tfGuts<nodep>:
4793 : : '(' tf_port_listE ')' ';' tfBodyE { $$ = addNextNull($2, $5); }
4794 : : | ';' tfBodyE { $$ = $2; }
4795 : : ;
4796 : :
4797 : : tfNewGuts<nodep>:
4798 : : '(' class_constructor_arg_listE ')' ';' tfBodyE { $$ = addNextNull($2, $5); }
4799 : : | ';' tfBodyE { $$ = $2; }
4800 : : ;
4801 : :
4802 : : tfBodyE<nodep>: // IEEE: part of function_body_declaration/task_body_declaration
4803 : : /* empty */ { $$ = nullptr; }
4804 : : | tf_item_declarationList { $$ = $1; }
4805 : : | tf_item_declarationList stmtList { $$ = addNextNull($1, $2); }
4806 : : | stmtList { $$ = $1; }
4807 : : ;
4808 : :
4809 : : tf_item_declarationList<nodep>:
4810 : : tf_item_declaration { $$ = $1; }
4811 : : | tf_item_declarationList tf_item_declaration { $$ = addNextNull($1, $2); }
4812 : : ;
4813 : :
4814 : : tf_item_declaration<nodep>: // ==IEEE: tf_item_declaration
4815 : : block_item_declaration { $$ = $1; }
4816 : : | tf_port_declaration { $$ = $1; }
4817 : : | tf_item_declarationVerilator { $$ = $1; }
4818 : : ;
4819 : :
4820 : : tf_item_declarationVerilator<nodep>: // Verilator extensions
4821 : : yVL_PUBLIC { $$ = new AstPragma{$1, VPragmaType::PUBLIC_TASK}; v3Global.dpi(true); }
4822 : : | yVL_NO_INLINE_TASK { $$ = new AstPragma{$1, VPragmaType::NO_INLINE_TASK}; }
4823 : : ;
4824 : :
4825 : : tf_port_listE<nodep>: // IEEE: tf_port_list + empty
4826 : : // // Empty covered by tf_port_item
4827 : : /*empty*/
4828 : : /*mid*/ { VARRESET_LIST(UNKNOWN); VARIO(INPUT); }
4829 : : /*cont*/ tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
4830 : : ;
4831 : :
4832 : : tf_port_listList<nodep>: // IEEE: part of tf_port_list
4833 : : tf_port_item { $$ = $1; }
4834 : : | tf_port_listList ',' tf_port_item { $$ = addNextNull($1, $3); }
4835 : : ;
4836 : :
4837 : : class_constructor_arg_listE<nodep>: // IEEE: class_constructor_arg_list or empty
4838 : : /*empty*/
4839 : : /*mid*/ { VARRESET_LIST(UNKNOWN); VARIO(INPUT); }
4840 : : /*cont*/ class_constructor_arg_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
4841 : : ;
4842 : :
4843 : : class_constructor_arg_listList<nodep>: // IEEE: part of class_constructor_arg_list
4844 : : class_constructor_arg { $$ = $1; }
4845 : : | class_constructor_arg_listList ',' class_constructor_arg { $$ = addNextNull($1, $3); }
4846 : : ;
4847 : :
4848 : : class_constructor_arg<nodep>: // ==IEEE: class_constructor_arg
4849 : : tf_port_item { $$ = $1; }
4850 : : | yDEFAULT { $$ = nullptr; BBUNSUP($1, "Unsupported: new constructor 'default' argument"); }
4851 : : ;
4852 : :
4853 : : tf_port_item<nodep>: // ==IEEE: tf_port_item
4854 : : // // We split tf_port_item into the type and assignment as don't know what follows a comma
4855 : : /* empty */ { $$ = nullptr; PINNUMINC(); } // For example a ",," port
4856 : : | tf_port_itemFront tf_port_itemAssignment { $$ = $2; }
4857 : : | tf_port_itemAssignment { $$ = $1; }
4858 : : ;
4859 : :
4860 : : tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type
4861 : : data_type { VARDTYPE($1); }
4862 : : | signingE rangeList
4863 : : { AstNodeDType* const dtp = GRAMMARP->addRange(
4864 : : new AstBasicDType{$2->fileline(), LOGIC_IMPLICIT, $1}, $2, true);
4865 : : VARDTYPE(dtp); }
4866 : : | signing
4867 : : { AstNodeDType* const dtp = new AstBasicDType{$<fl>1, LOGIC_IMPLICIT, $1};
4868 : : VARDTYPE(dtp); }
4869 : : | yVAR data_type { VARDTYPE($2); }
4870 : : | yVAR implicit_typeE { VARDTYPE($2); }
4871 : : //
4872 : : | tf_port_itemDir /*implicit*/ { VARDTYPE(nullptr); /*default_nettype-see spec*/ }
4873 : : | tf_port_itemDir data_type { VARDTYPE($2); }
4874 : : | tf_port_itemDir signingE rangeList
4875 : : { AstNodeDType* const dtp = GRAMMARP->addRange(
4876 : : new AstBasicDType{$3->fileline(), LOGIC_IMPLICIT, $2}, $3, true);
4877 : : VARDTYPE(dtp); }
4878 : : | tf_port_itemDir signing
4879 : : { AstNodeDType* const dtp = new AstBasicDType{$<fl>2, LOGIC_IMPLICIT, $2};
4880 : : VARDTYPE(dtp); }
4881 : : | tf_port_itemDir yVAR data_type { VARDTYPE($3); }
4882 : : | tf_port_itemDir yVAR implicit_typeE { VARDTYPE($3); }
4883 : : ;
4884 : :
4885 : : tf_port_itemDir: // IEEE: part of tf_port_item, direction
4886 : : port_direction { } // port_direction sets VARIO
4887 : : ;
4888 : :
4889 : : tf_port_itemAssignment<varp>: // IEEE: part of tf_port_item, which has assignment
4890 : : id variable_dimensionListE sigAttrListE exprEqE
4891 : : { $$ = VARDONEA($<fl>1, *$1, $2, $3); if ($4) $$->valuep($4); }
4892 : : ;
4893 : :
4894 : : parenE:
4895 : : /* empty */ { }
4896 : : | '(' ')' { }
4897 : : ;
4898 : :
4899 : : // method_call: // ==IEEE: method_call + method_call_body
4900 : : // // IEEE: method_call_root '.' method_identifier [ '(' list_of_arguments ')' ]
4901 : : // // "method_call_root '.' method_identifier" looks just like "expr '.' id"
4902 : : // // "method_call_root '.' method_identifier (...)" looks just like "expr '.' tf_call"
4903 : : // // IEEE: built_in_method_call
4904 : : // // method_call_root not needed, part of expr resolution
4905 : : // // What's left is below array_methodNoRoot
4906 : : array_methodNoRoot<nodeFTaskRefp>:
4907 : : yOR { $$ = new AstFuncRef{$1, "or"}; }
4908 : : | yAND { $$ = new AstFuncRef{$1, "and"}; }
4909 : : | yXOR { $$ = new AstFuncRef{$1, "xor"}; }
4910 : : | yUNIQUE { $$ = new AstFuncRef{$1, "unique"}; }
4911 : : ;
4912 : :
4913 : : array_methodWith<nodeExprp>:
4914 : : array_methodNoRoot parenE { $$ = $1; }
4915 : : | array_methodNoRoot parenE yWITH__PAREN '(' expr ')'
4916 : : { $$ = new AstWithParse{$3, $1, $5}; }
4917 : : | array_methodNoRoot '(' expr ')' yWITH__PAREN '(' expr ')'
4918 : : { $$ = new AstWithParse{$5, $1, $7}; $1->addArgsp(new AstArg{$<fl>3, "", $3}); }
4919 : : ;
4920 : :
4921 : : dpi_import_export<nodep>: // ==IEEE: dpi_import_export
4922 : : yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';'
4923 : : { $$ = $5;
4924 : : if (*$4 != "") $5->cname(*$4);
4925 : : $5->dpiContext($3 == iprop_CONTEXT);
4926 : : $5->dpiPure($3 == iprop_PURE);
4927 : : $5->dpiImport(true);
4928 : : GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); }
4929 : : | yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';'
4930 : : { $$ = $5;
4931 : : if (*$4 != "") $5->cname(*$4);
4932 : : $5->dpiContext($3 == iprop_CONTEXT);
4933 : : $5->dpiPure($3 == iprop_PURE);
4934 : : $5->dpiImport(true);
4935 : : $5->dpiTask(true);
4936 : : GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); }
4937 : : | yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';'
4938 : : { $$ = new AstDpiExport{$<fl>5, *$5, *$3};
4939 : : GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); }
4940 : : | yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';'
4941 : : { $$ = new AstDpiExport{$<fl>5, *$5, *$3};
4942 : : GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); }
4943 : : ;
4944 : :
4945 : : dpi_importLabelE<strp>: // IEEE: part of dpi_import_export
4946 : : /* empty */ { static string s; $$ = &s; }
4947 : : | idAny/*c_identifier*/ '=' { $$ = $1; $<fl>$ = $<fl>1; }
4948 : : ;
4949 : :
4950 : : dpi_tf_import_propertyE<iprop>: // IEEE: [ dpi_function_import_property + dpi_task_import_property ]
4951 : : /* empty */ { $$ = iprop_NONE; }
4952 : : | yCONTEXT { $$ = iprop_CONTEXT; }
4953 : : | yPURE { $$ = iprop_PURE; }
4954 : : ;
4955 : :
4956 : :
4957 : : //************************************************
4958 : : // Expressions
4959 : : //
4960 : : // ~l~ means this is the (l)eft hand side of any operator
4961 : : // it will get replaced by "", "f" or "s"equence
4962 : : // ~r~ means this is a (r)ight hand later expansion in the same statement,
4963 : : // not under parenthesis for <= disambiguation
4964 : : // it will get replaced by "", or "f"
4965 : : // ~p~ means this is a (p)arenthetized expression
4966 : : // it will get replaced by "", or "s"equence
4967 : :
4968 : : exprEqE<nodeExprp>: // IEEE: optional '=' expression (part of param_assignment)
4969 : : // // constant_param_expression: '$' is in expr
4970 : : /*empty*/ { $$ = nullptr; }
4971 : : | '=' expr { $$ = $2; }
4972 : : ;
4973 : :
4974 : : exprOrDataTypeEqE<nodep>: // IEEE: optional '=' expression (part of param_assignment)
4975 : : // // constant_param_expression: '$' is in expr
4976 : : /*empty*/ { $$ = nullptr; }
4977 : : | '=' exprOrDataType { $$ = $2; }
4978 : : ;
4979 : :
4980 : : constExpr<nodeExprp>:
4981 : : expr { $$ = $1; }
4982 : : ;
4983 : :
4984 : : exprE<nodeExprp>: // IEEE: optional expression
4985 : : /*empty*/ { $$ = nullptr; }
4986 : : | expr { $$ = $1; }
4987 : : ;
4988 : :
4989 : : expr<nodeExprp>: // IEEE: part of expression/constant_expression/primary
4990 : : // *SEE BELOW* // IEEE: primary/constant_primary
4991 : : //
4992 : : // // IEEE: unary_operator primary
4993 : : '+' ~r~expr %prec prUNARYARITH { $$ = $2; }
4994 : : | '-' ~r~expr %prec prUNARYARITH { $$ = new AstNegate{$1, $2}; }
4995 : : | '!' ~r~expr %prec prNEGATION { $$ = new AstLogNot{$1, $2}; }
4996 : : | '&' ~r~expr %prec prREDUCTION { $$ = new AstRedAnd{$1, $2}; }
4997 : : | '~' ~r~expr %prec prNEGATION { $$ = new AstNot{$1, $2}; }
4998 : : | '|' ~r~expr %prec prREDUCTION { $$ = new AstRedOr{$1, $2}; }
4999 : : | '^' ~r~expr %prec prREDUCTION { $$ = new AstRedXor{$1, $2}; }
5000 : : | yP_NAND ~r~expr %prec prREDUCTION { $$ = new AstLogNot{$1, new AstRedAnd{$1, $2}}; }
5001 : : | yP_NOR ~r~expr %prec prREDUCTION { $$ = new AstLogNot{$1, new AstRedOr{$1, $2}}; }
5002 : : | yP_XNOR ~r~expr %prec prREDUCTION { $$ = new AstLogNot{$1, new AstRedXor{$1, $2}}; }
5003 : : //
5004 : : // // IEEE: inc_or_dec_expression
5005 : : | ~l~inc_or_dec_expression { $<fl>$ = $<fl>1; $$ = $1; }
5006 : : //
5007 : : // // IEEE: '(' operator_assignment ')'
5008 : : // // Need exprScope of variable_lvalue to prevent conflict
5009 : : | '(' ~p~exprScope '=' expr ')'
5010 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, $4},
5011 : : $2->cloneTreePure(true)};
5012 : : ASSIGNEQEXPR($<fl>3); }
5013 : : | '(' ~p~exprScope yP_PLUSEQ expr ')'
5014 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstAdd{$3, $2->cloneTreePure(true), $4}},
5015 : : $2->cloneTreePure(true)}; }
5016 : : | '(' ~p~exprScope yP_MINUSEQ expr ')'
5017 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstSub{$3, $2->cloneTreePure(true), $4}},
5018 : : $2->cloneTreePure(true)}; }
5019 : : | '(' ~p~exprScope yP_TIMESEQ expr ')'
5020 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstMul{$3, $2->cloneTreePure(true), $4}},
5021 : : $2->cloneTreePure(true)}; }
5022 : : | '(' ~p~exprScope yP_DIVEQ expr ')'
5023 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstDiv{$3, $2->cloneTreePure(true), $4}},
5024 : : $2->cloneTreePure(true)}; }
5025 : : | '(' ~p~exprScope yP_MODEQ expr ')'
5026 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstModDiv{$3, $2->cloneTreePure(true), $4}},
5027 : : $2->cloneTreePure(true)}; }
5028 : : | '(' ~p~exprScope yP_ANDEQ expr ')'
5029 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstAnd{$3, $2->cloneTreePure(true), $4}},
5030 : : $2->cloneTreePure(true)}; }
5031 : : | '(' ~p~exprScope yP_OREQ expr ')'
5032 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstOr{$3, $2->cloneTreePure(true), $4}},
5033 : : $2->cloneTreePure(true)}; }
5034 : : | '(' ~p~exprScope yP_XOREQ expr ')'
5035 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstXor{$3, $2->cloneTreePure(true), $4}},
5036 : : $2->cloneTreePure(true)}; }
5037 : : | '(' ~p~exprScope yP_SLEFTEQ expr ')'
5038 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstShiftL{$3, $2->cloneTreePure(true), $4}},
5039 : : $2->cloneTreePure(true)}; }
5040 : : | '(' ~p~exprScope yP_SRIGHTEQ expr ')'
5041 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstShiftR{$3, $2->cloneTreePure(true), $4}},
5042 : : $2->cloneTreePure(true)}; }
5043 : : | '(' ~p~exprScope yP_SSRIGHTEQ expr ')'
5044 : : { $$ = new AstExprStmt{$1, new AstAssign{$3, $2, new AstShiftRS{$3, $2->cloneTreePure(true), $4}},
5045 : : $2->cloneTreePure(true)}; }
5046 : : //
5047 : : // // IEEE: expression binary_operator expression
5048 : : | ~l~expr '+' ~r~expr { $$ = new AstAdd{$2, $1, $3}; }
5049 : : | ~l~expr '-' ~r~expr { $$ = new AstSub{$2, $1, $3}; }
5050 : : | ~l~expr '*' ~r~expr { $$ = new AstMul{$2, $1, $3}; }
5051 : : | ~l~expr '/' ~r~expr { $$ = new AstDiv{$2, $1, $3}; }
5052 : : | ~l~expr '%' ~r~expr { $$ = new AstModDiv{$2, $1, $3}; }
5053 : : | ~l~expr yP_EQUAL ~r~expr { $$ = new AstEq{$2, $1, $3}; }
5054 : : | ~l~expr yP_NOTEQUAL ~r~expr { $$ = new AstNeq{$2, $1, $3}; }
5055 : : | ~l~expr yP_CASEEQUAL ~r~expr { $$ = new AstEqCase{$2, $1, $3}; }
5056 : : | ~l~expr yP_CASENOTEQUAL ~r~expr { $$ = new AstNeqCase{$2, $1, $3}; }
5057 : : | ~l~expr yP_WILDEQUAL ~r~expr { $$ = new AstEqWild{$2, $1, $3}; }
5058 : : | ~l~expr yP_WILDNOTEQUAL ~r~expr { $$ = new AstNeqWild{$2, $1, $3}; }
5059 : : | ~l~expr yP_ANDAND ~r~expr { $$ = new AstLogAnd{$2, $1, $3}; }
5060 : : | ~l~expr yP_OROR ~r~expr { $$ = new AstLogOr{$2, $1, $3}; }
5061 : : | ~l~expr yP_POW ~r~expr { $$ = new AstPow{$2, $1, $3}; }
5062 : : | ~l~expr '<' ~r~expr { $$ = new AstLt{$2, $1, $3}; }
5063 : : | ~l~expr '>' ~r~expr { $$ = new AstGt{$2, $1, $3}; }
5064 : : | ~l~expr yP_GTE ~r~expr { $$ = new AstGte{$2, $1, $3}; }
5065 : : | ~l~expr '&' ~r~expr { $$ = new AstAnd{$2, $1, $3}; }
5066 : : | ~l~expr '|' ~r~expr { $$ = new AstOr{$2, $1, $3}; }
5067 : : | ~l~expr '^' ~r~expr { $$ = new AstXor{$2, $1, $3}; }
5068 : : | ~l~expr yP_XNOR ~r~expr { $$ = new AstNot{$2, new AstXor{$2, $1, $3}}; }
5069 : : | ~l~expr yP_NOR ~r~expr
5070 : : { $$ = new AstNot{$2, new AstOr{$2, $1, $3}};
5071 : : $2->v3error("Syntax error: '~|' is not a 'nor' binary operator, but a unary '~ |'"
5072 : : << YYNEWLINE << $<fl>1->warnMore() << "... Suggest '~ (... | ...)'"); }
5073 : : | ~l~expr yP_NAND ~r~expr
5074 : : { $$ = new AstNot{$2, new AstAnd{$2, $1, $3}};
5075 : : $2->v3error("Syntax error: '~&' is not a 'nand' binary operator, but a unary '~ &'"
5076 : : << YYNEWLINE << $<fl>1->warnMore() << "... Suggest '~ (... & ...)'"); }
5077 : : | ~l~expr yP_SLEFT ~r~expr { $$ = new AstShiftL{$2, $1, $3}; }
5078 : : | ~l~expr yP_SRIGHT ~r~expr { $$ = new AstShiftR{$2, $1, $3}; }
5079 : : | ~l~expr yP_SSRIGHT ~r~expr { $$ = new AstShiftRS{$2, $1, $3}; }
5080 : : | ~l~expr yP_LTMINUSGT ~r~expr { $$ = new AstLogEq{$2, $1, $3}; }
5081 : : //
5082 : : // // IEEE: expression binary_operator expression (type compare see IEEE footnote)
5083 : : | type_referenceEq yP_CASEEQUAL type_referenceBoth { $$ = new AstEqT{$2, $1, $3}; }
5084 : : | type_referenceEq yP_CASENOTEQUAL type_referenceBoth { $$ = new AstNeqT{$2, $1, $3}; }
5085 : : | type_referenceEq yP_EQUAL type_referenceBoth { $$ = new AstEqT{$2, $1, $3}; }
5086 : : | type_referenceEq yP_NOTEQUAL type_referenceBoth { $$ = new AstNeqT{$2, $1, $3}; }
5087 : : // // IEEE: expr yP_MINUSGT expr (1800-2009)
5088 : : // // Full IEEE 1800-2023 18.7.2 "expr ->
5089 : : // // constraint_set" is split: this rule handles
5090 : : // // the bare-expression RHS as a boolean
5091 : : // // (AstLogIf), constraint_expression has one
5092 : : // // production per non-expression RHS shape.
5093 : : | ~l~expr yP_MINUSGT ~r~expr { $$ = new AstLogIf{$2, $1, $3}; }
5094 : : //
5095 : : // // <= is special, as we need to disambiguate it with <= assignment
5096 : : // // We copy all of expr to fexpr and rename this token to a fake one.
5097 : : | ~l~expr yP_LTE~f__IGNORE~ ~r~expr { $$ = new AstLte{$2, $1, $3}; }
5098 : : //
5099 : : // // IEEE: conditional_expression
5100 : : | ~l~expr '?' ~r~expr ':' ~r~expr { $$ = new AstCond{$2, $1, $3, $5}; }
5101 : : //
5102 : : // // IEEE: inside_expression
5103 : : | ~l~expr yINSIDE '{' range_list '}' { $$ = new AstInside{$2, $1, $4}; }
5104 : : //
5105 : : // // IEEE: tagged_union_expression
5106 : : // // yTAGGED__NONPRIMARY = tokenPipeline determined no primary follows
5107 : : | yTAGGED__NONPRIMARY idAny/*member*/ %prec prTAGGED
5108 : : { $$ = new AstTaggedExpr{$1, *$2, nullptr}; }
5109 : : // // yTAGGED = primary follows; handle specific primary types
5110 : : // // Parenthesized expression
5111 : : | yTAGGED idAny/*member*/ '(' expr ')' %prec prTAGGED
5112 : : { $$ = new AstTaggedExpr{$1, *$2, $4}; }
5113 : : // // Assignment patterns like tagged Add '{a, b, c}
5114 : : | yTAGGED idAny/*member*/ assignment_pattern %prec prTAGGED
5115 : : { $$ = new AstTaggedExpr{$1, *$2, $3}; }
5116 : : // // Integer literal
5117 : : | yTAGGED idAny/*member*/ yaINTNUM %prec prTAGGED
5118 : : { $$ = new AstTaggedExpr{$1, *$2, new AstConst{$<fl>3, *$3}}; }
5119 : : // // Float literal
5120 : : | yTAGGED idAny/*member*/ yaFLOATNUM %prec prTAGGED
5121 : : { $$ = new AstTaggedExpr{$1, *$2, new AstConst{$<fl>3, AstConst::RealDouble{}, $3}}; }
5122 : : // // String literal
5123 : : | yTAGGED idAny/*member*/ yaSTRING %prec prTAGGED
5124 : : { $$ = new AstTaggedExpr{$1, *$2, new AstConst{$<fl>3, AstConst::VerilogStringLiteral{}, *$3}}; }
5125 : : // // null literal
5126 : : | yTAGGED idAny/*member*/ yNULL %prec prTAGGED
5127 : : { $$ = new AstTaggedExpr{$1, *$2, new AstConst{$3, AstConst::Null{}}}; }
5128 : : // // Identifier as value
5129 : : | yTAGGED idAny/*member*/ idAny %prec prTAGGED
5130 : : { $$ = new AstTaggedExpr{$1, *$2, new AstParseRef{$<fl>3, *$3, nullptr, nullptr}}; }
5131 : : // // Concatenation
5132 : : | yTAGGED idAny/*member*/ '{' cateList '}' %prec prTAGGED
5133 : : { $$ = new AstTaggedExpr{$1, *$2, $4}; }
5134 : : //
5135 : : //======================// IEEE: primary/constant_primary
5136 : : //
5137 : : // // IEEE: primary_literal (minus string, which is handled specially)
5138 : : | yaINTNUM { $$ = new AstConst{$<fl>1, *$1}; }
5139 : : | yaFLOATNUM { $$ = new AstConst{$<fl>1, AstConst::RealDouble{}, $1}; }
5140 : : | timeNumAdjusted { $$ = $1; }
5141 : : | strAsInt~noStr__IGNORE~ { $$ = $1; }
5142 : : //
5143 : : // // IEEE: "... hierarchical_identifier select" see below
5144 : : //
5145 : : // // IEEE: empty_unpacked_array_concatenation
5146 : : // // IEEE: (aka empty_queue, empty_unpacked_array_concatenation)
5147 : : | '{' '}' { $$ = new AstEmptyQueue{$1}; }
5148 : : //
5149 : : // // IEEE: concatenation/constant_concatenation
5150 : : // // Part of exprOkLvalue below
5151 : : //
5152 : : // // IEEE: multiple_concatenation/constant_multiple_concatenation
5153 : : | '{' constExpr '{' cateList '}' '}'
5154 : : { $$ = new AstReplicate{$3, $4, $2}; }
5155 : : | '{' constExpr '{' cateList '}' '}' '[' expr ']'
5156 : : { $$ = new AstSelBit{$7, new AstReplicate{$3, $4, $2}, $8}; }
5157 : : | '{' constExpr '{' cateList '}' '}' '[' constExpr ':' constExpr ']'
5158 : : { $$ = new AstSelExtract{$7, new AstReplicate{$3, $4, $2}, $8, $10}; }
5159 : : | '{' constExpr '{' cateList '}' '}' '[' expr yP_PLUSCOLON constExpr ']'
5160 : : { $$ = new AstSelPlus{$7, new AstReplicate{$3, $4, $2}, $8, $10}; }
5161 : : | '{' constExpr '{' cateList '}' '}' '[' expr yP_MINUSCOLON constExpr ']'
5162 : : { $$ = new AstSelMinus{$7, new AstReplicate{$3, $4, $2}, $8, $10}; }
5163 : : // // UNSUP some other rules above
5164 : : //
5165 : : // // IEEE grammar error: function_subroutine_call [ range_expression ]
5166 : : // // should be instead: function_subroutine_call [ part_select_range ]
5167 : : | function_subroutine_callNoMethod
5168 : : { $$ = $1; }
5169 : : | function_subroutine_callNoMethod part_select_rangeList
5170 : : { $$ = GRAMMARP->scrubSel($1, $2); }
5171 : : // // method_call
5172 : : | ~l~expr '.' function_subroutine_callNoMethod
5173 : : { $$ = new AstDot{$2, false, $1, $3}; }
5174 : : | ~l~expr '.' function_subroutine_callNoMethod part_select_rangeList
5175 : : { $$ = GRAMMARP->scrubSel(new AstDot{$2, false, $1, $3}, $4); }
5176 : : // // method_call:array_method requires a '.'
5177 : : | ~l~expr '.' array_methodWith
5178 : : { $$ = new AstDot{$2, false, $1, $3}; }
5179 : : | ~l~expr '.' array_methodWith part_select_rangeList
5180 : : { $$ = GRAMMARP->scrubSel(new AstDot{$2, false, $1, $3}, $4); }
5181 : : //
5182 : : // // IEEE: let_expression
5183 : : // // see funcRef
5184 : : //
5185 : : // // IEEE: '(' mintypmax_expression ')'
5186 : : | ~noPar__IGNORE~'(' expr ')' { $$ = $2; }
5187 : : | ~noPar__IGNORE~'(' expr ':' expr ':' expr ')'
5188 : : { $$ = $4; MINTYPMAXDLYUNSUP($4); DEL($2); DEL($6); }
5189 : : // // PSL rule
5190 : : | '_' '(' expr ')' { $$ = $3; } // Arbitrary Verilog inside PSL
5191 : : //
5192 : : // // IEEE: cast/constant_cast
5193 : : // // expanded from casting_type
5194 : : | simple_typeNoRef yP_TICK '(' expr ')'
5195 : : { $$ = new AstCast{$2, $4, VFlagChildDType{}, $1}; }
5196 : : // // expanded from simple_type ps_type_identifier (part of simple_type)
5197 : : // // expanded from simple_type ps_parameter_identifier (part of simple_type)
5198 : : // // Causes conflict, so handled post-parse
5199 : : // // NO: packageClassScopeE idType yP_TICK '(' expr ')'
5200 : : //
5201 : : | yTYPE__ETC '(' exprOrDataType ')' yP_TICK '(' expr ')'
5202 : : { $$ = new AstCast{$1, $7, VFlagChildDType{},
5203 : : new AstRefDType{$1, AstRefDType::FlagTypeOfExpr{}, $3}}; }
5204 : : | ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned{$1, $4}; }
5205 : : | yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned{$1, $4}; }
5206 : : | ySTRING yP_TICK '(' expr ')' { $$ = new AstCvtPackString{$1, $4}; }
5207 : : | yCONST__ETC yP_TICK '(' expr ')' { $$ = $4; } // Not linting const presently
5208 : : // // Spec only allows primary with addition of a type reference
5209 : : // // We'll be more general, and later assert LHS was a type.
5210 : : | ~l~expr yP_TICK '(' expr ')' { $$ = new AstCastParse{$2, $4, $1}; }
5211 : : //
5212 : : // // IEEE: assignment_pattern_expression
5213 : : // // IEEE: streaming_concatenation
5214 : : // // See exprOkLvalue
5215 : : //
5216 : : // // IEEE: sequence_method_call
5217 : : // // Indistinguishable from function_subroutine_call:method_call
5218 : : //
5219 : : | '$' { $$ = new AstUnbounded{$<fl>1}; }
5220 : : | yNULL { $$ = new AstConst{$1, AstConst::Null{}}; }
5221 : : // // IEEE: yTHIS
5222 : : // // See exprScope
5223 : : //
5224 : : //----------------------
5225 : : //
5226 : : // // Part of expr that may also be used as lvalue
5227 : : | ~l~exprOkLvalue { $$ = $1; }
5228 : : //
5229 : : //----------------------
5230 : : //
5231 : : // // IEEE: cond_predicate - here to avoid reduce problems
5232 : : // // Note expr includes cond_pattern
5233 : : | ~l~expr yP_ANDANDAND ~r~expr { $$ = new AstConst{$2, AstConst::BitFalse{}};
5234 : : BBUNSUP($<fl>2, "Unsupported: &&& expression"); }
5235 : : //
5236 : : // // IEEE: cond_pattern - here to avoid reduce problems
5237 : : // // "expr yMATCHES pattern"
5238 : : // // IEEE: pattern - expanded here to avoid conflicts
5239 : : | ~l~expr yMATCHES patternNoExpr { $$ = new AstMatches{$2, $1, $3}; }
5240 : : | ~l~expr yMATCHES ~r~expr { $$ = new AstMatches{$2, $1, $3}; }
5241 : : //
5242 : : // // IEEE: expression_or_dist - here to avoid reduce problems
5243 : : // // "expr yDIST '{' dist_list '}'"
5244 : : | ~l~expr yDIST '{' dist_list '}' { $$ = new AstDist{$2, $1, $4}; }
5245 : : ;
5246 : :
5247 : : fexpr<nodeExprp>: // For use as first part of statement (disambiguates <=)
5248 : : BISONPRE_COPY(expr,{s/~l~/f/g; s/~r~/f/g; s/~f__IGNORE~/__IGNORE/g;}) // {copied}
5249 : : ;
5250 : :
5251 : : //UNSUPpev_expr<nodeExprp>: // IEEE: event_expression
5252 : : //UNSUP // // for yOR/, see event_expression
5253 : : //UNSUP //
5254 : : //UNSUP // // IEEE: [ edge_identifier ] expression [ yIFF expression ]
5255 : : //UNSUP // // expr alone see below
5256 : : //UNSUP senitemEdge { $$ = $1; }
5257 : : //UNSUP | ev_expr yIFF expr { }
5258 : : //UNSUP //
5259 : : //UNSUP // // IEEE: sequence_instance [ yIFF expression ]
5260 : : //UNSUP // // seq_inst is in expr, so matches senitem rule above
5261 : : //UNSUP //
5262 : : //UNSUP // // IEEE: event_expression yOR event_expression
5263 : : //UNSUP | ev_expr yOR ev_expr { }
5264 : : //UNSUP // // IEEE: event_expression ',' event_expression
5265 : : //UNSUP // // See real event_expression rule
5266 : : //UNSUP //
5267 : : //UNSUP //---------------------
5268 : : //UNSUP // // IEEE: expr
5269 : : //UNSUP | BISONPRE_COPY(expr,{s/~l~/ev_/g; s/~r~/ev_/g; s/~p~/ev_/g; s/~noPar__IGNORE~'.'/yP_PAR__IGNORE /g;}) // {copied}
5270 : : //UNSUP //
5271 : : //UNSUP // // IEEE: '(' event_expression ')'
5272 : : //UNSUP // // expr:'(' x ')' conflicts with event_expression:'(' event_expression ')'
5273 : : //UNSUP // // so we use a special expression class
5274 : : //UNSUP | '(' event_expression ')' { $<fl>$ = $<fl>1; $$ = "(...)"; }
5275 : : //UNSUP // // IEEE: From normal expr: '(' expr ':' expr ':' expr ')'
5276 : : //UNSUP // // But must avoid conflict
5277 : : //UNSUP | '(' event_expression ':' expr ':' expr ')' { $<fl>$ = $<fl>1; $$ = "(...)"; }
5278 : : //UNSUP ;
5279 : :
5280 : : exprNoStr<nodeExprp>: // expression with string removed
5281 : : BISONPRE_COPY(expr,{s/~noStr__IGNORE~/Ignore/g;}) // {copied}
5282 : : ;
5283 : :
5284 : : exprOkLvalue<nodeExprp>: // expression that's also OK to use as a variable_lvalue
5285 : : ~l~exprScope { $$ = $1; }
5286 : : // // IEEE: concatenation/constant_concatenation
5287 : : // // Replicate(1) required as otherwise "{a}" would not be self-determined
5288 : : | '{' cateList '}' { $$ = new AstReplicate{$1, $2, 1}; }
5289 : : | '{' cateList '}' '[' expr ']' { $$ = new AstSelBit{$4, new AstReplicate{$1, $2, 1}, $5}; }
5290 : : | '{' cateList '}' '[' constExpr ':' constExpr ']'
5291 : : { $$ = new AstSelExtract{$4, new AstReplicate{$1, $2, 1}, $5, $7}; }
5292 : : | '{' cateList '}' '[' expr yP_PLUSCOLON constExpr ']'
5293 : : { $$ = new AstSelPlus{$4, new AstReplicate{$1, $2, 1}, $5, $7}; }
5294 : : | '{' cateList '}' '[' expr yP_MINUSCOLON constExpr ']'
5295 : : { $$ = new AstSelMinus{$4, new AstReplicate{$1, $2, 1}, $5, $7}; }
5296 : : // // IEEE: assignment_pattern_expression
5297 : : // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
5298 : : // // We allow more here than the spec requires
5299 : : //UNSUP ~l~exprScope assignment_pattern { UNSUP }
5300 : : | data_type assignment_pattern { $$ = $2; if ($2) $2->childDTypep($1); }
5301 : : | assignment_pattern { $$ = $1; }
5302 : : //
5303 : : | streaming_concatenation { $$ = $1; }
5304 : : ;
5305 : :
5306 : : fexprOkLvalue<nodeExprp>: // exprOkLValue, For use as first part of statement (disambiguates <=)
5307 : : BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g}) // {copied}
5308 : : ;
5309 : :
5310 : : sexprOkLvalue<nodeExprp>: // exprOkLValue, For use by sequence_expr
5311 : : BISONPRE_COPY(exprOkLvalue,{s/~l~/s/g}) // {copied}
5312 : : ;
5313 : :
5314 : : pexprOkLvalue<nodeExprp>: // exprOkLValue, For use by property_expr
5315 : : BISONPRE_COPY(exprOkLvalue,{s/~l~/p/g}) // {copied}
5316 : : ;
5317 : :
5318 : : //UNSUPev_exprOkLvalue<nodeExprp>: // exprOkLValue, For use by ev_expr
5319 : : //UNSUP BISONPRE_COPY(exprOkLvalue,{s/~l~/ev_/g}) // {copied}
5320 : : //UNSUP ;
5321 : :
5322 : : //UNSUPpev_exprOkLvalue<nodeExprp>: // exprOkLValue, For use by ev_expr
5323 : : //UNSUP BISONPRE_COPY(exprOkLvalue,{s/~l~/pev_/g}) // {copied}
5324 : : //UNSUP ;
5325 : :
5326 : : fexprLvalue<nodeExprp>: // For use as first part of statement (disambiguates <=)
5327 : : fexprOkLvalue { $<fl>$ = $<fl>1; $$ = $1; }
5328 : : ;
5329 : :
5330 : : exprScope<nodeExprp>: // scope and variable for use to inside an expression
5331 : : // // Here we've split method_call_root | implicit_class_handle | class_scope | package_scope
5332 : : // // from the object being called and let expr's "." deal with resolving it.
5333 : : // // (note method_call_root was simplified to require a primary in 1800-2009)
5334 : : //
5335 : : // // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
5336 : : // // Or method_call_body without parenthesis
5337 : : // // See also varRefClassBit, which is the non-expr version of most of this
5338 : : yTHIS { $$ = new AstParseRef{$<fl>1, "this"}; }
5339 : : | yD_ROOT { $$ = new AstParseRef{$<fl>1, "$root"}; }
5340 : : | idArrayed { $$ = $1; }
5341 : : | packageClassScope idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
5342 : : | ~l~expr '.' idArrayed { $$ = new AstDot{$<fl>2, false, $1, $3}; }
5343 : : // // expr below must be a "yTHIS"
5344 : : | ~l~expr '.' ySUPER
5345 : : { AstParseRef* const anodep = VN_CAST($1, ParseRef);
5346 : : if (anodep && anodep->name() == "this") {
5347 : : $$ = new AstParseRef{$<fl>1, "super"};
5348 : : $1->deleteTree();
5349 : : } else {
5350 : : $$ = $1; $$->v3error("Syntax error: 'super' must be first name component, or after 'this.'");
5351 : : }
5352 : : }
5353 : : // // Part of implicit_class_handle
5354 : : | ySUPER { $$ = new AstParseRef{$<fl>1, "super"}; }
5355 : : ;
5356 : :
5357 : : fexprScope<nodeExprp>: // exprScope, For use as first part of statement (disambiguates <=)
5358 : : BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied}
5359 : : ;
5360 : :
5361 : : sexprScope<nodeExprp>: // exprScope, For use by sequence_expr
5362 : : BISONPRE_COPY(exprScope,{s/~l~/s/g}) // {copied}
5363 : : ;
5364 : :
5365 : : pexprScope<nodeExprp>: // exprScope, For use by property_expr
5366 : : BISONPRE_COPY(exprScope,{s/~l~/p/g}) // {copied}
5367 : : ;
5368 : :
5369 : : //UNSUPev_exprScope<nodeExprp>: // exprScope, For use by ev_expr
5370 : : //UNSUP BISONPRE_COPY(exprScope,{s/~l~/ev_/g}) // {copied}
5371 : : //UNSUP ;
5372 : :
5373 : : //UNSUPpev_exprScope<nodeExprp>: // exprScope, For use by ev_expr
5374 : : //UNSUP BISONPRE_COPY(exprScope,{s/~l~/pev_/g}) // {copied}
5375 : : //UNSUP ;
5376 : :
5377 : : // PLI calls exclude "" as integers, they're strings
5378 : : // For $c("foo","bar") we want "bar" as a string, not a Verilog integer.
5379 : : exprStrText<nodep>:
5380 : : exprNoStr { $$ = $1; }
5381 : : | yaSTRING { $$ = new AstText{$<fl>1, GRAMMARP->textQuoted($<fl>1, *$1)}; }
5382 : : ;
5383 : :
5384 : : exprTypeCompare<nodeExprp>:
5385 : : expr { $$ = $1; }
5386 : : | type_referenceBoth { $$ = $1; }
5387 : : ;
5388 : :
5389 : : cStrList<nodep>:
5390 : : exprStrText { $$ = $1; }
5391 : : | exprStrText ',' cStrList { $$ = $1->addNext($3); }
5392 : : ;
5393 : :
5394 : : cateList<nodeExprp>:
5395 : : // // Not just 'expr' to prevent conflict via stream_concOrExprOrType
5396 : : stream_expression { $$ = $1; }
5397 : : | cateList ',' stream_expression { $$ = new AstConcat{$2, $1, $3}; }
5398 : : ;
5399 : :
5400 : : exprListE<nodeExprp>:
5401 : : /* empty */ { $$ = nullptr; }
5402 : : | exprList { $$ = $1; }
5403 : : ;
5404 : :
5405 : : exprList<nodeExprp>:
5406 : : expr { $$ = $1; }
5407 : : | exprList ',' expr { $$ = $1->addNext($3); }
5408 : : ;
5409 : :
5410 : : exprEListE<nodep>: // expression list with empty commas allowed
5411 : : exprE { $$ = $1; }
5412 : : | exprEListE ',' exprE { $$ = addNextNull($1, $3); }
5413 : : ;
5414 : :
5415 : : exprDispList<nodeExprp>: // exprList for within $display
5416 : : expr { $$ = $1; }
5417 : : | exprDispList ',' expr { $$ = $1->addNext($3); }
5418 : : // // ,, creates a space in $display
5419 : : | exprDispList ',' /*empty*/
5420 : : { $$ = $1->addNext(new AstConst{$<fl>2, AstConst::VerilogStringLiteral{}, " "}); }
5421 : : ;
5422 : :
5423 : : vrdList<nodeExprp>:
5424 : : idClassSel { $$ = $1; }
5425 : : | vrdList ',' idClassSel { $$ = $1->addNext($3); }
5426 : : ;
5427 : :
5428 : : commasE:
5429 : : /* empty */ { } /* ignored */
5430 : : | ',' commasE { } /* ignored */
5431 : : ;
5432 : :
5433 : : commaVRDListE<nodeExprp>:
5434 : : /* empty */ { $$ = nullptr; }
5435 : : | ',' vrdList { $$ = $2; }
5436 : : ;
5437 : :
5438 : : argsExprList<nodeExprp>: // IEEE: part of list_of_arguments (used where ,, isn't legal)
5439 : : expr { $$ = $1; }
5440 : : | argsExprList ',' expr { $$ = $1->addNext($3); }
5441 : : ;
5442 : :
5443 : : argsExprListE<argp>: // IEEE: part of list_of_arguments
5444 : : argsExprOneE { $$ = $1; }
5445 : : | argsExprListE ',' argsExprOneE { $$ = $1->addNext($3); }
5446 : : ;
5447 : :
5448 : : //UNSUPpev_argsExprListE<nodeExprp>: // IEEE: part of list_of_arguments - pev_expr at bottom
5449 : : //UNSUP pev_argsExprOneE { $$ = $1; }
5450 : : //UNSUP | pev_argsExprListE ',' pev_argsExprOneE { $$ = addNextNull($1, $3); }
5451 : : //UNSUP ;
5452 : :
5453 : : argsExprOneE<argp>: // IEEE: part of list_of_arguments
5454 : : /*empty*/ { $$ = new AstArg{CRELINE(), "", nullptr}; }
5455 : : | expr { $$ = new AstArg{$1->fileline(), "", $1}; }
5456 : : ;
5457 : :
5458 : : //UNSUPpev_argsExprOneE<nodeExprp>: // IEEE: part of list_of_arguments - pev_expr at bottom
5459 : : //UNSUP /*empty*/ { $$ = nullptr; } // ,, is legal in list_of_arguments
5460 : : //UNSUP | pev_expr { $$ = $1; }
5461 : : //UNSUP ;
5462 : :
5463 : : argsDottedList<argp>: // IEEE: part of list_of_arguments
5464 : : argsDotted { $$ = $1; }
5465 : : | argsDottedList ',' argsDotted { $$ = addNextNull($1, $3); }
5466 : : ;
5467 : :
5468 : : //UNSUPpev_argsDottedList<nodeExprp>: // IEEE: part of list_of_arguments - pev_expr at bottom
5469 : : //UNSUP pev_argsDotted { $$ = $1; }
5470 : : //UNSUP | pev_argsDottedList ',' pev_argsDotted { $$ = addNextNull($1, $3); }
5471 : : //UNSUP ;
5472 : :
5473 : : argsDotted<argp>: // IEEE: part of list_of_arguments
5474 : : '.' idAny '(' ')' { $$ = new AstArg{$<fl>2, *$2, nullptr}; }
5475 : : | '.' idAny '(' expr ')' { $$ = new AstArg{$<fl>2, *$2, $4}; }
5476 : : ;
5477 : :
5478 : : //UNSUPpev_argsDotted<argp>: // IEEE: part of list_of_arguments - pev_expr at bottom
5479 : : //UNSUP '.' idAny '(' ')' { $$ = new AstArg{$<fl>2, *$2, nullptr}; }
5480 : : //UNSUP | '.' idAny '(' pev_expr ')' { $$ = new AstArg{$<fl>2, *$2, $4}; }
5481 : : //UNSUP ;
5482 : :
5483 : : streaming_concatenation<nodeStreamp>: // ==IEEE: streaming_concatenation
5484 : : // // Need to disambiguate {<< expr-{ ... expr-} stream_concat }
5485 : : // // From {<< stream-{ ... stream-} }
5486 : : // // Likewise simple_type's idScoped from constExpr's idScope
5487 : : // // Thus we allow always any two operations. Sorry
5488 : : // // IEEE: "'{' yP_SL/R stream_concatenation '}'"
5489 : : // // IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'"
5490 : : // // IEEE: "'{' yP_SL/R constExpr stream_concatenation '}'"
5491 : : '{' yP_SLEFT stream_concatenation '}'
5492 : : { $$ = new AstStreamL{$2, $3, new AstConst{$2, 1}}; }
5493 : : | '{' yP_SRIGHT stream_concatenation '}'
5494 : : { $$ = new AstStreamR{$2, $3, new AstConst{$2, 1}}; }
5495 : : | '{' yP_SLEFT stream_expressionOrDataType stream_concatenation '}'
5496 : : { $$ = new AstStreamL{$2, $4, new AstAttrOf{$1, VAttrType::DIM_BITS_OR_NUMBER, $3}}; }
5497 : : | '{' yP_SRIGHT stream_expressionOrDataType stream_concatenation '}'
5498 : : { $$ = new AstStreamR{$2, $4, new AstAttrOf{$1, VAttrType::DIM_BITS_OR_NUMBER, $3}}; }
5499 : : ;
5500 : :
5501 : : stream_concatenation<nodeExprp>: // ==IEEE: stream_concatenation
5502 : : // // '{' { stream_expression } '}'
5503 : : '{' cateList '}' { $$ = $2; }
5504 : : ;
5505 : :
5506 : : stream_expression<nodeExprp>: // ==IEEE: stream_expression
5507 : : // // IEEE: array_range_expression expanded below
5508 : : expr { $$ = $1; }
5509 : : | expr yWITH__BRA '[' expr ']'
5510 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5511 : : | expr yWITH__BRA '[' expr ':' expr ']'
5512 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5513 : : | expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']'
5514 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5515 : : | expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']'
5516 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5517 : : ;
5518 : :
5519 : : stream_expressionOrDataType<nodep>: // IEEE: from streaming_concatenation
5520 : : exprOrDataType { $$ = $1; }
5521 : : | expr yWITH__BRA '[' expr ']'
5522 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5523 : : | expr yWITH__BRA '[' expr ':' expr ']'
5524 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5525 : : | expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']'
5526 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5527 : : | expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']'
5528 : : { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); }
5529 : : ;
5530 : :
5531 : : //************************************************
5532 : : // Let
5533 : :
5534 : : letId<letp>: // IEEE: pert of let_declaration
5535 : : idAny/*let_identifieer*/
5536 : : { $<fl>$ = $<fl>1;
5537 : : $$ = new AstLet{$<fl>$, *$1}; }
5538 : : ;
5539 : :
5540 : : let_declaration<letp>: // IEEE: let_declaration
5541 : : yLET letId '=' expr ';'
5542 : : { $$ = $2;
5543 : : $$->addStmtsp(new AstStmtExpr{$1, $4}); }
5544 : : | yLET letId '(' let_port_listE ')' '=' expr ';'
5545 : : { $$ = $2;
5546 : : $$->addStmtsp(new AstStmtExpr{$1, $7});
5547 : : $$->addStmtsp($4); }
5548 : : ;
5549 : :
5550 : : let_port_listE<nodep>: // IEEE: [ let_port_list ]
5551 : : /*empty*/ { $$ = nullptr; }
5552 : : | /*emptyStart*/
5553 : : /*mid*/ { VARRESET_LIST(VAR); VARIO(INOUT); }
5554 : : /*cont*/ let_port_list { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
5555 : : ;
5556 : :
5557 : : let_port_list<nodep>: // IEEE: let_port_list
5558 : : let_port_item { $$ = $1; }
5559 : : | let_port_list ',' let_port_item { $$ = addNextNull($1, $3); }
5560 : : ;
5561 : :
5562 : : let_port_item<varp>: // IEEE: let_port_Item
5563 : : // // IEEE: Expanded let_formal_type
5564 : : yUNTYPED idAny/*formal_port_identifier*/ variable_dimensionListE exprEqE
5565 : : { $$ = new AstVar{$<fl>2, VVarType::VAR, *$2, VFlagChildDType{},
5566 : : new AstBasicDType{$<fl>2, LOGIC_IMPLICIT}};
5567 : : $$->direction(VDirection::INOUT);
5568 : : $$->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
5569 : : if ($4) $$->valuep($4);
5570 : : PINNUMINC(); }
5571 : : | data_type idAny/*formal_port_identifier*/ variable_dimensionListE exprEqE
5572 : : { BBUNSUP($<fl>1, "Unsupported: let typed ports");
5573 : : $$ = new AstVar{$<fl>2, VVarType::VAR, *$2, VFlagChildDType{},
5574 : : new AstBasicDType{$<fl>2, LOGIC_IMPLICIT}};
5575 : : $$->direction(VDirection::INOUT);
5576 : : $$->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
5577 : : if ($4) $$->valuep($4);
5578 : : PINNUMINC(); }
5579 : : | implicit_typeE id/*formal_port_identifier*/ variable_dimensionListE exprEqE
5580 : : { if ($1) BBUNSUP($<fl>1, "Unsupported: let typed ports");
5581 : : $$ = new AstVar{$<fl>2, VVarType::VAR, *$2, VFlagChildDType{},
5582 : : new AstBasicDType{$<fl>2, LOGIC_IMPLICIT}};
5583 : : $$->direction(VDirection::INOUT);
5584 : : $$->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
5585 : : if ($4) $$->valuep($4);
5586 : : PINNUMINC(); }
5587 : : ;
5588 : :
5589 : : //************************************************
5590 : : // Gate declarations
5591 : :
5592 : : gateDecl<nodep>:
5593 : : yBUF driveStrengthE delay_controlE gateBufList ';' { $$ = $4; STRENGTHUNSUP($2); DELAY_LIST($4, $3); }
5594 : : | yBUFIF0 driveStrengthE delay_controlE gateBufif0List ';' { $$ = $4; STRENGTHUNSUP($2); DELAY_LIST($4, $3); }
5595 : : | yBUFIF1 driveStrengthE delay_controlE gateBufif1List ';' { $$ = $4; STRENGTHUNSUP($2); DELAY_LIST($4, $3); }
5596 : : | yNOT driveStrengthE delay_controlE gateNotList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5597 : : | yNOTIF0 driveStrengthE delay_controlE gateNotif0List ';' { $$ = $4; STRENGTHUNSUP($2); DELAY_LIST($4, $3); }
5598 : : | yNOTIF1 driveStrengthE delay_controlE gateNotif1List ';' { $$ = $4; STRENGTHUNSUP($2); DELAY_LIST($4, $3); }
5599 : : | yAND driveStrengthE delay_controlE gateAndList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5600 : : | yNAND driveStrengthE delay_controlE gateNandList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5601 : : | yOR driveStrengthE delay_controlE gateOrList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5602 : : | yNOR driveStrengthE delay_controlE gateNorList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5603 : : | yXOR driveStrengthE delay_controlE gateXorList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5604 : : | yXNOR driveStrengthE delay_controlE gateXnorList ';' { $$ = $4; STRENGTH_LIST($4, $2); DELAY_LIST($4, $3); }
5605 : : | yPULLDOWN pulldown_strengthE delay_controlE gatePulldownList ';' { $$ = $4; DELAY_LIST($4, $3); }
5606 : : | yPULLUP pullup_strengthE delay_controlE gatePullupList ';' { $$ = $4; DELAY_LIST($4, $3); }
5607 : : | yNMOS delay_controlE gateBufif1List ';' { $$ = $3; DELAY_LIST($3, $2); }
5608 : : | yPMOS delay_controlE gateBufif0List ';' { $$ = $3; DELAY_LIST($3, $2); }
5609 : : //
5610 : : | yTRAN delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "tran"); }
5611 : : | yRCMOS delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "rcmos"); }
5612 : : | yCMOS delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "cmos"); }
5613 : : | yRNMOS delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "rmos"); }
5614 : : | yRPMOS delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "pmos"); }
5615 : : | yRTRAN delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "rtran"); }
5616 : : | yRTRANIF0 delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "rtranif0"); }
5617 : : | yRTRANIF1 delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "rtranif1"); }
5618 : : | yTRANIF0 delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "tranif0"); }
5619 : : | yTRANIF1 delay_controlE gateUnsupList ';' { $$ = $3; GATEUNSUP($3, "tranif1"); }
5620 : : ;
5621 : :
5622 : : gateBufList<nodep>:
5623 : : gateBuf { $$ = $1; }
5624 : : | gateBufList ',' gateBuf { $$ = $1->addNext($3); }
5625 : : ;
5626 : : gateBufif0List<nodep>:
5627 : : gateBufif0 { $$ = $1; }
5628 : : | gateBufif0List ',' gateBufif0 { $$ = $1->addNext($3); }
5629 : : ;
5630 : : gateBufif1List<nodep>:
5631 : : gateBufif1 { $$ = $1; }
5632 : : | gateBufif1List ',' gateBufif1 { $$ = $1->addNext($3); }
5633 : : ;
5634 : : gateNotList<nodep>:
5635 : : gateNot { $$ = $1; }
5636 : : | gateNotList ',' gateNot { $$ = $1->addNext($3); }
5637 : : ;
5638 : : gateNotif0List<nodep>:
5639 : : gateNotif0 { $$ = $1; }
5640 : : | gateNotif0List ',' gateNotif0 { $$ = $1->addNext($3); }
5641 : : ;
5642 : : gateNotif1List<nodep>:
5643 : : gateNotif1 { $$ = $1; }
5644 : : | gateNotif1List ',' gateNotif1 { $$ = $1->addNext($3); }
5645 : : ;
5646 : : gateAndList<nodep>:
5647 : : gateAnd { $$ = $1; }
5648 : : | gateAndList ',' gateAnd { $$ = $1->addNext($3); }
5649 : : ;
5650 : : gateNandList<nodep>:
5651 : : gateNand { $$ = $1; }
5652 : : | gateNandList ',' gateNand { $$ = $1->addNext($3); }
5653 : : ;
5654 : : gateOrList<nodep>:
5655 : : gateOr { $$ = $1; }
5656 : : | gateOrList ',' gateOr { $$ = $1->addNext($3); }
5657 : : ;
5658 : : gateNorList<nodep>:
5659 : : gateNor { $$ = $1; }
5660 : : | gateNorList ',' gateNor { $$ = $1->addNext($3); }
5661 : : ;
5662 : : gateXorList<nodep>:
5663 : : gateXor { $$ = $1; }
5664 : : | gateXorList ',' gateXor { $$ = $1->addNext($3); }
5665 : : ;
5666 : : gateXnorList<nodep>:
5667 : : gateXnor { $$ = $1; }
5668 : : | gateXnorList ',' gateXnor { $$ = $1->addNext($3); }
5669 : : ;
5670 : : gatePullupList<nodep>:
5671 : : gatePullup { $$ = $1; }
5672 : : | gatePullupList ',' gatePullup { $$ = $1->addNext($3); }
5673 : : ;
5674 : : gatePulldownList<nodep>:
5675 : : gatePulldown { $$ = $1; }
5676 : : | gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); }
5677 : : ;
5678 : : gateUnsupList<nodep>:
5679 : : gateUnsup { $$ = $1; }
5680 : : | gateUnsupList ',' gateUnsup { $$ = $1->addNext($3); }
5681 : : ;
5682 : :
5683 : : gateRangeE<nodep>:
5684 : : instRangeListE { $$ = $1; GATERANGE(GRAMMARP->scrubRange($1)); }
5685 : : ;
5686 : :
5687 : : gateBuf<nodep>:
5688 : : gateFront variable_lvalue ',' exprList ')'
5689 : : { AstNodeExpr* inp = $4;
5690 : : while (inp->nextp()) inp = VN_AS(inp->nextp(), NodeExpr);
5691 : : $$ = new AstImplicit{$<fl>1, inp->cloneTree(false)};
5692 : : AstNodeExpr* const rhsp = GRAMMARP->createGatePin(inp->cloneTree(false));
5693 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5694 : : $$->addNext(new AstAlways{ap});
5695 : : for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) {
5696 : : AstNodeExpr* const pinRhsp = GRAMMARP->createGatePin(inp->cloneTree(false));
5697 : : AstAssignW* const pinAssp = new AstAssignW{$<fl>1, outp->cloneTree(false), pinRhsp};
5698 : : $$->addNext(new AstAlways{pinAssp});
5699 : : }
5700 : : DEL($1); DEL($4); }
5701 : : ;
5702 : : gateNot<nodep>:
5703 : : gateFront variable_lvalue ',' exprList ')'
5704 : : { AstNodeExpr* inp = $4;
5705 : : while (inp->nextp()) inp = VN_AS(inp->nextp(), NodeExpr);
5706 : : $$ = new AstImplicit{$<fl>1, inp->cloneTree(false)};
5707 : : AstNodeExpr* const rhsp = new AstNot{$<fl>1, GRAMMARP->createGatePin(inp->cloneTree(false))};
5708 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5709 : : $$->addNext(new AstAlways{ap});
5710 : : for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) {
5711 : : AstNodeExpr* const pinRhsp = new AstNot{$<fl>1, GRAMMARP->createGatePin(inp->cloneTree(false))};
5712 : : AstAssignW* const pinAssp = new AstAssignW{$<fl>1, outp->cloneTree(false), pinRhsp};
5713 : : $$->addNext(new AstAlways{pinAssp});
5714 : : }
5715 : : DEL($1, $4); }
5716 : : ;
5717 : : gateBufif0<nodep>:
5718 : : gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
5719 : : { $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
5720 : : $<implicitp>$->addExprsp($4->cloneTree(false));
5721 : : AstNodeExpr* const rhsp = new AstBufIf1{$<fl>1, new AstNot{$<fl>1, $6}, $4};
5722 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5723 : : $$->addNext(new AstAlways{ap});
5724 : : DEL($1); }
5725 : : ;
5726 : : gateBufif1<nodep>:
5727 : : gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
5728 : : { $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
5729 : : $<implicitp>$->addExprsp($4->cloneTree(false));
5730 : : AstNodeExpr* const rhsp = new AstBufIf1{$<fl>1, $6, $4};
5731 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5732 : : $$->addNext(new AstAlways{ap});
5733 : : DEL($1); }
5734 : : ;
5735 : : gateNotif0<nodep>:
5736 : : gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
5737 : : { $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
5738 : : $<implicitp>$->addExprsp($4->cloneTree(false));
5739 : : AstNodeExpr* const rhsp = new AstBufIf1{$<fl>1, new AstNot{$<fl>1, $6}, new AstNot{$<fl>1, $4}};
5740 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5741 : : $$->addNext(new AstAlways{ap});
5742 : : DEL($1); }
5743 : : ;
5744 : : gateNotif1<nodep>:
5745 : : gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
5746 : : { $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
5747 : : $<implicitp>$->addExprsp($4->cloneTree(false));
5748 : : AstNodeExpr* const rhsp = new AstBufIf1{$<fl>1, $6, new AstNot{$<fl>1, $4}};
5749 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5750 : : $$->addNext(new AstAlways{ap});
5751 : : DEL($1); }
5752 : : ;
5753 : : gateAnd<nodep>:
5754 : : gateFront variable_lvalue ',' gateAndPinList ')'
5755 : : { $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
5756 : : AstNodeExpr* const rhsp = $4;
5757 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5758 : : $$->addNext(new AstAlways{ap});
5759 : : DEL($1); }
5760 : : ;
5761 : : gateNand<nodep>:
5762 : : gateFront variable_lvalue ',' gateAndPinList ')'
5763 : : { $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
5764 : : AstNodeExpr* const rhsp = new AstNot{$<fl>1, $4};
5765 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5766 : : $$->addNext(new AstAlways{ap});
5767 : : DEL($1); }
5768 : : ;
5769 : : gateOr<nodep>:
5770 : : gateFront variable_lvalue ',' gateOrPinList ')'
5771 : : { $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
5772 : : AstNodeExpr* const rhsp = $4;
5773 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5774 : : $$->addNext(new AstAlways{ap});
5775 : : DEL($1); }
5776 : : ;
5777 : : gateNor<nodep>:
5778 : : gateFront variable_lvalue ',' gateOrPinList ')'
5779 : : { $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
5780 : : AstNodeExpr* const rhsp = new AstNot{$<fl>1, $4};
5781 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5782 : : $$->addNext(new AstAlways{ap});
5783 : : DEL($1); }
5784 : : ;
5785 : : gateXor<nodep>:
5786 : : gateFront variable_lvalue ',' gateXorPinList ')'
5787 : : { $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
5788 : : AstNodeExpr* const rhsp = $4;
5789 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5790 : : $$->addNext(new AstAlways{ap});
5791 : : DEL($1); }
5792 : : ;
5793 : : gateXnor<nodep>:
5794 : : gateFront variable_lvalue ',' gateXorPinList ')'
5795 : : { $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
5796 : : AstNodeExpr* const rhsp = new AstNot{$<fl>1, $4};
5797 : : AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
5798 : : $$->addNext(new AstAlways{ap});
5799 : : DEL($1); }
5800 : : ;
5801 : : gatePullup<nodep>:
5802 : : gateFront variable_lvalue ')' { $$ = new AstPull{$<fl>1, $2, true}; DEL($1); }
5803 : : ;
5804 : : gatePulldown<nodep>:
5805 : : gateFront variable_lvalue ')' { $$ = new AstPull{$<fl>1, $2, false}; DEL($1); }
5806 : : ;
5807 : : gateUnsup<nodep>:
5808 : : gateFront gateUnsupPinList ')' { $$ = new AstImplicit{$<fl>1, $2}; DEL($1); }
5809 : : ;
5810 : :
5811 : : gateFront<nodep>:
5812 : : id/*gate*/ gateRangeE '(' { $$ = $2; $<fl>$ = $<fl>1; }
5813 : : | gateRangeE '(' { $$ = $1; $<fl>$ = $<fl>2; }
5814 : : ;
5815 : :
5816 : : gateAndPinList<nodeExprp>:
5817 : : gatePinExpr { $$ = $1; }
5818 : : | gateAndPinList ',' gatePinExpr { $$ = new AstAnd{$2, $1, $3}; }
5819 : : ;
5820 : : gateOrPinList<nodeExprp>:
5821 : : gatePinExpr { $$ = $1; }
5822 : : | gateOrPinList ',' gatePinExpr { $$ = new AstOr{$2, $1, $3}; }
5823 : : ;
5824 : : gateXorPinList<nodeExprp>:
5825 : : gatePinExpr { $$ = $1; }
5826 : : | gateXorPinList ',' gatePinExpr { $$ = new AstXor{$2, $1, $3}; }
5827 : : ;
5828 : : gateUnsupPinList<nodeExprp>:
5829 : : gatePinExpr { $$ = $1; }
5830 : : | gateUnsupPinList ',' gatePinExpr { $$ = addNextNull($1, $3); }
5831 : : ;
5832 : :
5833 : : gatePinExpr<nodeExprp>:
5834 : : expr { $$ = GRAMMARP->createGatePin($1); }
5835 : : ;
5836 : :
5837 : : strength0<strength>:
5838 : : ySUPPLY0 { $$ = VStrength::SUPPLY; }
5839 : : | ySTRONG0 { $$ = VStrength::STRONG; }
5840 : : | yPULL0 { $$ = VStrength::PULL; }
5841 : : | yWEAK0 { $$ = VStrength::WEAK; }
5842 : : ;
5843 : :
5844 : : strength1<strength>:
5845 : : ySUPPLY1 { $$ = VStrength::SUPPLY; }
5846 : : | ySTRONG1 { $$ = VStrength::STRONG; }
5847 : : | yPULL1 { $$ = VStrength::PULL; }
5848 : : | yWEAK1 { $$ = VStrength::WEAK; }
5849 : : ;
5850 : :
5851 : : driveStrengthE<strengthSpecp>:
5852 : : /* empty */ { $$ = nullptr; }
5853 : : | driveStrength { $$ = $1; }
5854 : : ;
5855 : :
5856 : : driveStrength<strengthSpecp>:
5857 : : yP_PAR__STRENGTH strength0 ',' strength1 ')' { $$ = new AstStrengthSpec{$1, $2, $4}; }
5858 : : | yP_PAR__STRENGTH strength1 ',' strength0 ')' { $$ = new AstStrengthSpec{$1, $4, $2}; }
5859 : : | yP_PAR__STRENGTH strength0 ',' yHIGHZ1 ')' { $$ = nullptr; BBUNSUP($<fl>4, "Unsupported: highz strength"); }
5860 : : | yP_PAR__STRENGTH strength1 ',' yHIGHZ0 ')' { $$ = nullptr; BBUNSUP($<fl>4, "Unsupported: highz strength"); }
5861 : : | yP_PAR__STRENGTH yHIGHZ0 ',' strength1 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: highz strength"); }
5862 : : | yP_PAR__STRENGTH yHIGHZ1 ',' strength0 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: highz strength"); }
5863 : : ;
5864 : :
5865 : : pulldown_strengthE<nodep>: // IEEE: [ pulldown_strength ]
5866 : : /* empty */ { $$ = nullptr; }
5867 : : | pulldown_strength { $$ = $1; }
5868 : : ;
5869 : :
5870 : : pulldown_strength<nodep>: // IEEE: pulldown_strength
5871 : : yP_PAR__STRENGTH strength0 ',' strength1 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: pulldown strength"); }
5872 : : | yP_PAR__STRENGTH strength1 ',' strength0 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: pulldown strength"); }
5873 : : | yP_PAR__STRENGTH strength0 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: pulldown strength"); }
5874 : : ;
5875 : :
5876 : : pullup_strengthE<nodep>: // IEEE: [ pullup_strength ]
5877 : : /* empty */ { $$ = nullptr; }
5878 : : | pullup_strength { $$ = $1; }
5879 : : ;
5880 : :
5881 : : pullup_strength<nodep>: // IEEE: pullup_strength
5882 : : yP_PAR__STRENGTH strength0 ',' strength1 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: pullup strength"); }
5883 : : | yP_PAR__STRENGTH strength1 ',' strength0 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: pullup strength"); }
5884 : : | yP_PAR__STRENGTH strength1 ')' { $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: pullup strength"); }
5885 : : ;
5886 : :
5887 : : //************************************************
5888 : : // Tables
5889 : :
5890 : : combinational_body<nodep>: // IEEE: combinational_body + sequential_body
5891 : : yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable{$1, $2}; }
5892 : : ;
5893 : :
5894 : : tableEntryList<udpTableLinep>: // IEEE: { combinational_entry + sequential_entry }
5895 : : tableLine { $$ = $1; }
5896 : : | tableEntryList tableLine { $$ = addNextNull($1, $2); }
5897 : : ;
5898 : :
5899 : : tableLine<udpTableLinep>:
5900 : : tableInputList yaTABLE_LRSEP tablelVal yaTABLE_LINEEND
5901 : : { $$ = new AstUdpTableLine{AstUdpTableLine::UdpCombo{}, $<fl>1, $1, $3}; }
5902 : : | tableInputList yaTABLE_LRSEP tablelVal yaTABLE_LRSEP tablelVal yaTABLE_LINEEND
5903 : : { $$ = new AstUdpTableLine{AstUdpTableLine::UdpSequential{}, $<fl>1, $1, $3, $5}; }
5904 : : ;
5905 : :
5906 : : tableInputList<udpTableLineValp>:
5907 : : tablelVal { $$ = $1; }
5908 : : | tableInputList tablelVal { $$ = addNextNull($1, $2); }
5909 : : ;
5910 : :
5911 : : tablelVal<udpTableLineValp>:
5912 : : yaTABLE_FIELD { $$ = new AstUdpTableLineVal{$<fl>1, *$1}; }
5913 : : | '(' yaTABLE_FIELD yaTABLE_FIELD ')' { $$ = new AstUdpTableLineVal{$<fl>2, *$2 + *$3}; }
5914 : : ;
5915 : :
5916 : : //************************************************
5917 : : // Specify
5918 : :
5919 : : specify_block<nodep>: // ==IEEE: specify_block
5920 : : specifyFront specify_itemList yENDSPECIFY { $$ = $2; }
5921 : : | specifyFront yENDSPECIFY { $$ = nullptr; }
5922 : : ;
5923 : :
5924 : : specifyFront: // IEEE: specify_block front
5925 : : ySPECIFY { GRAMMARP->m_specifyignWarned = false; }
5926 : : ;
5927 : :
5928 : : specify_itemList<nodep>: // IEEE: { specify_item }
5929 : : specify_item { $$ = $1; }
5930 : : | specify_itemList specify_item { $$ = addNextNull($1, $2); }
5931 : : ;
5932 : :
5933 : : specify_item<nodep>: // ==IEEE: specify_item
5934 : : specparam_declaration { $$ = $1; }
5935 : : | system_timing_check { $$ = $1; }
5936 : : | junkToSemiList ';'
5937 : : { $$ = nullptr;
5938 : : if (!GRAMMARP->m_specifyignWarned) {
5939 : : GRAMMARP->m_specifyignWarned = true;
5940 : : $1->v3warn(SPECIFYIGN, "Ignoring unsupported: specify block construct");
5941 : : }
5942 : : }
5943 : : ;
5944 : :
5945 : : specparam_declaration<nodep>: // ==IEEE: specparam_declaration
5946 : : specparam_declarationFront list_of_specparam_assignments ';'
5947 : : { $$ = $2; }
5948 : : ;
5949 : :
5950 : : specparam_declarationFront: // IEEE: part of specparam_declaration
5951 : : // // Front must execute first so VARDTYPE is ready before list of vars
5952 : : ySPECPARAM
5953 : : { VARRESET_NONLIST(SPECPARAM);
5954 : : AstNodeDType* dtp = new AstBasicDType{$1, VBasicDTypeKwd::DOUBLE};
5955 : : VARDTYPE(dtp); }
5956 : : | ySPECPARAM packed_dimension
5957 : : { VARRESET_NONLIST(SPECPARAM);
5958 : : AstNodeDType* const dtp = GRAMMARP->addRange(
5959 : : new AstBasicDType{$2->fileline(), LOGIC_IMPLICIT}, $2, true);
5960 : : VARDTYPE(dtp); }
5961 : : ;
5962 : :
5963 : : list_of_specparam_assignments<varp>: // ==IEEE: list_of_specparam_assignments
5964 : : specparam_assignment { $$ = $1; }
5965 : : | list_of_specparam_assignments ',' specparam_assignment { $$ = $1->addNext($3); }
5966 : : ;
5967 : :
5968 : : specparam_assignment<varp>: // ==IEEE: specparam_assignment
5969 : : idNotPathpulse sigAttrListE '=' minTypMax
5970 : : { $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
5971 : : if ($4) $$->valuep($4); }
5972 : : // // IEEE: pulse_control_specparam
5973 : : // // LRM grammar requires '(' as the first token after assignment,
5974 : : // // but IEEE provides an example in 30.7.1 where it is omitted.
5975 : : // // Other simulators also support it.
5976 : : | idPathpulse sigAttrListE '=' minTypMax
5977 : : { $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
5978 : : if ($4) $$->valuep($4); }
5979 : : | idPathpulse sigAttrListE '=' '(' minTypMax ',' minTypMax ')'
5980 : : { $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
5981 : : if ($5) $$->valuep($5);
5982 : : DEL($7); }
5983 : : ;
5984 : :
5985 : : system_timing_check<nodep>: // ==IEEE: system_timing_check
5986 : : setuphold_timing_check { $$ = $1; }
5987 : : ;
5988 : :
5989 : : setuphold_timing_check<nodep>: // ==IEEE: $setuphold_timing_check
5990 : : yD_SETUPHOLD '(' timing_check_event ',' timing_check_event ',' timing_check_limit ',' timing_check_limit ')' ';'
5991 : : { $$ = nullptr; DEL($3, $5, $7, $9); }
5992 : : | yD_SETUPHOLD '(' timing_check_event ',' timing_check_event ',' timing_check_limit ',' timing_check_limit ',' idAnyE ')' ';'
5993 : : { $$ = nullptr; DEL($3, $5, $7, $9); }
5994 : : | yD_SETUPHOLD '(' timing_check_event ',' timing_check_event ',' timing_check_limit ',' timing_check_limit ',' idAnyE ',' minTypMaxE ')' ';'
5995 : : { $$ = nullptr; DEL($3, $5, $7, $9, $13); }
5996 : : | yD_SETUPHOLD '(' timing_check_event ',' timing_check_event ',' timing_check_limit ',' timing_check_limit ',' idAnyE ',' minTypMaxE ',' minTypMaxE ')' ';'
5997 : : { $$ = nullptr; DEL($3, $5, $7, $9, $13, $15); }
5998 : : | yD_SETUPHOLD '(' timing_check_event ',' timing_check_event ',' timing_check_limit ',' timing_check_limit ',' idAnyE ',' minTypMaxE ',' minTypMaxE ',' delayed_referenceE ')' ';'
5999 : : { $$ = new AstSetuphold{$1, $3, $5, $17}; DEL($7, $9, $13, $15); }
6000 : : | yD_SETUPHOLD '(' timing_check_event ',' timing_check_event ',' timing_check_limit ',' timing_check_limit ',' idAnyE ',' minTypMaxE ',' minTypMaxE ',' delayed_referenceE ',' delayed_referenceE ')' ';'
6001 : : { $$ = new AstSetuphold{$1, $3, $5, $17, $19}; DEL($7, $9, $13, $15); }
6002 : : ;
6003 : :
6004 : : timing_check_event<nodeExprp>: // ==IEEE: $timing_check_event
6005 : : terminal_identifier { $$ = $1; }
6006 : : | yPOSEDGE terminal_identifier { $$ = $2; }
6007 : : | yNEGEDGE terminal_identifier { $$ = $2; }
6008 : : | yEDGE terminal_identifier { $$ = $2; }
6009 : : | yEDGE '[' edge_descriptor_list ']' terminal_identifier { $$ = $5; }
6010 : : | terminal_identifier yP_ANDANDAND expr { $$ = $1; DEL($3); }
6011 : : | yPOSEDGE terminal_identifier yP_ANDANDAND expr { $$ = $2; DEL($4); }
6012 : : | yNEGEDGE terminal_identifier yP_ANDANDAND expr { $$ = $2; DEL($4); }
6013 : : | yEDGE terminal_identifier yP_ANDANDAND expr { $$ = $2; DEL($4); }
6014 : : | yEDGE '[' edge_descriptor_list ']' terminal_identifier yP_ANDANDAND expr { $$ = $5; DEL($7); }
6015 : : ;
6016 : :
6017 : : edge_descriptor_list:
6018 : : yaEDGEDESC { }
6019 : : | edge_descriptor_list ',' yaEDGEDESC { }
6020 : : ;
6021 : :
6022 : : timing_check_limit<nodeExprp>:
6023 : : expr { $$ = $1; }
6024 : : | expr ':' expr ':' expr { $$ = $3; DEL($1, $5); }
6025 : : ;
6026 : :
6027 : : delayed_referenceE<nodeExprp>:
6028 : : /*empty*/ { $$ = nullptr; }
6029 : : | terminal_identifier { $$ = $1; }
6030 : : ;
6031 : :
6032 : : terminal_identifier<nodeExprp>:
6033 : : idArrayed { $$ = $1; }
6034 : : ;
6035 : :
6036 : : idAnyE<strp>:
6037 : : /*empty*/ { $$ = nullptr; }
6038 : : | idAny { $$ = $1; }
6039 : : ;
6040 : :
6041 : : junkToSemiList<fl>:
6042 : : junkToSemi { $$ = CRELINE(); }
6043 : : | junkToSemiList junkToSemi { $$ = CRELINE(); }
6044 : : ;
6045 : :
6046 : : junkToSemi:
6047 : : BISONPRE_NOT(';',yD_SETUPHOLD,yENDMODULE,yENDSPECIFY,ySPECPARAM) { }
6048 : : | error { } // LCOV_EXCL_LINE
6049 : : ;
6050 : :
6051 : : //************************************************
6052 : : // IDs
6053 : :
6054 : : id<strp>:
6055 : : yaID__ETC { $$ = $1; $<fl>$ = $<fl>1; }
6056 : : | yaID__PATHPULSE { $$ = $1; $<fl>$ = $<fl>1; }
6057 : : | idRandomize { $$ = $1; $<fl>$ = $<fl>1; }
6058 : : ;
6059 : :
6060 : : idAny<strp>: // Any kind of identifier
6061 : : yaID__ETC { $$ = $1; $<fl>$ = $<fl>1; }
6062 : : | yaID__PATHPULSE { $$ = $1; $<fl>$ = $<fl>1; }
6063 : : | yaID__aINST { $$ = $1; $<fl>$ = $<fl>1; }
6064 : : | yaID__aTYPE { $$ = $1; $<fl>$ = $<fl>1; }
6065 : : | idRandomize { $$ = $1; $<fl>$ = $<fl>1; }
6066 : : ;
6067 : :
6068 : : idNotPathpulse<strp>: // Id excluding specparam PATHPULSE$, IEEE: part of specparam_assignment
6069 : : yaID__ETC { $$ = $1; $<fl>$ = $<fl>1; }
6070 : : | idRandomize { $$ = $1; $<fl>$ = $<fl>1; }
6071 : : ;
6072 : :
6073 : : idPathpulse<strp>: // Id for specparam PATHPULSE$, IEEE: part of pulse_control_specparam
6074 : : yaID__PATHPULSE { $$ = $1; $<fl>$ = $<fl>1; }
6075 : : ;
6076 : :
6077 : : idAnyAsParseRef<parseRefp>: // Any kind of identifier as a ParseRef
6078 : : idAny
6079 : : { $$ = new AstParseRef{$<fl>1, *$1}; }
6080 : : ;
6081 : :
6082 : :
6083 : : idInst<strp>: // IEEE: instance_identifier or similar with another id then '('
6084 : : // // See V3ParseImp::tokenPipeScanIdInst
6085 : : // // [^': '@' '.'] yaID/*module_id*/ [ '#' '('...')' ] yaID/*name_of_instance*/ [ '['...']' ] '(' ...
6086 : : // // [^':' @' '.'] yaID/*module_id*/ [ '#' id|etc ] yaID/*name_of_instance*/ [ '['...']' ] '(' ...
6087 : : yaID__aINST { $$ = $1; $<fl>$ = $<fl>1; }
6088 : : ;
6089 : :
6090 : : idType<strp>: // IEEE: class_identifier or other type identifier
6091 : : // // Used where reference is needed
6092 : : yaID__aTYPE { $$ = $1; $<fl>$ = $<fl>1; }
6093 : : ;
6094 : :
6095 : : idInstType<strp>: // type_identifier for functions which have a following id then '('
6096 : : yaID__aINST { $$ = $1; $<fl>$ = $<fl>1; }
6097 : : | yaID__aTYPE { $$ = $1; $<fl>$ = $<fl>1; }
6098 : : ;
6099 : :
6100 : : idCC<strp>: // IEEE: class/package then ::
6101 : : // lexer matches this: yaID_LEX [ '#' '(' ... ')' ] yP_COLONCOLON
6102 : : yaID__CC { $$ = $1; $<fl>$ = $<fl>1; }
6103 : : ;
6104 : :
6105 : : idRandomize<strp>: // Keyword as an identifier
6106 : : yRANDOMIZE { static string s = "randomize"; $$ = &s; $<fl>$ = $<fl>1; }
6107 : : ;
6108 : :
6109 : : idSVKwd<strp>: // Warn about non-forward compatible Verilog 2001 code
6110 : : // // yBIT, yBYTE won't work here as causes conflicts
6111 : : yDO
6112 : : { static string s = "do" ; $$ = &s; ERRSVKWD($1, *$$); $<fl>$ = $<fl>1; }
6113 : : | yFINAL
6114 : : { static string s = "final"; $$ = &s; ERRSVKWD($1, *$$); $<fl>$ = $<fl>1; }
6115 : : ;
6116 : :
6117 : : variable_lvalue<nodeExprp>: // IEEE: variable_lvalue or net_lvalue
6118 : : // // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist
6119 : : idClassSel { $$ = $1; }
6120 : : | '{' variable_lvalueConcList '}' { $$ = $2; }
6121 : : // // IEEE: [ assignment_pattern_expression_type ] assignment_pattern_variable_lvalue
6122 : : // // We allow more assignment_pattern_expression_types then strictly required
6123 : : //UNSUP data_type yP_TICKBRA variable_lvalueList '}' { UNSUP }
6124 : : //UNSUP idClassSel yP_TICKBRA variable_lvalueList '}' { UNSUP }
6125 : : //UNSUP /**/ yP_TICKBRA variable_lvalueList '}' { UNSUP }
6126 : : | streaming_concatenation { $$ = $1; }
6127 : : ;
6128 : :
6129 : : variable_lvalueConcList<nodeExprp>: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}'
6130 : : variable_lvalue { $$ = $1; }
6131 : : | variable_lvalueConcList ',' variable_lvalue { $$ = new AstConcat{$2, $1, $3}; }
6132 : : ;
6133 : :
6134 : : //UNSUPvariable_lvalueList<nodeExprp>: // IEEE: part of variable_lvalue: variable_lvalue { ',' variable_lvalue }
6135 : : //UNSUP variable_lvalue { $$ = $1; }
6136 : : //UNSUP | variable_lvalueList ',' variable_lvalue { $$ = addNextNull($1, $3); }
6137 : : //UNSUP ;
6138 : :
6139 : : idClass<nodeExprp>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
6140 : : idDotted { $$ = $1; }
6141 : : // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
6142 : : | yTHIS '.' idDotted
6143 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "this"}, $3}; }
6144 : : | ySUPER '.' idDotted
6145 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "super"}, $3}; }
6146 : : | yTHIS '.' ySUPER '.' idDotted
6147 : : { $$ = new AstDot{$4, false, new AstParseRef{$<fl>3, "super"}, $5}; }
6148 : : // // Expanded: package_scope idDottedSel
6149 : : | packageClassScope idDotted { $$ = new AstDot{$<fl>2, true, $1, $2}; }
6150 : : ;
6151 : :
6152 : : idClassSel<nodeExprp>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
6153 : : idDottedSel { $$ = $1; }
6154 : : // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
6155 : : | yTHIS '.' idDottedSel
6156 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "this"}, $3}; }
6157 : : | ySUPER '.' idDottedSel
6158 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "super"}, $3}; }
6159 : : | yTHIS '.' ySUPER '.' idDottedSel
6160 : : { $$ = new AstDot{$4, false, new AstParseRef{$<fl>3, "super"}, $5}; }
6161 : : // // Expanded: package_scope idDottedSel
6162 : : | packageClassScope idDottedSel { $$ = new AstDot{$<fl>2, true, $1, $2}; }
6163 : : ;
6164 : :
6165 : : idClassSelForeach<foreachHeaderp>:
6166 : : idDottedForeach { $$ = $1; }
6167 : : // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
6168 : : | yTHIS '.' idDottedForeach
6169 : : { $3->fromp(new AstDot{$2, false, new AstParseRef{$<fl>1, "this"}, $3->fromp()->unlinkFrBack()}); $$ = $3; }
6170 : : | ySUPER '.' idDottedForeach
6171 : : { $3->fromp(new AstDot{$2, false, new AstParseRef{$<fl>1, "super"}, $3->fromp()->unlinkFrBack()}); $$ = $3; }
6172 : : | yTHIS '.' ySUPER '.' idDottedForeach
6173 : : { $5->fromp(new AstDot{$4, false, new AstParseRef{$<fl>3, "super"}, $5->fromp()->unlinkFrBack()}); $$ = $5; }
6174 : : // // Expanded: package_scope idForeach
6175 : : | packageClassScope idDottedForeach
6176 : : { $2->fromp(new AstDot{$<fl>2, true, $1, $2->fromp()->unlinkFrBack()}); $$ = $2; }
6177 : : ;
6178 : :
6179 : :
6180 : : // Dotted identifier for typedef - must have at least one '.'
6181 : : // First component is plain id or id with array index, subsequent components can have arrays
6182 : : idDottedOrArrayed<nodeExprp>:
6183 : : id '.' idArrayed
6184 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, *$1, nullptr, nullptr}, $3}; }
6185 : : | idDottedOrArrayed '.' idArrayed
6186 : : { $$ = new AstDot{$2, false, $1, $3}; }
6187 : : ;
6188 : :
6189 : : idDotted<nodeExprp>:
6190 : : yD_ROOT '.' idDottedMore
6191 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "$root"}, $3}; }
6192 : : | idDottedMore { $$ = $1; }
6193 : : ;
6194 : :
6195 : : idDottedSel<nodeExprp>:
6196 : : yD_ROOT '.' idDottedSelMore
6197 : : { $$ = new AstDot{$2, false, new AstParseRef{$<fl>1, "$root"}, $3}; }
6198 : : | idDottedSelMore { $$ = $1; }
6199 : : ;
6200 : :
6201 : : idDottedForeach<foreachHeaderp>:
6202 : : yD_ROOT '.' idDottedMoreForeach
6203 : : { $3->fromp(new AstDot{$2, false, new AstParseRef{$<fl>1, "$root"}, $3->fromp()->unlinkFrBack()}); $$ = $3; }
6204 : : | idDottedMoreForeach { $$ = $1; }
6205 : : ;
6206 : :
6207 : : idDottedMore<nodeExprp>:
6208 : : parseRefBase { $$ = $1; }
6209 : : | idDottedMore '.' parseRefBase { $$ = new AstDot{$2, false, $1, $3}; }
6210 : : ;
6211 : :
6212 : : idDottedSelMore<nodeExprp>:
6213 : : idArrayed { $$ = $1; }
6214 : : | idDottedSelMore '.' idArrayed { $$ = new AstDot{$2, false, $1, $3}; }
6215 : : ;
6216 : :
6217 : : idDottedMoreForeach<foreachHeaderp>:
6218 : : idArrayedForeach { $$ = $1; }
6219 : : | idDottedSelMore '.' idArrayedForeach
6220 : : { $3->fromp(new AstDot{$2, false, $1, $3->fromp()->unlinkFrBack()}); $$ = $3; }
6221 : : ;
6222 : :
6223 : : // Single component of dotted path, maybe [#].
6224 : : // Due to lookahead constraints, we can't know if [:] or [+:] are valid (last dotted part),
6225 : : // we'll assume so and cleanup later.
6226 : : // id below includes:
6227 : : // enum_identifier
6228 : : idArrayed<nodeExprp>: // IEEE: id + select
6229 : : id
6230 : : { $$ = new AstParseRef{$<fl>1, *$1, nullptr, nullptr}; }
6231 : : // // IEEE: id + part_select_range/constant_part_select_range
6232 : : | idArrayed '[' expr ']' { $$ = new AstSelBit{$2, $1, $3}; } // Or AstArraySel, don't know yet.
6233 : : | idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract{$2, $1, $3, $5}; }
6234 : : // // IEEE: id + indexed_range/constant_indexed_range
6235 : : | idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus{$2, $1, $3, $5}; }
6236 : : | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus{$2, $1, $3, $5}; }
6237 : : ;
6238 : :
6239 : : idArrayedForeach<foreachHeaderp>: // IEEE: id + select (under foreach expression)
6240 : : parseRefBase // Malformed, but accept for better error reporting
6241 : : { $$ = new AstForeachHeader{$<fl>1, $1, nullptr}; }
6242 : : | idArrayed '[' expr ']'
6243 : : { $$ = new AstForeachHeader{$2, $1, $3}; }
6244 : : | idArrayed '[' ']'
6245 : : { $$ = new AstForeachHeader{$2, $1, new AstEmpty{$3}}; }
6246 : : | idArrayed '[' parseRefBase ',' loop_variables ']'
6247 : : { $$ = new AstForeachHeader{$2, $1, addNextNull(static_cast<AstNode*>($3), $5)}; }
6248 : : | idArrayed '[' ',' loop_variables ']'
6249 : : { $$ = new AstForeachHeader{$2, $1, addNextNull(static_cast<AstNode*>(new AstEmpty{$3}), $4)}; }
6250 : : ;
6251 : :
6252 : : // ParseRef without any dots or vectorizaion
6253 : : parseRefBase<parseRefp>:
6254 : : id { $$ = new AstParseRef{$<fl>1, *$1}; }
6255 : : ;
6256 : :
6257 : : // yaSTRING shouldn't be used directly, instead via an abstraction below
6258 : : str<strp>: // yaSTRING but with \{escapes} need decoded
6259 : : yaSTRING { $$ = PARSEP->newString(GRAMMARP->unquoteString($<fl>1, *$1)); }
6260 : : ;
6261 : :
6262 : : strAsInt<nodeExprp>:
6263 : : yaSTRING
6264 : : { // Numeric context, so IEEE 1800-2017 11.10.3 "" is a "\000"
6265 : : $$ = new AstConst{$<fl>1, AstConst::VerilogStringLiteral{}, GRAMMARP->unquoteString($<fl>1, *$1)}; }
6266 : : ;
6267 : :
6268 : : strAsIntIgnore<nodeExprp>: // strAsInt, but never matches for when expr shouldn't parse strings
6269 : : yaSTRING__IGNORE { $$ = nullptr; yyerror("Impossible token"); }
6270 : : ;
6271 : :
6272 : : startLabelE<strp>:
6273 : : /* empty */ { $$ = nullptr; $<fl>$ = nullptr; }
6274 : : | ':' idAny { $$ = $2; $<fl>$ = $<fl>2; }
6275 : : ;
6276 : :
6277 : : endLabelE<strp>:
6278 : : /* empty */ { $$ = nullptr; $<fl>$ = nullptr; }
6279 : : | ':' idAny { $$ = $2; $<fl>$ = $<fl>2; }
6280 : : | ':' yNEW__ETC { static string n = "new"; $$ = &n; $<fl>$ = $<fl>2; }
6281 : : ;
6282 : :
6283 : : //************************************************
6284 : : // Clocking
6285 : :
6286 : : clocking_declaration<nodep>: // IEEE: clocking_declaration
6287 : : yCLOCKING idAny clocking_event ';' clocking_itemListE yENDCLOCKING endLabelE
6288 : : { $$ = new AstClocking{$<fl>2, *$2, $3, $5, false, false}; }
6289 : : | yDEFAULT yCLOCKING clocking_event ';' clocking_itemListE yENDCLOCKING endLabelE
6290 : : { $$ = new AstClocking{$<fl>2, "", $3, $5, true, false}; }
6291 : : | yDEFAULT yCLOCKING idAny clocking_event ';' clocking_itemListE yENDCLOCKING endLabelE
6292 : : { $$ = new AstClocking{$<fl>3, *$3, $4, $6, true, false}; }
6293 : : | yGLOBAL__CLOCKING yCLOCKING clocking_event ';' clocking_itemListE yENDCLOCKING endLabelE
6294 : : { $$ = new AstClocking{$<fl>2, "", $3, $5, false, true}; }
6295 : : | yGLOBAL__CLOCKING yCLOCKING idAny clocking_event ';' clocking_itemListE yENDCLOCKING endLabelE
6296 : : { $$ = new AstClocking{$<fl>3, *$3, $4, $6, false, true}; }
6297 : : ;
6298 : :
6299 : : clocking_eventE<senItemp>: // IEEE: optional clocking_event
6300 : : /* empty */ { $$ = nullptr; }
6301 : : | clocking_event { $$ = $1; }
6302 : : ;
6303 : :
6304 : : clocking_event<senItemp>: // IEEE: clocking_event
6305 : : // // IEEE: '@' ps_identifier
6306 : : // // IEEE: '@' hierarchical_identifier
6307 : : //UNSUP: '@' idClassSel/*ps_identifier*/
6308 : : '@' id
6309 : : { $$ = new AstSenItem{$<fl>2, VEdgeType::ET_CHANGED,
6310 : : new AstParseRef{$<fl>2, *$2, nullptr, nullptr}}; }
6311 : : | '@' '(' event_expression ')' { $$ = $3; }
6312 : : ;
6313 : :
6314 : : clocking_itemListE<nodep>:
6315 : : /* empty */ { $$ = nullptr; }
6316 : : | clocking_itemList { $$ = $1; }
6317 : : ;
6318 : :
6319 : : clocking_itemList<nodep>: // IEEE: [ clocking_item ]
6320 : : clocking_item { $$ = $1; }
6321 : : | clocking_itemList clocking_item { if ($1) $$ = addNextNull($1, $2); }
6322 : : ;
6323 : :
6324 : : clocking_item<nodep>: // IEEE: clocking_item
6325 : : yDEFAULT yINPUT clocking_skew ';' { $$ = new AstClockingItem{$<fl>1, VDirection::INPUT, $3, nullptr}; }
6326 : : | yDEFAULT yOUTPUT clocking_skew ';' { $$ = new AstClockingItem{$<fl>1, VDirection::OUTPUT, $3, nullptr}; }
6327 : : | yDEFAULT yINPUT clocking_skew yOUTPUT clocking_skew ';'
6328 : : { $$ = new AstClockingItem{$<fl>1, VDirection::INPUT, $3, nullptr};
6329 : : $$->addNext(new AstClockingItem{$<fl>4, VDirection::OUTPUT, $5, nullptr}); }
6330 : : | yINPUT clocking_skewE list_of_clocking_decl_assign ';'
6331 : : { $$ = GRAMMARP->makeClockingItemList($<fl>1, VDirection::INPUT, $2, $3); }
6332 : : | yOUTPUT clocking_skewE list_of_clocking_decl_assign ';'
6333 : : { $$ = GRAMMARP->makeClockingItemList($<fl>1, VDirection::OUTPUT, $2, $3); }
6334 : : | yINPUT clocking_skewE yOUTPUT clocking_skewE list_of_clocking_decl_assign ';'
6335 : : { $$ = GRAMMARP->makeClockingItemList($<fl>1, VDirection::INPUT, $2, $5->cloneTree(true));
6336 : : $$->addNext(GRAMMARP->makeClockingItemList($<fl>3, VDirection::OUTPUT, $4, $5)); }
6337 : : | yINOUT list_of_clocking_decl_assign ';'
6338 : : { $$ = GRAMMARP->makeClockingItemList($<fl>1, VDirection::INPUT, nullptr, $2->cloneTree(true));
6339 : : $$->addNext(GRAMMARP->makeClockingItemList($<fl>1, VDirection::OUTPUT, nullptr, $2)); }
6340 : : | assertion_item_declaration
6341 : : { $$ = $1;
6342 : : for (AstNode* nodep = $1; nodep; nodep = nodep->nextp()) {
6343 : : if (!VN_IS(nodep, Sequence)) {
6344 : : $$ = nullptr;
6345 : : BBUNSUP(nodep, "Unsupported: assertion items in clocking blocks");
6346 : : DEL($1);
6347 : : break;
6348 : : }
6349 : : }
6350 : : }
6351 : : ;
6352 : :
6353 : : list_of_clocking_decl_assign<nodep>: // IEEE: list_of_clocking_decl_assign
6354 : : clocking_decl_assign { $$ = $1; }
6355 : : | list_of_clocking_decl_assign ',' clocking_decl_assign
6356 : : { $$ = addNextNull($1, $3); }
6357 : : ;
6358 : :
6359 : : clocking_decl_assign<nodep>: // IEEE: clocking_decl_assign
6360 : : idAnyAsParseRef/*new-signal_identifier*/ exprEqE
6361 : : { AstParseRef* const refp = $1;
6362 : : $$ = refp;
6363 : : if ($2) $$ = new AstAssign{$<fl>2, refp, $2}; }
6364 : : ;
6365 : :
6366 : : clocking_skewE<nodeExprp>: // IEEE: [clocking_skew]
6367 : : /* empty */ { $$ = nullptr; }
6368 : : | clocking_skew { $$ = $1; }
6369 : : ;
6370 : :
6371 : : clocking_skew<nodeExprp>: // IEEE: clocking_skew
6372 : : delay_control { $$ = $1->lhsp()->unlinkFrBack(); $1->deleteTree(); }
6373 : : | yPOSEDGE delay_controlE { $$ = nullptr;
6374 : : BBUNSUP($1, "Unsupported: clocking event edge override"); DEL($2); }
6375 : : | yNEGEDGE delay_controlE { $$ = nullptr;
6376 : : BBUNSUP($1, "Unsupported: clocking event edge override"); DEL($2); }
6377 : : | yEDGE delay_controlE { $$ = nullptr;
6378 : : BBUNSUP($1, "Unsupported: clocking event edge override"); DEL($2); }
6379 : : ;
6380 : :
6381 : : cycle_delay<delayp>: // IEEE: cycle_delay
6382 : : yP_POUNDPOUND yaINTNUM
6383 : : { $$ = new AstDelay{$<fl>1, new AstConst{$<fl>2, *$2}, true}; }
6384 : : | yP_POUNDPOUND idAnyAsParseRef
6385 : : { $$ = new AstDelay{$<fl>1, $2, true}; }
6386 : : | yP_POUNDPOUND '(' expr ')'
6387 : : { $$ = new AstDelay{$<fl>1, $3, true}; }
6388 : : ;
6389 : :
6390 : : //************************************************
6391 : : // Asserts
6392 : :
6393 : : assertion_item_declaration<nodep>: // ==IEEE: assertion_item_declaration
6394 : : property_declaration { $$ = $1; }
6395 : : | sequence_declaration { $$ = $1; }
6396 : : | let_declaration { $$ = $1; }
6397 : : ;
6398 : :
6399 : : assertion_item<nodep>: // ==IEEE: assertion_item
6400 : : concurrent_assertion_item { $$ = $1; }
6401 : : | deferred_immediate_assertion_item
6402 : : { $$ = $1 ? new AstAlways{$1->fileline(), VAlwaysKwd::ALWAYS_COMB, nullptr, $1} : nullptr; }
6403 : : ;
6404 : :
6405 : : deferred_immediate_assertion_item<nodep>: // ==IEEE: deferred_immediate_assertion_item
6406 : : deferred_immediate_assertion_statement { $$ = $1; }
6407 : : | id/*block_identifier*/ ':' deferred_immediate_assertion_statement
6408 : : { $$ = new AstBegin{$<fl>1, *$1, $3, true}; }
6409 : : ;
6410 : :
6411 : : procedural_assertion_statement<nodeStmtp>: // ==IEEE: procedural_assertion_statement
6412 : : concurrent_assertion_statement { $$ = $1; }
6413 : : | immediate_assertion_statement { $$ = $1; }
6414 : : // // IEEE: checker_instantiation
6415 : : // // Unlike modules, checkers are the only "id id (...)" form in statements.
6416 : : //UNSUP checker_instantiation { $$ = $1; }
6417 : : ;
6418 : :
6419 : : immediate_assertion_statement<nodeStmtp>: // ==IEEE: immediate_assertion_statement
6420 : : simple_immediate_assertion_statement { $$ = $1; }
6421 : : | deferred_immediate_assertion_statement { $$ = $1; }
6422 : : ;
6423 : :
6424 : : simple_immediate_assertion_statement<nodeStmtp>: // ==IEEE: simple_immediate_assertion_statement
6425 : : // // action_block expanded here, for compatibility with AstAssert
6426 : : assertOrAssume '(' expr ')' stmt %prec prLOWER_THAN_ELSE
6427 : : { $$ = new AstAssert{$<fl>1, $3, $5, nullptr, VAssertType::SIMPLE_IMMEDIATE, $1}; }
6428 : : | assertOrAssume '(' expr ')' yELSE stmt
6429 : : { $$ = new AstAssert{$<fl>1, $3, nullptr, $6, VAssertType::SIMPLE_IMMEDIATE, $1}; }
6430 : : | assertOrAssume '(' expr ')' stmt yELSE stmt
6431 : : { $$ = new AstAssert{$<fl>1, $3, $5, $7, VAssertType::SIMPLE_IMMEDIATE, $1}; }
6432 : : // // IEEE: simple_immediate_cover_statement
6433 : : | yCOVER '(' expr ')' stmt { $$ = new AstCover{$1, $3, $5, VAssertType::SIMPLE_IMMEDIATE}; }
6434 : : ;
6435 : :
6436 : : assertOrAssume<assertdirectivetypeen>:
6437 : : yASSERT { $$ = VAssertDirectiveType::ASSERT; }
6438 : : | yASSUME { $$ = VAssertDirectiveType::ASSUME; }
6439 : : ;
6440 : :
6441 : : final_zero<asserttypeen>: // IEEE: part of deferred_immediate_assertion_statement
6442 : : '#' yaINTNUM
6443 : : { if ($2->isNeqZero()) { $<fl>2->v3error("Deferred assertions must use '#0' (IEEE 1800-2023 16.4)"); }
6444 : : $$ = VAssertType::OBSERVED_DEFERRED_IMMEDIATE; }
6445 : : // // 1800-2012:
6446 : : | yFINAL { $$ = VAssertType::FINAL_DEFERRED_IMMEDIATE; }
6447 : : ;
6448 : :
6449 : : deferred_immediate_assertion_statement<nodeStmtp>: // ==IEEE: deferred_immediate_assertion_statement
6450 : : // // IEEE: deferred_immediate_assert_statement
6451 : : assertOrAssume final_zero '(' expr ')' stmt %prec prLOWER_THAN_ELSE
6452 : : { $$ = new AstAssert{$<fl>1, $4, $6, nullptr, $2, $1}; }
6453 : : | assertOrAssume final_zero '(' expr ')' yELSE stmt
6454 : : { $$ = new AstAssert{$<fl>1, $4, nullptr, $7, $2, $1}; }
6455 : : | assertOrAssume final_zero '(' expr ')' stmt yELSE stmt
6456 : : { $$ = new AstAssert{$<fl>1, $4, $6, $8, $2, $1}; }
6457 : : // // IEEE: deferred_immediate_cover_statement
6458 : : | yCOVER final_zero '(' expr ')' stmt { $$ = new AstCover{$1, $4, $6, $2}; }
6459 : : ;
6460 : :
6461 : : concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
6462 : : concurrent_assertion_statement { $$ = $1; }
6463 : : | id/*block_identifier*/ ':' concurrent_assertion_statement
6464 : : { $$ = new AstBegin{$<fl>1, *$1, $3, true}; }
6465 : : // // IEEE: checker_instantiation
6466 : : // // identical to module_instantiation; see etcInst
6467 : : ;
6468 : :
6469 : : concurrent_assertion_statement<nodeStmtp>: // ==IEEE: concurrent_assertion_statement
6470 : : // // IEEE: assert_property_statement
6471 : : // // IEEE: assume_property_statement
6472 : : // // action_block expanded here
6473 : : assertOrAssume yPROPERTY '(' property_spec ')' stmt %prec prLOWER_THAN_ELSE
6474 : : { $$ = new AstAssert{$<fl>1, $4, $6, nullptr, VAssertType::CONCURRENT, $1}; }
6475 : : | assertOrAssume yPROPERTY '(' property_spec ')' stmt yELSE stmt
6476 : : { $$ = new AstAssert{$<fl>1, $4, $6, $8, VAssertType::CONCURRENT, $1}; }
6477 : : | assertOrAssume yPROPERTY '(' property_spec ')' yELSE stmt
6478 : : { $$ = new AstAssert{$<fl>1, $4, nullptr, $7, VAssertType::CONCURRENT, $1}; }
6479 : : // // IEEE: cover_property_statement
6480 : : | yCOVER yPROPERTY '(' property_spec ')' stmt
6481 : : { $$ = new AstCover{$1, $4, $6, VAssertType::CONCURRENT}; }
6482 : : // // IEEE: cover_sequence_statement
6483 : : | yCOVER ySEQUENCE '(' sexpr ')' stmt
6484 : : { $$ = nullptr; BBCOVERIGN($2, "Ignoring unsupported: cover sequence"); DEL($4, $6); }
6485 : : // // IEEE: yCOVER ySEQUENCE '(' clocking_event sexpr ')' stmt
6486 : : // // sexpr already includes "clocking_event sexpr"
6487 : : | yCOVER ySEQUENCE '(' clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt
6488 : : { $$ = nullptr; BBCOVERIGN($2, "Ignoring unsupported: cover sequence"); DEL($4, $8, $10, $12);}
6489 : : | yCOVER ySEQUENCE '(' yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt
6490 : : { $$ = nullptr; BBCOVERIGN($2, "Ignoring unsupported: cover sequence"); DEL($7, $9, $11); }
6491 : : // // IEEE: restrict_property_statement
6492 : : | yRESTRICT yPROPERTY '(' property_spec ')' ';'
6493 : : { $$ = new AstRestrict{$1, $4}; }
6494 : : ;
6495 : :
6496 : : property_declaration<nodeFTaskp>: // ==IEEE: property_declaration
6497 : : property_declarationFront property_port_listE ';' property_declarationBody
6498 : : yENDPROPERTY endLabelE
6499 : : { $$ = $1;
6500 : : $$->addStmtsp($2);
6501 : : $$->addStmtsp($4);
6502 : : GRAMMARP->endLabel($<fl>6, $$, $6);
6503 : : GRAMMARP->m_insideProperty = false;
6504 : : GRAMMARP->m_typedPropertyPort = false; }
6505 : : ;
6506 : :
6507 : : property_declarationFront<nodeFTaskp>: // IEEE: part of property_declaration
6508 : : yPROPERTY idAny/*property_identifier*/
6509 : : { $$ = new AstProperty{$<fl>2, *$2, nullptr};
6510 : : GRAMMARP->m_insideProperty = true; }
6511 : : ;
6512 : :
6513 : : property_port_listE<nodep>: // IEEE: [ ( [ property_port_list ] ) ]
6514 : : /* empty */ { $$ = nullptr; }
6515 : : | '(' ')' { $$ = nullptr; }
6516 : : | '(' property_port_list ')' { $$ = $2; }
6517 : : ;
6518 : :
6519 : : property_port_list<nodep>: // ==IEEE: property_port_list
6520 : : property_port_item { $$ = $1; }
6521 : : | property_port_list ',' property_port_item { $$ = addNextNull($1, $3); }
6522 : : ;
6523 : :
6524 : : property_port_item<nodep>: // IEEE: property_port_item/sequence_port_item
6525 : : // // Merged in sequence_port_item
6526 : : // // IEEE: property_lvar_port_direction ::= yINPUT
6527 : : // // prop IEEE: [ yLOCAL [ yINPUT ] ] property_formal_type
6528 : : // // id {variable_dimension} [ '=' property_actual_arg ]
6529 : : // // seq IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
6530 : : // // id {variable_dimension} [ '=' sequence_actual_arg ]
6531 : : property_port_itemFront property_port_itemAssignment { $$ = $2; }
6532 : : ;
6533 : :
6534 : : property_port_itemFront: // IEEE: part of property_port_item/sequence_port_item
6535 : : property_port_itemDirE property_formal_typeNoDt
6536 : : { VARDTYPE($2); }
6537 : : // // data_type_or_implicit
6538 : : | property_port_itemDirE data_type
6539 : : { VARDTYPE($2); GRAMMARP->m_typedPropertyPort = true; }
6540 : : | property_port_itemDirE yVAR data_type
6541 : : { VARDTYPE($3); GRAMMARP->m_typedPropertyPort = true; }
6542 : : | property_port_itemDirE yVAR implicit_typeE
6543 : : { VARDTYPE($3); }
6544 : : | property_port_itemDirE implicit_typeE
6545 : : { VARDTYPE($2); }
6546 : : ;
6547 : :
6548 : : property_port_itemAssignment<nodep>: // IEEE: part of property_port_item/sequence_port_item
6549 : : id variable_dimensionListE
6550 : : { $$ = VARDONEA($<fl>1, *$1, $2, nullptr); }
6551 : : | id variable_dimensionListE '=' property_actual_arg
6552 : : { $$ = VARDONEA($<fl>1, *$1, $2, $4);
6553 : : BBUNSUP($3, "Unsupported: property variable default value"); }
6554 : : ;
6555 : :
6556 : : property_port_itemDirE:
6557 : : /* empty */
6558 : : { VARIO(INPUT); }
6559 : : | yLOCAL__ETC
6560 : : { VARIO(INPUT);
6561 : : BBUNSUP($1, "Unsupported: property port 'local'"); }
6562 : : | yLOCAL__ETC yINPUT
6563 : : { VARIO(INPUT);
6564 : : BBUNSUP($1, "Unsupported: property port 'local'"); }
6565 : : ;
6566 : :
6567 : : property_declarationBody<nodep>: // IEEE: part of property_declaration
6568 : : assertion_variable_declarationList property_spec
6569 : : { $$ = addNextNull($1, $2); }
6570 : : | assertion_variable_declarationList property_spec ';'
6571 : : { $$ = addNextNull($1, $2); }
6572 : : // // IEEE-2012: Incorrectly has yCOVER ySEQUENCE then property_spec here.
6573 : : // // Fixed in IEEE 1800-2017
6574 : : | property_spec { $$ = $1; }
6575 : : | property_spec ';' { $$ = $1; }
6576 : : ;
6577 : :
6578 : : assertion_variable_declarationList<nodep>: // IEEE: part of assertion_variable_declaration
6579 : : assertion_variable_declaration { $$ = $1; }
6580 : : | assertion_variable_declarationList assertion_variable_declaration
6581 : : { $$ = addNextNull($1, $2); }
6582 : : ;
6583 : :
6584 : : sequence_declaration<nodeFTaskp>: // ==IEEE: sequence_declaration
6585 : : sequence_declarationFront sequence_port_listE ';' sequence_declarationBody
6586 : : /*cont*/ yENDSEQUENCE endLabelE
6587 : : { $$ = $1;
6588 : : $$->addStmtsp($2);
6589 : : $$->addStmtsp($4);
6590 : : GRAMMARP->endLabel($<fl>6, $$, $6);
6591 : : // Sequence declarations are allowed; they are inlined by V3AssertPre.
6592 : : // Sequences in unsupported contexts are reported by assertPreAll
6593 : : // after inlining.
6594 : : }
6595 : : ;
6596 : :
6597 : : sequence_declarationFront<nodeFTaskp>: // IEEE: part of sequence_declaration
6598 : : ySEQUENCE idAny/*new_sequence*/
6599 : : { $$ = new AstSequence{$<fl>2, *$2, nullptr}; }
6600 : : ;
6601 : :
6602 : : sequence_port_listE<nodep>: // IEEE: [ ( [ sequence_port_list ] ) ]
6603 : : // // IEEE: sequence_lvar_port_direction ::= yINPUT | yINOUT | yOUTPUT
6604 : : // // IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
6605 : : // // id {variable_dimension} [ '=' sequence_actual_arg ]
6606 : : // // All this is almost identically the same as a property.
6607 : : // // Difference is only yINOUT/yOUTPUT (which might be added to 1800-2012)
6608 : : // // and yPROPERTY. So save some work.
6609 : : property_port_listE { $$ = $1; }
6610 : : ;
6611 : :
6612 : : property_formal_typeNoDt<nodeDTypep>: // IEEE: property_formal_type (w/o implicit)
6613 : : sequence_formal_typeNoDt { $$ = $1; }
6614 : : | yPROPERTY
6615 : : { $$ = nullptr; GRAMMARP->m_typedPropertyPort = false;
6616 : : BBUNSUP($1, "Unsupported: property argument data type"); }
6617 : : ;
6618 : :
6619 : : sequence_formal_typeNoDt<nodeDTypep>: // ==IEEE: sequence_formal_type (w/o data_type_or_implicit)
6620 : : // IEEE: data_type_or_implicit
6621 : : // implicit expanded where used
6622 : : ySEQUENCE
6623 : : { $$ = nullptr; GRAMMARP->m_typedPropertyPort = false;
6624 : : BBUNSUP($1, "Unsupported: sequence argument data type"); }
6625 : : // IEEE-2009: yEVENT
6626 : : // already part of data_type. Removed in 1800-2012.
6627 : : | yUNTYPED
6628 : : { $$ = nullptr; GRAMMARP->m_typedPropertyPort = false; }
6629 : : ;
6630 : :
6631 : : sequence_declarationBody<nodep>: // IEEE: part of sequence_declaration
6632 : : // // 1800-2012 makes ';' optional
6633 : : assertion_variable_declarationList sexpr { $$ = addNextNull($1, $2); }
6634 : : | assertion_variable_declarationList sexpr ';' { $$ = addNextNull($1, $2); }
6635 : : | sexpr { $$ = $1; }
6636 : : | sexpr ';' { $$ = $1; }
6637 : : ;
6638 : :
6639 : : property_spec<propSpecp>: // IEEE: property_spec
6640 : : //UNSUP: This rule has been super-specialized to what is supported now
6641 : : //UNSUP remove below
6642 : : '@' '(' senitem ')' yDISABLE yIFF '(' expr ')' pexpr
6643 : : { $$ = new AstPropSpec{$1, $3, $8, $10}; }
6644 : : | '@' '(' senitem ')' pexpr
6645 : : { $$ = new AstPropSpec{$1, $3, nullptr, $5}; }
6646 : : | '@' senitemVar pexpr
6647 : : { $$ = new AstPropSpec{$1, $2, nullptr, $3}; }
6648 : : // // Disable applied after the event occurs,
6649 : : // // so no existing AST can represent this
6650 : : | yDISABLE yIFF '(' expr ')' '@' '(' senitemEdge ')' pexpr
6651 : : { $$ = new AstPropSpec{$1, $8, nullptr, new AstLogOr{$1, $4, $10}};
6652 : : BBUNSUP($<fl>1, "Unsupported: property '(disable iff (...) @ (...)'\n"
6653 : : + $<fl>1->warnMore()
6654 : : + "... Suggest use property '(@(...) disable iff (...))'"); }
6655 : : //UNSUP remove above
6656 : : | yDISABLE yIFF '(' expr ')' pexpr { $$ = new AstPropSpec{$4->fileline(), nullptr, $4, $6}; }
6657 : : | pexpr { $$ = new AstPropSpec{$1->fileline(), nullptr, nullptr, $1}; }
6658 : : ;
6659 : :
6660 : : property_exprCaseIf<nodeExprp>: // IEEE: part of property_expr for if/case
6661 : : yCASE '(' expr/*expression_or_dist*/ ')' property_case_itemList yENDCASE
6662 : : { $$ = new AstConst{$1, AstConst::BitFalse{}};
6663 : : BBUNSUP($<fl>1, "Unsupported: property case expression");
6664 : : DEL($3, $5); }
6665 : : | yCASE '(' expr/*expression_or_dist*/ ')' yENDCASE
6666 : : { $$ = new AstConst{$1, AstConst::BitFalse{}};
6667 : : BBUNSUP($<fl>1, "Unsupported: property case expression");
6668 : : DEL($3); }
6669 : : | yIF '(' expr/*expression_or_dist*/ ')' pexpr %prec prLOWER_THAN_ELSE
6670 : : { $$ = $5; BBUNSUP($<fl>1, "Unsupported: property case expression"); DEL($3); }
6671 : : | yIF '(' expr/*expression_or_dist*/ ')' pexpr yELSE pexpr
6672 : : { $$ = $5; BBUNSUP($<fl>1, "Unsupported: property case expression"); DEL($3, $7); }
6673 : : ;
6674 : :
6675 : : property_case_itemList<caseItemp>: // IEEE: {property_case_item}
6676 : : property_case_item { $$ = $1; }
6677 : : | property_case_itemList ',' property_case_item { $$ = addNextNull($1, $3); }
6678 : : ;
6679 : :
6680 : : property_case_item<caseItemp>: // ==IEEE: property_case_item
6681 : : // // IEEE: expression_or_dist { ',' expression_or_dist } ':' property_statement
6682 : : // // IEEE 1800-2012 changed from property_statement to property_expr
6683 : : // // IEEE 1800-2017 changed to require the semicolon
6684 : : caseCondList ':' pexpr { $$ = new AstCaseItem{$2, $1, $3}; }
6685 : : | caseCondList ':' pexpr ';' { $$ = new AstCaseItem{$2, $1, $3}; }
6686 : : | yDEFAULT pexpr { $$ = new AstCaseItem{$1, nullptr, $2}; }
6687 : : | yDEFAULT ':' pexpr ';' { $$ = new AstCaseItem{$1, nullptr, $3}; }
6688 : : ;
6689 : :
6690 : : //UNSUPpev_expr<nodep>: // IEEE: property_actual_arg | expr
6691 : : //UNSUP // // which expands to pexpr | event_expression
6692 : : //UNSUP // // Used in port and function calls, when we can't know yet if something
6693 : : //UNSUP // // is a function/sequence/property or instance/checker pin.
6694 : : //UNSUP //
6695 : : //UNSUP // // '(' pev_expr ')'
6696 : : //UNSUP // // Already in pexpr
6697 : : //UNSUP // // IEEE: event_expression ',' event_expression
6698 : : //UNSUP // // ','s are legal in event_expressions, but parens required to avoid conflict with port-sep-,
6699 : : //UNSUP // // IEEE: event_expression yOR event_expression
6700 : : //UNSUP // // Already in pexpr - needs removal there
6701 : : //UNSUP // // IEEE: event_expression yIFF expr
6702 : : //UNSUP // // Already in pexpr - needs removal there
6703 : : //UNSUP //
6704 : : //UNSUP senitemEdge { $$ = $1; }
6705 : : //UNSUP //
6706 : : //UNSUP //============= pexpr rules copied for pev_expr
6707 : : //UNSUP | BISONPRE_COPY_ONCE(pexpr,{s/~o~p/pev_/g; }) // {copied}
6708 : : //UNSUP //
6709 : : //UNSUP //============= sexpr rules copied for pev_expr
6710 : : //UNSUP | BISONPRE_COPY_ONCE(sexpr,{s/~p~s/pev_/g; }) // {copied}
6711 : : //UNSUP //
6712 : : //UNSUP //============= expr rules copied for pev_expr
6713 : : //UNSUP | BISONPRE_COPY_ONCE(expr,{s/~l~/pev_/g; s/~p~/pev_/g; s/~noPar__IGNORE~'.'/yP_PAR__IGNORE /g; }) // {copied}
6714 : : //UNSUP ;
6715 : :
6716 : : pexpr<nodeExprp>: // IEEE: property_expr (The name pexpr is important as regexps just add an "p" to expr.)
6717 : : //
6718 : : // // IEEE: sequence_expr
6719 : : // // Expanded below
6720 : : //
6721 : : // // IEEE: '(' pexpr ')'
6722 : : // // Expanded below
6723 : : //
6724 : : yNOT pexpr
6725 : : { $$ = new AstLogNot{$1, $2}; }
6726 : : | ySTRONG '(' sexpr ')'
6727 : : { $$ = $3; BBUNSUP($2, "Unsupported: strong (in property expression)"); }
6728 : : | yWEAK '(' sexpr ')'
6729 : : { $$ = $3; BBUNSUP($2, "Unsupported: weak (in property expression)"); }
6730 : : // // IEEE: pexpr yOR pexpr
6731 : : // // IEEE: pexpr yAND pexpr
6732 : : // // Under ~p~sexpr and/or ~p~sexpr
6733 : : //
6734 : : // // IEEE: "sequence_expr yP_ORMINUSGT pexpr"
6735 : : // // Instead we use pexpr to prevent conflicts
6736 : : | ~o~pexpr yP_ORMINUSGT pexpr { $$ = new AstImplication{$2, $1, $3, true}; }
6737 : : | ~o~pexpr yP_OREQGT pexpr { $$ = new AstImplication{$2, $1, $3, false}; }
6738 : : //
6739 : : // // IEEE-2009: property_statement
6740 : : // // IEEE-2012: yIF and yCASE
6741 : : | property_exprCaseIf { $$ = $1; }
6742 : : //
6743 : : | ~o~pexpr/*sexpr*/ yP_POUNDMINUSPD pexpr
6744 : : { $$ = $1; BBUNSUP($2, "Unsupported: #-# (in property expression)"); DEL($3); }
6745 : : | ~o~pexpr/*sexpr*/ yP_POUNDEQPD pexpr
6746 : : { $$ = $1; BBUNSUP($2, "Unsupported: #=# (in property expression)"); DEL($3); }
6747 : : | yNEXTTIME pexpr
6748 : : { $$ = $2; BBUNSUP($1, "Unsupported: nexttime (in property expression)"); }
6749 : : | yS_NEXTTIME pexpr
6750 : : { $$ = $2; BBUNSUP($1, "Unsupported: s_nexttime (in property expression)"); }
6751 : : | yNEXTTIME '[' constExpr ']' pexpr %prec yNEXTTIME
6752 : : { $$ = $5; BBUNSUP($1, "Unsupported: nexttime[] (in property expression)"); DEL($3); }
6753 : : | yS_NEXTTIME '[' constExpr ']' pexpr %prec yS_NEXTTIME
6754 : : { $$ = $5; BBUNSUP($1, "Unsupported: s_nexttime[] (in property expression)"); DEL($3); }
6755 : : | yALWAYS pexpr
6756 : : { $$ = $2; }
6757 : : | yALWAYS '[' constExpr ':' constExpr ']' pexpr %prec yALWAYS
6758 : : { $$ = new AstPropAlways{$1, $7, $3, $5, false}; }
6759 : : | yS_ALWAYS '[' constExpr ':' constExpr ']' pexpr %prec yS_ALWAYS
6760 : : { $$ = new AstPropAlways{$1, $7, $3, $5, true}; }
6761 : : | yS_ALWAYS pexpr
6762 : : { $$ = new AstPropAlways{$1, $2, new AstUnbounded{$1}, new AstUnbounded{$1}, true}; }
6763 : : | yS_EVENTUALLY pexpr
6764 : : {
6765 : 28 : $$ = new AstSEventually{$1, $2};
6766 : 84 : PARSEP->importIfInStd($1, "process", true);
6767 : : }
6768 : : | yS_EVENTUALLY anyrange pexpr %prec yS_EVENTUALLY
6769 : : { $$ = $3; BBUNSUP($1, "Unsupported: s_eventually[] (in property expression)"); DEL($2); }
6770 : : | yEVENTUALLY anyrange pexpr %prec yS_EVENTUALLY
6771 : : { $$ = $3; BBUNSUP($1, "Unsupported: eventually[] (in property expression)"); DEL($2); }
6772 : : | ~o~pexpr yUNTIL pexpr
6773 : : { $$ = new AstUntil{$2, $1, $3, false, false}; }
6774 : : | ~o~pexpr yS_UNTIL pexpr
6775 : : { $$ = new AstUntil{$2, $1, $3, true, false}; }
6776 : : | ~o~pexpr yUNTIL_WITH pexpr
6777 : : { $$ = new AstUntil{$2, $1, $3, false, true}; }
6778 : : | ~o~pexpr yS_UNTIL_WITH pexpr
6779 : : { $$ = new AstUntil{$2, $1, $3, true, true}; }
6780 : : | ~o~pexpr yIMPLIES pexpr
6781 : : { $$ = new AstLogOr{$2, new AstLogNot{$2, $1}, $3}; }
6782 : : // // yIFF also used by event_expression
6783 : : | ~o~pexpr yIFF pexpr
6784 : : { $$ = new AstLogEq{$2, $1, $3}; }
6785 : : | yACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec yACCEPT_ON
6786 : : { $$ = $5; BBUNSUP($2, "Unsupported: accept_on (in property expression)"); DEL($3); }
6787 : : | yREJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec yREJECT_ON
6788 : : { $$ = $5; BBUNSUP($2, "Unsupported: reject_on (in property expression)"); DEL($3); }
6789 : : | ySYNC_ACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_ACCEPT_ON
6790 : : { $$ = $5; BBUNSUP($2, "Unsupported: sync_accept_on (in property expression)"); DEL($3); }
6791 : : | ySYNC_REJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_REJECT_ON
6792 : : { $$ = $5; BBUNSUP($2, "Unsupported: sync_reject_on (in property expression)"); DEL($3); }
6793 : : //
6794 : : // // IEEE: "property_instance"
6795 : : // // Looks just like a function/method call
6796 : : //
6797 : : // // Note "clocking_event pexpr" overlaps
6798 : : // // property_statement_spec: clocking_event property_statement
6799 : : //
6800 : : // // Include property_specDisable to match property_spec rule
6801 : : //UNSUP clocking_event ~p~sexpr %prec prSEQ_CLOCKING
6802 : : //UNSUP { $$ = $2; BBUNSUP($2, "Unsupported: clocking event (in sequence expression)"); DEL($1); }
6803 : : //
6804 : : //============= sexpr rules copied for property_expr
6805 : : | BISONPRE_COPY_ONCE(sexpr,{s/~p~s/p/g; }) // {copied}
6806 : : //
6807 : : //============= expr rules copied for property_expr
6808 : : | BISONPRE_COPY_ONCE(expr,{s/~l~/p/g; s/~p~/p/g; s/~noPar__IGNORE~'.'/yP_PAR__IGNORE /g; }) // {copied}
6809 : : ;
6810 : :
6811 : : sexpr<nodeExprp>: // ==IEEE: sequence_expr (The name sexpr is important as regexps just add an "s" to expr.)
6812 : : // // ********* RULES COPIED IN sequence_exprProp
6813 : : // // For precedence, see IEEE 17.7.1
6814 : : //
6815 : : // // IEEE: "cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
6816 : : // // IEEE: "sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
6817 : : // // Both rules basically mean we can repeat sequences, so make it simpler:
6818 : : cycle_delay_range ~p~sexpr %prec yP_POUNDPOUND
6819 : : { $$ = new AstSExpr{$<fl>1, $1, $2}; }
6820 : : | ~p~sexpr cycle_delay_range sexpr %prec prPOUNDPOUND_MULTI
6821 : : { $$ = new AstSExpr{$<fl>2, $1, $2, $3}; }
6822 : : //
6823 : : // // IEEE: expression_or_dist [ boolean_abbrev ]
6824 : : // // Note expression_or_dist includes "expr"!
6825 : : // // sexpr/*sexpression_or_dist*/ --- Hardcoded below
6826 : : // // Consecutive repetition (IEEE 1800-2023 16.9.2)
6827 : : // // [*N] exact count
6828 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRASTAR constExpr ']'
6829 : : { $$ = new AstSConsRep{$<fl>2, $1, $3}; }
6830 : : // // [*N:M] range
6831 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRASTAR constExpr ':' constExpr ']'
6832 : : { $$ = new AstSConsRep{$<fl>2, $1, $3, $5, false}; } // LCOV_EXCL_LINE
6833 : : // // [+] = [*1:$]
6834 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRAPLUSKET
6835 : : { $$ = new AstSConsRep{$<fl>2, $1,
6836 : : new AstConst{$<fl>2, 1u}, nullptr, true}; }
6837 : : // // [*] = [*0:$]
6838 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRASTAR ']'
6839 : : { $$ = new AstSConsRep{$<fl>2, $1,
6840 : : new AstConst{$<fl>2, 0u}, nullptr, true}; }
6841 : : // // IEEE: goto_repetition (single count form)
6842 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRAMINUSGT constExpr ']'
6843 : : { $$ = new AstSGotoRep{$<fl>2, $1, $3}; }
6844 : : // // IEEE: goto_repetition (range form -- unsupported)
6845 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRAMINUSGT constExpr ':' constExpr ']'
6846 : : { $$ = $1; BBUNSUP($<fl>2, "Unsupported: [-> range goto repetition"); DEL($3); DEL($5); }
6847 : : // // IEEE: nonconsecutive_repetition (single count form)
6848 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRAEQ constExpr ']'
6849 : : { $$ = new AstSNonConsRep{$<fl>2, $1, $3}; }
6850 : : // // IEEE: nonconsecutive_repetition (range form -- unsupported)
6851 : : | ~p~sexpr/*sexpression_or_dist*/ yP_BRAEQ constExpr ':' constExpr ']'
6852 : : { $$ = $1; BBUNSUP($<fl>2, "Unsupported: [= range nonconsecutive repetition"); DEL($3); DEL($5); }
6853 : : // // All boolean_abbrev forms are now handled above:
6854 : : // // [*N], [*N:M], [+], [*] via AstSConsRep
6855 : : // // [->N], [->M:N] via AstSGotoRep
6856 : : // // [=N], [=M:N] via AstSNonConsRep
6857 : : //
6858 : : // // IEEE: "sequence_instance [ sequence_abbrev ]"
6859 : : // // version without sequence_abbrev looks just like normal function call
6860 : : // // version w/sequence_abbrev matches above;
6861 : : // // expression_or_dist:expr:func boolean_abbrev:sequence_abbrev
6862 : : //
6863 : : // // IEEE: '(' expression_or_dist {',' sequence_match_item } ')' [ boolean_abbrev ]
6864 : : // // IEEE: '(' sexpr {',' sequence_match_item } ')' [ sequence_abbrev ]
6865 : : // // As sequence_expr includes expression_or_dist, and boolean_abbrev includes sequence_abbrev:
6866 : : // // '(' sequence_expr {',' sequence_match_item } ')' [ boolean_abbrev ]
6867 : : // // "'(' sexpr ')' boolean_abbrev" matches "[sexpr:'(' expr ')'] boolean_abbrev" so we can drop it
6868 : : | '(' ~p~sexpr ')' { $$ = $2; }
6869 : : | '(' ~p~sexpr ',' sequence_match_itemList ')'
6870 : : { $$ = new AstExprStmt{$3, $4, $2}; }
6871 : : //
6872 : : // // AND/OR are between pexprs OR sexprs (IEEE 1800-2023 16.9.2, 16.11.2)
6873 : : // // For expression-level (boolean) operands, AstLogAnd/AstLogOr is correct.
6874 : : // // For temporal sequence operands (containing ##), the downstream
6875 : : // // V3Width "Implication with sequence expression" check will catch them.
6876 : : | ~p~sexpr yAND ~p~sexpr
6877 : : { $$ = new AstSAnd{$2, $1, $3}; }
6878 : : | ~p~sexpr yOR ~p~sexpr
6879 : : { $$ = new AstSOr{$2, $1, $3}; }
6880 : : // // Intersect always has an sexpr rhs
6881 : : | ~p~sexpr yINTERSECT sexpr
6882 : : { $$ = new AstSIntersect{$2, $1, $3}; }
6883 : : //
6884 : : | yFIRST_MATCH '(' sexpr ')'
6885 : : { $$ = $3; } // IEEE 16.9.8: no-op in deterministic DFA model
6886 : : | yFIRST_MATCH '(' sexpr ',' sequence_match_itemList ')'
6887 : : { $$ = $3; BBUNSUP($1, "Unsupported: first_match with sequence_match_items"); DEL($5); }
6888 : : | ~p~sexpr/*sexpression_or_dist*/ yTHROUGHOUT sexpr
6889 : : { $$ = new AstSThroughout{$2, $1, $3}; }
6890 : : // // Below pexpr's are really sequence_expr, but avoid conflict
6891 : : // // IEEE: sexpr yWITHIN sexpr
6892 : : | ~p~sexpr yWITHIN sexpr
6893 : : { $$ = new AstSWithin{$2, $1, $3}; }
6894 : : // // Note concurrent_assertion had duplicate rule for below
6895 : : //UNSUP clocking_event ~p~sexpr %prec prSEQ_CLOCKING { }
6896 : : //
6897 : : //============= expr rules copied for sequence_expr
6898 : : | BISONPRE_COPY_ONCE(expr,{s/~l~/s/g; s/~p~/s/g; s/~noPar__IGNORE~'.'/yP_PAR__IGNORE /g; }) // {copied}
6899 : : ;
6900 : :
6901 : : cycle_delay_range<delayp>: // IEEE: ==cycle_delay_range
6902 : : // // These three terms in 1800-2005 ONLY
6903 : : yP_POUNDPOUND intnumAsConst
6904 : : { $$ = new AstDelay{$1, $2, true}; }
6905 : : | yP_POUNDPOUND idAny
6906 : : { $$ = new AstDelay{$1, new AstParseRef{$<fl>2, *$2}, true}; }
6907 : : | yP_POUNDPOUND '(' constExpr ')'
6908 : : { $$ = new AstDelay{$1, $3, true}; }
6909 : : // // In 1800-2009 ONLY:
6910 : : // // IEEE: yP_POUNDPOUND constant_primary
6911 : : // // UNSUP: This causes a big grammar ambiguity
6912 : : // // as ()'s mismatch between primary and the following statement
6913 : : // // the sv-ac committee has been asked to clarify (Mantis 1901)
6914 : : | yP_POUNDPOUND '[' constExpr ':' constExpr ']'
6915 : : { $$ = new AstDelay{$1, $3, true};
6916 : : $$->rhsp($5); }
6917 : : | yP_POUNDPOUND yP_BRASTAR ']'
6918 : : { $$ = new AstDelay{$1, new AstConst{$1, 0}, true};
6919 : : $$->rhsp(new AstUnbounded{$1}); }
6920 : : | yP_POUNDPOUND yP_BRAPLUSKET
6921 : : { $$ = new AstDelay{$1, new AstConst{$1, 1}, true};
6922 : : $$->rhsp(new AstUnbounded{$1}); }
6923 : : ;
6924 : :
6925 : : sequence_match_itemList<nodep>: // IEEE: [sequence_match_item] part of sequence_expr
6926 : : sequence_match_item { $$ = $1; }
6927 : : | sequence_match_itemList ',' sequence_match_item { $$ = addNextNull($1, $3); }
6928 : : ;
6929 : :
6930 : : sequence_match_item<nodep>: // ==IEEE: sequence_match_item
6931 : : // // IEEE says: operator_assignment
6932 : : // // IEEE says: inc_or_dec_expression
6933 : : // // IEEE says: subroutine_call
6934 : : // // This is the same list as...
6935 : : for_step_assignment { $$ = $1; }
6936 : : ;
6937 : :
6938 : : // boolean_abbrev -- all forms now handled directly in sexpr rule:
6939 : : // // IEEE: consecutive_repetition -- [*N], [*N:M], [+], [*] via AstSConsRep
6940 : : // // IEEE: goto_repetition -- [->N] via AstSGotoRep, [->M:N] unsupported
6941 : : // // IEEE: nonconsecutive_repetition -- [=N] via AstSNonConsRep, [=M:N] unsupported
6942 : :
6943 : : //************************************************
6944 : : // Covergroup
6945 : :
6946 : : covergroup_declaration<nodep>: // ==IEEE: covergroup_declaration
6947 : : yCOVERGROUP idAny cgPortListE coverage_eventE ';'
6948 : : /*cont*/ coverage_spec_or_optionListE
6949 : : /*cont*/ yENDGROUP endLabelE
6950 : : { AstClass *cgClassp = new AstClass{$<fl>2, *$2, PARSEP->libname()};
6951 : : cgClassp->isCovergroup(true);
6952 : : AstFunc* const newp = new AstFunc{$<fl>1, "new", nullptr, nullptr};
6953 : : newp->fileline()->warnOff(V3ErrorCode::NORETURN, true);
6954 : : newp->classMethod(true);
6955 : : newp->isConstructor(true);
6956 : : newp->dtypep(cgClassp->dtypep());
6957 : : newp->addStmtsp($3);
6958 : : newp->addStmtsp($6);
6959 : : cgClassp->addMembersp(newp);
6960 : : GRAMMARP->createCoverGroupMethods(cgClassp, $4);
6961 : :
6962 : : $$ = cgClassp;
6963 : : GRAMMARP->endLabel($<fl>8, $$, $8);
6964 : : BBCOVERIGN($<fl>1, "Ignoring unsupported: covergroup");
6965 : : }
6966 : : | yCOVERGROUP yEXTENDS idAny ';'
6967 : : /*cont*/ coverage_spec_or_optionListE
6968 : : /*cont*/ yENDGROUP endLabelE
6969 : : { AstClass *cgClassp = new AstClass{$<fl>3, *$3, PARSEP->libname()};
6970 : : cgClassp->isCovergroup(true);
6971 : : AstFunc* const newp = new AstFunc{$<fl>1, "new", nullptr, nullptr};
6972 : : newp->fileline()->warnOff(V3ErrorCode::NORETURN, true);
6973 : : newp->classMethod(true);
6974 : : newp->isConstructor(true);
6975 : : newp->dtypep(cgClassp->dtypep());
6976 : : newp->addStmtsp($5);
6977 : : cgClassp->addMembersp(newp);
6978 : : GRAMMARP->createCoverGroupMethods(cgClassp, nullptr);
6979 : :
6980 : : $$ = cgClassp;
6981 : : GRAMMARP->endLabel($<fl>7, $$, $7);
6982 : : BBCOVERIGN($<fl>1, "Ignoring unsupported: covergroup");
6983 : : }
6984 : : ;
6985 : :
6986 : : cgPortListE<nodep>:
6987 : : /*empty*/ { $$ = nullptr; }
6988 : : | '(' tf_port_listE ')' { $$ = $2; }
6989 : : ;
6990 : :
6991 : : cgexpr<nodeExprp>: // IEEE-2012: covergroup_expression, before that just expression
6992 : : expr { $$ = $1; }
6993 : : ;
6994 : :
6995 : : coverage_spec_or_optionListE<nodep>: // IEEE: [{coverage_spec_or_option}]
6996 : : /* empty */ { $$ = nullptr; }
6997 : : | coverage_spec_or_optionList { $$ = $1; }
6998 : : ;
6999 : :
7000 : : coverage_spec_or_optionList<nodep>: // IEEE: {coverage_spec_or_option}
7001 : : coverage_spec_or_option { $$ = $1; }
7002 : : | coverage_spec_or_optionList coverage_spec_or_option { $$ = addNextNull($1, $2); }
7003 : : ;
7004 : :
7005 : : coverage_spec_or_option<nodep>: // ==IEEE: coverage_spec_or_option
7006 : : // // IEEE: coverage_spec
7007 : : cover_point { $$ = $1; }
7008 : : | cover_cross { $$ = $1; }
7009 : : | coverage_option ';' { $$ = $1; }
7010 : : | error { $$ = nullptr; } // LCOV_EXCL_LINE
7011 : : ;
7012 : :
7013 : : coverage_option<nodep>: // ==IEEE: coverage_option
7014 : : // // option/type_option aren't really keywords
7015 : : id/*yOPTION | yTYPE_OPTION*/ '.' idAny/*member_identifier*/ '=' expr
7016 : : { if (*$1 == "option") {
7017 : : $$ = new AstCgOptionAssign{$<fl>1, false, *$3, $5};
7018 : : } else if (*$1 == "type_option") {
7019 : : $$ = new AstCgOptionAssign{$<fl>1, true, *$3, $5};
7020 : : } else {
7021 : : $$ = nullptr;
7022 : : $<fl>1->v3error("Syntax error; expected 'option' or 'type_option': '" << *$1 << "'");
7023 : : DEL($5);
7024 : : } }
7025 : : ;
7026 : :
7027 : : cover_point<nodep>: // ==IEEE: cover_point
7028 : : // // [ [ data_type_or_implicit ] cover_point_identifier ':' ] yCOVERPOINT
7029 : : yCOVERPOINT expr iffE bins_or_empty
7030 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: coverpoint"); DEL($2, $3, $4); }
7031 : : // // IEEE-2012: class_scope before an ID
7032 : : | id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty
7033 : : { $$ = nullptr; BBCOVERIGN($<fl>3, "Ignoring unsupported: coverpoint"); DEL($4, $5, $6);}
7034 : : // // data_type_or_implicit expansion
7035 : : | data_type id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty
7036 : : { $$ = nullptr; BBCOVERIGN($<fl>4, "Ignoring unsupported: coverpoint"); DEL($1, $5, $6, $7);}
7037 : : | yVAR data_type id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty
7038 : : { $$ = nullptr; BBCOVERIGN($<fl>5, "Ignoring unsupported: coverpoint"); DEL($2, $6, $7, $8); }
7039 : : | yVAR implicit_typeE id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty
7040 : : { $$ = nullptr; BBCOVERIGN($<fl>5, "Ignoring unsupported: coverpoint"); DEL($2, $6, $7, $8); }
7041 : : | signingE rangeList id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty
7042 : : { $$ = nullptr; BBCOVERIGN($<fl>5, "Ignoring unsupported: coverpoint"); DEL($2, $6, $7, $8); }
7043 : : | signing id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty
7044 : : { $$ = nullptr; BBCOVERIGN($<fl>4, "Ignoring unsupported: coverpoint"); DEL($5, $6, $7); }
7045 : : // // IEEE-2012:
7046 : : | bins_or_empty { $$ = $1; }
7047 : : ;
7048 : :
7049 : : iffE<nodep>: // IEEE: part of cover_point, others
7050 : : /* empty */ { $$ = nullptr; }
7051 : : | yIFF '(' expr ')'
7052 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: cover 'iff'"); DEL($3); }
7053 : : ;
7054 : :
7055 : : bins_or_empty<nodep>: // ==IEEE: bins_or_empty
7056 : : '{' bins_or_optionsList '}' { $$ = $2; }
7057 : : | '{' '}' { $$ = nullptr; }
7058 : : | ';' { $$ = nullptr; }
7059 : : //
7060 : : | '{' bins_or_optionsList error '}' { $$ = $2; } // LCOV_EXCL_LINE
7061 : : | '{' error '}' { $$ = nullptr; } // LCOV_EXCL_LINE
7062 : : ;
7063 : :
7064 : : bins_or_optionsList<nodep>: // IEEE: { bins_or_options ';' }
7065 : : bins_or_options ';' { $$ = $1; }
7066 : : | bins_or_optionsList bins_or_options ';' { $$ = addNextNull($1, $2); }
7067 : : //
7068 : : | bins_or_optionsList error ';' { $$ = $1; } // LCOV_EXCL_LINE
7069 : : | error ';' { $$ = nullptr; } // LCOV_EXCL_LINE
7070 : : ;
7071 : :
7072 : : bins_or_options<nodep>: // ==IEEE: bins_or_options
7073 : : // // Superset of IEEE - we allow []'s in more places
7074 : : coverage_option { $$ = $1; }
7075 : : // // Can't use wildcardE as results in conflicts
7076 : : | bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' '{' range_list '}' iffE
7077 : : { $$ = nullptr; BBCOVERIGN($<fl>4, "Ignoring unsupported: cover bin specification"); DEL($3, $6, $8); }
7078 : : | bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' '{' range_list '}' yWITH__PAREN '(' cgexpr ')' iffE
7079 : : { $$ = nullptr; BBCOVERIGN($<fl>8, "Ignoring unsupported: cover bin 'with' specification"); DEL($3, $6, $10, $12); }
7080 : : | bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' id/*cover_point_id*/ yWITH__PAREN '(' cgexpr ')' iffE
7081 : : { $$ = nullptr; BBCOVERIGN($<fl>6, "Ignoring unsupported: cover bin 'with' specification"); DEL($3, $8, $10); }
7082 : : | yWILDCARD bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' '{' range_list '}' iffE
7083 : : { $$ = nullptr; BBCOVERIGN($<fl>5, "Ignoring unsupported: cover bin 'wildcard' specification"); DEL($4, $7, $9); }
7084 : : | yWILDCARD bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' '{' range_list '}' yWITH__PAREN '(' cgexpr ')' iffE
7085 : : { $$ = nullptr; BBCOVERIGN($<fl>9, "Ignoring unsupported: cover bin 'wildcard' 'with' specification"); DEL($4, $7, $11, $13); }
7086 : : //
7087 : : // // cgexpr part of trans_list
7088 : : | bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE
7089 : : { $$ = nullptr; BBCOVERIGN($<fl>4, "Ignoring unsupported: cover bin trans list"); DEL($3, $5, $6); }
7090 : : | yWILDCARD bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE
7091 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: cover bin 'wildcard' trans list"); DEL($4, $6, $7);}
7092 : : //
7093 : : | bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' yDEFAULT iffE
7094 : : { $$ = nullptr; BBCOVERIGN($<fl>5, "Ignoring unsupported: cover bin 'default'"); DEL($3, $6); }
7095 : : | bins_keyword idAny/*bin_identifier*/ bins_orBraE '=' yDEFAULT ySEQUENCE iffE
7096 : : { $$ = nullptr; BBCOVERIGN($<fl>6, "Ignoring unsupported: cover bin 'default' 'sequence'"); DEL($3, $7); }
7097 : : ;
7098 : :
7099 : : bins_orBraE<nodep>: // IEEE: part of bins_or_options:
7100 : : /* empty */ { $$ = nullptr; }
7101 : : | '[' ']' { $$ = nullptr; /*UNSUP*/ }
7102 : : | '[' cgexpr ']' { $$ = nullptr; /*UNSUP*/ DEL($2); }
7103 : : ;
7104 : :
7105 : : bins_keyword<fl>: // ==IEEE: bins_keyword
7106 : : yBINS { $$ = $1; /*UNSUP*/ }
7107 : : | yILLEGAL_BINS { $$ = $1; /*UNSUP*/ }
7108 : : | yIGNORE_BINS { $$ = $1; /*UNSUP*/ }
7109 : : ;
7110 : :
7111 : : trans_list<nodep>: // ==IEEE: trans_list
7112 : : '(' trans_set ')' { $$ = $2; }
7113 : : | trans_list ',' '(' trans_set ')' { $$ = addNextNull($1, $4); }
7114 : : ;
7115 : :
7116 : : trans_set<nodep>: // ==IEEE: trans_set
7117 : : trans_range_list { $$ = $1; }
7118 : : // // Note the { => } in the grammar, this is really a list
7119 : : | trans_set yP_EQGT trans_range_list
7120 : : { $$ = $1; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover trans set '=>'"); DEL($3); }
7121 : : ;
7122 : :
7123 : : trans_range_list<nodep>: // ==IEEE: trans_range_list
7124 : : trans_item { $$ = $1; }
7125 : : | trans_item yP_BRASTAR cgexpr ']'
7126 : : { $$ = nullptr; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover '[*'"); DEL($1, $3); }
7127 : : | trans_item yP_BRASTAR cgexpr ':' cgexpr ']'
7128 : : { $$ = nullptr; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover '[*'"); DEL($1, $3, $5); }
7129 : : | trans_item yP_BRAMINUSGT cgexpr ']'
7130 : : { $$ = nullptr; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover '[->'"); DEL($1, $3); }
7131 : : | trans_item yP_BRAMINUSGT cgexpr ':' cgexpr ']'
7132 : : { $$ = nullptr; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover '[->'"); DEL($1, $3, $5); }
7133 : : | trans_item yP_BRAEQ cgexpr ']'
7134 : : { $$ = nullptr; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover '[='"); DEL($1, $3); }
7135 : : | trans_item yP_BRAEQ cgexpr ':' cgexpr ']'
7136 : : { $$ = nullptr; BBCOVERIGN($<fl>2, "Ignoring unsupported: cover '[='"); DEL($1, $3, $5); }
7137 : : ;
7138 : :
7139 : : trans_item<nodep>: // ==IEEE: range_list
7140 : : covergroup_range_list { $$ = $1; }
7141 : : ;
7142 : :
7143 : : covergroup_range_list<nodep>: // ==IEEE: covergroup_range_list
7144 : : covergroup_value_range { $$ = $1; }
7145 : : | covergroup_range_list ',' covergroup_value_range { $$ = addNextNull($1, $3); }
7146 : : ;
7147 : :
7148 : :
7149 : : cover_cross<nodep>: // ==IEEE: cover_cross
7150 : : id/*cover_point_identifier*/ ':' yCROSS list_of_cross_items iffE cross_body
7151 : : { $$ = nullptr; BBCOVERIGN($<fl>3, "Ignoring unsupported: cover cross"); DEL($4, $5, $6); }
7152 : : | yCROSS list_of_cross_items iffE cross_body
7153 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: cover cross"); DEL($2, $3, $4); }
7154 : : ;
7155 : :
7156 : : list_of_cross_items<nodep>: // ==IEEE: list_of_cross_items
7157 : : cross_item ',' cross_item { $$ = addNextNull($1, $3); }
7158 : : | cross_item ',' cross_item ',' cross_itemList
7159 : : { $$ = addNextNull(addNextNull($1, $3), $5); }
7160 : : ;
7161 : :
7162 : : cross_itemList<nodep>: // IEEE: part of list_of_cross_items
7163 : : cross_item { $$ = $1; }
7164 : : | cross_itemList ',' cross_item { $$ = addNextNull($1, $3); }
7165 : : ;
7166 : :
7167 : : cross_item<nodep>: // ==IEEE: cross_item
7168 : : idDotted/*cover_point_identifier or variable_identifier*/ { $1->deleteTree(); $$ = nullptr; /*UNSUP*/ }
7169 : : ;
7170 : :
7171 : : cross_body<nodep>: // ==IEEE: cross_body
7172 : : '{' '}' { $$ = nullptr; }
7173 : : // // IEEE-2012: No semicolon here, mistake in spec
7174 : : | '{' cross_body_itemList '}' { $$ = $2; }
7175 : : | ';' { $$ = nullptr; }
7176 : : //
7177 : : | '{' cross_body_itemList error '}' { $$ = $2; } // LCOV_EXCL_LINE
7178 : : | '{' error '}' { $$ = nullptr; } // LCOV_EXCL_LINE
7179 : : ;
7180 : :
7181 : : cross_body_itemList<nodep>: // IEEE: part of cross_body
7182 : : cross_body_item { $$ = $1; }
7183 : : | cross_body_itemList cross_body_item { $$ = addNextNull($1, $2); }
7184 : : ;
7185 : :
7186 : : cross_body_item<nodep>: // ==IEEE: cross_body_item
7187 : : function_declaration
7188 : : { $$ = $1; BBCOVERIGN($1->fileline(), "Ignoring unsupported: coverage cross 'function' declaration"); }
7189 : : // // IEEE: bins_selection_or_option
7190 : : | coverage_option ';' { $$ = $1; }
7191 : : // // IEEE: bins_selection
7192 : : | bins_keyword idAny/*new-bin_identifier*/ '=' select_expression iffE ';'
7193 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: coverage cross bin"); DEL($4, $5); }
7194 : : | error ';' { $$ = nullptr; } // LCOV_EXCL_LINE
7195 : : ;
7196 : :
7197 : : select_expression<nodep>: // ==IEEE: select_expression
7198 : : select_expression_r
7199 : : { $$ = $1; }
7200 : : | select_expression yP_ANDAND select_expression
7201 : : { $$ = nullptr; BBCOVERIGN($2, "Ignoring unsupported: coverage select expression '&&'"); DEL($1, $3); }
7202 : : | select_expression yP_OROR select_expression
7203 : : { $$ = nullptr; BBCOVERIGN($2, "Ignoring unsupported: coverage select expression '||'"); DEL($1, $3); }
7204 : : ;
7205 : :
7206 : : // This non-terminal exists to disambiguate select_expression and make "with" bind tighter
7207 : : select_expression_r<nodep>:
7208 : : // // IEEE: select_condition expanded here
7209 : : yBINSOF '(' bins_expression ')'
7210 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: coverage select expression 'binsof'"); DEL($3); }
7211 : : | '!' yBINSOF '(' bins_expression ')'
7212 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: coverage select expression 'binsof'"); DEL($4); }
7213 : : | yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}'
7214 : : { $$ = nullptr; BBCOVERIGN($5, "Ignoring unsupported: coverage select expression 'intersect'"); DEL($3, $7); }
7215 : : | '!' yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}' { }
7216 : : { $$ = nullptr; BBCOVERIGN($5, "Ignoring unsupported: coverage select expression 'intersect'"); DEL($4, $8); }
7217 : : | yWITH__PAREN '(' cgexpr ')'
7218 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: coverage select expression with"); DEL($3); }
7219 : : | '!' yWITH__PAREN '(' cgexpr ')'
7220 : : { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: coverage select expression with"); DEL($4); }
7221 : : | select_expression_r yWITH__PAREN '(' cgexpr ')'
7222 : : { $$ = nullptr; BBCOVERIGN($2, "Ignoring unsupported: coverage select expression with"); DEL($1, $4); }
7223 : : // // IEEE-2012: Need clarification as to precedence
7224 : : //UNSUP yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr { }
7225 : : // // IEEE-2012: Need clarification as to precedence
7226 : : //UNSUP '!' yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr { }
7227 : : //
7228 : : | '(' select_expression ')' { $$ = $2; }
7229 : : // // IEEE-2012: cross_identifier
7230 : : // // Part of covergroup_expression - generic identifier
7231 : : // // IEEE-2012: Need clarification as to precedence
7232 : : //UNSUP cgexpr { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: coverage select expression"); }
7233 : : //
7234 : : // // IEEE: cross_set_expression [ yMATCHES integer_covergroup_expression ]
7235 : : // // covergroup_expression [ yMATCHES ( integer_covergroup_expression | '$' ) ]
7236 : : // // Need precedence fix
7237 : : //UNSUP cgexpr yMATCHES cgexpr {..}
7238 : : //UNSUP // Below are all removed
7239 : : | idAny '(' list_of_argumentsE ')'
7240 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: coverage select function call"); DEL($3); }
7241 : : //UNSUP // Above are all removed, replace with:
7242 : : ;
7243 : :
7244 : : bins_expression<nodep>: // ==IEEE: bins_expression
7245 : : // // "cover_point_identifier" and "variable_identifier" look identical
7246 : : // IEEE specifies:
7247 : : // bins_expression ::=
7248 : : // variable_identifier
7249 : : // | cover_point_identifier [ . bin_identifier ]
7250 : : // Verilator supports hierarchical reference in a place of variable identifier.
7251 : : // This is an extension based on other simulators.
7252 : : idDotted
7253 : : { $$ = nullptr; /*UNSUP*/ DEL($1); }
7254 : : ;
7255 : :
7256 : : coverage_eventE<nodep>: // IEEE: [ coverage_event ]
7257 : : /* empty */ { $$ = nullptr; }
7258 : : | clocking_event
7259 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: coverage clocking event"); DEL($1); }
7260 : : | yWITH__ETC yFUNCTION idAny/*"sample"*/ '(' tf_port_listE ')'
7261 : : { if (*$3 != "sample") {
7262 : : $<fl>3->v3error("Coverage sampling function must be named 'sample'");
7263 : : $$ = nullptr;
7264 : : DEL($5);
7265 : : } else {
7266 : : $$ = $5;
7267 : : }
7268 : : }
7269 : : | yP_ATAT '(' block_event_expression ')'
7270 : : { $$ = nullptr; BBCOVERIGN($<fl>1, "Ignoring unsupported: coverage '@@' events"); DEL($3); }
7271 : : ;
7272 : :
7273 : : block_event_expression<nodep>: // ==IEEE: block_event_expression
7274 : : block_event_expressionTerm { $$ = nullptr; /*UNSUP @@*/ DEL($1); }
7275 : : | block_event_expression yOR block_event_expressionTerm { $$ = nullptr; /*UNSUP @@*/ DEL($1, $3); }
7276 : : ;
7277 : :
7278 : : block_event_expressionTerm<nodep>: // IEEE: part of block_event_expression
7279 : : yBEGIN hierarchical_btf_identifier { $$ = nullptr; /*UNSUP @@*/ DEL($2); }
7280 : : | yEND hierarchical_btf_identifier { $$ = nullptr; /*UNSUP @@*/ DEL($2); }
7281 : : ;
7282 : :
7283 : : hierarchical_btf_identifier<nodep>: // ==IEEE: hierarchical_btf_identifier
7284 : : // // hierarchical_tf_identifier + hierarchical_block_identifier
7285 : : // // method_identifier
7286 : : packageClassScopeE idAny { $$ = nullptr; /*UNSUP*/ DEL($1); }
7287 : : ;
7288 : :
7289 : : //**********************************************************************
7290 : : // Randsequence
7291 : :
7292 : : randsequence_statement<nodeStmtp>: // ==IEEE: randsequence_statement
7293 : : yRANDSEQUENCE '(' ')' rs_productionList yENDSEQUENCE
7294 : : { $$ = new AstRandSequence{$1, "", $4};
7295 : : v3Global.useRandSequence(true); }
7296 : : | yRANDSEQUENCE '(' idAny/*rs_production_identifier*/ ')' rs_productionList yENDSEQUENCE
7297 : : { $$ = new AstRandSequence{$1, *$3, $5};
7298 : : v3Global.useRandSequence(true); }
7299 : : ;
7300 : :
7301 : : rs_productionList<rSProdp>: // IEEE: rs_production+
7302 : : rs_production { $$ = $1; }
7303 : : | rs_productionList rs_production { $$ = addNextNull($1, $2); }
7304 : : ;
7305 : :
7306 : : rs_production<rSProdp>: // ==IEEE: rs_production
7307 : : rs_productionFront ':' rs_ruleList ';'
7308 : : { $$ = $1; $1->addRulesp($3); }
7309 : : ;
7310 : :
7311 : : rs_productionFront<rSProdp>: // IEEE: part of rs_production
7312 : : rs_funcId/*rs_production_identifier*/ { $$ = $1; }
7313 : : | rs_funcId '(' tf_port_listE ')' { $$ = $1; $$->addPortsp($3); }
7314 : : ;
7315 : :
7316 : : rs_funcId<rSProdp>: // IEEE: part of rs_production
7317 : : /**/ rs_fId
7318 : : { $$ = $1; } // Note is void as default, not logic as default like functions
7319 : : | signingE rangeList rs_fId
7320 : : { $$ = $3;
7321 : : $$->fvarp(new AstVar{$<fl>1, VVarType::PORT, $3->name(), VFlagChildDType{},
7322 : : GRAMMARP->addRange(new AstBasicDType{$<fl>3, LOGIC_IMPLICIT, $1}, $2, true)}); }
7323 : : | signing rs_fId
7324 : : { $$ = $2;
7325 : : $$->fvarp(new AstVar{$<fl>1, VVarType::PORT, $2->name(), VFlagChildDType{},
7326 : : new AstBasicDType{$<fl>2, LOGIC_IMPLICIT, $1}}); }
7327 : : | data_type rs_fId
7328 : : { $$ = $2;
7329 : : $$->fvarp(new AstVar{$<fl>1, VVarType::PORT, $2->name(), VFlagChildDType{},
7330 : : $1}); }
7331 : : | yVOID rs_fId
7332 : : { $$ = $2; }
7333 : : ;
7334 : :
7335 : : rs_fId<rSProdp>: // IEEE: part of rs_production
7336 : : id
7337 : : { $<fl>$ = $<fl>1;
7338 : : $$ = new AstRSProd{$<fl>$, *$1, nullptr, nullptr}; }
7339 : : ;
7340 : :
7341 : : rs_ruleList<rSRulep>: // IEEE: rs_rule+ part of rs_production
7342 : : rs_rule { $$ = $1; }
7343 : : | rs_ruleList '|' rs_rule { $$ = addNextNull($1, $3); }
7344 : : ;
7345 : :
7346 : : rs_rule<rSRulep>: // ==IEEE: rs_rule
7347 : : rs_production_list
7348 : : { $$ = new AstRSRule{$1->fileline(), nullptr, $1, nullptr}; }
7349 : : | rs_production_list yP_COLONEQ rs_weight_specification
7350 : : { $$ = new AstRSRule{$1->fileline(), $3, $1, nullptr}; }
7351 : : | rs_production_list yP_COLONEQ rs_weight_specification rs_code_block
7352 : : { $$ = new AstRSRule{$1->fileline(), $3, $1, $4}; }
7353 : : ;
7354 : :
7355 : : rs_production_list<rSProdListp>: // ==IEEE: rs_production_list
7356 : : rs_prodList
7357 : : { $$ = new AstRSProdList{CRELINE(), nullptr, $1}; }
7358 : : | yRAND yJOIN rs_production_item rs_production_itemList
7359 : : { $$ = new AstRSProdList{$1, new AstConst{$2, AstConst::RealDouble{}, 0.5}, $3};
7360 : : $$->randJoin(true);
7361 : : $$->addProdsp($4); }
7362 : : | yRAND yJOIN '(' expr ')' rs_production_item rs_production_itemList
7363 : : { $$ = new AstRSProdList{$1, $4, $6};
7364 : : $$->randJoin(true);
7365 : : $$->addProdsp($7); }
7366 : : ;
7367 : :
7368 : : rs_weight_specification<nodeExprp>: // ==IEEE: rs_weight_specification
7369 : : intnumAsConst { $$ = $1; }
7370 : : | idClassSel/*ps_identifier*/ { $$ = $1; }
7371 : : | '(' expr ')' { $$ = $2; }
7372 : : ;
7373 : :
7374 : : rs_code_block<nodep>: // ==IEEE: rs_code_block
7375 : : '{' '}' { $$ = nullptr; }
7376 : : | '{' rs_code_blockItemList '}' { $$ = $2; }
7377 : : ;
7378 : :
7379 : : rs_code_blockItemList<nodep>: // IEEE: part of rs_code_block
7380 : : rs_code_blockItem { $$ = $1; }
7381 : : | rs_code_blockItemList rs_code_blockItem { $$ = addNextNull($1, $2); }
7382 : : ;
7383 : :
7384 : : rs_code_blockItem<nodep>: // IEEE: part of rs_code_block
7385 : : data_declaration { $$ = $1; }
7386 : : | stmt { $$ = $1; }
7387 : : ;
7388 : :
7389 : : rs_prodList<nodep>: // IEEE: rs_prod+
7390 : : rs_prod { $$ = $1; }
7391 : : | rs_prodList rs_prod { $$ = addNextNull($1, $2); }
7392 : : ;
7393 : :
7394 : : rs_prod<nodep>: // ==IEEE: rs_prod
7395 : : rs_production_item { $$ = $1; }
7396 : : | rs_code_block { $$ = $1; }
7397 : : // // IEEE: rs_if_else
7398 : : | yIF '(' expr ')' rs_production_item %prec prLOWER_THAN_ELSE
7399 : : { $$ = new AstIf{$<fl>1, $3, $5, nullptr}; }
7400 : : | yIF '(' expr ')' rs_production_item yELSE rs_production_item
7401 : : { $$ = new AstIf{$<fl>1, $3, $5, $7}; }
7402 : : // // IEEE: rs_repeat
7403 : : | yREPEAT '(' expr ')' rs_production_item
7404 : : { $$ = new AstRepeat{$<fl>1, $3, $5}; }
7405 : : // // IEEE: rs_case
7406 : : | yCASE '(' expr ')' rs_case_itemList yENDCASE
7407 : : { $$ = new AstCase{$<fl>1, VCaseType::CT_RANDSEQUENCE, $3, $5}; }
7408 : : ;
7409 : :
7410 : : rs_production_itemList<nodep>: // IEEE: rs_production_item+
7411 : : rs_production_item { $$ = $1; }
7412 : : | rs_production_itemList rs_production_item { $$ = addNextNull($1, $2); }
7413 : : ;
7414 : :
7415 : : rs_production_item<nodep>: // ==IEEE: rs_production_item
7416 : : idAny/*production_identifier*/
7417 : : { $$ = new AstRSProdItem{$<fl>1, *$1, nullptr}; }
7418 : : | idAny/*production_identifier*/ '(' list_of_argumentsE ')'
7419 : : { $$ = new AstRSProdItem{$<fl>1, *$1, $3}; }
7420 : : ;
7421 : :
7422 : : rs_case_itemList<caseItemp>: // IEEE: rs_case_item+
7423 : : rs_case_item { $$ = $1; }
7424 : : | rs_case_itemList rs_case_item { $$ = addNextNull($1, $2); }
7425 : : ;
7426 : :
7427 : : rs_case_item<caseItemp>: // ==IEEE: rs_case_item
7428 : : caseCondList ':' rs_production_item ';'
7429 : : { $$ = new AstCaseItem{$<fl>1, $1, $3}; }
7430 : : | yDEFAULT rs_production_item ';'
7431 : : { $$ = new AstCaseItem{$<fl>1, nullptr, $2}; }
7432 : : | yDEFAULT ':' rs_production_item ';'
7433 : : { $$ = new AstCaseItem{$<fl>1, nullptr, $3}; }
7434 : : ;
7435 : :
7436 : : //**********************************************************************
7437 : : // Checker
7438 : :
7439 : : checker_declaration<nodeModulep>: // ==IEEE: part of checker_declaration
7440 : : checkerFront checker_port_listE ';'
7441 : : checker_or_generate_itemListE yENDCHECKER endLabelE
7442 : : { $$ = $1;
7443 : : $1->modTrace(GRAMMARP->allTracingOn($1->fileline()));
7444 : : if ($2) $1->addStmtsp($2);
7445 : : if ($4) $1->addStmtsp($4);
7446 : : GRAMMARP->endLabel($<fl>6, $1, $6); }
7447 : : ;
7448 : :
7449 : : checkerFront<nodeModulep>: // IEEE: part of checker_declaration
7450 : : yCHECKER idAny/*checker_identifier*/
7451 : : { $$ = new AstModule{$<fl>2, *$2, PARSEP->libname(), AstModule::Checker{}};
7452 : : $$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
7453 : : $$->timeunit(PARSEP->timeLastUnit());
7454 : : PARSEP->rootp()->timeprecisionMerge($$->fileline(),
7455 : : PARSEP->timeLastPrec());
7456 : : $$->unconnectedDrive(PARSEP->unconnectedDrive()); }
7457 : : | checkerFront sigAttrScope { $$ = $1; }
7458 : : ;
7459 : :
7460 : : checker_port_listE<nodep>: // IEEE: [ ( [ checker_port_list ] ) ]
7461 : : /* empty */ { $$ = nullptr; }
7462 : : | '(' ')' { $$ = nullptr; }
7463 : : | '('
7464 : : /*mid*/ { VARRESET_LIST(PORT); GRAMMARP->m_pinAnsi = true; }
7465 : : /*cont*/ checker_port_list ')'
7466 : : { $$ = $3; }
7467 : : ;
7468 : :
7469 : : checker_port_list<nodep>: // ==IEEE: checker_port_list
7470 : : checker_port_item { $$ = $1; }
7471 : : | checker_port_list ',' checker_port_item { $$ = addNextNull($1, $3); }
7472 : : ;
7473 : :
7474 : : checker_port_item<nodep>: // IEEE: checker_port_item
7475 : : checker_port_itemFront checker_port_itemAssignment { $$ = $2; }
7476 : : ;
7477 : :
7478 : : checker_port_itemFront: // IEEE: part of checker_port_item
7479 : : checker_port_directionE property_formal_typeNoDt
7480 : : { VARDTYPE($2); }
7481 : : // // data_type_or_implicit
7482 : : | checker_port_directionE data_type
7483 : : { VARDTYPE($2); GRAMMARP->m_typedPropertyPort = true; }
7484 : : | checker_port_directionE yVAR data_type
7485 : : { VARDTYPE($3); GRAMMARP->m_typedPropertyPort = true; }
7486 : : | checker_port_directionE yVAR implicit_typeE
7487 : : { VARDTYPE($3); }
7488 : : | checker_port_directionE implicit_typeE
7489 : : { VARDTYPE($2); }
7490 : : ;
7491 : :
7492 : : checker_port_directionE: // IEEE: [ checker_port_direction ]
7493 : : /* empty */ { VARIO(INPUT); }
7494 : : | yINPUT { VARIO(INPUT); }
7495 : : | yOUTPUT { VARIO(OUTPUT); }
7496 : : ;
7497 : :
7498 : : checker_port_itemAssignment<nodep>: // IEEE: part of checker_port_direction
7499 : : id variable_dimensionListE
7500 : : { $$ = new AstPort{CRELINE(), PINNUMINC(), *$1};
7501 : : $$->addNext(VARDONEA($<fl>1, *$1, $2, nullptr)); }
7502 : : | id variable_dimensionListE '=' property_actual_arg
7503 : : { $$ = new AstPort{CRELINE(), PINNUMINC(), *$1};
7504 : : $$->addNext(VARDONEA($<fl>1, *$1, $2, $4));
7505 : : BBUNSUP($3, "Unsupported: checker port variable default value"); }
7506 : : ;
7507 : :
7508 : : checker_or_generate_itemListE<nodep>: // IEEE: [{ checker_or_generate_itemList }]
7509 : : /* empty */ { $$ = nullptr; }
7510 : : | checker_or_generate_itemList { $$ = $1; }
7511 : : ;
7512 : :
7513 : : checker_or_generate_itemList<nodep>: // IEEE: { checker_or_generate_itemList }
7514 : : checker_or_generate_item { $$ = $1; }
7515 : : | checker_or_generate_itemList checker_or_generate_item { $$ = addNextNull($1, $2); }
7516 : : ;
7517 : :
7518 : : checker_or_generate_item<nodep>: // ==IEEE: checker_or_generate_item
7519 : : checker_or_generate_item_declaration { $$ = $1; }
7520 : : | initial_construct { $$ = $1; }
7521 : : // // IEEE: checker_construct
7522 : : | always_construct { $$ = $1; }
7523 : : | final_construct { $$ = $1; }
7524 : : | assertion_item { $$ = $1; }
7525 : : | continuous_assign { $$ = $1; }
7526 : : | checker_generate_item { $$ = $1; }
7527 : : ;
7528 : :
7529 : : checker_or_generate_item_declaration<nodep>: // ==IEEE: checker_or_generate_item_declaration
7530 : : data_declaration { $$ = $1; }
7531 : : | yRAND data_declaration
7532 : : { $$ = $2; BBUNSUP($1, "Unsupported: checker rand"); }
7533 : : | function_declaration { $$ = $1; }
7534 : : | checker_declaration
7535 : : { $$ = nullptr; BBUNSUP($1, "Unsupported: recursive 'checker'"); DEL($1); }
7536 : : | assertion_item_declaration { $$ = $1; }
7537 : : | covergroup_declaration { $$ = $1; }
7538 : : // // IEEE deprecated: overload_declaration
7539 : : | genvar_declaration { $$ = $1; }
7540 : : | clocking_declaration { $$ = $1; }
7541 : : | modDefaultClocking { $$ = $1; }
7542 : : | defaultDisable { $$ = $1; }
7543 : : | ';' { $$ = nullptr; }
7544 : : ;
7545 : :
7546 : : checker_generate_item<nodep>: // ==IEEE: checker_generate_item
7547 : : // // Specialized for checker so need "c_" prefixes here
7548 : : c_loop_generate_construct { $$ = $1; }
7549 : : | c_conditional_generate_construct { $$ = $1; }
7550 : : | c_generate_region { $$ = $1; }
7551 : : //
7552 : : | severity_system_task { $$ = $1; }
7553 : : ;
7554 : :
7555 : : //UNSUPchecker_instantiation<nodep>:
7556 : : //UNSUP // // Only used for procedural_assertion_item's
7557 : : //UNSUP // // Version in concurrent_assertion_item looks like etcInst
7558 : : //UNSUP // // Thus instead of *_checker_port_connection we can use etcInst's instPinListE
7559 : : //UNSUP id/*checker_identifier*/ id '(' instPinListE ')' ';' { }
7560 : : //UNSUP ;
7561 : :
7562 : : //**********************************************************************
7563 : : // Class
7564 : :
7565 : : class_declaration<nodep>: // ==IEEE: part of class_declaration
7566 : : // // IEEE-2012: using this also for interface_class_declaration
7567 : : // // The classExtendsE rule relies on classFront having the
7568 : : // // new class scope correct via classFront
7569 : : classFront parameter_port_listE classExtendsE classImplementsE ';'
7570 : : /*mid*/ { // Allow resolving types declared in base extends class
7571 : : $1->hasParameterList($<flag>2);
7572 : : }
7573 : : /*cont*/ class_itemListEnd endLabelE
7574 : : { $$ = $1; $1->addMembersp($2);
7575 : : $1->addExtendsp($3);
7576 : : $1->addExtendsp($4);
7577 : : $1->addMembersp($7);
7578 : : GRAMMARP->endLabel($<fl>8, $1, $8); }
7579 : : ;
7580 : :
7581 : : classFront<classp>: // IEEE: part of class_declaration
7582 : : // // IEEE 1800-2023: lifetimeE replaced with final_specifierE
7583 : : classVirtualE yCLASS final_specifierE lifetimeE idAny/*class_identifier*/
7584 : : { $$ = new AstClass{$2, *$5, PARSEP->libname()};
7585 : : $$->baseOverride($3);
7586 : : $$->isVirtual($1);
7587 : : v3Global.setHasClasses(); }
7588 : : // // IEEE: part of interface_class_declaration
7589 : : // // IEEE 1800-2023: lifetimeE removed
7590 : : | yINTERFACE yCLASS idAny/*class_identifier*/
7591 : : { $$ = new AstClass{$2, *$3, PARSEP->libname()};
7592 : : $$->isInterfaceClass(true);
7593 : : v3Global.setHasClasses(); }
7594 : : ;
7595 : :
7596 : : classVirtualE<cbool>:
7597 : : /* empty */ { $$ = false; }
7598 : : | yVIRTUAL__CLASS { $$ = true; }
7599 : : ;
7600 : :
7601 : : classExtendsE<classExtendsp>: // IEEE: part of class_declaration
7602 : : // // The classExtendsE rule relies on classFront having the
7603 : : // // new class scope correct via classFront
7604 : : /* empty */ { $$ = nullptr; }
7605 : : | yEXTENDS classExtendsList { $$ = $2; }
7606 : : ;
7607 : :
7608 : : classExtendsList<classExtendsp>: // IEEE: part of class_declaration
7609 : : classExtendsOne { $$ = $1; }
7610 : : | classExtendsList ',' classExtendsOne { $$ = addNextNull($1, $3); }
7611 : : ;
7612 : :
7613 : : classExtendsOne<classExtendsp>: // IEEE: part of class_declaration
7614 : : class_typeExtImpList
7615 : : { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements}; }
7616 : : | class_typeExtImpList '(' list_of_argumentsE ')'
7617 : : { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements};
7618 : : $$->addArgsp($3); }
7619 : : // // IEEE-2023: Added: yEXTENDS class_type '(' yDEFAULT ')'
7620 : : | class_typeExtImpList '(' yDEFAULT ')'
7621 : : { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements};
7622 : : BBUNSUP($<fl>2, "Unsupported: 'extends' with 'default'"); }
7623 : : ;
7624 : :
7625 : : classImplementsE<classExtendsp>: // IEEE: part of class_declaration
7626 : : // // All 1800-2012
7627 : : /* empty */ { $$ = nullptr; }
7628 : : | yIMPLEMENTS
7629 : : /*mid*/ { GRAMMARP->m_inImplements = true; }
7630 : : /*cont*/ classImplementsList
7631 : : { $$ = $3;
7632 : : GRAMMARP->m_inImplements = false; }
7633 : : ;
7634 : :
7635 : : classImplementsList<classExtendsp>: // IEEE: part of class_declaration
7636 : : // // All 1800-2012
7637 : : classExtendsOne { $$ = $1; }
7638 : : | classImplementsList ',' classExtendsOne
7639 : : { $$ = addNextNull($1, $3); }
7640 : : ;
7641 : :
7642 : : class_typeExtImpList<nodeExprp>: // IEEE: class_type: "[package_scope] id [ parameter_value_assignment ]"
7643 : : // // but allow yaID__aTYPE for extends/implements
7644 : : // // If you follow the rules down, class_type is really a list via ps_class_identifier
7645 : : class_typeExtImpOne { $$ = $1; }
7646 : : | class_typeExtImpList yP_COLONCOLON class_typeExtImpOne
7647 : : { $$ = new AstDot{$<fl>1, true, $1, $3}; }
7648 : : ;
7649 : :
7650 : : class_typeExtImpOne<nodeExprp>: // part of IEEE: class_type, where we either get a package_scope component or class
7651 : : // // If you follow the rules down, class_type is really a list via ps_class_identifier
7652 : : // // Not listed in IEEE, but see bug627 any parameter type maybe a class
7653 : : // // If idAny below is a class, parameter_value is legal
7654 : : // // If idAny below is a package, parameter_value is not legal
7655 : : // // If idAny below is otherwise, not legal
7656 : : idAny
7657 : : /*mid*/ { /* no nextId as not refing it above this*/ }
7658 : : /*cont*/ parameter_value_assignmentClassE
7659 : : { $$ = new AstClassOrPackageRef{$<fl>1, *$1, nullptr, $3}; }
7660 : : | idCC
7661 : : /*mid*/ { /* no nextId as not refing it above this*/ }
7662 : : /*cont*/ parameter_value_assignmentClassE
7663 : : { $$ = new AstClassOrPackageRef{$<fl>1, *$1, nullptr, $3}; }
7664 : : //
7665 : : // // package_sopeIdFollows expanded
7666 : : | yD_UNIT yP_COLONCOLON
7667 : : { $$ = new AstClassOrPackageRef{$<fl>1, "$unit", nullptr, nullptr}; }
7668 : : ;
7669 : :
7670 : : //=========
7671 : : // Package scoping - to traverse the symbol table properly, the final identifer
7672 : : // must be included in the rules below.
7673 : : // Each of these must end with {symsPackageDone | symsClassDone}
7674 : :
7675 : : //=== Below rules assume special scoping per above
7676 : :
7677 : : packageClassScopeNoId<nodeExprp>: // IEEE: [package_scope] not followed by yaID
7678 : : packageClassScope { $$ = $1; }
7679 : : ;
7680 : :
7681 : : packageClassScopeE<nodeExprp>: // IEEE: [package_scope]
7682 : : // // IMPORTANT: The lexer will parse the following ID to be in the found package
7683 : : // // if not needed must use packageClassScopeNoId
7684 : : // // TODO: To support classes should return generic type, not packagep
7685 : : // // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
7686 : : /* empty */ { $$ = nullptr; }
7687 : : | packageClassScope { $$ = $1; }
7688 : : ;
7689 : :
7690 : : packageClassScope<nodeExprp>: // IEEE: class_scope
7691 : : // // IEEE: "class_type yP_COLONCOLON"
7692 : : // // IMPORTANT: The lexer will parse the following ID to be in the found package
7693 : : // // if not needed must use packageClassScopeNoId
7694 : : // // In this parser <package_identifier>:: and <class_identifier>:: are indistinguishible
7695 : : packageClassScopeList { $$ = $1; }
7696 : : | localNextId yP_COLONCOLON { $$ = $1; }
7697 : : | dollarUnitNextId yP_COLONCOLON { $$ = $1; }
7698 : : | dollarUnitNextId yP_COLONCOLON packageClassScopeList
7699 : : { $$ = new AstDot{$2, true, $1, $3}; }
7700 : : ;
7701 : :
7702 : : packageClassScopeList<nodeExprp>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
7703 : : // // Or IEEE: [package_scope]
7704 : : // // IMPORTANT: The lexer will parse the following ID to be in the found package
7705 : : // // if not needed must use packageClassScopeNoId
7706 : : // // In this parser <package_identifier>:: and <class_identifier>:: are indistinguishible
7707 : : // // If you follow the rules down, class_type is really a list via ps_class_identifier
7708 : : packageClassScopeItem { $$ = $1; }
7709 : : | packageClassScopeList packageClassScopeItem
7710 : : { $$ = new AstDot{$<fl>2, true, $1, $2}; }
7711 : : ;
7712 : :
7713 : : packageClassScopeItem<nodeExprp>: // IEEE: package_scope or [package_scope]::[class_scope]
7714 : : // // IMPORTANT: The lexer will parse the following ID to be in the found package
7715 : : // // if not needed must use packageClassScopeNoId
7716 : : // // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
7717 : : // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token
7718 : : idCC
7719 : : /*mid*/ { }
7720 : : /*cont*/ yP_COLONCOLON
7721 : : { $$ = new AstClassOrPackageRef{$<fl>1, *$1, nullptr, nullptr}; }
7722 : : //
7723 : : | idCC parameter_value_assignmentClass
7724 : : /*mid*/ { }
7725 : : /*cont*/ yP_COLONCOLON
7726 : : { $$ = new AstClassOrPackageRef{$<fl>1, *$1, nullptr, $2}; }
7727 : : ;
7728 : :
7729 : : dollarUnitNextId<nodeExprp>: // $unit
7730 : : // // IMPORTANT: The lexer will parse the following ID to be in the found package
7731 : : // // if not needed must use packageClassScopeNoId
7732 : : // // Must call nextId without any additional tokens following
7733 : : yD_UNIT
7734 : : { $$ = new AstClassOrPackageRef{$1, "$unit", nullptr, nullptr}; }
7735 : : ;
7736 : :
7737 : : localNextId<nodeExprp>: // local::
7738 : : // // IMPORTANT: The lexer will parse the following ID to be in the found package
7739 : : // // if not needed must use packageClassScopeNoId
7740 : : // // Must call nextId without any additional tokens following
7741 : : yLOCAL__COLONCOLON
7742 : : { $$ = new AstClassOrPackageRef{$1, "local::", nullptr, nullptr}; }
7743 : : ;
7744 : :
7745 : : //^^^=========
7746 : :
7747 : : class_itemListEnd<nodep>:
7748 : : yENDCLASS { $$ = nullptr; }
7749 : : | class_itemList yENDCLASS { $$ = $1; }
7750 : : | error yENDCLASS { $$ = nullptr; } // LCOV_EXCL_LINE
7751 : : | class_itemList error yENDCLASS { $$ = $1; } // LCOV_EXCL_LINE
7752 : : ;
7753 : :
7754 : : class_itemList<nodep>:
7755 : : class_item { $$ = $1; }
7756 : : | class_itemList class_item { $$ = addNextNull($1, $2); }
7757 : : ;
7758 : :
7759 : : class_item<nodep>: // ==IEEE: class_item
7760 : : class_property { $$ = $1; }
7761 : : | class_method { $$ = $1; }
7762 : : | class_constraint { $$ = $1; }
7763 : : //
7764 : : | class_declaration { $$ = $1; }
7765 : : | timeunits_declaration { $$ = $1; }
7766 : : | covergroup_declaration
7767 : : {
7768 : : const string cgName = $1->name();
7769 : : $1->name("__vlAnonCG_" + cgName);
7770 : : AstVar* const newp = new AstVar{$1->fileline(), VVarType::VAR, cgName,
7771 : : VFlagChildDType{}, new AstRefDType($1->fileline(), $1->name())};
7772 : : $$ = addNextNull($1, newp);
7773 : : }
7774 : : // // local_parameter_declaration under parameter_declaration
7775 : : | parameter_declaration ';' { $$ = $1; }
7776 : : | ';' { $$ = nullptr; }
7777 : : // // Verilator specific
7778 : : | vlScBlock { $$ = $1; }
7779 : : //
7780 : : | error ';' { $$ = nullptr; } // LCOV_EXCL_LINE
7781 : : ;
7782 : :
7783 : : class_method<nodep>: // ==IEEE: class_method
7784 : : memberQualListE task_declaration { $$ = $2; $1.applyToNodes($2); }
7785 : : | memberQualListE function_declaration { $$ = $2; $1.applyToNodes($2); }
7786 : : | yPURE yVIRTUAL__ETC memberQualListE method_prototype ';'
7787 : : { $$ = $4; $3.applyToNodes($4); $4->pureVirtual(true); $4->isVirtual(true); }
7788 : : | yEXTERN memberQualListE method_prototype ';'
7789 : : { $$ = $3; $2.applyToNodes($3); $3->isExternProto(true); }
7790 : : // // IEEE: "method_qualifierE class_constructor_declaration"
7791 : : // // part of function_declaration
7792 : : | yEXTERN memberQualListE class_constructor_prototype
7793 : : { $$ = $3; $2.applyToNodes($3); $3->isExternProto(true); }
7794 : : ;
7795 : :
7796 : : dynamic_override_specifiersE<baseOverride>: // IEEE: dynamic_override_specifiers or empty
7797 : : /* empty */ { $$ = VBaseOverride{}; }
7798 : : // // IEEE: Expanded [ initial_or_extends_specifier ] [ final_specifier ]
7799 : : // // Note lifetime used by members is instead under memberQual
7800 : : | ':' yINITIAL { $$ = VBaseOverride{VBaseOverride::Initial{}}; }
7801 : : | ':' yEXTENDS { $$ = VBaseOverride{VBaseOverride::Extends{}}; }
7802 : : | ':' yINITIAL ':' yFINAL { $$ = VBaseOverride{VBaseOverride::Initial{}};
7803 : : $$.combine(VBaseOverride{VBaseOverride::Final{}}); }
7804 : : | ':' yEXTENDS ':' yFINAL { $$ = VBaseOverride{VBaseOverride::Extends{}};
7805 : : $$.combine(VBaseOverride{VBaseOverride::Final{}}); }
7806 : : | ':' yFINAL { $$ = VBaseOverride{VBaseOverride::Final{}}; }
7807 : : ;
7808 : :
7809 : : final_specifierE<baseOverride>: // ==IEEE: final_specifier (similar to dynamic_override_specifiers)
7810 : : /* empty */ { $$ = VBaseOverride{}; }
7811 : : | ':' yFINAL { $$ = VBaseOverride{VBaseOverride::Final{}}; }
7812 : : ;
7813 : :
7814 : : // IEEE: class_constructor_prototype
7815 : : // See function_declaration
7816 : :
7817 : : memberQualListE<qualifiers>: // Called from class_property for all qualifiers before yVAR
7818 : : // // Also before method declarations, to prevent grammar conflict
7819 : : // // Thus both types of qualifiers (method/property) are here
7820 : : /*empty*/ { $$ = VMemberQualifiers::none(); }
7821 : : | memberQualList { $$ = $1; }
7822 : : ;
7823 : :
7824 : : memberQualList<qualifiers>:
7825 : : memberQualOne { $$ = $1; }
7826 : : | memberQualList memberQualOne { $$ = VMemberQualifiers::combine($1, $2); }
7827 : : ;
7828 : :
7829 : : memberQualOne<qualifiers>: // IEEE: property_qualifier + method_qualifier
7830 : : // // Part of method_qualifier and property_qualifier
7831 : : // // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
7832 : : yPROTECTED { $$ = VMemberQualifiers::none(); $$.m_protected = true; }
7833 : : | yLOCAL__ETC { $$ = VMemberQualifiers::none(); $$.m_local = true; }
7834 : : | ySTATIC__ETC { $$ = VMemberQualifiers::none(); $$.m_static = true; }
7835 : : // // Part of method_qualifier only
7836 : : | yVIRTUAL__ETC { $$ = VMemberQualifiers::none(); $$.m_virtual = true; }
7837 : : // // Part of property_qualifier only
7838 : : | random_qualifier { $$ = $1; }
7839 : : // // Part of data_declaration, but not in data_declarationVarFrontClass
7840 : : | yCONST__ETC { $$ = VMemberQualifiers::none(); $$.m_const = true; }
7841 : : ;
7842 : :
7843 : : //**********************************************************************
7844 : : // Constraints
7845 : :
7846 : : class_constraint<constraintp>: // ==IEEE: class_constraint
7847 : : // // IEEE: constraint_declaration
7848 : : constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew constraint_block
7849 : : { $$ = $4; $$->isStatic($1); $$->baseOverride($3); $$->addItemsp($5); }
7850 : : // // IEEE: constraint_prototype + constraint_prototype_qualifier
7851 : : | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';'
7852 : : { $$ = $4; $$->isStatic($1); $$->baseOverride($3);
7853 : : $$->isExternProto(true); }
7854 : : | yEXTERN constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';'
7855 : : { $$ = $5; $$->isStatic($2); $$->baseOverride($4);
7856 : : $$->isExternProto(true); $$->isExternExplicit(true); }
7857 : : | yPURE constraintStaticE yCONSTRAINT constraintIdNew ';'
7858 : : { $$ = $4; $$->isKwdPure($1); $$->isStatic($2); }
7859 : : ;
7860 : :
7861 : : constraintIdNew<constraintp>: // IEEE: id part of class_constraint
7862 : : idAny/*constraint_identifier*/
7863 : : { $$ = new AstConstraint{$<fl>1, *$1, nullptr}; }
7864 : : ;
7865 : :
7866 : : constraint_block<nodep>: // ==IEEE: constraint_block
7867 : : '{' '}' { $$ = nullptr; }
7868 : : | '{' constraint_block_itemList '}' { $$ = $2; }
7869 : : //
7870 : : | '{' error '}' { $$ = nullptr; } // LCOV_EXCL_LINE
7871 : : | '{' constraint_block_itemList error '}' { $$ = $2; } // LCOV_EXCL_LINE
7872 : : ;
7873 : :
7874 : : constraint_block_itemList<nodep>: // IEEE: { constraint_block_item }
7875 : : constraint_block_item { $$ = $1; }
7876 : : | constraint_block_itemList constraint_block_item { $$ = addNextNull($1, $2); }
7877 : : ;
7878 : :
7879 : : constraint_block_item<nodep>: // ==IEEE: constraint_block_item
7880 : : constraint_expression { $$ = $1; }
7881 : : | ySOLVE solve_before_list yBEFORE solve_before_list ';'
7882 : : { $$ = new AstConstraintBefore{$1, $2, $4}; }
7883 : : ;
7884 : :
7885 : : solve_before_list<nodeExprp>: // ==IEEE: solve_before_list
7886 : : constraint_primary { $$ = $1; }
7887 : : | solve_before_list ',' constraint_primary { $$ = addNextNull($1, $3); }
7888 : : ;
7889 : :
7890 : : constraint_primary<nodeExprp>: // ==IEEE: constraint_primary
7891 : : // // exprScope more general than:
7892 : : // // [ implicit_class_handle '.' | class_scope ] hierarchical_identifier select [ '(' ')' ]
7893 : : exprScope { $$ = $1; }
7894 : : ;
7895 : :
7896 : : constraint_expressionList<nodep>: // ==IEEE: { constraint_expression }
7897 : : constraint_expression { $$ = $1; }
7898 : : | ySOLVE solve_before_list yBEFORE solve_before_list ';'
7899 : : { $$ = new AstConstraintBefore{$1, $2, $4}; }
7900 : : | constraint_expressionList constraint_expression { $$ = addNextNull($1, $2); }
7901 : : | constraint_expressionList ySOLVE solve_before_list yBEFORE solve_before_list ';'
7902 : : { $$ = addNextNull($1, new AstConstraintBefore{$<fl>2, $3, $5}); }
7903 : : ;
7904 : :
7905 : : constraint_expression<nodep>: // ==IEEE: constraint_expression
7906 : : expr/*expression_or_dist*/ ';'
7907 : : { $$ = new AstConstraintExpr{$1->fileline(), $1}; }
7908 : : // // 1800-2012:
7909 : : | ySOFT expr/*expression_or_dist*/ ';'
7910 : : { AstConstraintExpr* const newp = new AstConstraintExpr{$1, $2};
7911 : : newp->isSoft(true);
7912 : : $$ = newp; }
7913 : : // // 1800-2012:
7914 : : // // IEEE: uniqueness_constraint ';'
7915 : : | yUNIQUE '{' range_list '}' ';'
7916 : : { $$ = new AstConstraintUnique{$1, $3}; }
7917 : : // // IEEE: expr yP_MINUSGT constraint_set
7918 : : // // The bare-expression case "expr -> expr ;"
7919 : : // // arrives via the general expr rule above
7920 : : // // (AstLogIf) and matches "expr ';'". Each
7921 : : // // production below covers one constraint_set
7922 : : // // shape that is not a plain expression and
7923 : : // // builds an outer AstConstraintIf wrapping the
7924 : : // // statement V3Randomize already knows how to
7925 : : // // lower (with disable-soft hoisted by the
7926 : : // // ConstraintExprVisitor pre-pass).
7927 : : | expr yP_MINUSGT '{' constraint_expressionList '}'
7928 : : { $$ = new AstConstraintIf{$2, $1, $4, nullptr}; }
7929 : : | expr yP_MINUSGT yIF '(' expr ')' constraint_set %prec prLOWER_THAN_ELSE
7930 : : { $$ = new AstConstraintIf{$2, $1,
7931 : : new AstConstraintIf{$3, $5, $7, nullptr}, nullptr}; }
7932 : : | expr yP_MINUSGT yIF '(' expr ')' constraint_set yELSE constraint_set
7933 : : { $$ = new AstConstraintIf{$2, $1,
7934 : : new AstConstraintIf{$3, $5, $7, $9}, nullptr}; }
7935 : : | expr yP_MINUSGT yFOREACH '(' idClassSelForeach ')' constraint_set
7936 : : { $$ = new AstConstraintIf{$2, $1,
7937 : : new AstConstraintForeach{$3, $5, $7}, nullptr}; }
7938 : : | expr yP_MINUSGT yUNIQUE '{' range_list '}' ';'
7939 : : { $$ = new AstConstraintIf{$2, $1,
7940 : : new AstConstraintUnique{$3, $5}, nullptr}; }
7941 : : | expr yP_MINUSGT ySOFT expr ';'
7942 : : { AstConstraintExpr* const innerp = new AstConstraintExpr{$3, $4};
7943 : : innerp->isSoft(true);
7944 : : $$ = new AstConstraintIf{$2, $1, innerp, nullptr}; }
7945 : : | expr yP_MINUSGT yDISABLE ySOFT constraint_primary ';'
7946 : : { AstConstraintExpr* const innerp = new AstConstraintExpr{$3, $5};
7947 : : innerp->isDisableSoft(true);
7948 : : $$ = new AstConstraintIf{$2, $1, innerp, nullptr}; }
7949 : : | yIF '(' expr ')' constraint_set %prec prLOWER_THAN_ELSE
7950 : : { $$ = new AstConstraintIf{$1, $3, $5, nullptr}; }
7951 : : | yIF '(' expr ')' constraint_set yELSE constraint_set
7952 : : { $$ = new AstConstraintIf{$1, $3, $5, $7}; }
7953 : : // // IEEE says array_identifier here, but dotted accepted in VMM + 1800-2009
7954 : : | yFOREACH '(' idClassSelForeach ')' constraint_set
7955 : : { $$ = new AstConstraintForeach{$1, $3, $5}; }
7956 : : // // soft is 1800-2012
7957 : : | yDISABLE ySOFT constraint_primary ';'
7958 : : { AstConstraintExpr* const newp = new AstConstraintExpr{$1, $3};
7959 : : newp->isDisableSoft(true);
7960 : : $$ = newp; }
7961 : : //
7962 : : | error ';'
7963 : : { $$ = nullptr; } // LCOV_EXCL_LINE
7964 : : ;
7965 : :
7966 : : constraint_set<nodep>: // ==IEEE: constraint_set
7967 : : constraint_expression { $$ = $1; }
7968 : : | '{' constraint_expressionList '}' { $$ = $2; }
7969 : : //
7970 : : | '{' error '}' { $$ = nullptr; } // LCOV_EXCL_LINE
7971 : : | '{' constraint_expressionList error '}' { $$ = $2; } // LCOV_EXCL_LINE
7972 : : ;
7973 : :
7974 : : dist_list<distItemp>: // ==IEEE: dist_list
7975 : : dist_item { $$ = $1; }
7976 : : | dist_list ',' dist_item { $$ = addNextNull($1, $3); }
7977 : : ;
7978 : :
7979 : : dist_item<distItemp>: // ==IEEE: dist_item + dist_weight
7980 : : value_range
7981 : : { $$ = new AstDistItem{$1->fileline(), $1, new AstConst{$1->fileline(), 1}}; }
7982 : : | value_range yP_COLONEQ expr
7983 : : { $$ = new AstDistItem{$2, $1, $3}; }
7984 : : | value_range yP_COLONDIV expr
7985 : : { $$ = new AstDistItem{$2, $1, $3}; $$->isWhole(true); }
7986 : : // // IEEE 1800-2023 added:
7987 : : | yDEFAULT yP_COLONDIV expr
7988 : : { BBUNSUP($<fl>2, "Unsupported: 'default :/' constraint");
7989 : : $$ = nullptr; DEL($3); }
7990 : : ;
7991 : :
7992 : : extern_constraint_declaration<constraintp>: // ==IEEE: extern_constraint_declaration
7993 : : constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE constraintIdNew constraint_block
7994 : : { $$ = $5; $$->isStatic($1); $$->isExternDef(true);
7995 : : $$->baseOverride($3); $$->classOrPackagep($4); $$->addItemsp($6); }
7996 : : ;
7997 : :
7998 : : constraintStaticE<cbool>: // IEEE: part of extern_constraint_declaration
7999 : : /* empty */ { $$ = false; }
8000 : : | ySTATIC__CONSTRAINT { $$ = true; }
8001 : : ;
8002 : :
8003 : : //**********************************************************************
8004 : : // Constants
8005 : :
8006 : : timeNumAdjusted<nodeExprp>: // Time constant, adjusted to module's time units/precision
8007 : : yaTIMENUM
8008 : : { $$ = new AstTimeImport{$<fl>1, new AstConst{$<fl>1, AstConst::RealDouble{}, $1}}; }
8009 : : ;
8010 : :
8011 : : //**********************************************************************
8012 : : // Generic tokens
8013 : :
8014 : : colon<fl>: // Generic colon that isn't making a label (e.g. in a case_item)
8015 : : ':' { $$ = $1; }
8016 : : | yP_COLON__BEGIN { $$ = $1; }
8017 : : | yP_COLON__FORK { $$ = $1; }
8018 : : ;
8019 : :
8020 : : //**********************************************************************
8021 : : // Config - config...endconfig
8022 : :
8023 : : config_declaration: // == IEEE: config_declaration
8024 : : yCONFIG idAny/*config_identifier*/ ';'
8025 : : /*cont*/ configParameterListE design_statement config_rule_statementListE
8026 : : /*cont*/ yENDCONFIG endLabelE
8027 : : { AstConfig* const newp = new AstConfig{$1, PARSEP->libname(), *$2};
8028 : : newp->addDesignp($5);
8029 : : newp->addItemsp($4);
8030 : : newp->addItemsp($6);
8031 : : GRAMMARP->endLabel($<fl>7, *$2, $8);
8032 : : PARSEP->rootp()->addMiscsp(newp); }
8033 : : ;
8034 : :
8035 : : configParameterListE<nodep>: // IEEE: { local_parameter_declaration ';' }
8036 : : /* empty */ { $$ = nullptr; }
8037 : : | configParameterList { $$ = $1; }
8038 : : ;
8039 : :
8040 : : configParameterList<nodep>: // IEEE: part of config_declaration
8041 : : configParameter { $$ = nullptr; DEL($1); }
8042 : : | configParameterList configParameter { $$ = addNextNull($1, $2); }
8043 : : ;
8044 : :
8045 : : configParameter<nodep>: // IEEE: part of config_declaration
8046 : : parameter_declaration ';'
8047 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: config localparam declaration"); DEL($1); }
8048 : : ;
8049 : :
8050 : : design_statement<configCellp>: // == IEEE: design_statement
8051 : : yDESIGN configCellList ';' { $$ = $2; }
8052 : : ;
8053 : :
8054 : : configCellList<configCellp>: // IEEE: part of design_statement
8055 : : configCell { $$ = $1; }
8056 : : | configCellList configCell { $$ = addNextNull($1, $2); }
8057 : : ;
8058 : :
8059 : : configCell<configCellp>: // IEEE: part of design_statement, part of cell_clause
8060 : : idAny/*cell_identifier*/
8061 : : { $$ = new AstConfigCell{$<fl>1, PARSEP->libname(), *$1}; }
8062 : : | idAny/*library_identifier*/ '.' idAny/*cell_identifier*/
8063 : : { $$ = new AstConfigCell{$<fl>1, *$1, *$3}; }
8064 : : ;
8065 : :
8066 : : config_rule_statementListE<nodep>: // IEEE: { config_rule }
8067 : : /* empty */ { $$ = nullptr; }
8068 : : | config_rule_statementList { $$ = $1; }
8069 : : ;
8070 : :
8071 : : config_rule_statementList<nodep>: // IEEE: { config_rule }
8072 : : config_rule_statement { $$ = $1; }
8073 : : | config_rule_statementList config_rule_statement { $$ = addNextNull($1, $2); }
8074 : : ;
8075 : :
8076 : : config_rule_statement<nodep>: // == IEEE: config_rule_statement
8077 : : // // IEEE: default_clause
8078 : : yDEFAULT liblist_clause ';'
8079 : : { $$ = new AstConfigRule{$1, nullptr, $2, false}; }
8080 : : // // IEEE: inst_clause
8081 : : | yINSTANCE inst_name liblist_clause ';'
8082 : : { $$ = new AstConfigRule{$1, $2, $3, false}; }
8083 : : | yINSTANCE inst_name use_clause ';'
8084 : : { $$ = new AstConfigRule{$1, $2, $3, false}; }
8085 : : // // IEEE: cell_clause
8086 : : | yCELL configCell liblist_clause ';'
8087 : : { $$ = new AstConfigRule{$1, $2, $3, true}; }
8088 : : | yCELL configCell use_clause ';'
8089 : : { $$ = new AstConfigRule{$1, $2, $3, true}; }
8090 : : | error ';'
8091 : : { $$ = nullptr; } // LCOV_EXCL_LINE
8092 : : ;
8093 : :
8094 : : inst_name<nodeExprp>: // == IEEE: inst_name
8095 : : idAnyAsParseRef/*topmodule_identifier*/
8096 : : { $$ = $1; }
8097 : : | idAnyAsParseRef/*topmodule_identifier*/ inst_nameInstanceList
8098 : : { $$ = new AstDot{$<fl>1, false, $1, $2}; }
8099 : : ;
8100 : :
8101 : : inst_nameInstanceList<nodeExprp>: // IEEE: part of inst_name
8102 : : '.' idAnyAsParseRef/*instance_identifier*/
8103 : : { $$ = $2; }
8104 : : | inst_nameInstanceList '.' idAnyAsParseRef/*instance_identifier*/
8105 : : { $$ = new AstDot{$<fl>2, false, $1, $3}; }
8106 : : ;
8107 : :
8108 : : liblist_clause<nodep>: // == IEEE: liblist_clause
8109 : : yLIBLIST { $$ = nullptr; }
8110 : : | yLIBLIST liblistLibraryList { $$ = $2; }
8111 : : ;
8112 : :
8113 : : liblistLibraryList<nodeExprp>: // IEEE: part of liblist_clause
8114 : : idAnyAsParseRef/*library_identifier*/
8115 : : { $$ = $1; }
8116 : : | liblistLibraryList idAnyAsParseRef/*library_identifier*/
8117 : : { $$ = addNextNull($1, $2); }
8118 : : ;
8119 : :
8120 : : use_clause<nodep>: // == IEEE: use_clause
8121 : : yUSE idAny/*cell_identifier*/ useAssignmentListE colonConfigE
8122 : : { $$ = new AstConfigUse{$1, "", *$2, $3, $4}; }
8123 : : | yUSE idAny/*library_identifier*/ '.' idAny/*cell_identifier*/ useAssignmentListE colonConfigE
8124 : : { $$ = new AstConfigUse{$1, *$2, *$4, $5, $6}; }
8125 : : | yUSE useAssignmentListE colonConfigE
8126 : : { $$ = new AstConfigUse{$1, "", "", $2, $3}; }
8127 : : ;
8128 : :
8129 : : useAssignmentListE<pinp>: // IEEE: part of use clause
8130 : : /* empty */ { $$ = nullptr; }
8131 : : // // IEEE is missing the '#' '(', but examples need it
8132 : : | '#' '(' ')' { $$ = nullptr; }
8133 : : | '#' '(' useAssignmentList ')' { $$ = $3; }
8134 : : ;
8135 : :
8136 : : useAssignmentList<pinp>: // IEEE: part of use_clause
8137 : : useAssignment { $$ = $1; }
8138 : : | useAssignmentList ',' useAssignment { $$ = addNextNull($1, $3); }
8139 : : ;
8140 : :
8141 : : useAssignment<pinp>: // IEEE: part of use_clause
8142 : : // // IEEE: named_parameter_assignment
8143 : : '.' idAny/*parameter_identifier*/ '(' ')'
8144 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: 'config use' parameter assignment"); }
8145 : : | '.' idAny/*parameter_identifier*/ '(' exprOrDataType ')'
8146 : : { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: 'config use' parameter assignment"); DEL($4); }
8147 : : ;
8148 : :
8149 : : colonConfigE<cbool>: // IEEE: [ ':' yCONFIG]
8150 : : /* empty */ { $$ = false; }
8151 : : | ':' yCONFIG { $$ = true; }
8152 : : ;
8153 : :
8154 : : //**********************************************************************
8155 : : // Config - lib.map
8156 : : //
8157 : :
8158 : : library_declaration<nodep>: // IEEE: library_declaration
8159 : : yLIBRARY yaSTRING file_path_specList incdirE ';'
8160 : : { $$ = new AstLibrary{$<fl>1, *$2, $3, $4}; }
8161 : : ;
8162 : : incdirE<nodeExprp>: // IEEE: [ '-' yINCDIR file_path_specList ';']
8163 : : /* empty */ { $$ = nullptr; }
8164 : : // https://accellera.mantishub.io/view.php?id=1166
8165 : : | yINCDIR file_path_specList { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: config incdir"); }
8166 : : ;
8167 : : include_statement<nodep>: // IEEE: include_statement
8168 : : yINCLUDE file_path_spec ';' { $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: config include"); }
8169 : : ;
8170 : : file_path_specList<nodeExprp>: // IEEE: file_path_spec { ',' file_path_spec }
8171 : : file_path_spec { $$ = $1; }
8172 : : | file_path_specList ',' file_path_spec { $$ = addNextNull($1, $3); }
8173 : : ;
8174 : : file_path_spec<nodeExprp>: // IEEE: file_path_spec
8175 : : yaSTRING { $$ = new AstParseRef{$<fl>1, *$1}; }
8176 : : ;
8177 : :
8178 : : //**********************************************************************
8179 : : // VLT Files
8180 : :
8181 : : vltItem:
8182 : : // // TODO support arbitrary order of arguments
8183 : : vltOffFront
8184 : : { V3Control::addIgnore($1, false, "*", 0, 0); }
8185 : : | vltOffFront vltDFile
8186 : : { V3Control::addIgnore($1, false, *$2, 0, 0); }
8187 : : | vltOffFront vltDFile yVLT_D_LINES yaINTNUM
8188 : : { V3Control::addIgnore($1, false, *$2, $4->toUInt(), $4->toUInt()); }
8189 : : | vltOffFront vltDFile yVLT_D_LINES yaINTNUM '-' yaINTNUM
8190 : : { V3Control::addIgnore($1, false, *$2, $4->toUInt(), $6->toUInt()); }
8191 : : | vltOffFront vltDFile vltDMatch
8192 : : { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) {
8193 : : $<fl>1->v3error("Argument -match only supported for lint_off");
8194 : : } else {
8195 : : V3Control::addIgnoreMatch($1, *$2, "", *$3);
8196 : : }}
8197 : : | vltOffFront vltDFile vltDContents
8198 : : { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) {
8199 : : $<fl>1->v3error("Argument -match only supported for lint_off");
8200 : : } else {
8201 : : V3Control::addIgnoreMatch($1, *$2, *$3, "*");
8202 : : }}
8203 : : | vltOffFront vltDFile vltDContents vltDMatch
8204 : : { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) {
8205 : : $<fl>1->v3error("Argument -match only supported for lint_off");
8206 : : } else {
8207 : : V3Control::addIgnoreMatch($1, *$2, *$3, *$4);
8208 : : }}
8209 : : | vltOffFront vltDScope
8210 : : { if ($1 != V3ErrorCode::I_TRACING) {
8211 : : $<fl>1->v3error("Argument -scope only supported for tracing_on/off");
8212 : : } else {
8213 : : V3Control::addScopeTraceOn(false, *$2, 0);
8214 : : }}
8215 : : | vltOffFront vltDScope vltDLevels
8216 : : { if ($1 != V3ErrorCode::I_TRACING) {
8217 : : $<fl>1->v3error("Argument -scope only supported for tracing_on/off_off");
8218 : : } else {
8219 : : V3Control::addScopeTraceOn(false, *$2, $3->toUInt());
8220 : : }}
8221 : : | vltOnFront
8222 : : { V3Control::addIgnore($1, true, "*", 0, 0); }
8223 : : | vltOnFront vltDFile
8224 : : { V3Control::addIgnore($1, true, *$2, 0, 0); }
8225 : : | vltOnFront vltDFile yVLT_D_LINES yaINTNUM
8226 : : { V3Control::addIgnore($1, true, *$2, $4->toUInt(), $4->toUInt()); }
8227 : : | vltOnFront vltDFile yVLT_D_LINES yaINTNUM '-' yaINTNUM
8228 : : { V3Control::addIgnore($1, true, *$2, $4->toUInt(), $6->toUInt()); }
8229 : : | vltOnFront vltDScope
8230 : : { if ($1 != V3ErrorCode::I_TRACING) {
8231 : : $<fl>1->v3error("Argument -scope only supported for tracing_on/off");
8232 : : } else {
8233 : : V3Control::addScopeTraceOn(true, *$2, 0);
8234 : : }}
8235 : : | vltOnFront vltDScope vltDLevels
8236 : : { if ($1 != V3ErrorCode::I_TRACING) {
8237 : : $<fl>1->v3error("Argument -scope only supported for tracing_on/off_off");
8238 : : } else {
8239 : : V3Control::addScopeTraceOn(true, *$2, $3->toUInt());
8240 : : }}
8241 : : | vltVarAttrFront vltDModuleE vltDFTaskE vltVarAttrSpecE attr_event_controlE
8242 : : { V3Control::addVarAttr($<fl>1, *$2, *$3, GRAMMARP->m_vltVarSpecKind, *$4, $1, $5); }
8243 : : | vltVarAttrFrontDeprecated vltDModuleE vltDFTaskE vltVarAttrSpecE
8244 : : { /* Historical, now has no effect */ }
8245 : : | vltInlineFront vltDModuleE vltDFTaskE
8246 : : { V3Control::addInline($<fl>1, *$2, *$3, $1); }
8247 : : | yVLT_COVERAGE_BLOCK_OFF vltDFile
8248 : : { V3Control::addCoverageBlockOff(*$2, 0); }
8249 : : | yVLT_COVERAGE_BLOCK_OFF vltDFile yVLT_D_LINES yaINTNUM
8250 : : { V3Control::addCoverageBlockOff(*$2, $4->toUInt()); }
8251 : : | yVLT_COVERAGE_BLOCK_OFF vltDModule vltDBlock
8252 : : { V3Control::addCoverageBlockOff(*$2, *$3); }
8253 : : | yVLT_FULL_CASE vltDFile
8254 : : { V3Control::addCaseFull(*$2, 0); }
8255 : : | yVLT_FULL_CASE vltDFile yVLT_D_LINES yaINTNUM
8256 : : { V3Control::addCaseFull(*$2, $4->toUInt()); }
8257 : : | yVLT_HIER_BLOCK vltDModuleE
8258 : : { V3Control::addModulePragma(*$2, VPragmaType::HIER_BLOCK); }
8259 : : | yVLT_HIER_PARAMS vltDModuleE
8260 : : { V3Control::addModulePragma(*$2, VPragmaType::HIER_PARAMS); }
8261 : : | yVLT_HIER_WORKERS vltDModuleE vltDWorkers
8262 : : { V3Control::addHierWorkers($<fl>1, *$2, $3->toSInt()); }
8263 : : | yVLT_HIER_WORKERS vltDHierDpi vltDWorkers
8264 : : { V3Control::addHierWorkers($<fl>1, *$2, $3->toSInt()); }
8265 : : | yVLT_PARALLEL_CASE vltDFile
8266 : : { V3Control::addCaseParallel(*$2, 0); }
8267 : : | yVLT_PARALLEL_CASE vltDFile yVLT_D_LINES yaINTNUM
8268 : : { V3Control::addCaseParallel(*$2, $4->toUInt()); }
8269 : : | yVLT_PROFILE_DATA vltDHierDpi vltDCost
8270 : : { V3Control::addProfileData($<fl>1, *$2, $3->toUQuad()); }
8271 : : | yVLT_PROFILE_DATA vltDModel vltDMtask vltDCost
8272 : : { V3Control::addProfileData($<fl>1, *$2, *$3, $4->toUQuad()); }
8273 : : | yVLT_VERILATOR_LIB vltDModule
8274 : : { V3Control::addModulePragma(*$2, VPragmaType::VERILATOR_LIB); }
8275 : : ;
8276 : :
8277 : : vltOffFront<errcodeen>:
8278 : : yVLT_COVERAGE_OFF { $$ = V3ErrorCode::I_COVERAGE; }
8279 : : | yVLT_TIMING_OFF { $$ = V3ErrorCode::I_TIMING; }
8280 : : | yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; }
8281 : : | yVLT_LINT_OFF { $$ = V3ErrorCode::I_LINT; }
8282 : : | yVLT_LINT_OFF yVLT_D_RULE idAny
8283 : : { $$ = V3ErrorCode{*$3};
8284 : : if ($$ == V3ErrorCode::EC_ERROR) $1->v3error("Unknown error code: '" << *$3 << "'"); }
8285 : : ;
8286 : :
8287 : : vltOnFront<errcodeen>:
8288 : : yVLT_COVERAGE_ON { $$ = V3ErrorCode::I_COVERAGE; }
8289 : : | yVLT_TIMING_ON { $$ = V3ErrorCode::I_TIMING; }
8290 : : | yVLT_TRACING_ON { $$ = V3ErrorCode::I_TRACING; }
8291 : : | yVLT_LINT_ON { $$ = V3ErrorCode::I_LINT; }
8292 : : | yVLT_LINT_ON yVLT_D_RULE idAny
8293 : : { $$ = V3ErrorCode{*$3};
8294 : : if ($$ == V3ErrorCode::EC_ERROR) $1->v3error("Unknown error code: '" << *$3 << "'"); }
8295 : : ;
8296 : :
8297 : : vltDBlock<strp>: // --block <arg>
8298 : : yVLT_D_BLOCK str { $$ = $2; }
8299 : : ;
8300 : :
8301 : : vltDContents<strp>:
8302 : : yVLT_D_CONTENTS str { $$ = $2; }
8303 : : ;
8304 : :
8305 : : vltDCost<nump>: // --cost <arg>
8306 : : yVLT_D_COST yaINTNUM { $$ = $2; }
8307 : : ;
8308 : :
8309 : : vltDFile<strp>: // --file <arg>
8310 : : yVLT_D_FILE str { $$ = $2; }
8311 : : ;
8312 : :
8313 : : vltDHierDpi<strp>: // --hier-dpi <arg>
8314 : : yVLT_D_HIER_DPI str { $$ = $2; }
8315 : : ;
8316 : :
8317 : : vltDLevels<nump>: // --levels <arg>
8318 : : yVLT_D_LEVELS yaINTNUM { $$ = $2; }
8319 : : ;
8320 : :
8321 : : vltDMatch<strp>: // --match <arg>
8322 : : yVLT_D_MATCH str { $$ = $2; }
8323 : : ;
8324 : :
8325 : : vltDModel<strp>: // --model <arg>
8326 : : yVLT_D_MODEL str { $$ = $2; }
8327 : : ;
8328 : :
8329 : : vltDMtask<strp>: // --mtask <arg>
8330 : : yVLT_D_MTASK str { $$ = $2; }
8331 : : ;
8332 : :
8333 : : vltDModule<strp>: // --module <arg>
8334 : : yVLT_D_MODULE str { $$ = $2; }
8335 : : ;
8336 : :
8337 : : vltDModuleE<strp>: // [--module <arg>]
8338 : : /* empty */
8339 : : { static string unit = "$unit"; $$ = &unit; } // .vlt uses prettyName
8340 : : | vltDModule
8341 : : { $$ = $1; }
8342 : : ;
8343 : :
8344 : : vltDScope<strp>: // --scope <arg>
8345 : : yVLT_D_SCOPE str { $$ = $2; }
8346 : : ;
8347 : :
8348 : : vltDFTaskE<strp>:
8349 : : /* empty */ { static string empty; $$ = ∅ }
8350 : : | yVLT_D_FUNCTION str { $$ = $2; }
8351 : : | yVLT_D_TASK str { $$ = $2; }
8352 : : ;
8353 : :
8354 : : vltDWorkers<nump>: // --workers <arg>
8355 : : yVLT_D_WORKERS yaINTNUM { $$ = $2; }
8356 : : ;
8357 : :
8358 : : vltInlineFront<cbool>:
8359 : : yVLT_INLINE { $$ = true; }
8360 : : | yVLT_NO_INLINE { $$ = false; }
8361 : : ;
8362 : :
8363 : : vltVarAttrSpecE<strp>:
8364 : : /* empty */
8365 : : { GRAMMARP->m_vltVarSpecKind = V3Control::VarSpecKind::VAR; static std::string empty; $$ = ∅ }
8366 : : | yVLT_D_PARAM str
8367 : : { GRAMMARP->m_vltVarSpecKind = V3Control::VarSpecKind::PARAM; $$ = $2; }
8368 : : | yVLT_D_PORT str
8369 : : { GRAMMARP->m_vltVarSpecKind = V3Control::VarSpecKind::PORT; $$ = $2; }
8370 : : | yVLT_D_VAR str
8371 : : { GRAMMARP->m_vltVarSpecKind = V3Control::VarSpecKind::VAR; $$ = $2; }
8372 : : ;
8373 : :
8374 : : vltVarAttrFront<attrtypeen>:
8375 : : yVLT_ISOLATE_ASSIGNMENTS { $$ = VAttrType::VAR_ISOLATE_ASSIGNMENTS; }
8376 : : | yVLT_FORCEABLE { $$ = VAttrType::VAR_FORCEABLE; }
8377 : : | yVLT_PUBLIC { $$ = VAttrType::VAR_PUBLIC; v3Global.dpi(true); }
8378 : : | yVLT_PUBLIC_FLAT { $$ = VAttrType::VAR_PUBLIC_FLAT; v3Global.dpi(true); }
8379 : : | yVLT_PUBLIC_FLAT_RD { $$ = VAttrType::VAR_PUBLIC_FLAT_RD; v3Global.dpi(true); }
8380 : : | yVLT_PUBLIC_FLAT_RW { $$ = VAttrType::VAR_PUBLIC_FLAT_RW; v3Global.dpi(true); }
8381 : : | yVLT_SC_BIGUINT { $$ = VAttrType::VAR_SC_BIGUINT; }
8382 : : | yVLT_SC_BV { $$ = VAttrType::VAR_SC_BV; }
8383 : : | yVLT_SFORMAT { $$ = VAttrType::VAR_SFORMAT; }
8384 : : | yVLT_SPLIT_VAR { $$ = VAttrType::VAR_SPLIT_VAR; }
8385 : : ;
8386 : :
8387 : : vltVarAttrFrontDeprecated:
8388 : : yVLT_CLOCK_ENABLE { }
8389 : : | yVLT_CLOCKER { }
8390 : : | yVLT_NO_CLOCKER { }
8391 : : ;
8392 : :
8393 : : //**********************************************************************
8394 : : %%
8395 : : // For implementation functions see V3ParseGrammar.cpp
8396 : :
8397 : : //YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead
8398 : : // --report=lookahead
8399 : : // --report=itemset
8400 : : // --graph
|