verilog: also set location for simple_behavioral_stmt
[yosys.git] / frontends / verilog / verilog_parser.y
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * ---
19 *
20 * The Verilog frontend.
21 *
22 * This frontend is using the AST frontend library (see frontends/ast/).
23 * Thus this frontend does not generate RTLIL code directly but creates an
24 * AST directly from the Verilog parse tree and then passes this AST to
25 * the AST frontend library.
26 *
27 * ---
28 *
29 * This is the actual bison parser for Verilog code. The AST ist created directly
30 * from the bison reduce functions here. Note that this code uses a few global
31 * variables to hold the state of the AST generator and therefore this parser is
32 * not reentrant.
33 *
34 */
35
36 %{
37 #include <list>
38 #include <stack>
39 #include <string.h>
40 #include "frontends/verilog/verilog_frontend.h"
41 #include "frontends/verilog/verilog_parser.tab.hh"
42 #include "kernel/log.h"
43
44 #define YYLEX_PARAM &yylval, &yylloc
45
46 USING_YOSYS_NAMESPACE
47 using namespace AST;
48 using namespace VERILOG_FRONTEND;
49
50 YOSYS_NAMESPACE_BEGIN
51 namespace VERILOG_FRONTEND {
52 int port_counter;
53 std::map<std::string, int> port_stubs;
54 std::map<std::string, AstNode*> *attr_list, default_attr_list;
55 std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
56 std::map<std::string, AstNode*> *albuf;
57 std::vector<AstNode*> ast_stack;
58 struct AstNode *astbuf1, *astbuf2, *astbuf3;
59 struct AstNode *current_function_or_task;
60 struct AstNode *current_ast, *current_ast_mod;
61 int current_function_or_task_port_id;
62 std::vector<char> case_type_stack;
63 bool do_not_require_port_stubs;
64 bool default_nettype_wire;
65 bool sv_mode, formal_mode, lib_mode, specify_mode;
66 bool noassert_mode, noassume_mode, norestrict_mode;
67 bool assume_asserts_mode, assert_assumes_mode;
68 bool current_wire_rand, current_wire_const;
69 bool current_modport_input, current_modport_output;
70 std::istream *lexin;
71 }
72 YOSYS_NAMESPACE_END
73
74 #define SET_AST_NODE_LOC(WHICH, BEGIN, END) \
75 do { (WHICH)->location.first_line = (BEGIN).first_line; \
76 (WHICH)->location.first_column = (BEGIN).first_column; \
77 (WHICH)->location.last_line = (END).last_line; \
78 (WHICH)->location.last_column = (END).last_column; } while(0)
79
80 #define SET_RULE_LOC(LHS, BEGIN, END) \
81 do { (LHS).first_line = (BEGIN).first_line; \
82 (LHS).first_column = (BEGIN).first_column; \
83 (LHS).last_line = (END).last_line; \
84 (LHS).last_column = (END).last_column; } while(0)
85
86 int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
87
88 static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
89 {
90 for (auto &it : *al) {
91 if (ast->attributes.count(it.first) > 0)
92 delete ast->attributes[it.first];
93 ast->attributes[it.first] = it.second;
94 }
95 delete al;
96 }
97
98 static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
99 {
100 for (auto &it : *al) {
101 if (ast->attributes.count(it.first) > 0)
102 delete ast->attributes[it.first];
103 ast->attributes[it.first] = it.second->clone();
104 }
105 }
106
107 static void free_attr(std::map<std::string, AstNode*> *al)
108 {
109 for (auto &it : *al)
110 delete it.second;
111 delete al;
112 }
113
114 struct specify_target {
115 char polarity_op;
116 AstNode *dst, *dat;
117 };
118
119 struct specify_triple {
120 AstNode *t_min, *t_avg, *t_max;
121 };
122
123 struct specify_rise_fall {
124 specify_triple rise;
125 specify_triple fall;
126 };
127
128 static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true)
129 {
130 auto range = new AstNode(AST_RANGE);
131 range->children.push_back(AstNode::mkconst_int(msb, true));
132 range->children.push_back(AstNode::mkconst_int(lsb, true));
133 range->is_signed = isSigned;
134 return range;
135 }
136
137 static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned = true)
138 {
139 auto range = makeRange(msb, lsb, isSigned);
140 parent->children.push_back(range);
141 }
142 %}
143
144 %define api.prefix {frontend_verilog_yy}
145 %define api.pure
146
147 /* The union is defined in the header, so we need to provide all the
148 * includes it requires
149 */
150 %code requires {
151 #include <map>
152 #include <string>
153 #include "frontends/verilog/verilog_frontend.h"
154 }
155
156 %union {
157 std::string *string;
158 struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast;
159 std::map<std::string, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
160 struct specify_target *specify_target_ptr;
161 struct specify_triple *specify_triple_ptr;
162 struct specify_rise_fall *specify_rise_fall_ptr;
163 bool boolean;
164 char ch;
165 }
166
167 %token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
168 %token <string> TOK_SVA_LABEL TOK_SPECIFY_OPER TOK_MSG_TASKS
169 %token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER TOK_FINAL
170 %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
171 %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
172 %token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
173 %token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR TOK_WILDCARD_CONNECT
174 %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_WAND TOK_WOR TOK_REG TOK_LOGIC
175 %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL
176 %token TOK_ALWAYS_FF TOK_ALWAYS_COMB TOK_ALWAYS_LATCH
177 %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT
178 %token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC
179 %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT
180 %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK TOK_SPECIFY
181 %token TOK_IGNORED_SPECIFY TOK_ENDSPECIFY TOK_SPECPARAM TOK_SPECIFY_AND TOK_IGNORED_SPECIFY_AND
182 %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
183 %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
184 %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
185 %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
186 %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
187 %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
188
189 %type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
190 %type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
191 %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
192 %type <ast> opt_enum_init
193 %type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
194 %type <al> attr case_attr
195
196 %type <specify_target_ptr> specify_target
197 %type <specify_triple_ptr> specify_triple specify_opt_triple
198 %type <specify_rise_fall_ptr> specify_rise_fall
199 %type <ast> specify_if specify_condition
200 %type <ch> specify_edge
201
202 // operator precedence from low to high
203 %left OP_LOR
204 %left OP_LAND
205 %left '|' OP_NOR
206 %left '^' OP_XNOR
207 %left '&' OP_NAND
208 %left OP_EQ OP_NE OP_EQX OP_NEX
209 %left '<' OP_LE OP_GE '>'
210 %left OP_SHL OP_SHR OP_SSHL OP_SSHR
211 %left '+' '-'
212 %left '*' '/' '%'
213 %left OP_POW
214 %right UNARY_OPS
215
216 %define parse.error verbose
217 %define parse.lac full
218
219 %nonassoc FAKE_THEN
220 %nonassoc TOK_ELSE
221
222 %debug
223 %locations
224
225 %%
226
227 input: {
228 ast_stack.clear();
229 ast_stack.push_back(current_ast);
230 } design {
231 ast_stack.pop_back();
232 log_assert(GetSize(ast_stack) == 0);
233 for (auto &it : default_attr_list)
234 delete it.second;
235 default_attr_list.clear();
236 };
237
238 design:
239 module design |
240 defattr design |
241 task_func_decl design |
242 param_decl design |
243 localparam_decl design |
244 typedef_decl design |
245 package design |
246 interface design |
247 /* empty */;
248
249 attr:
250 {
251 if (attr_list != nullptr)
252 attr_list_stack.push(attr_list);
253 attr_list = new std::map<std::string, AstNode*>;
254 for (auto &it : default_attr_list)
255 (*attr_list)[it.first] = it.second->clone();
256 } attr_opt {
257 $$ = attr_list;
258 if (!attr_list_stack.empty()) {
259 attr_list = attr_list_stack.top();
260 attr_list_stack.pop();
261 } else
262 attr_list = nullptr;
263 };
264
265 attr_opt:
266 attr_opt ATTR_BEGIN opt_attr_list ATTR_END {
267 SET_RULE_LOC(@$, @2, @$);
268 }|
269 /* empty */;
270
271 defattr:
272 DEFATTR_BEGIN {
273 if (attr_list != nullptr)
274 attr_list_stack.push(attr_list);
275 attr_list = new std::map<std::string, AstNode*>;
276 for (auto &it : default_attr_list)
277 delete it.second;
278 default_attr_list.clear();
279 } opt_attr_list {
280 attr_list->swap(default_attr_list);
281 delete attr_list;
282 if (!attr_list_stack.empty()) {
283 attr_list = attr_list_stack.top();
284 attr_list_stack.pop();
285 } else
286 attr_list = nullptr;
287 } DEFATTR_END;
288
289 opt_attr_list:
290 attr_list | /* empty */;
291
292 attr_list:
293 attr_assign |
294 attr_list ',' attr_assign;
295
296 attr_assign:
297 hierarchical_id {
298 if (attr_list->count(*$1) != 0)
299 delete (*attr_list)[*$1];
300 (*attr_list)[*$1] = AstNode::mkconst_int(1, false);
301 delete $1;
302 } |
303 hierarchical_id '=' expr {
304 if (attr_list->count(*$1) != 0)
305 delete (*attr_list)[*$1];
306 (*attr_list)[*$1] = $3;
307 delete $1;
308 };
309
310 hierarchical_id:
311 TOK_ID {
312 $$ = $1;
313 } |
314 hierarchical_id TOK_PACKAGESEP TOK_ID {
315 if ($3->compare(0, 1, "\\") == 0)
316 *$1 += "::" + $3->substr(1);
317 else
318 *$1 += "::" + *$3;
319 delete $3;
320 $$ = $1;
321 } |
322 hierarchical_id '.' TOK_ID {
323 if ($3->compare(0, 1, "\\") == 0)
324 *$1 += "." + $3->substr(1);
325 else
326 *$1 += "." + *$3;
327 delete $3;
328 $$ = $1;
329 };
330
331 hierarchical_type_id:
332 '(' hierarchical_id ')' { $$ = $2; };
333
334 module:
335 attr TOK_MODULE TOK_ID {
336 do_not_require_port_stubs = false;
337 AstNode *mod = new AstNode(AST_MODULE);
338 ast_stack.back()->children.push_back(mod);
339 ast_stack.push_back(mod);
340 current_ast_mod = mod;
341 port_stubs.clear();
342 port_counter = 0;
343 mod->str = *$3;
344 append_attr(mod, $1);
345 delete $3;
346 } module_para_opt module_args_opt ';' module_body TOK_ENDMODULE {
347 if (port_stubs.size() != 0)
348 frontend_verilog_yyerror("Missing details for module port `%s'.",
349 port_stubs.begin()->first.c_str());
350 SET_AST_NODE_LOC(ast_stack.back(), @2, @$);
351 ast_stack.pop_back();
352 log_assert(ast_stack.size() == 1);
353 current_ast_mod = NULL;
354 };
355
356 module_para_opt:
357 '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | /* empty */;
358
359 module_para_list:
360 single_module_para | module_para_list ',' single_module_para;
361
362 single_module_para:
363 /* empty */ |
364 attr TOK_PARAMETER {
365 if (astbuf1) delete astbuf1;
366 astbuf1 = new AstNode(AST_PARAMETER);
367 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
368 append_attr(astbuf1, $1);
369 } param_type single_param_decl |
370 attr TOK_LOCALPARAM {
371 if (astbuf1) delete astbuf1;
372 astbuf1 = new AstNode(AST_LOCALPARAM);
373 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
374 append_attr(astbuf1, $1);
375 } param_type single_param_decl |
376 single_param_decl;
377
378 module_args_opt:
379 '(' ')' | /* empty */ | '(' module_args optional_comma ')';
380
381 module_args:
382 module_arg | module_args ',' module_arg;
383
384 optional_comma:
385 ',' | /* empty */;
386
387 module_arg_opt_assignment:
388 '=' expr {
389 if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
390 AstNode *wire = new AstNode(AST_IDENTIFIER);
391 wire->str = ast_stack.back()->children.back()->str;
392 if (ast_stack.back()->children.back()->is_input) {
393 AstNode *n = ast_stack.back()->children.back();
394 if (n->attributes.count("\\defaultvalue"))
395 delete n->attributes.at("\\defaultvalue");
396 n->attributes["\\defaultvalue"] = $2;
397 } else
398 if (ast_stack.back()->children.back()->is_reg || ast_stack.back()->children.back()->is_logic)
399 ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2))));
400 else
401 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2));
402 } else
403 frontend_verilog_yyerror("SystemVerilog interface in module port list cannot have a default value.");
404 } |
405 /* empty */;
406
407 module_arg:
408 TOK_ID {
409 if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
410 AstNode *node = ast_stack.back()->children.back()->clone();
411 node->str = *$1;
412 node->port_id = ++port_counter;
413 ast_stack.back()->children.push_back(node);
414 SET_AST_NODE_LOC(node, @1, @1);
415 } else {
416 if (port_stubs.count(*$1) != 0)
417 frontend_verilog_yyerror("Duplicate module port `%s'.", $1->c_str());
418 port_stubs[*$1] = ++port_counter;
419 }
420 delete $1;
421 } module_arg_opt_assignment |
422 TOK_ID {
423 astbuf1 = new AstNode(AST_INTERFACEPORT);
424 astbuf1->children.push_back(new AstNode(AST_INTERFACEPORTTYPE));
425 astbuf1->children[0]->str = *$1;
426 delete $1;
427 } TOK_ID { /* SV interfaces */
428 if (!sv_mode)
429 frontend_verilog_yyerror("Interface found in port list (%s). This is not supported unless read_verilog is called with -sv!", $3->c_str());
430 astbuf2 = astbuf1->clone(); // really only needed if multiple instances of same type.
431 astbuf2->str = *$3;
432 delete $3;
433 astbuf2->port_id = ++port_counter;
434 ast_stack.back()->children.push_back(astbuf2);
435 delete astbuf1; // really only needed if multiple instances of same type.
436 } module_arg_opt_assignment |
437 attr wire_type range TOK_ID {
438 AstNode *node = $2;
439 node->str = *$4;
440 SET_AST_NODE_LOC(node, @4, @4);
441 node->port_id = ++port_counter;
442 if ($3 != NULL)
443 node->children.push_back($3);
444 if (!node->is_input && !node->is_output)
445 frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $4->c_str());
446 if (node->is_reg && node->is_input && !node->is_output && !sv_mode)
447 frontend_verilog_yyerror("Input port `%s' is declared as register.", $4->c_str());
448 ast_stack.back()->children.push_back(node);
449 append_attr(node, $1);
450 delete $4;
451 } module_arg_opt_assignment |
452 '.' '.' '.' {
453 do_not_require_port_stubs = true;
454 };
455
456 package:
457 attr TOK_PACKAGE TOK_ID {
458 AstNode *mod = new AstNode(AST_PACKAGE);
459 ast_stack.back()->children.push_back(mod);
460 ast_stack.push_back(mod);
461 current_ast_mod = mod;
462 mod->str = *$3;
463 append_attr(mod, $1);
464 } ';' package_body TOK_ENDPACKAGE {
465 ast_stack.pop_back();
466 current_ast_mod = NULL;
467 };
468
469 package_body:
470 package_body package_body_stmt
471 | // optional
472 ;
473
474 package_body_stmt:
475 typedef_decl |
476 localparam_decl;
477
478 interface:
479 TOK_INTERFACE TOK_ID {
480 do_not_require_port_stubs = false;
481 AstNode *intf = new AstNode(AST_INTERFACE);
482 ast_stack.back()->children.push_back(intf);
483 ast_stack.push_back(intf);
484 current_ast_mod = intf;
485 port_stubs.clear();
486 port_counter = 0;
487 intf->str = *$2;
488 delete $2;
489 } module_para_opt module_args_opt ';' interface_body TOK_ENDINTERFACE {
490 if (port_stubs.size() != 0)
491 frontend_verilog_yyerror("Missing details for module port `%s'.",
492 port_stubs.begin()->first.c_str());
493 ast_stack.pop_back();
494 log_assert(ast_stack.size() == 1);
495 current_ast_mod = NULL;
496 };
497
498 interface_body:
499 interface_body interface_body_stmt |;
500
501 interface_body_stmt:
502 param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
503 modport_stmt;
504
505 non_opt_delay:
506 '#' TOK_ID { delete $2; } |
507 '#' TOK_CONSTVAL { delete $2; } |
508 '#' TOK_REALVAL { delete $2; } |
509 '#' '(' expr ')' { delete $3; } |
510 '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; };
511
512 delay:
513 non_opt_delay | /* empty */;
514
515 wire_type:
516 {
517 astbuf3 = new AstNode(AST_WIRE);
518 current_wire_rand = false;
519 current_wire_const = false;
520 } wire_type_token_list {
521 $$ = astbuf3;
522 SET_RULE_LOC(@$, @2, @$);
523 };
524
525 wire_type_token_list:
526 wire_type_token |
527 wire_type_token_list wire_type_token |
528 wire_type_token_io |
529 hierarchical_type_id {
530 astbuf3->is_custom_type = true;
531 astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
532 astbuf3->children.back()->str = *$1;
533 };
534
535 wire_type_token_io:
536 TOK_INPUT {
537 astbuf3->is_input = true;
538 } |
539 TOK_OUTPUT {
540 astbuf3->is_output = true;
541 } |
542 TOK_INOUT {
543 astbuf3->is_input = true;
544 astbuf3->is_output = true;
545 };
546
547 wire_type_token:
548 TOK_WIRE {
549 } |
550 TOK_WOR {
551 astbuf3->is_wor = true;
552 } |
553 TOK_WAND {
554 astbuf3->is_wand = true;
555 } |
556 TOK_REG {
557 astbuf3->is_reg = true;
558 } |
559 TOK_LOGIC {
560 astbuf3->is_logic = true;
561 } |
562 TOK_VAR {
563 astbuf3->is_logic = true;
564 } |
565 TOK_INTEGER {
566 astbuf3->is_reg = true;
567 astbuf3->range_left = 31;
568 astbuf3->range_right = 0;
569 astbuf3->is_signed = true;
570 } |
571 TOK_GENVAR {
572 astbuf3->type = AST_GENVAR;
573 astbuf3->is_reg = true;
574 astbuf3->is_signed = true;
575 astbuf3->range_left = 31;
576 astbuf3->range_right = 0;
577 } |
578 TOK_SIGNED {
579 astbuf3->is_signed = true;
580 } |
581 TOK_RAND {
582 current_wire_rand = true;
583 } |
584 TOK_CONST {
585 current_wire_const = true;
586 };
587
588 non_opt_range:
589 '[' expr ':' expr ']' {
590 $$ = new AstNode(AST_RANGE);
591 $$->children.push_back($2);
592 $$->children.push_back($4);
593 } |
594 '[' expr TOK_POS_INDEXED expr ']' {
595 $$ = new AstNode(AST_RANGE);
596 AstNode *expr = new AstNode(AST_CONCAT, $2);
597 $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), $4), AstNode::mkconst_int(1, true)));
598 $$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
599 } |
600 '[' expr TOK_NEG_INDEXED expr ']' {
601 $$ = new AstNode(AST_RANGE);
602 AstNode *expr = new AstNode(AST_CONCAT, $2);
603 $$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
604 $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), AstNode::mkconst_int(1, true)), $4));
605 } |
606 '[' expr ']' {
607 $$ = new AstNode(AST_RANGE);
608 $$->children.push_back($2);
609 };
610
611 non_opt_multirange:
612 non_opt_range non_opt_range {
613 $$ = new AstNode(AST_MULTIRANGE, $1, $2);
614 } |
615 non_opt_multirange non_opt_range {
616 $$ = $1;
617 $$->children.push_back($2);
618 };
619
620 range:
621 non_opt_range {
622 $$ = $1;
623 } |
624 /* empty */ {
625 $$ = NULL;
626 };
627
628 range_or_multirange:
629 range { $$ = $1; } |
630 non_opt_multirange { $$ = $1; };
631
632 range_or_signed_int:
633 range {
634 $$ = $1;
635 } |
636 TOK_INTEGER {
637 $$ = new AstNode(AST_RANGE);
638 $$->children.push_back(AstNode::mkconst_int(31, true));
639 $$->children.push_back(AstNode::mkconst_int(0, true));
640 $$->is_signed = true;
641 };
642
643 module_body:
644 module_body module_body_stmt |
645 /* the following line makes the generate..endgenrate keywords optional */
646 module_body gen_stmt |
647 /* empty */;
648
649 module_body_stmt:
650 task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
651 enum_decl |
652 always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
653
654 checker_decl:
655 TOK_CHECKER TOK_ID ';' {
656 AstNode *node = new AstNode(AST_GENBLOCK);
657 node->str = *$2;
658 ast_stack.back()->children.push_back(node);
659 ast_stack.push_back(node);
660 } module_body TOK_ENDCHECKER {
661 delete $2;
662 ast_stack.pop_back();
663 };
664
665 task_func_decl:
666 attr TOK_DPI_FUNCTION TOK_ID TOK_ID {
667 current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3), AstNode::mkconst_str(*$4));
668 current_function_or_task->str = *$4;
669 append_attr(current_function_or_task, $1);
670 ast_stack.back()->children.push_back(current_function_or_task);
671 delete $3;
672 delete $4;
673 } opt_dpi_function_args ';' {
674 current_function_or_task = NULL;
675 } |
676 attr TOK_DPI_FUNCTION TOK_ID '=' TOK_ID TOK_ID {
677 current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$5), AstNode::mkconst_str(*$3));
678 current_function_or_task->str = *$6;
679 append_attr(current_function_or_task, $1);
680 ast_stack.back()->children.push_back(current_function_or_task);
681 delete $3;
682 delete $5;
683 delete $6;
684 } opt_dpi_function_args ';' {
685 current_function_or_task = NULL;
686 } |
687 attr TOK_DPI_FUNCTION TOK_ID ':' TOK_ID '=' TOK_ID TOK_ID {
688 current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$7), AstNode::mkconst_str(*$3 + ":" + RTLIL::unescape_id(*$5)));
689 current_function_or_task->str = *$8;
690 append_attr(current_function_or_task, $1);
691 ast_stack.back()->children.push_back(current_function_or_task);
692 delete $3;
693 delete $5;
694 delete $7;
695 delete $8;
696 } opt_dpi_function_args ';' {
697 current_function_or_task = NULL;
698 } |
699 attr TOK_TASK opt_automatic TOK_ID {
700 current_function_or_task = new AstNode(AST_TASK);
701 current_function_or_task->str = *$4;
702 append_attr(current_function_or_task, $1);
703 ast_stack.back()->children.push_back(current_function_or_task);
704 ast_stack.push_back(current_function_or_task);
705 current_function_or_task_port_id = 1;
706 delete $4;
707 } task_func_args_opt ';' task_func_body TOK_ENDTASK {
708 current_function_or_task = NULL;
709 ast_stack.pop_back();
710 } |
711 attr TOK_FUNCTION opt_automatic opt_signed range_or_signed_int TOK_ID {
712 current_function_or_task = new AstNode(AST_FUNCTION);
713 current_function_or_task->str = *$6;
714 append_attr(current_function_or_task, $1);
715 ast_stack.back()->children.push_back(current_function_or_task);
716 ast_stack.push_back(current_function_or_task);
717 AstNode *outreg = new AstNode(AST_WIRE);
718 outreg->str = *$6;
719 outreg->is_signed = $4;
720 outreg->is_reg = true;
721 if ($5 != NULL) {
722 outreg->children.push_back($5);
723 outreg->is_signed = $4 || $5->is_signed;
724 $5->is_signed = false;
725 }
726 current_function_or_task->children.push_back(outreg);
727 current_function_or_task_port_id = 1;
728 delete $6;
729 } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION {
730 current_function_or_task = NULL;
731 ast_stack.pop_back();
732 };
733
734 dpi_function_arg:
735 TOK_ID TOK_ID {
736 current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
737 delete $1;
738 delete $2;
739 } |
740 TOK_ID {
741 current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
742 delete $1;
743 };
744
745 opt_dpi_function_args:
746 '(' dpi_function_args ')' |
747 /* empty */;
748
749 dpi_function_args:
750 dpi_function_args ',' dpi_function_arg |
751 dpi_function_args ',' |
752 dpi_function_arg |
753 /* empty */;
754
755 opt_automatic:
756 TOK_AUTOMATIC |
757 /* empty */;
758
759 opt_signed:
760 TOK_SIGNED {
761 $$ = true;
762 } |
763 /* empty */ {
764 $$ = false;
765 };
766
767 task_func_args_opt:
768 '(' ')' | /* empty */ | '(' {
769 albuf = nullptr;
770 astbuf1 = nullptr;
771 astbuf2 = nullptr;
772 } task_func_args optional_comma {
773 delete astbuf1;
774 if (astbuf2 != NULL)
775 delete astbuf2;
776 free_attr(albuf);
777 } ')';
778
779 task_func_args:
780 task_func_port | task_func_args ',' task_func_port;
781
782 task_func_port:
783 attr wire_type range {
784 if (albuf) {
785 delete astbuf1;
786 if (astbuf2 != NULL)
787 delete astbuf2;
788 free_attr(albuf);
789 }
790 albuf = $1;
791 astbuf1 = $2;
792 astbuf2 = $3;
793 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
794 if (astbuf2) {
795 frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions (task/function arguments)");
796 } else {
797 astbuf2 = new AstNode(AST_RANGE);
798 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
799 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
800 }
801 }
802 if (astbuf2 && astbuf2->children.size() != 2)
803 frontend_verilog_yyerror("task/function argument range must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
804 } wire_name | wire_name;
805
806 task_func_body:
807 task_func_body behavioral_stmt |
808 /* empty */;
809
810 /*************************** specify parser ***************************/
811
812 specify_block:
813 TOK_SPECIFY specify_item_list TOK_ENDSPECIFY;
814
815 specify_item_list:
816 specify_item specify_item_list |
817 /* empty */;
818
819 specify_item:
820 specify_if '(' specify_edge expr TOK_SPECIFY_OPER specify_target ')' '=' specify_rise_fall ';' {
821 AstNode *en_expr = $1;
822 char specify_edge = $3;
823 AstNode *src_expr = $4;
824 string *oper = $5;
825 specify_target *target = $6;
826 specify_rise_fall *timing = $9;
827
828 if (specify_edge != 0 && target->dat == nullptr)
829 frontend_verilog_yyerror("Found specify edge but no data spec.\n");
830
831 AstNode *cell = new AstNode(AST_CELL);
832 ast_stack.back()->children.push_back(cell);
833 cell->str = stringf("$specify$%d", autoidx++);
834 cell->children.push_back(new AstNode(AST_CELLTYPE));
835 cell->children.back()->str = target->dat ? "$specify3" : "$specify2";
836
837 char oper_polarity = 0;
838 char oper_type = oper->at(0);
839
840 if (oper->size() == 3) {
841 oper_polarity = oper->at(0);
842 oper_type = oper->at(1);
843 }
844
845 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(oper_type == '*', false, 1)));
846 cell->children.back()->str = "\\FULL";
847
848 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(oper_polarity != 0, false, 1)));
849 cell->children.back()->str = "\\SRC_DST_PEN";
850
851 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(oper_polarity == '+', false, 1)));
852 cell->children.back()->str = "\\SRC_DST_POL";
853
854 cell->children.push_back(new AstNode(AST_PARASET, timing->rise.t_min));
855 cell->children.back()->str = "\\T_RISE_MIN";
856
857 cell->children.push_back(new AstNode(AST_PARASET, timing->rise.t_avg));
858 cell->children.back()->str = "\\T_RISE_TYP";
859
860 cell->children.push_back(new AstNode(AST_PARASET, timing->rise.t_max));
861 cell->children.back()->str = "\\T_RISE_MAX";
862
863 cell->children.push_back(new AstNode(AST_PARASET, timing->fall.t_min));
864 cell->children.back()->str = "\\T_FALL_MIN";
865
866 cell->children.push_back(new AstNode(AST_PARASET, timing->fall.t_avg));
867 cell->children.back()->str = "\\T_FALL_TYP";
868
869 cell->children.push_back(new AstNode(AST_PARASET, timing->fall.t_max));
870 cell->children.back()->str = "\\T_FALL_MAX";
871
872 cell->children.push_back(new AstNode(AST_ARGUMENT, en_expr ? en_expr : AstNode::mkconst_int(1, false, 1)));
873 cell->children.back()->str = "\\EN";
874
875 cell->children.push_back(new AstNode(AST_ARGUMENT, src_expr));
876 cell->children.back()->str = "\\SRC";
877
878 cell->children.push_back(new AstNode(AST_ARGUMENT, target->dst));
879 cell->children.back()->str = "\\DST";
880
881 if (target->dat)
882 {
883 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(specify_edge != 0, false, 1)));
884 cell->children.back()->str = "\\EDGE_EN";
885
886 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(specify_edge == 'p', false, 1)));
887 cell->children.back()->str = "\\EDGE_POL";
888
889 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(target->polarity_op != 0, false, 1)));
890 cell->children.back()->str = "\\DAT_DST_PEN";
891
892 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(target->polarity_op == '+', false, 1)));
893 cell->children.back()->str = "\\DAT_DST_POL";
894
895 cell->children.push_back(new AstNode(AST_ARGUMENT, target->dat));
896 cell->children.back()->str = "\\DAT";
897 }
898
899 delete oper;
900 delete target;
901 delete timing;
902 } |
903 TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' specify_triple specify_opt_triple ')' ';' {
904 if (*$1 != "$setup" && *$1 != "$hold" && *$1 != "$setuphold" && *$1 != "$removal" && *$1 != "$recovery" &&
905 *$1 != "$recrem" && *$1 != "$skew" && *$1 != "$timeskew" && *$1 != "$fullskew" && *$1 != "$nochange")
906 frontend_verilog_yyerror("Unsupported specify rule type: %s\n", $1->c_str());
907
908 AstNode *src_pen = AstNode::mkconst_int($3 != 0, false, 1);
909 AstNode *src_pol = AstNode::mkconst_int($3 == 'p', false, 1);
910 AstNode *src_expr = $4, *src_en = $5 ? $5 : AstNode::mkconst_int(1, false, 1);
911
912 AstNode *dst_pen = AstNode::mkconst_int($7 != 0, false, 1);
913 AstNode *dst_pol = AstNode::mkconst_int($7 == 'p', false, 1);
914 AstNode *dst_expr = $8, *dst_en = $9 ? $9 : AstNode::mkconst_int(1, false, 1);
915
916 specify_triple *limit = $11;
917 specify_triple *limit2 = $12;
918
919 AstNode *cell = new AstNode(AST_CELL);
920 ast_stack.back()->children.push_back(cell);
921 cell->str = stringf("$specify$%d", autoidx++);
922 cell->children.push_back(new AstNode(AST_CELLTYPE));
923 cell->children.back()->str = "$specrule";
924
925 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_str(*$1)));
926 cell->children.back()->str = "\\TYPE";
927
928 cell->children.push_back(new AstNode(AST_PARASET, limit->t_min));
929 cell->children.back()->str = "\\T_LIMIT_MIN";
930
931 cell->children.push_back(new AstNode(AST_PARASET, limit->t_avg));
932 cell->children.back()->str = "\\T_LIMIT_TYP";
933
934 cell->children.push_back(new AstNode(AST_PARASET, limit->t_max));
935 cell->children.back()->str = "\\T_LIMIT_MAX";
936
937 cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_min : AstNode::mkconst_int(0, true)));
938 cell->children.back()->str = "\\T_LIMIT2_MIN";
939
940 cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_avg : AstNode::mkconst_int(0, true)));
941 cell->children.back()->str = "\\T_LIMIT2_TYP";
942
943 cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_max : AstNode::mkconst_int(0, true)));
944 cell->children.back()->str = "\\T_LIMIT2_MAX";
945
946 cell->children.push_back(new AstNode(AST_PARASET, src_pen));
947 cell->children.back()->str = "\\SRC_PEN";
948
949 cell->children.push_back(new AstNode(AST_PARASET, src_pol));
950 cell->children.back()->str = "\\SRC_POL";
951
952 cell->children.push_back(new AstNode(AST_PARASET, dst_pen));
953 cell->children.back()->str = "\\DST_PEN";
954
955 cell->children.push_back(new AstNode(AST_PARASET, dst_pol));
956 cell->children.back()->str = "\\DST_POL";
957
958 cell->children.push_back(new AstNode(AST_ARGUMENT, src_en));
959 cell->children.back()->str = "\\SRC_EN";
960
961 cell->children.push_back(new AstNode(AST_ARGUMENT, src_expr));
962 cell->children.back()->str = "\\SRC";
963
964 cell->children.push_back(new AstNode(AST_ARGUMENT, dst_en));
965 cell->children.back()->str = "\\DST_EN";
966
967 cell->children.push_back(new AstNode(AST_ARGUMENT, dst_expr));
968 cell->children.back()->str = "\\DST";
969
970 delete $1;
971 };
972
973 specify_opt_triple:
974 ',' specify_triple {
975 $$ = $2;
976 } |
977 /* empty */ {
978 $$ = nullptr;
979 };
980
981 specify_if:
982 TOK_IF '(' expr ')' {
983 $$ = $3;
984 } |
985 /* empty */ {
986 $$ = nullptr;
987 };
988
989 specify_condition:
990 TOK_SPECIFY_AND expr {
991 $$ = $2;
992 } |
993 /* empty */ {
994 $$ = nullptr;
995 };
996
997 specify_target:
998 expr {
999 $$ = new specify_target;
1000 $$->polarity_op = 0;
1001 $$->dst = $1;
1002 $$->dat = nullptr;
1003 } |
1004 '(' expr ':' expr ')'{
1005 $$ = new specify_target;
1006 $$->polarity_op = 0;
1007 $$->dst = $2;
1008 $$->dat = $4;
1009 } |
1010 '(' expr TOK_NEG_INDEXED expr ')'{
1011 $$ = new specify_target;
1012 $$->polarity_op = '-';
1013 $$->dst = $2;
1014 $$->dat = $4;
1015 } |
1016 '(' expr TOK_POS_INDEXED expr ')'{
1017 $$ = new specify_target;
1018 $$->polarity_op = '+';
1019 $$->dst = $2;
1020 $$->dat = $4;
1021 };
1022
1023 specify_edge:
1024 TOK_POSEDGE { $$ = 'p'; } |
1025 TOK_NEGEDGE { $$ = 'n'; } |
1026 { $$ = 0; };
1027
1028 specify_rise_fall:
1029 specify_triple {
1030 $$ = new specify_rise_fall;
1031 $$->rise = *$1;
1032 $$->fall.t_min = $1->t_min->clone();
1033 $$->fall.t_avg = $1->t_avg->clone();
1034 $$->fall.t_max = $1->t_max->clone();
1035 delete $1;
1036 } |
1037 '(' specify_triple ',' specify_triple ')' {
1038 $$ = new specify_rise_fall;
1039 $$->rise = *$2;
1040 $$->fall = *$4;
1041 delete $2;
1042 delete $4;
1043 } |
1044 '(' specify_triple ',' specify_triple ',' specify_triple ')' {
1045 $$ = new specify_rise_fall;
1046 $$->rise = *$2;
1047 $$->fall = *$4;
1048 delete $2;
1049 delete $4;
1050 delete $6;
1051 log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
1052 } |
1053 '(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
1054 $$ = new specify_rise_fall;
1055 $$->rise = *$2;
1056 $$->fall = *$4;
1057 delete $2;
1058 delete $4;
1059 delete $6;
1060 delete $8;
1061 delete $10;
1062 delete $12;
1063 log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
1064 } |
1065 '(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
1066 $$ = new specify_rise_fall;
1067 $$->rise = *$2;
1068 $$->fall = *$4;
1069 delete $2;
1070 delete $4;
1071 delete $6;
1072 delete $8;
1073 delete $10;
1074 delete $12;
1075 delete $14;
1076 delete $16;
1077 delete $18;
1078 delete $20;
1079 delete $22;
1080 delete $24;
1081 log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
1082 }
1083
1084 specify_triple:
1085 expr {
1086 $$ = new specify_triple;
1087 $$->t_min = $1;
1088 $$->t_avg = $1->clone();
1089 $$->t_max = $1->clone();
1090 } |
1091 expr ':' expr ':' expr {
1092 $$ = new specify_triple;
1093 $$->t_min = $1;
1094 $$->t_avg = $3;
1095 $$->t_max = $5;
1096 };
1097
1098 /******************** ignored specify parser **************************/
1099
1100 ignored_specify_block:
1101 TOK_IGNORED_SPECIFY ignored_specify_item_opt TOK_ENDSPECIFY |
1102 TOK_IGNORED_SPECIFY TOK_ENDSPECIFY ;
1103
1104 ignored_specify_item_opt:
1105 ignored_specify_item_opt ignored_specify_item |
1106 ignored_specify_item ;
1107
1108 ignored_specify_item:
1109 specparam_declaration
1110 // | pulsestyle_declaration
1111 // | showcancelled_declaration
1112 | path_declaration
1113 | system_timing_declaration
1114 ;
1115
1116 specparam_declaration:
1117 TOK_SPECPARAM list_of_specparam_assignments ';' |
1118 TOK_SPECPARAM specparam_range list_of_specparam_assignments ';' ;
1119
1120 // IEEE 1364-2005 calls this sinmply 'range' but the current 'range' rule allows empty match
1121 // and the 'non_opt_range' rule allows index ranges not allowed by 1364-2005
1122 // exxxxtending this for SV specparam would change this anyhow
1123 specparam_range:
1124 '[' ignspec_constant_expression ':' ignspec_constant_expression ']' ;
1125
1126 list_of_specparam_assignments:
1127 specparam_assignment | list_of_specparam_assignments ',' specparam_assignment;
1128
1129 specparam_assignment:
1130 ignspec_id '=' ignspec_expr ;
1131
1132 ignspec_opt_cond:
1133 TOK_IF '(' ignspec_expr ')' | /* empty */;
1134
1135 path_declaration :
1136 simple_path_declaration ';'
1137 // | edge_sensitive_path_declaration
1138 // | state_dependent_path_declaration
1139 ;
1140
1141 simple_path_declaration :
1142 ignspec_opt_cond parallel_path_description '=' path_delay_value |
1143 ignspec_opt_cond full_path_description '=' path_delay_value
1144 ;
1145
1146 path_delay_value :
1147 '(' ignspec_expr list_of_path_delay_extra_expressions ')'
1148 | ignspec_expr
1149 | ignspec_expr list_of_path_delay_extra_expressions
1150 ;
1151
1152 list_of_path_delay_extra_expressions :
1153 ',' ignspec_expr
1154 | ',' ignspec_expr list_of_path_delay_extra_expressions
1155 ;
1156
1157 specify_edge_identifier :
1158 TOK_POSEDGE | TOK_NEGEDGE ;
1159
1160 parallel_path_description :
1161 '(' specify_input_terminal_descriptor opt_polarity_operator '=' '>' specify_output_terminal_descriptor ')' |
1162 '(' specify_edge_identifier specify_input_terminal_descriptor '=' '>' '(' specify_output_terminal_descriptor opt_polarity_operator ':' ignspec_expr ')' ')' |
1163 '(' specify_edge_identifier specify_input_terminal_descriptor '=' '>' '(' specify_output_terminal_descriptor TOK_POS_INDEXED ignspec_expr ')' ')' ;
1164
1165 full_path_description :
1166 '(' list_of_path_inputs '*' '>' list_of_path_outputs ')' |
1167 '(' specify_edge_identifier list_of_path_inputs '*' '>' '(' list_of_path_outputs opt_polarity_operator ':' ignspec_expr ')' ')' |
1168 '(' specify_edge_identifier list_of_path_inputs '*' '>' '(' list_of_path_outputs TOK_POS_INDEXED ignspec_expr ')' ')' ;
1169
1170 // This was broken into 2 rules to solve shift/reduce conflicts
1171 list_of_path_inputs :
1172 specify_input_terminal_descriptor opt_polarity_operator |
1173 specify_input_terminal_descriptor more_path_inputs opt_polarity_operator ;
1174
1175 more_path_inputs :
1176 ',' specify_input_terminal_descriptor |
1177 more_path_inputs ',' specify_input_terminal_descriptor ;
1178
1179 list_of_path_outputs :
1180 specify_output_terminal_descriptor |
1181 list_of_path_outputs ',' specify_output_terminal_descriptor ;
1182
1183 opt_polarity_operator :
1184 '+'
1185 | '-'
1186 | ;
1187
1188 // Good enough for the time being
1189 specify_input_terminal_descriptor :
1190 ignspec_id ;
1191
1192 // Good enough for the time being
1193 specify_output_terminal_descriptor :
1194 ignspec_id ;
1195
1196 system_timing_declaration :
1197 ignspec_id '(' system_timing_args ')' ';' ;
1198
1199 system_timing_arg :
1200 TOK_POSEDGE ignspec_id |
1201 TOK_NEGEDGE ignspec_id |
1202 ignspec_expr ;
1203
1204 system_timing_args :
1205 system_timing_arg |
1206 system_timing_args TOK_IGNORED_SPECIFY_AND system_timing_arg |
1207 system_timing_args ',' system_timing_arg ;
1208
1209 // for the time being this is OK, but we may write our own expr here.
1210 // as I'm not sure it is legal to use a full expr here (probably not)
1211 // On the other hand, other rules requiring constant expressions also use 'expr'
1212 // (such as param assignment), so we may leave this as-is, perhaps adding runtime checks for constant-ness
1213 ignspec_constant_expression:
1214 expr { delete $1; };
1215
1216 ignspec_expr:
1217 expr { delete $1; } |
1218 expr ':' expr ':' expr {
1219 delete $1;
1220 delete $3;
1221 delete $5;
1222 };
1223
1224 ignspec_id:
1225 TOK_ID { delete $1; }
1226 range_or_multirange { delete $3; };
1227
1228 /**********************************************************************/
1229
1230 param_signed:
1231 TOK_SIGNED {
1232 astbuf1->is_signed = true;
1233 } | /* empty */;
1234
1235 param_integer:
1236 TOK_INTEGER {
1237 if (astbuf1->children.size() != 1)
1238 frontend_verilog_yyerror("Internal error in param_integer - should not happen?");
1239 astbuf1->children.push_back(new AstNode(AST_RANGE));
1240 astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true));
1241 astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true));
1242 astbuf1->is_signed = true;
1243 } | /* empty */;
1244
1245 param_real:
1246 TOK_REAL {
1247 if (astbuf1->children.size() != 1)
1248 frontend_verilog_yyerror("Parameter already declared as integer, cannot set to real.");
1249 astbuf1->children.push_back(new AstNode(AST_REALVALUE));
1250 } | /* empty */;
1251
1252 param_range:
1253 range {
1254 if ($1 != NULL) {
1255 if (astbuf1->children.size() != 1)
1256 frontend_verilog_yyerror("integer/real parameters should not have a range.");
1257 astbuf1->children.push_back($1);
1258 }
1259 };
1260
1261 param_type:
1262 param_signed param_integer param_real param_range |
1263 hierarchical_type_id {
1264 astbuf1->is_custom_type = true;
1265 astbuf1->children.push_back(new AstNode(AST_WIRETYPE));
1266 astbuf1->children.back()->str = *$1;
1267 };
1268
1269 param_decl:
1270 attr TOK_PARAMETER {
1271 astbuf1 = new AstNode(AST_PARAMETER);
1272 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
1273 append_attr(astbuf1, $1);
1274 } param_type param_decl_list ';' {
1275 delete astbuf1;
1276 };
1277
1278 localparam_decl:
1279 attr TOK_LOCALPARAM {
1280 astbuf1 = new AstNode(AST_LOCALPARAM);
1281 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
1282 append_attr(astbuf1, $1);
1283 } param_type param_decl_list ';' {
1284 delete astbuf1;
1285 };
1286
1287 param_decl_list:
1288 single_param_decl | param_decl_list ',' single_param_decl;
1289
1290 single_param_decl:
1291 TOK_ID '=' expr {
1292 AstNode *node;
1293 if (astbuf1 == nullptr) {
1294 if (!sv_mode)
1295 frontend_verilog_yyerror("In pure Verilog (not SystemVerilog), parameter/localparam with an initializer must use the parameter/localparam keyword");
1296 node = new AstNode(AST_PARAMETER);
1297 node->children.push_back(AstNode::mkconst_int(0, true));
1298 } else {
1299 node = astbuf1->clone();
1300 }
1301 node->str = *$1;
1302 delete node->children[0];
1303 node->children[0] = $3;
1304 ast_stack.back()->children.push_back(node);
1305 delete $1;
1306 };
1307
1308 defparam_decl:
1309 TOK_DEFPARAM defparam_decl_list ';';
1310
1311 defparam_decl_list:
1312 single_defparam_decl | defparam_decl_list ',' single_defparam_decl;
1313
1314 single_defparam_decl:
1315 range rvalue '=' expr {
1316 AstNode *node = new AstNode(AST_DEFPARAM);
1317 node->children.push_back($2);
1318 node->children.push_back($4);
1319 if ($1 != NULL)
1320 node->children.push_back($1);
1321 ast_stack.back()->children.push_back(node);
1322 };
1323
1324 enum_type: TOK_ENUM {
1325 static int enum_count;
1326 // create parent node for the enum
1327 astbuf2 = new AstNode(AST_ENUM);
1328 ast_stack.back()->children.push_back(astbuf2);
1329 astbuf2->str = std::string("$enum");
1330 astbuf2->str += std::to_string(enum_count++);
1331 // create the template for the names
1332 astbuf1 = new AstNode(AST_ENUM_ITEM);
1333 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
1334 } param_signed enum_base_type '{' enum_name_list '}' { // create template for the enum vars
1335 auto tnode = astbuf1->clone();
1336 delete astbuf1;
1337 astbuf1 = tnode;
1338 tnode->type = AST_WIRE;
1339 tnode->attributes["\\enum_type"] = AstNode::mkconst_str(astbuf2->str);
1340 // drop constant but keep any range
1341 delete tnode->children[0];
1342 tnode->children.erase(tnode->children.begin()); }
1343 ;
1344
1345 enum_base_type: int_vec param_range
1346 | int_atom
1347 | /* nothing */ {astbuf1->is_reg = true; addRange(astbuf1); }
1348 ;
1349
1350 int_atom: TOK_INTEGER {astbuf1->is_reg=true; addRange(astbuf1); } // probably should do byte, range [7:0] here
1351 ;
1352
1353 int_vec: TOK_REG {astbuf1->is_reg = true;}
1354 | TOK_LOGIC {astbuf1->is_logic = true;}
1355 ;
1356
1357 enum_name_list:
1358 enum_name_decl
1359 | enum_name_list ',' enum_name_decl
1360 ;
1361
1362 enum_name_decl:
1363 TOK_ID opt_enum_init {
1364 // put in fn
1365 log_assert(astbuf1);
1366 log_assert(astbuf2);
1367 auto node = astbuf1->clone();
1368 node->str = *$1;
1369 delete $1;
1370 delete node->children[0];
1371 node->children[0] = $2 ?: new AstNode(AST_NONE);
1372 astbuf2->children.push_back(node);
1373 }
1374 ;
1375
1376 opt_enum_init:
1377 '=' basic_expr { $$ = $2; } // TODO: restrict this
1378 | /* optional */ { $$ = NULL; }
1379 ;
1380
1381 enum_var_list:
1382 enum_var
1383 | enum_var_list ',' enum_var
1384 ;
1385
1386 enum_var: TOK_ID {
1387 log_assert(astbuf1);
1388 log_assert(astbuf2);
1389 auto node = astbuf1->clone();
1390 ast_stack.back()->children.push_back(node);
1391 node->str = *$1;
1392 delete $1;
1393 node->is_enum = true;
1394 }
1395 ;
1396
1397 enum_decl: enum_type enum_var_list ';' {
1398 //enum_type creates astbuf1 for use by typedef only
1399 delete astbuf1;
1400 }
1401 ;
1402
1403 wire_decl:
1404 attr wire_type range {
1405 albuf = $1;
1406 astbuf1 = $2;
1407 astbuf2 = $3;
1408 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
1409 if (astbuf2) {
1410 frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
1411 } else {
1412 astbuf2 = new AstNode(AST_RANGE);
1413 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
1414 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
1415 }
1416 }
1417 if (astbuf2 && astbuf2->children.size() != 2)
1418 frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
1419 } delay wire_name_list {
1420 delete astbuf1;
1421 if (astbuf2 != NULL)
1422 delete astbuf2;
1423 free_attr(albuf);
1424 } ';' |
1425 attr TOK_SUPPLY0 TOK_ID {
1426 ast_stack.back()->children.push_back(new AstNode(AST_WIRE));
1427 ast_stack.back()->children.back()->str = *$3;
1428 append_attr(ast_stack.back()->children.back(), $1);
1429 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1)));
1430 ast_stack.back()->children.back()->children[0]->str = *$3;
1431 delete $3;
1432 } opt_supply_wires ';' |
1433 attr TOK_SUPPLY1 TOK_ID {
1434 ast_stack.back()->children.push_back(new AstNode(AST_WIRE));
1435 ast_stack.back()->children.back()->str = *$3;
1436 append_attr(ast_stack.back()->children.back(), $1);
1437 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(1, false, 1)));
1438 ast_stack.back()->children.back()->children[0]->str = *$3;
1439 delete $3;
1440 } opt_supply_wires ';';
1441
1442 opt_supply_wires:
1443 /* empty */ |
1444 opt_supply_wires ',' TOK_ID {
1445 AstNode *wire_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-2)->clone();
1446 AstNode *assign_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-1)->clone();
1447 wire_node->str = *$3;
1448 assign_node->children[0]->str = *$3;
1449 ast_stack.back()->children.push_back(wire_node);
1450 ast_stack.back()->children.push_back(assign_node);
1451 delete $3;
1452 };
1453
1454 wire_name_list:
1455 wire_name_and_opt_assign | wire_name_list ',' wire_name_and_opt_assign;
1456
1457 wire_name_and_opt_assign:
1458 wire_name {
1459 bool attr_anyconst = false;
1460 bool attr_anyseq = false;
1461 bool attr_allconst = false;
1462 bool attr_allseq = false;
1463 if (ast_stack.back()->children.back()->get_bool_attribute("\\anyconst")) {
1464 delete ast_stack.back()->children.back()->attributes.at("\\anyconst");
1465 ast_stack.back()->children.back()->attributes.erase("\\anyconst");
1466 attr_anyconst = true;
1467 }
1468 if (ast_stack.back()->children.back()->get_bool_attribute("\\anyseq")) {
1469 delete ast_stack.back()->children.back()->attributes.at("\\anyseq");
1470 ast_stack.back()->children.back()->attributes.erase("\\anyseq");
1471 attr_anyseq = true;
1472 }
1473 if (ast_stack.back()->children.back()->get_bool_attribute("\\allconst")) {
1474 delete ast_stack.back()->children.back()->attributes.at("\\allconst");
1475 ast_stack.back()->children.back()->attributes.erase("\\allconst");
1476 attr_allconst = true;
1477 }
1478 if (ast_stack.back()->children.back()->get_bool_attribute("\\allseq")) {
1479 delete ast_stack.back()->children.back()->attributes.at("\\allseq");
1480 ast_stack.back()->children.back()->attributes.erase("\\allseq");
1481 attr_allseq = true;
1482 }
1483 if (current_wire_rand || attr_anyconst || attr_anyseq || attr_allconst || attr_allseq) {
1484 AstNode *wire = new AstNode(AST_IDENTIFIER);
1485 AstNode *fcall = new AstNode(AST_FCALL);
1486 wire->str = ast_stack.back()->children.back()->str;
1487 fcall->str = current_wire_const ? "\\$anyconst" : "\\$anyseq";
1488 if (attr_anyconst)
1489 fcall->str = "\\$anyconst";
1490 if (attr_anyseq)
1491 fcall->str = "\\$anyseq";
1492 if (attr_allconst)
1493 fcall->str = "\\$allconst";
1494 if (attr_allseq)
1495 fcall->str = "\\$allseq";
1496 fcall->attributes["\\reg"] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str));
1497 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall));
1498 }
1499 } |
1500 wire_name '=' expr {
1501 AstNode *wire = new AstNode(AST_IDENTIFIER);
1502 wire->str = ast_stack.back()->children.back()->str;
1503 if (astbuf1->is_input) {
1504 if (astbuf1->attributes.count("\\defaultvalue"))
1505 delete astbuf1->attributes.at("\\defaultvalue");
1506 astbuf1->attributes["\\defaultvalue"] = $3;
1507 }
1508 else if (astbuf1->is_reg || astbuf1->is_logic){
1509 AstNode *assign = new AstNode(AST_ASSIGN_LE, wire, $3);
1510 AstNode *block = new AstNode(AST_BLOCK, assign);
1511 AstNode *init = new AstNode(AST_INITIAL, block);
1512
1513 SET_AST_NODE_LOC(assign, @1, @3);
1514 SET_AST_NODE_LOC(block, @1, @3);
1515 SET_AST_NODE_LOC(init, @1, @3);
1516
1517 ast_stack.back()->children.push_back(init);
1518 }
1519 else {
1520 AstNode *assign = new AstNode(AST_ASSIGN, wire, $3);
1521 SET_AST_NODE_LOC(assign, @1, @3);
1522 ast_stack.back()->children.push_back(assign);
1523 }
1524
1525 };
1526
1527 wire_name:
1528 TOK_ID range_or_multirange {
1529 if (astbuf1 == nullptr)
1530 frontend_verilog_yyerror("Internal error - should not happen - no AST_WIRE node.");
1531 AstNode *node = astbuf1->clone();
1532 node->str = *$1;
1533 append_attr_clone(node, albuf);
1534 if (astbuf2 != NULL)
1535 node->children.push_back(astbuf2->clone());
1536 if ($2 != NULL) {
1537 if (node->is_input || node->is_output)
1538 frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions.");
1539 if (!astbuf2 && !node->is_custom_type) {
1540 AstNode *rng = new AstNode(AST_RANGE);
1541 rng->children.push_back(AstNode::mkconst_int(0, true));
1542 rng->children.push_back(AstNode::mkconst_int(0, true));
1543 node->children.push_back(rng);
1544 }
1545 node->type = AST_MEMORY;
1546 auto *rangeNode = $2;
1547 if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
1548 // SV array size [n], rewrite as [n-1:0]
1549 rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
1550 rangeNode->children.push_back(AstNode::mkconst_int(0, false));
1551 }
1552 node->children.push_back(rangeNode);
1553 }
1554 if (current_function_or_task == NULL) {
1555 if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) {
1556 port_stubs[*$1] = ++port_counter;
1557 }
1558 if (port_stubs.count(*$1) != 0) {
1559 if (!node->is_input && !node->is_output)
1560 frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $1->c_str());
1561 if (node->is_reg && node->is_input && !node->is_output && !sv_mode)
1562 frontend_verilog_yyerror("Input port `%s' is declared as register.", $1->c_str());
1563 node->port_id = port_stubs[*$1];
1564 port_stubs.erase(*$1);
1565 } else {
1566 if (node->is_input || node->is_output)
1567 frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
1568 }
1569 } else {
1570 if (node->is_input || node->is_output)
1571 node->port_id = current_function_or_task_port_id++;
1572 }
1573 //FIXME: for some reason, TOK_ID has a location which always points to one column *after* the real last column...
1574 SET_AST_NODE_LOC(node, @1, @1);
1575 ast_stack.back()->children.push_back(node);
1576
1577 delete $1;
1578 };
1579
1580 assign_stmt:
1581 TOK_ASSIGN delay assign_expr_list ';';
1582
1583 assign_expr_list:
1584 assign_expr | assign_expr_list ',' assign_expr;
1585
1586 assign_expr:
1587 lvalue '=' expr {
1588 AstNode *node = new AstNode(AST_ASSIGN, $1, $3);
1589 SET_AST_NODE_LOC(node, @$, @$);
1590 ast_stack.back()->children.push_back(node);
1591 };
1592
1593 typedef_decl:
1594 TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
1595 astbuf1 = $2;
1596 astbuf2 = $3;
1597 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
1598 if (astbuf2) {
1599 frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
1600 } else {
1601 astbuf2 = new AstNode(AST_RANGE);
1602 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
1603 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
1604 }
1605 }
1606 if (astbuf2 && astbuf2->children.size() != 2)
1607 frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
1608 if (astbuf2)
1609 astbuf1->children.push_back(astbuf2);
1610
1611 if ($5 != NULL) {
1612 if (!astbuf2) {
1613 AstNode *rng = new AstNode(AST_RANGE);
1614 rng->children.push_back(AstNode::mkconst_int(0, true));
1615 rng->children.push_back(AstNode::mkconst_int(0, true));
1616 astbuf1->children.push_back(rng);
1617 }
1618 astbuf1->type = AST_MEMORY;
1619 auto *rangeNode = $5;
1620 if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
1621 // SV array size [n], rewrite as [n-1:0]
1622 rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
1623 rangeNode->children.push_back(AstNode::mkconst_int(0, false));
1624 }
1625 astbuf1->children.push_back(rangeNode);
1626 }
1627
1628 ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
1629 ast_stack.back()->children.back()->str = *$4;
1630 } |
1631 TOK_TYPEDEF enum_type TOK_ID ';' {
1632 ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
1633 ast_stack.back()->children.back()->str = *$3;
1634 }
1635 ;
1636
1637 cell_stmt:
1638 attr TOK_ID {
1639 astbuf1 = new AstNode(AST_CELL);
1640 append_attr(astbuf1, $1);
1641 astbuf1->children.push_back(new AstNode(AST_CELLTYPE));
1642 astbuf1->children[0]->str = *$2;
1643 delete $2;
1644 } cell_parameter_list_opt cell_list ';' {
1645 delete astbuf1;
1646 } |
1647 attr tok_prim_wrapper delay {
1648 astbuf1 = new AstNode(AST_PRIMITIVE);
1649 astbuf1->str = *$2;
1650 append_attr(astbuf1, $1);
1651 delete $2;
1652 } prim_list ';' {
1653 delete astbuf1;
1654 };
1655
1656 tok_prim_wrapper:
1657 TOK_PRIMITIVE {
1658 $$ = $1;
1659 } |
1660 TOK_OR {
1661 $$ = new std::string("or");
1662 };
1663
1664 cell_list:
1665 single_cell |
1666 cell_list ',' single_cell;
1667
1668 single_cell:
1669 TOK_ID {
1670 astbuf2 = astbuf1->clone();
1671 if (astbuf2->type != AST_PRIMITIVE)
1672 astbuf2->str = *$1;
1673 delete $1;
1674 ast_stack.back()->children.push_back(astbuf2);
1675 } '(' cell_port_list ')' {
1676 SET_AST_NODE_LOC(astbuf2, @1, @$);
1677 } |
1678 TOK_ID non_opt_range {
1679 astbuf2 = astbuf1->clone();
1680 if (astbuf2->type != AST_PRIMITIVE)
1681 astbuf2->str = *$1;
1682 delete $1;
1683 ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2));
1684 } '(' cell_port_list ')'{
1685 SET_AST_NODE_LOC(astbuf2, @1, @$);
1686 SET_AST_NODE_LOC(astbuf3, @1, @$);
1687 };
1688
1689 prim_list:
1690 single_prim |
1691 prim_list ',' single_prim;
1692
1693 single_prim:
1694 single_cell |
1695 /* no name */ {
1696 astbuf2 = astbuf1->clone();
1697 ast_stack.back()->children.push_back(astbuf2);
1698 } '(' cell_port_list ')';
1699
1700 cell_parameter_list_opt:
1701 '#' '(' cell_parameter_list ')' | /* empty */;
1702
1703 cell_parameter_list:
1704 cell_parameter | cell_parameter_list ',' cell_parameter;
1705
1706 cell_parameter:
1707 /* empty */ |
1708 expr {
1709 AstNode *node = new AstNode(AST_PARASET);
1710 astbuf1->children.push_back(node);
1711 node->children.push_back($1);
1712 } |
1713 '.' TOK_ID '(' expr ')' {
1714 AstNode *node = new AstNode(AST_PARASET);
1715 node->str = *$2;
1716 astbuf1->children.push_back(node);
1717 node->children.push_back($4);
1718 delete $2;
1719 };
1720
1721 cell_port_list:
1722 cell_port_list_rules {
1723 // remove empty args from end of list
1724 while (!astbuf2->children.empty()) {
1725 AstNode *node = astbuf2->children.back();
1726 if (node->type != AST_ARGUMENT) break;
1727 if (!node->children.empty()) break;
1728 if (!node->str.empty()) break;
1729 astbuf2->children.pop_back();
1730 delete node;
1731 }
1732
1733 // check port types
1734 bool has_positional_args = false;
1735 bool has_named_args = false;
1736 for (auto node : astbuf2->children) {
1737 if (node->type != AST_ARGUMENT) continue;
1738 if (node->str.empty())
1739 has_positional_args = true;
1740 else
1741 has_named_args = true;
1742 }
1743
1744 if (has_positional_args && has_named_args)
1745 frontend_verilog_yyerror("Mix of positional and named cell ports.");
1746 };
1747
1748 cell_port_list_rules:
1749 cell_port | cell_port_list_rules ',' cell_port;
1750
1751 cell_port:
1752 attr {
1753 AstNode *node = new AstNode(AST_ARGUMENT);
1754 astbuf2->children.push_back(node);
1755 free_attr($1);
1756 } |
1757 attr expr {
1758 AstNode *node = new AstNode(AST_ARGUMENT);
1759 astbuf2->children.push_back(node);
1760 node->children.push_back($2);
1761 free_attr($1);
1762 } |
1763 attr '.' TOK_ID '(' expr ')' {
1764 AstNode *node = new AstNode(AST_ARGUMENT);
1765 node->str = *$3;
1766 astbuf2->children.push_back(node);
1767 node->children.push_back($5);
1768 delete $3;
1769 free_attr($1);
1770 } |
1771 attr '.' TOK_ID '(' ')' {
1772 AstNode *node = new AstNode(AST_ARGUMENT);
1773 node->str = *$3;
1774 astbuf2->children.push_back(node);
1775 delete $3;
1776 free_attr($1);
1777 } |
1778 attr '.' TOK_ID {
1779 AstNode *node = new AstNode(AST_ARGUMENT);
1780 node->str = *$3;
1781 astbuf2->children.push_back(node);
1782 node->children.push_back(new AstNode(AST_IDENTIFIER));
1783 node->children.back()->str = *$3;
1784 delete $3;
1785 free_attr($1);
1786 } |
1787 attr TOK_WILDCARD_CONNECT {
1788 if (!sv_mode)
1789 frontend_verilog_yyerror("Wildcard port connections are only supported in SystemVerilog mode.");
1790 astbuf2->attributes[ID(wildcard_port_conns)] = AstNode::mkconst_int(1, false);
1791 };
1792
1793 always_comb_or_latch:
1794 TOK_ALWAYS_COMB {
1795 $$ = false;
1796 } |
1797 TOK_ALWAYS_LATCH {
1798 $$ = true;
1799 };
1800
1801 always_or_always_ff:
1802 TOK_ALWAYS {
1803 $$ = false;
1804 } |
1805 TOK_ALWAYS_FF {
1806 $$ = true;
1807 };
1808
1809 always_stmt:
1810 attr always_or_always_ff {
1811 AstNode *node = new AstNode(AST_ALWAYS);
1812 append_attr(node, $1);
1813 if ($2)
1814 node->attributes[ID(always_ff)] = AstNode::mkconst_int(1, false);
1815 ast_stack.back()->children.push_back(node);
1816 ast_stack.push_back(node);
1817 } always_cond {
1818 AstNode *block = new AstNode(AST_BLOCK);
1819 ast_stack.back()->children.push_back(block);
1820 ast_stack.push_back(block);
1821 } behavioral_stmt {
1822 SET_AST_NODE_LOC(ast_stack.back(), @6, @6);
1823 ast_stack.pop_back();
1824
1825 SET_AST_NODE_LOC(ast_stack.back(), @2, @$);
1826 ast_stack.pop_back();
1827
1828 SET_RULE_LOC(@$, @2, @$);
1829 } |
1830 attr always_comb_or_latch {
1831 AstNode *node = new AstNode(AST_ALWAYS);
1832 append_attr(node, $1);
1833 if ($2)
1834 node->attributes[ID(always_latch)] = AstNode::mkconst_int(1, false);
1835 else
1836 node->attributes[ID(always_comb)] = AstNode::mkconst_int(1, false);
1837 ast_stack.back()->children.push_back(node);
1838 ast_stack.push_back(node);
1839 AstNode *block = new AstNode(AST_BLOCK);
1840 ast_stack.back()->children.push_back(block);
1841 ast_stack.push_back(block);
1842 } behavioral_stmt {
1843 ast_stack.pop_back();
1844 ast_stack.pop_back();
1845 } |
1846 attr TOK_INITIAL {
1847 AstNode *node = new AstNode(AST_INITIAL);
1848 append_attr(node, $1);
1849 ast_stack.back()->children.push_back(node);
1850 ast_stack.push_back(node);
1851 AstNode *block = new AstNode(AST_BLOCK);
1852 ast_stack.back()->children.push_back(block);
1853 ast_stack.push_back(block);
1854 } behavioral_stmt {
1855 ast_stack.pop_back();
1856 ast_stack.pop_back();
1857 };
1858
1859 always_cond:
1860 '@' '(' always_events ')' |
1861 '@' '(' '*' ')' |
1862 '@' ATTR_BEGIN ')' |
1863 '@' '(' ATTR_END |
1864 '@' '*' |
1865 /* empty */;
1866
1867 always_events:
1868 always_event |
1869 always_events TOK_OR always_event |
1870 always_events ',' always_event;
1871
1872 always_event:
1873 TOK_POSEDGE expr {
1874 AstNode *node = new AstNode(AST_POSEDGE);
1875 ast_stack.back()->children.push_back(node);
1876 node->children.push_back($2);
1877 } |
1878 TOK_NEGEDGE expr {
1879 AstNode *node = new AstNode(AST_NEGEDGE);
1880 ast_stack.back()->children.push_back(node);
1881 node->children.push_back($2);
1882 } |
1883 expr {
1884 AstNode *node = new AstNode(AST_EDGE);
1885 ast_stack.back()->children.push_back(node);
1886 node->children.push_back($1);
1887 };
1888
1889 opt_label:
1890 ':' TOK_ID {
1891 $$ = $2;
1892 } |
1893 /* empty */ {
1894 $$ = NULL;
1895 };
1896
1897 opt_sva_label:
1898 TOK_SVA_LABEL ':' {
1899 $$ = $1;
1900 } |
1901 /* empty */ {
1902 $$ = NULL;
1903 };
1904
1905 opt_property:
1906 TOK_PROPERTY {
1907 $$ = true;
1908 } |
1909 TOK_FINAL {
1910 $$ = false;
1911 } |
1912 /* empty */ {
1913 $$ = false;
1914 };
1915
1916 modport_stmt:
1917 TOK_MODPORT TOK_ID {
1918 AstNode *modport = new AstNode(AST_MODPORT);
1919 ast_stack.back()->children.push_back(modport);
1920 ast_stack.push_back(modport);
1921 modport->str = *$2;
1922 delete $2;
1923 } modport_args_opt {
1924 ast_stack.pop_back();
1925 log_assert(ast_stack.size() == 2);
1926 } ';'
1927
1928 modport_args_opt:
1929 '(' ')' | '(' modport_args optional_comma ')';
1930
1931 modport_args:
1932 modport_arg | modport_args ',' modport_arg;
1933
1934 modport_arg:
1935 modport_type_token modport_member |
1936 modport_member
1937
1938 modport_member:
1939 TOK_ID {
1940 AstNode *modport_member = new AstNode(AST_MODPORTMEMBER);
1941 ast_stack.back()->children.push_back(modport_member);
1942 modport_member->str = *$1;
1943 modport_member->is_input = current_modport_input;
1944 modport_member->is_output = current_modport_output;
1945 delete $1;
1946 }
1947
1948 modport_type_token:
1949 TOK_INPUT {current_modport_input = 1; current_modport_output = 0;} | TOK_OUTPUT {current_modport_input = 0; current_modport_output = 1;}
1950
1951 assert:
1952 opt_sva_label TOK_ASSERT opt_property '(' expr ')' ';' {
1953 if (noassert_mode) {
1954 delete $5;
1955 } else {
1956 AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
1957 if ($1 != nullptr)
1958 node->str = *$1;
1959 ast_stack.back()->children.push_back(node);
1960 }
1961 if ($1 != nullptr)
1962 delete $1;
1963 } |
1964 opt_sva_label TOK_ASSUME opt_property '(' expr ')' ';' {
1965 if (noassume_mode) {
1966 delete $5;
1967 } else {
1968 AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5);
1969 if ($1 != nullptr)
1970 node->str = *$1;
1971 ast_stack.back()->children.push_back(node);
1972 }
1973 if ($1 != nullptr)
1974 delete $1;
1975 } |
1976 opt_sva_label TOK_ASSERT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
1977 if (noassert_mode) {
1978 delete $6;
1979 } else {
1980 AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
1981 if ($1 != nullptr)
1982 node->str = *$1;
1983 ast_stack.back()->children.push_back(node);
1984 }
1985 if ($1 != nullptr)
1986 delete $1;
1987 } |
1988 opt_sva_label TOK_ASSUME opt_property '(' TOK_EVENTUALLY expr ')' ';' {
1989 if (noassume_mode) {
1990 delete $6;
1991 } else {
1992 AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6);
1993 if ($1 != nullptr)
1994 node->str = *$1;
1995 ast_stack.back()->children.push_back(node);
1996 }
1997 if ($1 != nullptr)
1998 delete $1;
1999 } |
2000 opt_sva_label TOK_COVER opt_property '(' expr ')' ';' {
2001 AstNode *node = new AstNode(AST_COVER, $5);
2002 if ($1 != nullptr) {
2003 node->str = *$1;
2004 delete $1;
2005 }
2006 ast_stack.back()->children.push_back(node);
2007 } |
2008 opt_sva_label TOK_COVER opt_property '(' ')' ';' {
2009 AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
2010 if ($1 != nullptr) {
2011 node->str = *$1;
2012 delete $1;
2013 }
2014 ast_stack.back()->children.push_back(node);
2015 } |
2016 opt_sva_label TOK_COVER ';' {
2017 AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
2018 if ($1 != nullptr) {
2019 node->str = *$1;
2020 delete $1;
2021 }
2022 ast_stack.back()->children.push_back(node);
2023 } |
2024 opt_sva_label TOK_RESTRICT opt_property '(' expr ')' ';' {
2025 if (norestrict_mode) {
2026 delete $5;
2027 } else {
2028 AstNode *node = new AstNode(AST_ASSUME, $5);
2029 if ($1 != nullptr)
2030 node->str = *$1;
2031 ast_stack.back()->children.push_back(node);
2032 }
2033 if (!$3)
2034 log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
2035 if ($1 != nullptr)
2036 delete $1;
2037 } |
2038 opt_sva_label TOK_RESTRICT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
2039 if (norestrict_mode) {
2040 delete $6;
2041 } else {
2042 AstNode *node = new AstNode(AST_FAIR, $6);
2043 if ($1 != nullptr)
2044 node->str = *$1;
2045 ast_stack.back()->children.push_back(node);
2046 }
2047 if (!$3)
2048 log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
2049 if ($1 != nullptr)
2050 delete $1;
2051 };
2052
2053 assert_property:
2054 opt_sva_label TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' {
2055 ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5));
2056 if ($1 != nullptr) {
2057 ast_stack.back()->children.back()->str = *$1;
2058 delete $1;
2059 }
2060 } |
2061 opt_sva_label TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' {
2062 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
2063 if ($1 != nullptr) {
2064 ast_stack.back()->children.back()->str = *$1;
2065 delete $1;
2066 }
2067 } |
2068 opt_sva_label TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
2069 ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6));
2070 if ($1 != nullptr) {
2071 ast_stack.back()->children.back()->str = *$1;
2072 delete $1;
2073 }
2074 } |
2075 opt_sva_label TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
2076 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
2077 if ($1 != nullptr) {
2078 ast_stack.back()->children.back()->str = *$1;
2079 delete $1;
2080 }
2081 } |
2082 opt_sva_label TOK_COVER TOK_PROPERTY '(' expr ')' ';' {
2083 ast_stack.back()->children.push_back(new AstNode(AST_COVER, $5));
2084 if ($1 != nullptr) {
2085 ast_stack.back()->children.back()->str = *$1;
2086 delete $1;
2087 }
2088 } |
2089 opt_sva_label TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' {
2090 if (norestrict_mode) {
2091 delete $5;
2092 } else {
2093 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
2094 if ($1 != nullptr) {
2095 ast_stack.back()->children.back()->str = *$1;
2096 delete $1;
2097 }
2098 }
2099 } |
2100 opt_sva_label TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
2101 if (norestrict_mode) {
2102 delete $6;
2103 } else {
2104 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
2105 if ($1 != nullptr) {
2106 ast_stack.back()->children.back()->str = *$1;
2107 delete $1;
2108 }
2109 }
2110 };
2111
2112 simple_behavioral_stmt:
2113 lvalue '=' delay expr {
2114 AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $4);
2115 ast_stack.back()->children.push_back(node);
2116 SET_AST_NODE_LOC(node, @1, @4);
2117 } |
2118 lvalue TOK_INCREMENT {
2119 AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_ADD, $1->clone(), AstNode::mkconst_int(1, true)));
2120 ast_stack.back()->children.push_back(node);
2121 SET_AST_NODE_LOC(node, @1, @2);
2122 } |
2123 lvalue TOK_DECREMENT {
2124 AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_SUB, $1->clone(), AstNode::mkconst_int(1, true)));
2125 ast_stack.back()->children.push_back(node);
2126 SET_AST_NODE_LOC(node, @1, @2);
2127 } |
2128 lvalue OP_LE delay expr {
2129 AstNode *node = new AstNode(AST_ASSIGN_LE, $1, $4);
2130 ast_stack.back()->children.push_back(node);
2131 SET_AST_NODE_LOC(node, @1, @4);
2132 };
2133
2134 // this production creates the obligatory if-else shift/reduce conflict
2135 behavioral_stmt:
2136 defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
2137 non_opt_delay behavioral_stmt |
2138 simple_behavioral_stmt ';' | ';' |
2139 hierarchical_id attr {
2140 AstNode *node = new AstNode(AST_TCALL);
2141 node->str = *$1;
2142 delete $1;
2143 ast_stack.back()->children.push_back(node);
2144 ast_stack.push_back(node);
2145 append_attr(node, $2);
2146 } opt_arg_list ';'{
2147 ast_stack.pop_back();
2148 } |
2149 TOK_MSG_TASKS attr {
2150 AstNode *node = new AstNode(AST_TCALL);
2151 node->str = *$1;
2152 delete $1;
2153 ast_stack.back()->children.push_back(node);
2154 ast_stack.push_back(node);
2155 append_attr(node, $2);
2156 } opt_arg_list ';'{
2157 ast_stack.pop_back();
2158 } |
2159 attr TOK_BEGIN opt_label {
2160 AstNode *node = new AstNode(AST_BLOCK);
2161 ast_stack.back()->children.push_back(node);
2162 ast_stack.push_back(node);
2163 append_attr(node, $1);
2164 if ($3 != NULL)
2165 node->str = *$3;
2166 } behavioral_stmt_list TOK_END opt_label {
2167 if ($3 != NULL && $7 != NULL && *$3 != *$7)
2168 frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1);
2169 if ($3 != NULL)
2170 delete $3;
2171 if ($7 != NULL)
2172 delete $7;
2173 ast_stack.pop_back();
2174 } |
2175 attr TOK_FOR '(' {
2176 AstNode *node = new AstNode(AST_FOR);
2177 ast_stack.back()->children.push_back(node);
2178 ast_stack.push_back(node);
2179 append_attr(node, $1);
2180 } simple_behavioral_stmt ';' expr {
2181 ast_stack.back()->children.push_back($7);
2182 } ';' simple_behavioral_stmt ')' {
2183 AstNode *block = new AstNode(AST_BLOCK);
2184 ast_stack.back()->children.push_back(block);
2185 ast_stack.push_back(block);
2186 } behavioral_stmt {
2187 SET_AST_NODE_LOC(ast_stack.back(), @13, @13);
2188 ast_stack.pop_back();
2189 SET_AST_NODE_LOC(ast_stack.back(), @2, @13);
2190 ast_stack.pop_back();
2191 } |
2192 attr TOK_WHILE '(' expr ')' {
2193 AstNode *node = new AstNode(AST_WHILE);
2194 ast_stack.back()->children.push_back(node);
2195 ast_stack.push_back(node);
2196 append_attr(node, $1);
2197 AstNode *block = new AstNode(AST_BLOCK);
2198 ast_stack.back()->children.push_back($4);
2199 ast_stack.back()->children.push_back(block);
2200 ast_stack.push_back(block);
2201 } behavioral_stmt {
2202 SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
2203 ast_stack.pop_back();
2204 ast_stack.pop_back();
2205 } |
2206 attr TOK_REPEAT '(' expr ')' {
2207 AstNode *node = new AstNode(AST_REPEAT);
2208 ast_stack.back()->children.push_back(node);
2209 ast_stack.push_back(node);
2210 append_attr(node, $1);
2211 AstNode *block = new AstNode(AST_BLOCK);
2212 ast_stack.back()->children.push_back($4);
2213 ast_stack.back()->children.push_back(block);
2214 ast_stack.push_back(block);
2215 } behavioral_stmt {
2216 SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
2217 ast_stack.pop_back();
2218 ast_stack.pop_back();
2219 } |
2220 attr TOK_IF '(' expr ')' {
2221 AstNode *node = new AstNode(AST_CASE);
2222 AstNode *block = new AstNode(AST_BLOCK);
2223 AstNode *cond = new AstNode(AST_COND, AstNode::mkconst_int(1, false, 1), block);
2224 SET_AST_NODE_LOC(cond, @4, @4);
2225 ast_stack.back()->children.push_back(node);
2226 node->children.push_back(new AstNode(AST_REDUCE_BOOL, $4));
2227 node->children.push_back(cond);
2228 ast_stack.push_back(node);
2229 ast_stack.push_back(block);
2230 append_attr(node, $1);
2231 } behavioral_stmt {
2232 SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
2233 } optional_else {
2234 ast_stack.pop_back();
2235 SET_AST_NODE_LOC(ast_stack.back(), @2, @9);
2236 ast_stack.pop_back();
2237 } |
2238 case_attr case_type '(' expr ')' {
2239 AstNode *node = new AstNode(AST_CASE, $4);
2240 ast_stack.back()->children.push_back(node);
2241 ast_stack.push_back(node);
2242 append_attr(node, $1);
2243 SET_AST_NODE_LOC(ast_stack.back(), @4, @4);
2244 } opt_synopsys_attr case_body TOK_ENDCASE {
2245 SET_AST_NODE_LOC(ast_stack.back(), @2, @9);
2246 case_type_stack.pop_back();
2247 ast_stack.pop_back();
2248 };
2249
2250 unique_case_attr:
2251 /* empty */ {
2252 $$ = false;
2253 } |
2254 TOK_PRIORITY case_attr {
2255 $$ = $2;
2256 } |
2257 TOK_UNIQUE case_attr {
2258 $$ = true;
2259 };
2260
2261 case_attr:
2262 attr unique_case_attr {
2263 if ($2) (*$1)["\\parallel_case"] = AstNode::mkconst_int(1, false);
2264 $$ = $1;
2265 };
2266
2267 case_type:
2268 TOK_CASE {
2269 case_type_stack.push_back(0);
2270 } |
2271 TOK_CASEX {
2272 case_type_stack.push_back('x');
2273 } |
2274 TOK_CASEZ {
2275 case_type_stack.push_back('z');
2276 };
2277
2278 opt_synopsys_attr:
2279 opt_synopsys_attr TOK_SYNOPSYS_FULL_CASE {
2280 if (ast_stack.back()->attributes.count("\\full_case") == 0)
2281 ast_stack.back()->attributes["\\full_case"] = AstNode::mkconst_int(1, false);
2282 } |
2283 opt_synopsys_attr TOK_SYNOPSYS_PARALLEL_CASE {
2284 if (ast_stack.back()->attributes.count("\\parallel_case") == 0)
2285 ast_stack.back()->attributes["\\parallel_case"] = AstNode::mkconst_int(1, false);
2286 } |
2287 /* empty */;
2288
2289 behavioral_stmt_list:
2290 behavioral_stmt_list behavioral_stmt |
2291 /* empty */;
2292
2293 optional_else:
2294 TOK_ELSE {
2295 AstNode *block = new AstNode(AST_BLOCK);
2296 AstNode *cond = new AstNode(AST_COND, new AstNode(AST_DEFAULT), block);
2297 SET_AST_NODE_LOC(cond, @1, @1);
2298
2299 ast_stack.pop_back();
2300 ast_stack.back()->children.push_back(cond);
2301 ast_stack.push_back(block);
2302 } behavioral_stmt {
2303 SET_AST_NODE_LOC(ast_stack.back(), @3, @3);
2304 } |
2305 /* empty */ %prec FAKE_THEN;
2306
2307 case_body:
2308 case_body case_item |
2309 /* empty */;
2310
2311 case_item:
2312 {
2313 AstNode *node = new AstNode(
2314 case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
2315 case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
2316 ast_stack.back()->children.push_back(node);
2317 ast_stack.push_back(node);
2318 } case_select {
2319 AstNode *block = new AstNode(AST_BLOCK);
2320 ast_stack.back()->children.push_back(block);
2321 ast_stack.push_back(block);
2322 case_type_stack.push_back(0);
2323 } behavioral_stmt {
2324 case_type_stack.pop_back();
2325 SET_AST_NODE_LOC(ast_stack.back(), @4, @4);
2326 ast_stack.pop_back();
2327 ast_stack.pop_back();
2328 };
2329
2330 gen_case_body:
2331 gen_case_body gen_case_item |
2332 /* empty */;
2333
2334 gen_case_item:
2335 {
2336 AstNode *node = new AstNode(
2337 case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
2338 case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
2339 ast_stack.back()->children.push_back(node);
2340 ast_stack.push_back(node);
2341 } case_select {
2342 case_type_stack.push_back(0);
2343 SET_AST_NODE_LOC(ast_stack.back(), @2, @2);
2344 } gen_stmt_or_null {
2345 case_type_stack.pop_back();
2346 ast_stack.pop_back();
2347 };
2348
2349 case_select:
2350 case_expr_list ':' |
2351 TOK_DEFAULT;
2352
2353 case_expr_list:
2354 TOK_DEFAULT {
2355 AstNode *node = new AstNode(AST_DEFAULT);
2356 SET_AST_NODE_LOC(node, @1, @1);
2357 ast_stack.back()->children.push_back(node);
2358 } |
2359 TOK_SVA_LABEL {
2360 AstNode *node = new AstNode(AST_IDENTIFIER);
2361 SET_AST_NODE_LOC(node, @1, @1);
2362 ast_stack.back()->children.push_back(node);
2363 ast_stack.back()->children.back()->str = *$1;
2364 delete $1;
2365 } |
2366 expr {
2367 ast_stack.back()->children.push_back($1);
2368 } |
2369 case_expr_list ',' expr {
2370 ast_stack.back()->children.push_back($3);
2371 };
2372
2373 rvalue:
2374 hierarchical_id '[' expr ']' '.' rvalue {
2375 $$ = new AstNode(AST_PREFIX, $3, $6);
2376 $$->str = *$1;
2377 delete $1;
2378 } |
2379 hierarchical_id range {
2380 $$ = new AstNode(AST_IDENTIFIER, $2);
2381 $$->str = *$1;
2382 delete $1;
2383 if ($2 == nullptr && ($$->str == "\\$initstate" ||
2384 $$->str == "\\$anyconst" || $$->str == "\\$anyseq" ||
2385 $$->str == "\\$allconst" || $$->str == "\\$allseq"))
2386 $$->type = AST_FCALL;
2387 } |
2388 hierarchical_id non_opt_multirange {
2389 $$ = new AstNode(AST_IDENTIFIER, $2);
2390 $$->str = *$1;
2391 delete $1;
2392 };
2393
2394 lvalue:
2395 rvalue {
2396 $$ = $1;
2397 } |
2398 '{' lvalue_concat_list '}' {
2399 $$ = $2;
2400 };
2401
2402 lvalue_concat_list:
2403 expr {
2404 $$ = new AstNode(AST_CONCAT);
2405 $$->children.push_back($1);
2406 } |
2407 expr ',' lvalue_concat_list {
2408 $$ = $3;
2409 $$->children.push_back($1);
2410 };
2411
2412 opt_arg_list:
2413 '(' arg_list optional_comma ')' |
2414 /* empty */;
2415
2416 arg_list:
2417 arg_list2 |
2418 /* empty */;
2419
2420 arg_list2:
2421 single_arg |
2422 arg_list ',' single_arg;
2423
2424 single_arg:
2425 expr {
2426 ast_stack.back()->children.push_back($1);
2427 };
2428
2429 module_gen_body:
2430 module_gen_body gen_stmt_or_module_body_stmt |
2431 /* empty */;
2432
2433 gen_stmt_or_module_body_stmt:
2434 gen_stmt | module_body_stmt;
2435
2436 // this production creates the obligatory if-else shift/reduce conflict
2437 gen_stmt:
2438 TOK_FOR '(' {
2439 AstNode *node = new AstNode(AST_GENFOR);
2440 ast_stack.back()->children.push_back(node);
2441 ast_stack.push_back(node);
2442 } simple_behavioral_stmt ';' expr {
2443 ast_stack.back()->children.push_back($6);
2444 } ';' simple_behavioral_stmt ')' gen_stmt_block {
2445 ast_stack.pop_back();
2446 } |
2447 TOK_IF '(' expr ')' {
2448 AstNode *node = new AstNode(AST_GENIF);
2449 ast_stack.back()->children.push_back(node);
2450 ast_stack.push_back(node);
2451 ast_stack.back()->children.push_back($3);
2452 } gen_stmt_block opt_gen_else {
2453 ast_stack.pop_back();
2454 } |
2455 case_type '(' expr ')' {
2456 AstNode *node = new AstNode(AST_GENCASE, $3);
2457 ast_stack.back()->children.push_back(node);
2458 ast_stack.push_back(node);
2459 } gen_case_body TOK_ENDCASE {
2460 case_type_stack.pop_back();
2461 ast_stack.pop_back();
2462 } |
2463 TOK_BEGIN opt_label {
2464 AstNode *node = new AstNode(AST_GENBLOCK);
2465 node->str = $2 ? *$2 : std::string();
2466 ast_stack.back()->children.push_back(node);
2467 ast_stack.push_back(node);
2468 } module_gen_body TOK_END opt_label {
2469 if ($2 != NULL)
2470 delete $2;
2471 if ($6 != NULL)
2472 delete $6;
2473 ast_stack.pop_back();
2474 } |
2475 TOK_MSG_TASKS {
2476 AstNode *node = new AstNode(AST_TECALL);
2477 node->str = *$1;
2478 delete $1;
2479 ast_stack.back()->children.push_back(node);
2480 ast_stack.push_back(node);
2481 } opt_arg_list ';'{
2482 ast_stack.pop_back();
2483 };
2484
2485 gen_stmt_block:
2486 {
2487 AstNode *node = new AstNode(AST_GENBLOCK);
2488 ast_stack.back()->children.push_back(node);
2489 ast_stack.push_back(node);
2490 } gen_stmt_or_module_body_stmt {
2491 ast_stack.pop_back();
2492 };
2493
2494 gen_stmt_or_null:
2495 gen_stmt_block | ';';
2496
2497 opt_gen_else:
2498 TOK_ELSE gen_stmt_or_null | /* empty */ %prec FAKE_THEN;
2499
2500 expr:
2501 basic_expr {
2502 $$ = $1;
2503 } |
2504 basic_expr '?' attr expr ':' expr {
2505 $$ = new AstNode(AST_TERNARY);
2506 $$->children.push_back($1);
2507 $$->children.push_back($4);
2508 $$->children.push_back($6);
2509 SET_AST_NODE_LOC($$, @1, @$);
2510 append_attr($$, $3);
2511 };
2512
2513 basic_expr:
2514 rvalue {
2515 $$ = $1;
2516 } |
2517 '(' expr ')' TOK_CONSTVAL {
2518 if ($4->compare(0, 1, "'") != 0)
2519 frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str());
2520 AstNode *bits = $2;
2521 AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
2522 if (val == NULL)
2523 log_error("Value conversion failed: `%s'\n", $4->c_str());
2524 $$ = new AstNode(AST_TO_BITS, bits, val);
2525 delete $4;
2526 } |
2527 hierarchical_id TOK_CONSTVAL {
2528 if ($2->compare(0, 1, "'") != 0)
2529 frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str());
2530 AstNode *bits = new AstNode(AST_IDENTIFIER);
2531 bits->str = *$1;
2532 SET_AST_NODE_LOC(bits, @1, @1);
2533 AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
2534 if (val == NULL)
2535 log_error("Value conversion failed: `%s'\n", $2->c_str());
2536 $$ = new AstNode(AST_TO_BITS, bits, val);
2537 delete $1;
2538 delete $2;
2539 } |
2540 TOK_CONSTVAL TOK_CONSTVAL {
2541 $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
2542 if ($$ == NULL || (*$2)[0] != '\'')
2543 log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str());
2544 delete $1;
2545 delete $2;
2546 } |
2547 TOK_CONSTVAL {
2548 $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
2549 if ($$ == NULL)
2550 log_error("Value conversion failed: `%s'\n", $1->c_str());
2551 delete $1;
2552 } |
2553 TOK_REALVAL {
2554 $$ = new AstNode(AST_REALVALUE);
2555 char *p = (char*)malloc(GetSize(*$1) + 1), *q;
2556 for (int i = 0, j = 0; j < GetSize(*$1); j++)
2557 if ((*$1)[j] != '_')
2558 p[i++] = (*$1)[j], p[i] = 0;
2559 $$->realvalue = strtod(p, &q);
2560 SET_AST_NODE_LOC($$, @1, @1);
2561 log_assert(*q == 0);
2562 delete $1;
2563 free(p);
2564 } |
2565 TOK_STRING {
2566 $$ = AstNode::mkconst_str(*$1);
2567 delete $1;
2568 } |
2569 hierarchical_id attr {
2570 AstNode *node = new AstNode(AST_FCALL);
2571 node->str = *$1;
2572 delete $1;
2573 ast_stack.push_back(node);
2574 SET_AST_NODE_LOC(node, @1, @1);
2575 append_attr(node, $2);
2576 } '(' arg_list optional_comma ')' {
2577 $$ = ast_stack.back();
2578 ast_stack.pop_back();
2579 } |
2580 TOK_TO_SIGNED attr '(' expr ')' {
2581 $$ = new AstNode(AST_TO_SIGNED, $4);
2582 append_attr($$, $2);
2583 } |
2584 TOK_TO_UNSIGNED attr '(' expr ')' {
2585 $$ = new AstNode(AST_TO_UNSIGNED, $4);
2586 append_attr($$, $2);
2587 } |
2588 '(' expr ')' {
2589 $$ = $2;
2590 } |
2591 '(' expr ':' expr ':' expr ')' {
2592 delete $2;
2593 $$ = $4;
2594 delete $6;
2595 } |
2596 '{' concat_list '}' {
2597 $$ = $2;
2598 } |
2599 '{' expr '{' concat_list '}' '}' {
2600 $$ = new AstNode(AST_REPLICATE, $2, $4);
2601 } |
2602 '~' attr basic_expr %prec UNARY_OPS {
2603 $$ = new AstNode(AST_BIT_NOT, $3);
2604 SET_AST_NODE_LOC($$, @1, @3);
2605 append_attr($$, $2);
2606 } |
2607 basic_expr '&' attr basic_expr {
2608 $$ = new AstNode(AST_BIT_AND, $1, $4);
2609 SET_AST_NODE_LOC($$, @1, @4);
2610 append_attr($$, $3);
2611 } |
2612 basic_expr OP_NAND attr basic_expr {
2613 $$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_AND, $1, $4));
2614 SET_AST_NODE_LOC($$, @1, @4);
2615 append_attr($$, $3);
2616 } |
2617 basic_expr '|' attr basic_expr {
2618 $$ = new AstNode(AST_BIT_OR, $1, $4);
2619 SET_AST_NODE_LOC($$, @1, @4);
2620 append_attr($$, $3);
2621 } |
2622 basic_expr OP_NOR attr basic_expr {
2623 $$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_OR, $1, $4));
2624 SET_AST_NODE_LOC($$, @1, @4);
2625 append_attr($$, $3);
2626 } |
2627 basic_expr '^' attr basic_expr {
2628 $$ = new AstNode(AST_BIT_XOR, $1, $4);
2629 SET_AST_NODE_LOC($$, @1, @4);
2630 append_attr($$, $3);
2631 } |
2632 basic_expr OP_XNOR attr basic_expr {
2633 $$ = new AstNode(AST_BIT_XNOR, $1, $4);
2634 SET_AST_NODE_LOC($$, @1, @4);
2635 append_attr($$, $3);
2636 } |
2637 '&' attr basic_expr %prec UNARY_OPS {
2638 $$ = new AstNode(AST_REDUCE_AND, $3);
2639 SET_AST_NODE_LOC($$, @1, @3);
2640 append_attr($$, $2);
2641 } |
2642 OP_NAND attr basic_expr %prec UNARY_OPS {
2643 $$ = new AstNode(AST_REDUCE_AND, $3);
2644 SET_AST_NODE_LOC($$, @1, @3);
2645 append_attr($$, $2);
2646 $$ = new AstNode(AST_LOGIC_NOT, $$);
2647 } |
2648 '|' attr basic_expr %prec UNARY_OPS {
2649 $$ = new AstNode(AST_REDUCE_OR, $3);
2650 SET_AST_NODE_LOC($$, @1, @3);
2651 append_attr($$, $2);
2652 } |
2653 OP_NOR attr basic_expr %prec UNARY_OPS {
2654 $$ = new AstNode(AST_REDUCE_OR, $3);
2655 SET_AST_NODE_LOC($$, @1, @3);
2656 append_attr($$, $2);
2657 $$ = new AstNode(AST_LOGIC_NOT, $$);
2658 SET_AST_NODE_LOC($$, @1, @3);
2659 } |
2660 '^' attr basic_expr %prec UNARY_OPS {
2661 $$ = new AstNode(AST_REDUCE_XOR, $3);
2662 SET_AST_NODE_LOC($$, @1, @3);
2663 append_attr($$, $2);
2664 } |
2665 OP_XNOR attr basic_expr %prec UNARY_OPS {
2666 $$ = new AstNode(AST_REDUCE_XNOR, $3);
2667 SET_AST_NODE_LOC($$, @1, @3);
2668 append_attr($$, $2);
2669 } |
2670 basic_expr OP_SHL attr basic_expr {
2671 $$ = new AstNode(AST_SHIFT_LEFT, $1, new AstNode(AST_TO_UNSIGNED, $4));
2672 SET_AST_NODE_LOC($$, @1, @4);
2673 append_attr($$, $3);
2674 } |
2675 basic_expr OP_SHR attr basic_expr {
2676 $$ = new AstNode(AST_SHIFT_RIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4));
2677 SET_AST_NODE_LOC($$, @1, @4);
2678 append_attr($$, $3);
2679 } |
2680 basic_expr OP_SSHL attr basic_expr {
2681 $$ = new AstNode(AST_SHIFT_SLEFT, $1, new AstNode(AST_TO_UNSIGNED, $4));
2682 SET_AST_NODE_LOC($$, @1, @4);
2683 append_attr($$, $3);
2684 } |
2685 basic_expr OP_SSHR attr basic_expr {
2686 $$ = new AstNode(AST_SHIFT_SRIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4));
2687 SET_AST_NODE_LOC($$, @1, @4);
2688 append_attr($$, $3);
2689 } |
2690 basic_expr '<' attr basic_expr {
2691 $$ = new AstNode(AST_LT, $1, $4);
2692 SET_AST_NODE_LOC($$, @1, @4);
2693 append_attr($$, $3);
2694 } |
2695 basic_expr OP_LE attr basic_expr {
2696 $$ = new AstNode(AST_LE, $1, $4);
2697 SET_AST_NODE_LOC($$, @1, @4);
2698 append_attr($$, $3);
2699 } |
2700 basic_expr OP_EQ attr basic_expr {
2701 $$ = new AstNode(AST_EQ, $1, $4);
2702 SET_AST_NODE_LOC($$, @1, @4);
2703 append_attr($$, $3);
2704 } |
2705 basic_expr OP_NE attr basic_expr {
2706 $$ = new AstNode(AST_NE, $1, $4);
2707 SET_AST_NODE_LOC($$, @1, @4);
2708 append_attr($$, $3);
2709 } |
2710 basic_expr OP_EQX attr basic_expr {
2711 $$ = new AstNode(AST_EQX, $1, $4);
2712 SET_AST_NODE_LOC($$, @1, @4);
2713 append_attr($$, $3);
2714 } |
2715 basic_expr OP_NEX attr basic_expr {
2716 $$ = new AstNode(AST_NEX, $1, $4);
2717 SET_AST_NODE_LOC($$, @1, @4);
2718 append_attr($$, $3);
2719 } |
2720 basic_expr OP_GE attr basic_expr {
2721 $$ = new AstNode(AST_GE, $1, $4);
2722 SET_AST_NODE_LOC($$, @1, @4);
2723 append_attr($$, $3);
2724 } |
2725 basic_expr '>' attr basic_expr {
2726 $$ = new AstNode(AST_GT, $1, $4);
2727 SET_AST_NODE_LOC($$, @1, @4);
2728 append_attr($$, $3);
2729 } |
2730 basic_expr '+' attr basic_expr {
2731 $$ = new AstNode(AST_ADD, $1, $4);
2732 SET_AST_NODE_LOC($$, @1, @4);
2733 append_attr($$, $3);
2734 } |
2735 basic_expr '-' attr basic_expr {
2736 $$ = new AstNode(AST_SUB, $1, $4);
2737 SET_AST_NODE_LOC($$, @1, @4);
2738 append_attr($$, $3);
2739 } |
2740 basic_expr '*' attr basic_expr {
2741 $$ = new AstNode(AST_MUL, $1, $4);
2742 SET_AST_NODE_LOC($$, @1, @4);
2743 append_attr($$, $3);
2744 } |
2745 basic_expr '/' attr basic_expr {
2746 $$ = new AstNode(AST_DIV, $1, $4);
2747 SET_AST_NODE_LOC($$, @1, @4);
2748 append_attr($$, $3);
2749 } |
2750 basic_expr '%' attr basic_expr {
2751 $$ = new AstNode(AST_MOD, $1, $4);
2752 SET_AST_NODE_LOC($$, @1, @4);
2753 append_attr($$, $3);
2754 } |
2755 basic_expr OP_POW attr basic_expr {
2756 $$ = new AstNode(AST_POW, $1, $4);
2757 SET_AST_NODE_LOC($$, @1, @4);
2758 append_attr($$, $3);
2759 } |
2760 '+' attr basic_expr %prec UNARY_OPS {
2761 $$ = new AstNode(AST_POS, $3);
2762 SET_AST_NODE_LOC($$, @1, @3);
2763 append_attr($$, $2);
2764 } |
2765 '-' attr basic_expr %prec UNARY_OPS {
2766 $$ = new AstNode(AST_NEG, $3);
2767 SET_AST_NODE_LOC($$, @1, @3);
2768 append_attr($$, $2);
2769 } |
2770 basic_expr OP_LAND attr basic_expr {
2771 $$ = new AstNode(AST_LOGIC_AND, $1, $4);
2772 SET_AST_NODE_LOC($$, @1, @4);
2773 append_attr($$, $3);
2774 } |
2775 basic_expr OP_LOR attr basic_expr {
2776 $$ = new AstNode(AST_LOGIC_OR, $1, $4);
2777 SET_AST_NODE_LOC($$, @1, @4);
2778 append_attr($$, $3);
2779 } |
2780 '!' attr basic_expr %prec UNARY_OPS {
2781 $$ = new AstNode(AST_LOGIC_NOT, $3);
2782 SET_AST_NODE_LOC($$, @1, @3);
2783 append_attr($$, $2);
2784 };
2785
2786 concat_list:
2787 expr {
2788 $$ = new AstNode(AST_CONCAT, $1);
2789 } |
2790 expr ',' concat_list {
2791 $$ = $3;
2792 $$->children.push_back($1);
2793 };