2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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.
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.
20 * The Verilog frontend.
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.
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
40 #include "frontends/verilog/verilog_frontend.h"
41 #include "frontends/verilog/verilog_parser.tab.hh"
42 #include "kernel/log.h"
44 #define YYLEX_PARAM &yylval, &yylloc
48 using namespace VERILOG_FRONTEND;
51 namespace VERILOG_FRONTEND {
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;
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)
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)
86 int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
88 static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
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;
98 static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
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();
107 static void free_attr(std::map<std::string, AstNode*> *al)
114 struct specify_target {
119 struct specify_triple {
120 AstNode *t_min, *t_avg, *t_max;
123 struct specify_rise_fall {
128 static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true)
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;
137 static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned = true)
139 auto range = makeRange(msb, lsb, isSigned);
140 parent->children.push_back(range);
144 %define api.prefix {frontend_verilog_yy}
147 /* The union is defined in the header, so we need to provide all the
148 * includes it requires
153 #include "frontends/verilog/verilog_frontend.h"
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;
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
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
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
202 // operator precedence from low to high
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
216 %define parse.error verbose
217 %define parse.lac full
229 ast_stack.push_back(current_ast);
231 ast_stack.pop_back();
232 log_assert(GetSize(ast_stack) == 0);
233 for (auto &it : default_attr_list)
235 default_attr_list.clear();
241 task_func_decl design |
243 localparam_decl design |
244 typedef_decl design |
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();
258 if (!attr_list_stack.empty()) {
259 attr_list = attr_list_stack.top();
260 attr_list_stack.pop();
266 attr_opt ATTR_BEGIN opt_attr_list ATTR_END {
267 SET_RULE_LOC(@$, @2, @$);
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)
278 default_attr_list.clear();
280 attr_list->swap(default_attr_list);
282 if (!attr_list_stack.empty()) {
283 attr_list = attr_list_stack.top();
284 attr_list_stack.pop();
290 attr_list | /* empty */;
294 attr_list ',' attr_assign;
298 if (attr_list->count(*$1) != 0)
299 delete (*attr_list)[*$1];
300 (*attr_list)[*$1] = AstNode::mkconst_int(1, false);
303 hierarchical_id '=' expr {
304 if (attr_list->count(*$1) != 0)
305 delete (*attr_list)[*$1];
306 (*attr_list)[*$1] = $3;
314 hierarchical_id TOK_PACKAGESEP TOK_ID {
315 if ($3->compare(0, 1, "\\") == 0)
316 *$1 += "::" + $3->substr(1);
322 hierarchical_id '.' TOK_ID {
323 if ($3->compare(0, 1, "\\") == 0)
324 *$1 += "." + $3->substr(1);
331 hierarchical_type_id:
332 '(' hierarchical_id ')' { $$ = $2; };
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;
344 append_attr(mod, $1);
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;
357 '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | /* empty */;
360 single_module_para | module_para_list ',' single_module_para;
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 |
379 '(' ')' | /* empty */ | '(' module_args optional_comma ')';
382 module_arg | module_args ',' module_arg;
387 module_arg_opt_assignment:
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;
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))));
401 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2));
403 frontend_verilog_yyerror("SystemVerilog interface in module port list cannot have a default value.");
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();
412 node->port_id = ++port_counter;
413 ast_stack.back()->children.push_back(node);
414 SET_AST_NODE_LOC(node, @1, @1);
416 if (port_stubs.count(*$1) != 0)
417 frontend_verilog_yyerror("Duplicate module port `%s'.", $1->c_str());
418 port_stubs[*$1] = ++port_counter;
421 } module_arg_opt_assignment |
423 astbuf1 = new AstNode(AST_INTERFACEPORT);
424 astbuf1->children.push_back(new AstNode(AST_INTERFACEPORTTYPE));
425 astbuf1->children[0]->str = *$1;
427 } TOK_ID { /* SV interfaces */
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.
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 {
440 SET_AST_NODE_LOC(node, @4, @4);
441 node->port_id = ++port_counter;
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);
451 } module_arg_opt_assignment |
453 do_not_require_port_stubs = true;
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;
463 append_attr(mod, $1);
464 } ';' package_body TOK_ENDPACKAGE {
465 ast_stack.pop_back();
466 current_ast_mod = NULL;
470 package_body package_body_stmt
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;
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;
499 interface_body interface_body_stmt |;
502 param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
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; };
513 non_opt_delay | /* empty */;
517 astbuf3 = new AstNode(AST_WIRE);
518 current_wire_rand = false;
519 current_wire_const = false;
520 } wire_type_token_list {
522 SET_RULE_LOC(@$, @2, @$);
525 wire_type_token_list:
527 wire_type_token_list wire_type_token |
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;
537 astbuf3->is_input = true;
540 astbuf3->is_output = true;
543 astbuf3->is_input = true;
544 astbuf3->is_output = true;
551 astbuf3->is_wor = true;
554 astbuf3->is_wand = true;
557 astbuf3->is_reg = true;
560 astbuf3->is_logic = true;
563 astbuf3->is_logic = true;
566 astbuf3->is_reg = true;
567 astbuf3->range_left = 31;
568 astbuf3->range_right = 0;
569 astbuf3->is_signed = true;
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;
579 astbuf3->is_signed = true;
582 current_wire_rand = true;
585 current_wire_const = true;
589 '[' expr ':' expr ']' {
590 $$ = new AstNode(AST_RANGE);
591 $$->children.push_back($2);
592 $$->children.push_back($4);
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)));
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));
607 $$ = new AstNode(AST_RANGE);
608 $$->children.push_back($2);
612 non_opt_range non_opt_range {
613 $$ = new AstNode(AST_MULTIRANGE, $1, $2);
615 non_opt_multirange non_opt_range {
617 $$->children.push_back($2);
630 non_opt_multirange { $$ = $1; };
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;
644 module_body module_body_stmt |
645 /* the following line makes the generate..endgenrate keywords optional */
646 module_body gen_stmt |
650 task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
652 always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
655 TOK_CHECKER TOK_ID ';' {
656 AstNode *node = new AstNode(AST_GENBLOCK);
658 ast_stack.back()->children.push_back(node);
659 ast_stack.push_back(node);
660 } module_body TOK_ENDCHECKER {
662 ast_stack.pop_back();
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);
673 } opt_dpi_function_args ';' {
674 current_function_or_task = NULL;
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);
684 } opt_dpi_function_args ';' {
685 current_function_or_task = NULL;
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);
696 } opt_dpi_function_args ';' {
697 current_function_or_task = NULL;
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;
707 } task_func_args_opt ';' task_func_body TOK_ENDTASK {
708 current_function_or_task = NULL;
709 ast_stack.pop_back();
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);
719 outreg->is_signed = $4;
720 outreg->is_reg = true;
722 outreg->children.push_back($5);
723 outreg->is_signed = $4 || $5->is_signed;
724 $5->is_signed = false;
726 current_function_or_task->children.push_back(outreg);
727 current_function_or_task_port_id = 1;
729 } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION {
730 current_function_or_task = NULL;
731 ast_stack.pop_back();
736 current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
741 current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
745 opt_dpi_function_args:
746 '(' dpi_function_args ')' |
750 dpi_function_args ',' dpi_function_arg |
751 dpi_function_args ',' |
768 '(' ')' | /* empty */ | '(' {
772 } task_func_args optional_comma {
780 task_func_port | task_func_args ',' task_func_port;
783 attr wire_type range {
793 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
795 frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions (task/function arguments)");
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));
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;
807 task_func_body behavioral_stmt |
810 /*************************** specify parser ***************************/
813 TOK_SPECIFY specify_item_list TOK_ENDSPECIFY;
816 specify_item specify_item_list |
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;
825 specify_target *target = $6;
826 specify_rise_fall *timing = $9;
828 if (specify_edge != 0 && target->dat == nullptr)
829 frontend_verilog_yyerror("Found specify edge but no data spec.\n");
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";
837 char oper_polarity = 0;
838 char oper_type = oper->at(0);
840 if (oper->size() == 3) {
841 oper_polarity = oper->at(0);
842 oper_type = oper->at(1);
845 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(oper_type == '*', false, 1)));
846 cell->children.back()->str = "\\FULL";
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";
851 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(oper_polarity == '+', false, 1)));
852 cell->children.back()->str = "\\SRC_DST_POL";
854 cell->children.push_back(new AstNode(AST_PARASET, timing->rise.t_min));
855 cell->children.back()->str = "\\T_RISE_MIN";
857 cell->children.push_back(new AstNode(AST_PARASET, timing->rise.t_avg));
858 cell->children.back()->str = "\\T_RISE_TYP";
860 cell->children.push_back(new AstNode(AST_PARASET, timing->rise.t_max));
861 cell->children.back()->str = "\\T_RISE_MAX";
863 cell->children.push_back(new AstNode(AST_PARASET, timing->fall.t_min));
864 cell->children.back()->str = "\\T_FALL_MIN";
866 cell->children.push_back(new AstNode(AST_PARASET, timing->fall.t_avg));
867 cell->children.back()->str = "\\T_FALL_TYP";
869 cell->children.push_back(new AstNode(AST_PARASET, timing->fall.t_max));
870 cell->children.back()->str = "\\T_FALL_MAX";
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";
875 cell->children.push_back(new AstNode(AST_ARGUMENT, src_expr));
876 cell->children.back()->str = "\\SRC";
878 cell->children.push_back(new AstNode(AST_ARGUMENT, target->dst));
879 cell->children.back()->str = "\\DST";
883 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(specify_edge != 0, false, 1)));
884 cell->children.back()->str = "\\EDGE_EN";
886 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_int(specify_edge == 'p', false, 1)));
887 cell->children.back()->str = "\\EDGE_POL";
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";
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";
895 cell->children.push_back(new AstNode(AST_ARGUMENT, target->dat));
896 cell->children.back()->str = "\\DAT";
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());
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);
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);
916 specify_triple *limit = $11;
917 specify_triple *limit2 = $12;
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";
925 cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_str(*$1)));
926 cell->children.back()->str = "\\TYPE";
928 cell->children.push_back(new AstNode(AST_PARASET, limit->t_min));
929 cell->children.back()->str = "\\T_LIMIT_MIN";
931 cell->children.push_back(new AstNode(AST_PARASET, limit->t_avg));
932 cell->children.back()->str = "\\T_LIMIT_TYP";
934 cell->children.push_back(new AstNode(AST_PARASET, limit->t_max));
935 cell->children.back()->str = "\\T_LIMIT_MAX";
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";
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";
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";
946 cell->children.push_back(new AstNode(AST_PARASET, src_pen));
947 cell->children.back()->str = "\\SRC_PEN";
949 cell->children.push_back(new AstNode(AST_PARASET, src_pol));
950 cell->children.back()->str = "\\SRC_POL";
952 cell->children.push_back(new AstNode(AST_PARASET, dst_pen));
953 cell->children.back()->str = "\\DST_PEN";
955 cell->children.push_back(new AstNode(AST_PARASET, dst_pol));
956 cell->children.back()->str = "\\DST_POL";
958 cell->children.push_back(new AstNode(AST_ARGUMENT, src_en));
959 cell->children.back()->str = "\\SRC_EN";
961 cell->children.push_back(new AstNode(AST_ARGUMENT, src_expr));
962 cell->children.back()->str = "\\SRC";
964 cell->children.push_back(new AstNode(AST_ARGUMENT, dst_en));
965 cell->children.back()->str = "\\DST_EN";
967 cell->children.push_back(new AstNode(AST_ARGUMENT, dst_expr));
968 cell->children.back()->str = "\\DST";
982 TOK_IF '(' expr ')' {
990 TOK_SPECIFY_AND expr {
999 $$ = new specify_target;
1000 $$->polarity_op = 0;
1004 '(' expr ':' expr ')'{
1005 $$ = new specify_target;
1006 $$->polarity_op = 0;
1010 '(' expr TOK_NEG_INDEXED expr ')'{
1011 $$ = new specify_target;
1012 $$->polarity_op = '-';
1016 '(' expr TOK_POS_INDEXED expr ')'{
1017 $$ = new specify_target;
1018 $$->polarity_op = '+';
1024 TOK_POSEDGE { $$ = 'p'; } |
1025 TOK_NEGEDGE { $$ = 'n'; } |
1030 $$ = new specify_rise_fall;
1032 $$->fall.t_min = $1->t_min->clone();
1033 $$->fall.t_avg = $1->t_avg->clone();
1034 $$->fall.t_max = $1->t_max->clone();
1037 '(' specify_triple ',' specify_triple ')' {
1038 $$ = new specify_rise_fall;
1044 '(' specify_triple ',' specify_triple ',' specify_triple ')' {
1045 $$ = new specify_rise_fall;
1051 log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
1053 '(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
1054 $$ = new specify_rise_fall;
1063 log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
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;
1081 log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
1086 $$ = new specify_triple;
1088 $$->t_avg = $1->clone();
1089 $$->t_max = $1->clone();
1091 expr ':' expr ':' expr {
1092 $$ = new specify_triple;
1098 /******************** ignored specify parser **************************/
1100 ignored_specify_block:
1101 TOK_IGNORED_SPECIFY ignored_specify_item_opt TOK_ENDSPECIFY |
1102 TOK_IGNORED_SPECIFY TOK_ENDSPECIFY ;
1104 ignored_specify_item_opt:
1105 ignored_specify_item_opt ignored_specify_item |
1106 ignored_specify_item ;
1108 ignored_specify_item:
1109 specparam_declaration
1110 // | pulsestyle_declaration
1111 // | showcancelled_declaration
1113 | system_timing_declaration
1116 specparam_declaration:
1117 TOK_SPECPARAM list_of_specparam_assignments ';' |
1118 TOK_SPECPARAM specparam_range list_of_specparam_assignments ';' ;
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
1124 '[' ignspec_constant_expression ':' ignspec_constant_expression ']' ;
1126 list_of_specparam_assignments:
1127 specparam_assignment | list_of_specparam_assignments ',' specparam_assignment;
1129 specparam_assignment:
1130 ignspec_id '=' ignspec_expr ;
1133 TOK_IF '(' ignspec_expr ')' | /* empty */;
1136 simple_path_declaration ';'
1137 // | edge_sensitive_path_declaration
1138 // | state_dependent_path_declaration
1141 simple_path_declaration :
1142 ignspec_opt_cond parallel_path_description '=' path_delay_value |
1143 ignspec_opt_cond full_path_description '=' path_delay_value
1147 '(' ignspec_expr list_of_path_delay_extra_expressions ')'
1149 | ignspec_expr list_of_path_delay_extra_expressions
1152 list_of_path_delay_extra_expressions :
1154 | ',' ignspec_expr list_of_path_delay_extra_expressions
1157 specify_edge_identifier :
1158 TOK_POSEDGE | TOK_NEGEDGE ;
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 ')' ')' ;
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 ')' ')' ;
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 ;
1176 ',' specify_input_terminal_descriptor |
1177 more_path_inputs ',' specify_input_terminal_descriptor ;
1179 list_of_path_outputs :
1180 specify_output_terminal_descriptor |
1181 list_of_path_outputs ',' specify_output_terminal_descriptor ;
1183 opt_polarity_operator :
1188 // Good enough for the time being
1189 specify_input_terminal_descriptor :
1192 // Good enough for the time being
1193 specify_output_terminal_descriptor :
1196 system_timing_declaration :
1197 ignspec_id '(' system_timing_args ')' ';' ;
1200 TOK_POSEDGE ignspec_id |
1201 TOK_NEGEDGE ignspec_id |
1204 system_timing_args :
1206 system_timing_args TOK_IGNORED_SPECIFY_AND system_timing_arg |
1207 system_timing_args ',' system_timing_arg ;
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; };
1217 expr { delete $1; } |
1218 expr ':' expr ':' expr {
1225 TOK_ID { delete $1; }
1226 range_or_multirange { delete $3; };
1228 /**********************************************************************/
1232 astbuf1->is_signed = true;
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;
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));
1255 if (astbuf1->children.size() != 1)
1256 frontend_verilog_yyerror("integer/real parameters should not have a range.");
1257 astbuf1->children.push_back($1);
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;
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 ';' {
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 ';' {
1288 single_param_decl | param_decl_list ',' single_param_decl;
1293 if (astbuf1 == nullptr) {
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));
1299 node = astbuf1->clone();
1302 delete node->children[0];
1303 node->children[0] = $3;
1304 ast_stack.back()->children.push_back(node);
1309 TOK_DEFPARAM defparam_decl_list ';';
1312 single_defparam_decl | defparam_decl_list ',' single_defparam_decl;
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);
1320 node->children.push_back($1);
1321 ast_stack.back()->children.push_back(node);
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();
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()); }
1345 enum_base_type: int_vec param_range
1347 | /* nothing */ {astbuf1->is_reg = true; addRange(astbuf1); }
1350 int_atom: TOK_INTEGER {astbuf1->is_reg=true; addRange(astbuf1); } // probably should do byte, range [7:0] here
1353 int_vec: TOK_REG {astbuf1->is_reg = true;}
1354 | TOK_LOGIC {astbuf1->is_logic = true;}
1359 | enum_name_list ',' enum_name_decl
1363 TOK_ID opt_enum_init {
1365 log_assert(astbuf1);
1366 log_assert(astbuf2);
1367 auto node = astbuf1->clone();
1370 delete node->children[0];
1371 node->children[0] = $2 ?: new AstNode(AST_NONE);
1372 astbuf2->children.push_back(node);
1377 '=' basic_expr { $$ = $2; } // TODO: restrict this
1378 | /* optional */ { $$ = NULL; }
1383 | enum_var_list ',' enum_var
1387 log_assert(astbuf1);
1388 log_assert(astbuf2);
1389 auto node = astbuf1->clone();
1390 ast_stack.back()->children.push_back(node);
1393 node->is_enum = true;
1397 enum_decl: enum_type enum_var_list ';' {
1398 //enum_type creates astbuf1 for use by typedef only
1404 attr wire_type range {
1408 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
1410 frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
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));
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 {
1421 if (astbuf2 != NULL)
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;
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;
1440 } opt_supply_wires ';';
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);
1455 wire_name_and_opt_assign | wire_name_list ',' wire_name_and_opt_assign;
1457 wire_name_and_opt_assign:
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;
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");
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;
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");
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";
1489 fcall->str = "\\$anyconst";
1491 fcall->str = "\\$anyseq";
1493 fcall->str = "\\$allconst";
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));
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;
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);
1513 SET_AST_NODE_LOC(assign, @1, @3);
1514 SET_AST_NODE_LOC(block, @1, @3);
1515 SET_AST_NODE_LOC(init, @1, @3);
1517 ast_stack.back()->children.push_back(init);
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);
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();
1533 append_attr_clone(node, albuf);
1534 if (astbuf2 != NULL)
1535 node->children.push_back(astbuf2->clone());
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);
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));
1552 node->children.push_back(rangeNode);
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;
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);
1566 if (node->is_input || node->is_output)
1567 frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
1570 if (node->is_input || node->is_output)
1571 node->port_id = current_function_or_task_port_id++;
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);
1581 TOK_ASSIGN delay assign_expr_list ';';
1584 assign_expr | assign_expr_list ',' assign_expr;
1588 AstNode *node = new AstNode(AST_ASSIGN, $1, $3);
1589 SET_AST_NODE_LOC(node, @$, @$);
1590 ast_stack.back()->children.push_back(node);
1594 TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
1597 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
1599 frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
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));
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>]");
1609 astbuf1->children.push_back(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);
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));
1625 astbuf1->children.push_back(rangeNode);
1628 ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
1629 ast_stack.back()->children.back()->str = *$4;
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;
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;
1644 } cell_parameter_list_opt cell_list ';' {
1647 attr tok_prim_wrapper delay {
1648 astbuf1 = new AstNode(AST_PRIMITIVE);
1650 append_attr(astbuf1, $1);
1661 $$ = new std::string("or");
1666 cell_list ',' single_cell;
1670 astbuf2 = astbuf1->clone();
1671 if (astbuf2->type != AST_PRIMITIVE)
1674 ast_stack.back()->children.push_back(astbuf2);
1675 } '(' cell_port_list ')' {
1676 SET_AST_NODE_LOC(astbuf2, @1, @$);
1678 TOK_ID non_opt_range {
1679 astbuf2 = astbuf1->clone();
1680 if (astbuf2->type != AST_PRIMITIVE)
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, @$);
1691 prim_list ',' single_prim;
1696 astbuf2 = astbuf1->clone();
1697 ast_stack.back()->children.push_back(astbuf2);
1698 } '(' cell_port_list ')';
1700 cell_parameter_list_opt:
1701 '#' '(' cell_parameter_list ')' | /* empty */;
1703 cell_parameter_list:
1704 cell_parameter | cell_parameter_list ',' cell_parameter;
1709 AstNode *node = new AstNode(AST_PARASET);
1710 astbuf1->children.push_back(node);
1711 node->children.push_back($1);
1713 '.' TOK_ID '(' expr ')' {
1714 AstNode *node = new AstNode(AST_PARASET);
1716 astbuf1->children.push_back(node);
1717 node->children.push_back($4);
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();
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;
1741 has_named_args = true;
1744 if (has_positional_args && has_named_args)
1745 frontend_verilog_yyerror("Mix of positional and named cell ports.");
1748 cell_port_list_rules:
1749 cell_port | cell_port_list_rules ',' cell_port;
1753 AstNode *node = new AstNode(AST_ARGUMENT);
1754 astbuf2->children.push_back(node);
1758 AstNode *node = new AstNode(AST_ARGUMENT);
1759 astbuf2->children.push_back(node);
1760 node->children.push_back($2);
1763 attr '.' TOK_ID '(' expr ')' {
1764 AstNode *node = new AstNode(AST_ARGUMENT);
1766 astbuf2->children.push_back(node);
1767 node->children.push_back($5);
1771 attr '.' TOK_ID '(' ')' {
1772 AstNode *node = new AstNode(AST_ARGUMENT);
1774 astbuf2->children.push_back(node);
1779 AstNode *node = new AstNode(AST_ARGUMENT);
1781 astbuf2->children.push_back(node);
1782 node->children.push_back(new AstNode(AST_IDENTIFIER));
1783 node->children.back()->str = *$3;
1787 attr TOK_WILDCARD_CONNECT {
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);
1793 always_comb_or_latch:
1801 always_or_always_ff:
1810 attr always_or_always_ff {
1811 AstNode *node = new AstNode(AST_ALWAYS);
1812 append_attr(node, $1);
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);
1818 AstNode *block = new AstNode(AST_BLOCK);
1819 ast_stack.back()->children.push_back(block);
1820 ast_stack.push_back(block);
1822 SET_AST_NODE_LOC(ast_stack.back(), @6, @6);
1823 ast_stack.pop_back();
1825 SET_AST_NODE_LOC(ast_stack.back(), @2, @$);
1826 ast_stack.pop_back();
1828 SET_RULE_LOC(@$, @2, @$);
1830 attr always_comb_or_latch {
1831 AstNode *node = new AstNode(AST_ALWAYS);
1832 append_attr(node, $1);
1834 node->attributes[ID(always_latch)] = AstNode::mkconst_int(1, false);
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);
1843 ast_stack.pop_back();
1844 ast_stack.pop_back();
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);
1855 ast_stack.pop_back();
1856 ast_stack.pop_back();
1860 '@' '(' always_events ')' |
1862 '@' ATTR_BEGIN ')' |
1869 always_events TOK_OR always_event |
1870 always_events ',' always_event;
1874 AstNode *node = new AstNode(AST_POSEDGE);
1875 ast_stack.back()->children.push_back(node);
1876 node->children.push_back($2);
1879 AstNode *node = new AstNode(AST_NEGEDGE);
1880 ast_stack.back()->children.push_back(node);
1881 node->children.push_back($2);
1884 AstNode *node = new AstNode(AST_EDGE);
1885 ast_stack.back()->children.push_back(node);
1886 node->children.push_back($1);
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);
1923 } modport_args_opt {
1924 ast_stack.pop_back();
1925 log_assert(ast_stack.size() == 2);
1929 '(' ')' | '(' modport_args optional_comma ')';
1932 modport_arg | modport_args ',' modport_arg;
1935 modport_type_token modport_member |
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;
1949 TOK_INPUT {current_modport_input = 1; current_modport_output = 0;} | TOK_OUTPUT {current_modport_input = 0; current_modport_output = 1;}
1952 opt_sva_label TOK_ASSERT opt_property '(' expr ')' ';' {
1953 if (noassert_mode) {
1956 AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
1959 ast_stack.back()->children.push_back(node);
1964 opt_sva_label TOK_ASSUME opt_property '(' expr ')' ';' {
1965 if (noassume_mode) {
1968 AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5);
1971 ast_stack.back()->children.push_back(node);
1976 opt_sva_label TOK_ASSERT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
1977 if (noassert_mode) {
1980 AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
1983 ast_stack.back()->children.push_back(node);
1988 opt_sva_label TOK_ASSUME opt_property '(' TOK_EVENTUALLY expr ')' ';' {
1989 if (noassume_mode) {
1992 AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6);
1995 ast_stack.back()->children.push_back(node);
2000 opt_sva_label TOK_COVER opt_property '(' expr ')' ';' {
2001 AstNode *node = new AstNode(AST_COVER, $5);
2002 if ($1 != nullptr) {
2006 ast_stack.back()->children.push_back(node);
2008 opt_sva_label TOK_COVER opt_property '(' ')' ';' {
2009 AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
2010 if ($1 != nullptr) {
2014 ast_stack.back()->children.push_back(node);
2016 opt_sva_label TOK_COVER ';' {
2017 AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
2018 if ($1 != nullptr) {
2022 ast_stack.back()->children.push_back(node);
2024 opt_sva_label TOK_RESTRICT opt_property '(' expr ')' ';' {
2025 if (norestrict_mode) {
2028 AstNode *node = new AstNode(AST_ASSUME, $5);
2031 ast_stack.back()->children.push_back(node);
2034 log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
2038 opt_sva_label TOK_RESTRICT opt_property '(' TOK_EVENTUALLY expr ')' ';' {
2039 if (norestrict_mode) {
2042 AstNode *node = new AstNode(AST_FAIR, $6);
2045 ast_stack.back()->children.push_back(node);
2048 log_file_warning(current_filename, get_line_num(), "SystemVerilog does not allow \"restrict\" without \"property\".\n");
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;
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;
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;
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;
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;
2089 opt_sva_label TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' {
2090 if (norestrict_mode) {
2093 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
2094 if ($1 != nullptr) {
2095 ast_stack.back()->children.back()->str = *$1;
2100 opt_sva_label TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
2101 if (norestrict_mode) {
2104 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
2105 if ($1 != nullptr) {
2106 ast_stack.back()->children.back()->str = *$1;
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);
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);
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);
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);
2134 // this production creates the obligatory if-else shift/reduce conflict
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);
2143 ast_stack.back()->children.push_back(node);
2144 ast_stack.push_back(node);
2145 append_attr(node, $2);
2147 ast_stack.pop_back();
2149 TOK_MSG_TASKS attr {
2150 AstNode *node = new AstNode(AST_TCALL);
2153 ast_stack.back()->children.push_back(node);
2154 ast_stack.push_back(node);
2155 append_attr(node, $2);
2157 ast_stack.pop_back();
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);
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);
2173 ast_stack.pop_back();
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);
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();
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);
2202 SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
2203 ast_stack.pop_back();
2204 ast_stack.pop_back();
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);
2216 SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
2217 ast_stack.pop_back();
2218 ast_stack.pop_back();
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);
2232 SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
2234 ast_stack.pop_back();
2235 SET_AST_NODE_LOC(ast_stack.back(), @2, @9);
2236 ast_stack.pop_back();
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();
2254 TOK_PRIORITY case_attr {
2257 TOK_UNIQUE case_attr {
2262 attr unique_case_attr {
2263 if ($2) (*$1)["\\parallel_case"] = AstNode::mkconst_int(1, false);
2269 case_type_stack.push_back(0);
2272 case_type_stack.push_back('x');
2275 case_type_stack.push_back('z');
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);
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);
2289 behavioral_stmt_list:
2290 behavioral_stmt_list behavioral_stmt |
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);
2299 ast_stack.pop_back();
2300 ast_stack.back()->children.push_back(cond);
2301 ast_stack.push_back(block);
2303 SET_AST_NODE_LOC(ast_stack.back(), @3, @3);
2305 /* empty */ %prec FAKE_THEN;
2308 case_body case_item |
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);
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);
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();
2331 gen_case_body gen_case_item |
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);
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();
2350 case_expr_list ':' |
2355 AstNode *node = new AstNode(AST_DEFAULT);
2356 SET_AST_NODE_LOC(node, @1, @1);
2357 ast_stack.back()->children.push_back(node);
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;
2367 ast_stack.back()->children.push_back($1);
2369 case_expr_list ',' expr {
2370 ast_stack.back()->children.push_back($3);
2374 hierarchical_id '[' expr ']' '.' rvalue {
2375 $$ = new AstNode(AST_PREFIX, $3, $6);
2379 hierarchical_id range {
2380 $$ = new AstNode(AST_IDENTIFIER, $2);
2383 if ($2 == nullptr && ($$->str == "\\$initstate" ||
2384 $$->str == "\\$anyconst" || $$->str == "\\$anyseq" ||
2385 $$->str == "\\$allconst" || $$->str == "\\$allseq"))
2386 $$->type = AST_FCALL;
2388 hierarchical_id non_opt_multirange {
2389 $$ = new AstNode(AST_IDENTIFIER, $2);
2398 '{' lvalue_concat_list '}' {
2404 $$ = new AstNode(AST_CONCAT);
2405 $$->children.push_back($1);
2407 expr ',' lvalue_concat_list {
2409 $$->children.push_back($1);
2413 '(' arg_list optional_comma ')' |
2422 arg_list ',' single_arg;
2426 ast_stack.back()->children.push_back($1);
2430 module_gen_body gen_stmt_or_module_body_stmt |
2433 gen_stmt_or_module_body_stmt:
2434 gen_stmt | module_body_stmt;
2436 // this production creates the obligatory if-else shift/reduce conflict
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();
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();
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();
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 {
2473 ast_stack.pop_back();
2476 AstNode *node = new AstNode(AST_TECALL);
2479 ast_stack.back()->children.push_back(node);
2480 ast_stack.push_back(node);
2482 ast_stack.pop_back();
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();
2495 gen_stmt_block | ';';
2498 TOK_ELSE gen_stmt_or_null | /* empty */ %prec FAKE_THEN;
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);
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());
2521 AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
2523 log_error("Value conversion failed: `%s'\n", $4->c_str());
2524 $$ = new AstNode(AST_TO_BITS, bits, val);
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);
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);
2535 log_error("Value conversion failed: `%s'\n", $2->c_str());
2536 $$ = new AstNode(AST_TO_BITS, bits, val);
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());
2548 $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
2550 log_error("Value conversion failed: `%s'\n", $1->c_str());
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);
2566 $$ = AstNode::mkconst_str(*$1);
2569 hierarchical_id attr {
2570 AstNode *node = new AstNode(AST_FCALL);
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();
2580 TOK_TO_SIGNED attr '(' expr ')' {
2581 $$ = new AstNode(AST_TO_SIGNED, $4);
2582 append_attr($$, $2);
2584 TOK_TO_UNSIGNED attr '(' expr ')' {
2585 $$ = new AstNode(AST_TO_UNSIGNED, $4);
2586 append_attr($$, $2);
2591 '(' expr ':' expr ':' expr ')' {
2596 '{' concat_list '}' {
2599 '{' expr '{' concat_list '}' '}' {
2600 $$ = new AstNode(AST_REPLICATE, $2, $4);
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);
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);
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);
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);
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);
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);
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);
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);
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, $$);
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);
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);
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);
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);
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);
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);
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);
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);
2690 basic_expr '<' attr basic_expr {
2691 $$ = new AstNode(AST_LT, $1, $4);
2692 SET_AST_NODE_LOC($$, @1, @4);
2693 append_attr($$, $3);
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);
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);
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);
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);
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);
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);
2725 basic_expr '>' attr basic_expr {
2726 $$ = new AstNode(AST_GT, $1, $4);
2727 SET_AST_NODE_LOC($$, @1, @4);
2728 append_attr($$, $3);
2730 basic_expr '+' attr basic_expr {
2731 $$ = new AstNode(AST_ADD, $1, $4);
2732 SET_AST_NODE_LOC($$, @1, @4);
2733 append_attr($$, $3);
2735 basic_expr '-' attr basic_expr {
2736 $$ = new AstNode(AST_SUB, $1, $4);
2737 SET_AST_NODE_LOC($$, @1, @4);
2738 append_attr($$, $3);
2740 basic_expr '*' attr basic_expr {
2741 $$ = new AstNode(AST_MUL, $1, $4);
2742 SET_AST_NODE_LOC($$, @1, @4);
2743 append_attr($$, $3);
2745 basic_expr '/' attr basic_expr {
2746 $$ = new AstNode(AST_DIV, $1, $4);
2747 SET_AST_NODE_LOC($$, @1, @4);
2748 append_attr($$, $3);
2750 basic_expr '%' attr basic_expr {
2751 $$ = new AstNode(AST_MOD, $1, $4);
2752 SET_AST_NODE_LOC($$, @1, @4);
2753 append_attr($$, $3);
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);
2760 '+' attr basic_expr %prec UNARY_OPS {
2761 $$ = new AstNode(AST_POS, $3);
2762 SET_AST_NODE_LOC($$, @1, @3);
2763 append_attr($$, $2);
2765 '-' attr basic_expr %prec UNARY_OPS {
2766 $$ = new AstNode(AST_NEG, $3);
2767 SET_AST_NODE_LOC($$, @1, @3);
2768 append_attr($$, $2);
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);
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);
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);
2788 $$ = new AstNode(AST_CONCAT, $1);
2790 expr ',' concat_list {
2792 $$->children.push_back($1);