9fa2a1a2f7a57c2ee38afcac9d2fdb4236d4ce9d
[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 <string.h>
39 #include "frontends/verilog/verilog_frontend.h"
40 #include "kernel/log.h"
41
42 USING_YOSYS_NAMESPACE
43 using namespace AST;
44 using namespace VERILOG_FRONTEND;
45
46 YOSYS_NAMESPACE_BEGIN
47 namespace VERILOG_FRONTEND {
48 int port_counter;
49 std::map<std::string, int> port_stubs;
50 std::map<std::string, AstNode*> attr_list, default_attr_list;
51 std::map<std::string, AstNode*> *albuf;
52 std::vector<AstNode*> ast_stack;
53 struct AstNode *astbuf1, *astbuf2, *astbuf3;
54 struct AstNode *current_function_or_task;
55 struct AstNode *current_ast, *current_ast_mod;
56 int current_function_or_task_port_id;
57 std::vector<char> case_type_stack;
58 bool do_not_require_port_stubs;
59 bool default_nettype_wire;
60 bool sv_mode, formal_mode, lib_mode;
61 bool norestrict_mode, assume_asserts_mode;
62 bool current_wire_rand, current_wire_const;
63 std::istream *lexin;
64 }
65 YOSYS_NAMESPACE_END
66
67 static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
68 {
69 for (auto &it : *al) {
70 if (ast->attributes.count(it.first) > 0)
71 delete ast->attributes[it.first];
72 ast->attributes[it.first] = it.second;
73 }
74 delete al;
75 }
76
77 static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
78 {
79 for (auto &it : *al) {
80 if (ast->attributes.count(it.first) > 0)
81 delete ast->attributes[it.first];
82 ast->attributes[it.first] = it.second->clone();
83 }
84 }
85
86 static void free_attr(std::map<std::string, AstNode*> *al)
87 {
88 for (auto &it : *al)
89 delete it.second;
90 delete al;
91 }
92
93 %}
94
95 %name-prefix "frontend_verilog_yy"
96
97 %union {
98 std::string *string;
99 struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast;
100 std::map<std::string, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
101 bool boolean;
102 }
103
104 %token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
105 %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
106 %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
107 %token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
108 %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG
109 %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL
110 %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT
111 %token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR
112 %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT
113 %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK
114 %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
115 %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
116 %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
117 %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_ASSUME
118 %token TOK_RESTRICT TOK_COVER TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
119 %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
120 %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
121
122 %type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
123 %type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
124 %type <string> opt_label tok_prim_wrapper hierarchical_id
125 %type <boolean> opt_signed unique_case_attr
126 %type <al> attr case_attr
127
128 // operator precedence from low to high
129 %left OP_LOR
130 %left OP_LAND
131 %left '|' OP_NOR
132 %left '^' OP_XNOR
133 %left '&' OP_NAND
134 %left OP_EQ OP_NE OP_EQX OP_NEX
135 %left '<' OP_LE OP_GE '>'
136 %left OP_SHL OP_SHR OP_SSHL OP_SSHR
137 %left '+' '-'
138 %left '*' '/' '%'
139 %left OP_POW
140 %right UNARY_OPS
141
142 %define parse.error verbose
143 %define parse.lac full
144
145 %expect 2
146 %debug
147
148 %%
149
150 input: {
151 ast_stack.clear();
152 ast_stack.push_back(current_ast);
153 } design {
154 ast_stack.pop_back();
155 log_assert(GetSize(ast_stack) == 0);
156 for (auto &it : default_attr_list)
157 delete it.second;
158 default_attr_list.clear();
159 };
160
161 design:
162 module design |
163 defattr design |
164 task_func_decl design |
165 param_decl design |
166 localparam_decl design |
167 package design |
168 /* empty */;
169
170 attr:
171 {
172 for (auto &it : attr_list)
173 delete it.second;
174 attr_list.clear();
175 for (auto &it : default_attr_list)
176 attr_list[it.first] = it.second->clone();
177 } attr_opt {
178 std::map<std::string, AstNode*> *al = new std::map<std::string, AstNode*>;
179 al->swap(attr_list);
180 $$ = al;
181 };
182
183 attr_opt:
184 attr_opt ATTR_BEGIN opt_attr_list ATTR_END |
185 /* empty */;
186
187 defattr:
188 DEFATTR_BEGIN {
189 for (auto &it : default_attr_list)
190 delete it.second;
191 default_attr_list.clear();
192 for (auto &it : attr_list)
193 delete it.second;
194 attr_list.clear();
195 } opt_attr_list {
196 default_attr_list = attr_list;
197 attr_list.clear();
198 } DEFATTR_END;
199
200 opt_attr_list:
201 attr_list | /* empty */;
202
203 attr_list:
204 attr_assign |
205 attr_list ',' attr_assign;
206
207 attr_assign:
208 hierarchical_id {
209 if (attr_list.count(*$1) != 0)
210 delete attr_list[*$1];
211 attr_list[*$1] = AstNode::mkconst_int(1, false);
212 delete $1;
213 } |
214 hierarchical_id '=' expr {
215 if (attr_list.count(*$1) != 0)
216 delete attr_list[*$1];
217 attr_list[*$1] = $3;
218 delete $1;
219 };
220
221 hierarchical_id:
222 TOK_ID {
223 $$ = $1;
224 } |
225 hierarchical_id TOK_PACKAGESEP TOK_ID {
226 if ($3->substr(0, 1) == "\\")
227 *$1 += "::" + $3->substr(1);
228 else
229 *$1 += "::" + *$3;
230 delete $3;
231 $$ = $1;
232 } |
233 hierarchical_id '.' TOK_ID {
234 if ($3->substr(0, 1) == "\\")
235 *$1 += "." + $3->substr(1);
236 else
237 *$1 += "." + *$3;
238 delete $3;
239 $$ = $1;
240 };
241
242 module:
243 attr TOK_MODULE TOK_ID {
244 do_not_require_port_stubs = false;
245 AstNode *mod = new AstNode(AST_MODULE);
246 ast_stack.back()->children.push_back(mod);
247 ast_stack.push_back(mod);
248 current_ast_mod = mod;
249 port_stubs.clear();
250 port_counter = 0;
251 mod->str = *$3;
252 append_attr(mod, $1);
253 delete $3;
254 } module_para_opt module_args_opt ';' module_body TOK_ENDMODULE {
255 if (port_stubs.size() != 0)
256 frontend_verilog_yyerror("Missing details for module port `%s'.",
257 port_stubs.begin()->first.c_str());
258 ast_stack.pop_back();
259 log_assert(ast_stack.size() == 1);
260 current_ast_mod = NULL;
261 };
262
263 module_para_opt:
264 '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | /* empty */;
265
266 module_para_list:
267 single_module_para | module_para_list ',' single_module_para;
268
269 single_module_para:
270 /* empty */ |
271 TOK_PARAMETER {
272 if (astbuf1) delete astbuf1;
273 astbuf1 = new AstNode(AST_PARAMETER);
274 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
275 } param_signed param_integer param_range single_param_decl |
276 TOK_LOCALPARAM {
277 if (astbuf1) delete astbuf1;
278 astbuf1 = new AstNode(AST_LOCALPARAM);
279 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
280 } param_signed param_integer param_range single_param_decl |
281 single_param_decl;
282
283 module_args_opt:
284 '(' ')' | /* empty */ | '(' module_args optional_comma ')';
285
286 module_args:
287 module_arg | module_args ',' module_arg;
288
289 optional_comma:
290 ',' | /* empty */;
291
292 module_arg_opt_assignment:
293 '=' expr {
294 if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
295 AstNode *wire = new AstNode(AST_IDENTIFIER);
296 wire->str = ast_stack.back()->children.back()->str;
297 if (ast_stack.back()->children.back()->is_reg)
298 ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2))));
299 else
300 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2));
301 } else
302 frontend_verilog_yyerror("Syntax error.");
303 } |
304 /* empty */;
305
306 module_arg:
307 TOK_ID {
308 if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
309 AstNode *node = ast_stack.back()->children.back()->clone();
310 node->str = *$1;
311 node->port_id = ++port_counter;
312 ast_stack.back()->children.push_back(node);
313 } else {
314 if (port_stubs.count(*$1) != 0)
315 frontend_verilog_yyerror("Duplicate module port `%s'.", $1->c_str());
316 port_stubs[*$1] = ++port_counter;
317 }
318 delete $1;
319 } module_arg_opt_assignment |
320 attr wire_type range TOK_ID {
321 AstNode *node = $2;
322 node->str = *$4;
323 node->port_id = ++port_counter;
324 if ($3 != NULL)
325 node->children.push_back($3);
326 if (!node->is_input && !node->is_output)
327 frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $4->c_str());
328 if (node->is_reg && node->is_input && !node->is_output && !sv_mode)
329 frontend_verilog_yyerror("Input port `%s' is declared as register.", $4->c_str());
330 ast_stack.back()->children.push_back(node);
331 append_attr(node, $1);
332 delete $4;
333 } module_arg_opt_assignment |
334 '.' '.' '.' {
335 do_not_require_port_stubs = true;
336 };
337
338 package:
339 attr TOK_PACKAGE TOK_ID {
340 AstNode *mod = new AstNode(AST_PACKAGE);
341 ast_stack.back()->children.push_back(mod);
342 ast_stack.push_back(mod);
343 current_ast_mod = mod;
344 mod->str = *$3;
345 append_attr(mod, $1);
346 } ';' package_body TOK_ENDPACKAGE {
347 ast_stack.pop_back();
348 current_ast_mod = NULL;
349 };
350
351 package_body:
352 package_body package_body_stmt |;
353
354 package_body_stmt:
355 localparam_decl;
356
357 non_opt_delay:
358 '#' TOK_ID { delete $2; } |
359 '#' TOK_CONSTVAL { delete $2; } |
360 '#' '(' expr ')' { delete $3; } |
361 '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; };
362
363 delay:
364 non_opt_delay | /* empty */;
365
366 wire_type:
367 {
368 astbuf3 = new AstNode(AST_WIRE);
369 current_wire_rand = false;
370 current_wire_const = false;
371 } wire_type_token_list delay {
372 $$ = astbuf3;
373 };
374
375 wire_type_token_list:
376 wire_type_token | wire_type_token_list wire_type_token;
377
378 wire_type_token:
379 TOK_INPUT {
380 astbuf3->is_input = true;
381 } |
382 TOK_OUTPUT {
383 astbuf3->is_output = true;
384 } |
385 TOK_INOUT {
386 astbuf3->is_input = true;
387 astbuf3->is_output = true;
388 } |
389 TOK_WIRE {
390 } |
391 TOK_REG {
392 astbuf3->is_reg = true;
393 } |
394 TOK_INTEGER {
395 astbuf3->is_reg = true;
396 astbuf3->range_left = 31;
397 astbuf3->range_right = 0;
398 astbuf3->is_signed = true;
399 } |
400 TOK_GENVAR {
401 astbuf3->type = AST_GENVAR;
402 astbuf3->is_reg = true;
403 astbuf3->range_left = 31;
404 astbuf3->range_right = 0;
405 } |
406 TOK_SIGNED {
407 astbuf3->is_signed = true;
408 } |
409 TOK_RAND {
410 current_wire_rand = true;
411 } |
412 TOK_CONST {
413 current_wire_const = true;
414 };
415
416 non_opt_range:
417 '[' expr ':' expr ']' {
418 $$ = new AstNode(AST_RANGE);
419 $$->children.push_back($2);
420 $$->children.push_back($4);
421 } |
422 '[' expr TOK_POS_INDEXED expr ']' {
423 $$ = new AstNode(AST_RANGE);
424 $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), $4), AstNode::mkconst_int(1, true)));
425 $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
426 } |
427 '[' expr TOK_NEG_INDEXED expr ']' {
428 $$ = new AstNode(AST_RANGE);
429 $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
430 $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), AstNode::mkconst_int(1, true)), $4));
431 } |
432 '[' expr ']' {
433 $$ = new AstNode(AST_RANGE);
434 $$->children.push_back($2);
435 };
436
437 non_opt_multirange:
438 non_opt_range non_opt_range {
439 $$ = new AstNode(AST_MULTIRANGE, $1, $2);
440 } |
441 non_opt_multirange non_opt_range {
442 $$ = $1;
443 $$->children.push_back($2);
444 };
445
446 range:
447 non_opt_range {
448 $$ = $1;
449 } |
450 /* empty */ {
451 $$ = NULL;
452 };
453
454 range_or_multirange:
455 range { $$ = $1; } |
456 non_opt_multirange { $$ = $1; };
457
458 range_or_signed_int:
459 range {
460 $$ = $1;
461 } |
462 TOK_INTEGER {
463 $$ = new AstNode(AST_RANGE);
464 $$->children.push_back(AstNode::mkconst_int(31, true));
465 $$->children.push_back(AstNode::mkconst_int(0, true));
466 $$->is_signed = true;
467 };
468
469 module_body:
470 module_body module_body_stmt |
471 /* the following line makes the generate..endgenrate keywords optional */
472 module_body gen_stmt |
473 /* empty */;
474
475 module_body_stmt:
476 task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt |
477 always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl;
478
479 checker_decl:
480 TOK_CHECKER TOK_ID ';' {
481 AstNode *node = new AstNode(AST_GENBLOCK);
482 node->str = *$2;
483 ast_stack.back()->children.push_back(node);
484 ast_stack.push_back(node);
485 } module_body TOK_ENDCHECKER {
486 delete $2;
487 ast_stack.pop_back();
488 };
489
490 task_func_decl:
491 attr TOK_DPI_FUNCTION TOK_ID TOK_ID {
492 current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3), AstNode::mkconst_str(*$4));
493 current_function_or_task->str = *$4;
494 append_attr(current_function_or_task, $1);
495 ast_stack.back()->children.push_back(current_function_or_task);
496 delete $3;
497 delete $4;
498 } opt_dpi_function_args ';' {
499 current_function_or_task = NULL;
500 } |
501 attr TOK_DPI_FUNCTION TOK_ID '=' TOK_ID TOK_ID {
502 current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$5), AstNode::mkconst_str(*$3));
503 current_function_or_task->str = *$6;
504 append_attr(current_function_or_task, $1);
505 ast_stack.back()->children.push_back(current_function_or_task);
506 delete $3;
507 delete $5;
508 delete $6;
509 } opt_dpi_function_args ';' {
510 current_function_or_task = NULL;
511 } |
512 attr TOK_DPI_FUNCTION TOK_ID ':' TOK_ID '=' TOK_ID TOK_ID {
513 current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$7), AstNode::mkconst_str(*$3 + ":" + RTLIL::unescape_id(*$5)));
514 current_function_or_task->str = *$8;
515 append_attr(current_function_or_task, $1);
516 ast_stack.back()->children.push_back(current_function_or_task);
517 delete $3;
518 delete $5;
519 delete $7;
520 delete $8;
521 } opt_dpi_function_args ';' {
522 current_function_or_task = NULL;
523 } |
524 attr TOK_TASK TOK_ID {
525 current_function_or_task = new AstNode(AST_TASK);
526 current_function_or_task->str = *$3;
527 append_attr(current_function_or_task, $1);
528 ast_stack.back()->children.push_back(current_function_or_task);
529 ast_stack.push_back(current_function_or_task);
530 current_function_or_task_port_id = 1;
531 delete $3;
532 } task_func_args_opt ';' task_func_body TOK_ENDTASK {
533 current_function_or_task = NULL;
534 ast_stack.pop_back();
535 } |
536 attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID {
537 current_function_or_task = new AstNode(AST_FUNCTION);
538 current_function_or_task->str = *$5;
539 append_attr(current_function_or_task, $1);
540 ast_stack.back()->children.push_back(current_function_or_task);
541 ast_stack.push_back(current_function_or_task);
542 AstNode *outreg = new AstNode(AST_WIRE);
543 outreg->str = *$5;
544 outreg->is_signed = $3;
545 if ($4 != NULL) {
546 outreg->children.push_back($4);
547 outreg->is_signed = $3 || $4->is_signed;
548 $4->is_signed = false;
549 }
550 current_function_or_task->children.push_back(outreg);
551 current_function_or_task_port_id = 1;
552 delete $5;
553 } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION {
554 current_function_or_task = NULL;
555 ast_stack.pop_back();
556 };
557
558 dpi_function_arg:
559 TOK_ID TOK_ID {
560 current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
561 delete $1;
562 delete $2;
563 } |
564 TOK_ID {
565 current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
566 delete $1;
567 };
568
569 opt_dpi_function_args:
570 '(' dpi_function_args ')' |
571 /* empty */;
572
573 dpi_function_args:
574 dpi_function_args ',' dpi_function_arg |
575 dpi_function_args ',' |
576 dpi_function_arg |
577 /* empty */;
578
579 opt_signed:
580 TOK_SIGNED {
581 $$ = true;
582 } |
583 /* empty */ {
584 $$ = false;
585 };
586
587 task_func_args_opt:
588 '(' ')' | /* empty */ | '(' {
589 albuf = nullptr;
590 astbuf1 = nullptr;
591 astbuf2 = nullptr;
592 } task_func_args optional_comma {
593 delete astbuf1;
594 if (astbuf2 != NULL)
595 delete astbuf2;
596 free_attr(albuf);
597 } ')';
598
599 task_func_args:
600 task_func_port | task_func_args ',' task_func_port;
601
602 task_func_port:
603 attr wire_type range {
604 if (albuf) {
605 delete astbuf1;
606 if (astbuf2 != NULL)
607 delete astbuf2;
608 free_attr(albuf);
609 }
610 albuf = $1;
611 astbuf1 = $2;
612 astbuf2 = $3;
613 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
614 if (astbuf2) {
615 frontend_verilog_yyerror("Syntax error.");
616 } else {
617 astbuf2 = new AstNode(AST_RANGE);
618 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
619 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
620 }
621 }
622 if (astbuf2 && astbuf2->children.size() != 2)
623 frontend_verilog_yyerror("Syntax error.");
624 } wire_name | wire_name;
625
626 task_func_body:
627 task_func_body behavioral_stmt |
628 /* empty */;
629
630 param_signed:
631 TOK_SIGNED {
632 astbuf1->is_signed = true;
633 } | /* empty */;
634
635 param_integer:
636 TOK_INTEGER {
637 if (astbuf1->children.size() != 1)
638 frontend_verilog_yyerror("Syntax error.");
639 astbuf1->children.push_back(new AstNode(AST_RANGE));
640 astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true));
641 astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true));
642 astbuf1->is_signed = true;
643 } | /* empty */;
644
645 param_real:
646 TOK_REAL {
647 if (astbuf1->children.size() != 1)
648 frontend_verilog_yyerror("Syntax error.");
649 astbuf1->children.push_back(new AstNode(AST_REALVALUE));
650 } | /* empty */;
651
652 param_range:
653 range {
654 if ($1 != NULL) {
655 if (astbuf1->children.size() != 1)
656 frontend_verilog_yyerror("Syntax error.");
657 astbuf1->children.push_back($1);
658 }
659 };
660
661 param_decl:
662 TOK_PARAMETER {
663 astbuf1 = new AstNode(AST_PARAMETER);
664 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
665 } param_signed param_integer param_real param_range param_decl_list ';' {
666 delete astbuf1;
667 };
668
669 localparam_decl:
670 TOK_LOCALPARAM {
671 astbuf1 = new AstNode(AST_LOCALPARAM);
672 astbuf1->children.push_back(AstNode::mkconst_int(0, true));
673 } param_signed param_integer param_real param_range param_decl_list ';' {
674 delete astbuf1;
675 };
676
677 param_decl_list:
678 single_param_decl | param_decl_list ',' single_param_decl;
679
680 single_param_decl:
681 TOK_ID '=' expr {
682 if (astbuf1 == nullptr)
683 frontend_verilog_yyerror("syntax error");
684 AstNode *node = astbuf1->clone();
685 node->str = *$1;
686 delete node->children[0];
687 node->children[0] = $3;
688 ast_stack.back()->children.push_back(node);
689 delete $1;
690 };
691
692 defparam_decl:
693 TOK_DEFPARAM defparam_decl_list ';';
694
695 defparam_decl_list:
696 single_defparam_decl | defparam_decl_list ',' single_defparam_decl;
697
698 single_defparam_decl:
699 range rvalue '=' expr {
700 AstNode *node = new AstNode(AST_DEFPARAM);
701 node->children.push_back($2);
702 node->children.push_back($4);
703 if ($1 != NULL)
704 node->children.push_back($1);
705 ast_stack.back()->children.push_back(node);
706 };
707
708 wire_decl:
709 attr wire_type range {
710 albuf = $1;
711 astbuf1 = $2;
712 astbuf2 = $3;
713 if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
714 if (astbuf2) {
715 frontend_verilog_yyerror("Syntax error.");
716 } else {
717 astbuf2 = new AstNode(AST_RANGE);
718 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
719 astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
720 }
721 }
722 if (astbuf2 && astbuf2->children.size() != 2)
723 frontend_verilog_yyerror("Syntax error.");
724 } wire_name_list {
725 delete astbuf1;
726 if (astbuf2 != NULL)
727 delete astbuf2;
728 free_attr(albuf);
729 } ';' |
730 attr TOK_SUPPLY0 TOK_ID {
731 ast_stack.back()->children.push_back(new AstNode(AST_WIRE));
732 ast_stack.back()->children.back()->str = *$3;
733 append_attr(ast_stack.back()->children.back(), $1);
734 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1)));
735 ast_stack.back()->children.back()->children[0]->str = *$3;
736 delete $3;
737 } opt_supply_wires ';' |
738 attr TOK_SUPPLY1 TOK_ID {
739 ast_stack.back()->children.push_back(new AstNode(AST_WIRE));
740 ast_stack.back()->children.back()->str = *$3;
741 append_attr(ast_stack.back()->children.back(), $1);
742 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(1, false, 1)));
743 ast_stack.back()->children.back()->children[0]->str = *$3;
744 delete $3;
745 } opt_supply_wires ';';
746
747 opt_supply_wires:
748 /* empty */ |
749 opt_supply_wires ',' TOK_ID {
750 AstNode *wire_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-2)->clone();
751 AstNode *assign_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-1)->clone();
752 wire_node->str = *$3;
753 assign_node->children[0]->str = *$3;
754 ast_stack.back()->children.push_back(wire_node);
755 ast_stack.back()->children.push_back(assign_node);
756 delete $3;
757 };
758
759 wire_name_list:
760 wire_name_and_opt_assign | wire_name_list ',' wire_name_and_opt_assign;
761
762 wire_name_and_opt_assign:
763 wire_name {
764 if (current_wire_rand) {
765 AstNode *wire = new AstNode(AST_IDENTIFIER);
766 AstNode *fcall = new AstNode(AST_FCALL);
767 wire->str = ast_stack.back()->children.back()->str;
768 fcall->str = current_wire_const ? "\\$anyconst" : "\\$anyseq";
769 fcall->attributes["\\reg"] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str));
770 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall));
771 }
772 } |
773 wire_name '=' expr {
774 AstNode *wire = new AstNode(AST_IDENTIFIER);
775 wire->str = ast_stack.back()->children.back()->str;
776 if (astbuf1->is_reg)
777 ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $3))));
778 else
779 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $3));
780 };
781
782 wire_name:
783 TOK_ID range_or_multirange {
784 if (astbuf1 == nullptr)
785 frontend_verilog_yyerror("Syntax error.");
786 AstNode *node = astbuf1->clone();
787 node->str = *$1;
788 append_attr_clone(node, albuf);
789 if (astbuf2 != NULL)
790 node->children.push_back(astbuf2->clone());
791 if ($2 != NULL) {
792 if (node->is_input || node->is_output)
793 frontend_verilog_yyerror("Syntax error.");
794 if (!astbuf2) {
795 AstNode *rng = new AstNode(AST_RANGE);
796 rng->children.push_back(AstNode::mkconst_int(0, true));
797 rng->children.push_back(AstNode::mkconst_int(0, true));
798 node->children.push_back(rng);
799 }
800 node->type = AST_MEMORY;
801 node->children.push_back($2);
802 }
803 if (current_function_or_task == NULL) {
804 if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) {
805 port_stubs[*$1] = ++port_counter;
806 }
807 if (port_stubs.count(*$1) != 0) {
808 if (!node->is_input && !node->is_output)
809 frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $1->c_str());
810 if (node->is_reg && node->is_input && !node->is_output && !sv_mode)
811 frontend_verilog_yyerror("Input port `%s' is declared as register.", $1->c_str());
812 node->port_id = port_stubs[*$1];
813 port_stubs.erase(*$1);
814 } else {
815 if (node->is_input || node->is_output)
816 frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
817 }
818 } else {
819 if (node->is_input || node->is_output)
820 node->port_id = current_function_or_task_port_id++;
821 }
822 ast_stack.back()->children.push_back(node);
823 delete $1;
824 };
825
826 assign_stmt:
827 TOK_ASSIGN delay assign_expr_list ';';
828
829 assign_expr_list:
830 assign_expr | assign_expr_list ',' assign_expr;
831
832 assign_expr:
833 lvalue '=' expr {
834 ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
835 };
836
837 cell_stmt:
838 attr TOK_ID {
839 astbuf1 = new AstNode(AST_CELL);
840 append_attr(astbuf1, $1);
841 astbuf1->children.push_back(new AstNode(AST_CELLTYPE));
842 astbuf1->children[0]->str = *$2;
843 delete $2;
844 } cell_parameter_list_opt cell_list ';' {
845 delete astbuf1;
846 } |
847 attr tok_prim_wrapper delay {
848 astbuf1 = new AstNode(AST_PRIMITIVE);
849 astbuf1->str = *$2;
850 append_attr(astbuf1, $1);
851 delete $2;
852 } prim_list ';' {
853 delete astbuf1;
854 };
855
856 tok_prim_wrapper:
857 TOK_PRIMITIVE {
858 $$ = $1;
859 } |
860 TOK_OR {
861 $$ = new std::string("or");
862 };
863
864 cell_list:
865 single_cell |
866 cell_list ',' single_cell;
867
868 single_cell:
869 TOK_ID {
870 astbuf2 = astbuf1->clone();
871 if (astbuf2->type != AST_PRIMITIVE)
872 astbuf2->str = *$1;
873 delete $1;
874 ast_stack.back()->children.push_back(astbuf2);
875 } '(' cell_port_list ')' |
876 TOK_ID non_opt_range {
877 astbuf2 = astbuf1->clone();
878 if (astbuf2->type != AST_PRIMITIVE)
879 astbuf2->str = *$1;
880 delete $1;
881 ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2));
882 } '(' cell_port_list ')';
883
884 prim_list:
885 single_prim |
886 prim_list ',' single_prim;
887
888 single_prim:
889 single_cell |
890 /* no name */ {
891 astbuf2 = astbuf1->clone();
892 ast_stack.back()->children.push_back(astbuf2);
893 } '(' cell_port_list ')';
894
895 cell_parameter_list_opt:
896 '#' '(' cell_parameter_list ')' | /* empty */;
897
898 cell_parameter_list:
899 cell_parameter | cell_parameter_list ',' cell_parameter;
900
901 cell_parameter:
902 /* empty */ |
903 expr {
904 AstNode *node = new AstNode(AST_PARASET);
905 astbuf1->children.push_back(node);
906 node->children.push_back($1);
907 } |
908 '.' TOK_ID '(' expr ')' {
909 AstNode *node = new AstNode(AST_PARASET);
910 node->str = *$2;
911 astbuf1->children.push_back(node);
912 node->children.push_back($4);
913 delete $2;
914 };
915
916 cell_port_list:
917 cell_port_list_rules {
918 // remove empty args from end of list
919 while (!astbuf2->children.empty()) {
920 AstNode *node = astbuf2->children.back();
921 if (node->type != AST_ARGUMENT) break;
922 if (!node->children.empty()) break;
923 if (!node->str.empty()) break;
924 astbuf2->children.pop_back();
925 delete node;
926 }
927
928 // check port types
929 bool has_positional_args = false;
930 bool has_named_args = false;
931 for (auto node : astbuf2->children) {
932 if (node->type != AST_ARGUMENT) continue;
933 if (node->str.empty())
934 has_positional_args = true;
935 else
936 has_named_args = true;
937 }
938
939 if (has_positional_args && has_named_args)
940 frontend_verilog_yyerror("Mix of positional and named cell ports.");
941 };
942
943 cell_port_list_rules:
944 cell_port | cell_port_list_rules ',' cell_port;
945
946 cell_port:
947 /* empty */ {
948 AstNode *node = new AstNode(AST_ARGUMENT);
949 astbuf2->children.push_back(node);
950 } |
951 expr {
952 AstNode *node = new AstNode(AST_ARGUMENT);
953 astbuf2->children.push_back(node);
954 node->children.push_back($1);
955 } |
956 '.' TOK_ID '(' expr ')' {
957 AstNode *node = new AstNode(AST_ARGUMENT);
958 node->str = *$2;
959 astbuf2->children.push_back(node);
960 node->children.push_back($4);
961 delete $2;
962 } |
963 '.' TOK_ID '(' ')' {
964 AstNode *node = new AstNode(AST_ARGUMENT);
965 node->str = *$2;
966 astbuf2->children.push_back(node);
967 delete $2;
968 };
969
970 always_stmt:
971 attr TOK_ALWAYS {
972 AstNode *node = new AstNode(AST_ALWAYS);
973 append_attr(node, $1);
974 ast_stack.back()->children.push_back(node);
975 ast_stack.push_back(node);
976 } always_cond {
977 AstNode *block = new AstNode(AST_BLOCK);
978 ast_stack.back()->children.push_back(block);
979 ast_stack.push_back(block);
980 } behavioral_stmt {
981 ast_stack.pop_back();
982 ast_stack.pop_back();
983 } |
984 attr TOK_INITIAL {
985 AstNode *node = new AstNode(AST_INITIAL);
986 append_attr(node, $1);
987 ast_stack.back()->children.push_back(node);
988 ast_stack.push_back(node);
989 AstNode *block = new AstNode(AST_BLOCK);
990 ast_stack.back()->children.push_back(block);
991 ast_stack.push_back(block);
992 } behavioral_stmt {
993 ast_stack.pop_back();
994 ast_stack.pop_back();
995 };
996
997 always_cond:
998 '@' '(' always_events ')' |
999 '@' '(' '*' ')' |
1000 '@' ATTR_BEGIN ')' |
1001 '@' '(' ATTR_END |
1002 '@' '*' |
1003 /* empty */;
1004
1005 always_events:
1006 always_event |
1007 always_events TOK_OR always_event |
1008 always_events ',' always_event;
1009
1010 always_event:
1011 TOK_POSEDGE expr {
1012 AstNode *node = new AstNode(AST_POSEDGE);
1013 ast_stack.back()->children.push_back(node);
1014 node->children.push_back($2);
1015 } |
1016 TOK_NEGEDGE expr {
1017 AstNode *node = new AstNode(AST_NEGEDGE);
1018 ast_stack.back()->children.push_back(node);
1019 node->children.push_back($2);
1020 } |
1021 expr {
1022 AstNode *node = new AstNode(AST_EDGE);
1023 ast_stack.back()->children.push_back(node);
1024 node->children.push_back($1);
1025 };
1026
1027 opt_label:
1028 ':' TOK_ID {
1029 $$ = $2;
1030 } |
1031 /* empty */ {
1032 $$ = NULL;
1033 };
1034
1035 assert:
1036 TOK_ASSERT '(' expr ')' ';' {
1037 ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $3));
1038 } |
1039 TOK_ASSUME '(' expr ')' ';' {
1040 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $3));
1041 } |
1042 TOK_ASSERT '(' TOK_EVENTUALLY expr ')' ';' {
1043 ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $4));
1044 } |
1045 TOK_ASSUME '(' TOK_EVENTUALLY expr ')' ';' {
1046 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $4));
1047 } |
1048 TOK_COVER '(' expr ')' ';' {
1049 ast_stack.back()->children.push_back(new AstNode(AST_COVER, $3));
1050 } |
1051 TOK_COVER '(' ')' ';' {
1052 ast_stack.back()->children.push_back(new AstNode(AST_COVER, AstNode::mkconst_int(1, false)));
1053 } |
1054 TOK_COVER ';' {
1055 ast_stack.back()->children.push_back(new AstNode(AST_COVER, AstNode::mkconst_int(1, false)));
1056 } |
1057 TOK_RESTRICT '(' expr ')' ';' {
1058 if (norestrict_mode)
1059 delete $3;
1060 else
1061 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $3));
1062 } |
1063 TOK_RESTRICT '(' TOK_EVENTUALLY expr ')' ';' {
1064 if (norestrict_mode)
1065 delete $4;
1066 else
1067 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $4));
1068 };
1069
1070 assert_property:
1071 TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' {
1072 ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $4));
1073 } |
1074 TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' {
1075 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4));
1076 } |
1077 TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
1078 ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $5));
1079 } |
1080 TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
1081 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5));
1082 } |
1083 TOK_COVER TOK_PROPERTY '(' expr ')' ';' {
1084 ast_stack.back()->children.push_back(new AstNode(AST_COVER, $4));
1085 } |
1086 TOK_RESTRICT TOK_PROPERTY '(' expr ')' ';' {
1087 if (norestrict_mode)
1088 delete $4;
1089 else
1090 ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $4));
1091 } |
1092 TOK_RESTRICT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
1093 if (norestrict_mode)
1094 delete $5;
1095 else
1096 ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $5));
1097 };
1098
1099 simple_behavioral_stmt:
1100 lvalue '=' delay expr {
1101 AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $4);
1102 ast_stack.back()->children.push_back(node);
1103 } |
1104 lvalue TOK_INCREMENT {
1105 AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_ADD, $1->clone(), AstNode::mkconst_int(1, true)));
1106 ast_stack.back()->children.push_back(node);
1107 } |
1108 lvalue TOK_DECREMENT {
1109 AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_SUB, $1->clone(), AstNode::mkconst_int(1, true)));
1110 ast_stack.back()->children.push_back(node);
1111 } |
1112 lvalue OP_LE delay expr {
1113 AstNode *node = new AstNode(AST_ASSIGN_LE, $1, $4);
1114 ast_stack.back()->children.push_back(node);
1115 };
1116
1117 // this production creates the obligatory if-else shift/reduce conflict
1118 behavioral_stmt:
1119 defattr | assert | wire_decl | param_decl | localparam_decl |
1120 non_opt_delay behavioral_stmt |
1121 simple_behavioral_stmt ';' | ';' |
1122 hierarchical_id attr {
1123 AstNode *node = new AstNode(AST_TCALL);
1124 node->str = *$1;
1125 delete $1;
1126 ast_stack.back()->children.push_back(node);
1127 ast_stack.push_back(node);
1128 append_attr(node, $2);
1129 } opt_arg_list ';'{
1130 ast_stack.pop_back();
1131 } |
1132 attr TOK_BEGIN opt_label {
1133 AstNode *node = new AstNode(AST_BLOCK);
1134 ast_stack.back()->children.push_back(node);
1135 ast_stack.push_back(node);
1136 append_attr(node, $1);
1137 if ($3 != NULL)
1138 node->str = *$3;
1139 } behavioral_stmt_list TOK_END opt_label {
1140 if ($3 != NULL && $7 != NULL && *$3 != *$7)
1141 frontend_verilog_yyerror("Syntax error.");
1142 if ($3 != NULL)
1143 delete $3;
1144 if ($7 != NULL)
1145 delete $7;
1146 ast_stack.pop_back();
1147 } |
1148 attr TOK_FOR '(' {
1149 AstNode *node = new AstNode(AST_FOR);
1150 ast_stack.back()->children.push_back(node);
1151 ast_stack.push_back(node);
1152 append_attr(node, $1);
1153 } simple_behavioral_stmt ';' expr {
1154 ast_stack.back()->children.push_back($7);
1155 } ';' simple_behavioral_stmt ')' {
1156 AstNode *block = new AstNode(AST_BLOCK);
1157 ast_stack.back()->children.push_back(block);
1158 ast_stack.push_back(block);
1159 } behavioral_stmt {
1160 ast_stack.pop_back();
1161 ast_stack.pop_back();
1162 } |
1163 attr TOK_WHILE '(' expr ')' {
1164 AstNode *node = new AstNode(AST_WHILE);
1165 ast_stack.back()->children.push_back(node);
1166 ast_stack.push_back(node);
1167 append_attr(node, $1);
1168 AstNode *block = new AstNode(AST_BLOCK);
1169 ast_stack.back()->children.push_back($4);
1170 ast_stack.back()->children.push_back(block);
1171 ast_stack.push_back(block);
1172 } behavioral_stmt {
1173 ast_stack.pop_back();
1174 ast_stack.pop_back();
1175 } |
1176 attr TOK_REPEAT '(' expr ')' {
1177 AstNode *node = new AstNode(AST_REPEAT);
1178 ast_stack.back()->children.push_back(node);
1179 ast_stack.push_back(node);
1180 append_attr(node, $1);
1181 AstNode *block = new AstNode(AST_BLOCK);
1182 ast_stack.back()->children.push_back($4);
1183 ast_stack.back()->children.push_back(block);
1184 ast_stack.push_back(block);
1185 } behavioral_stmt {
1186 ast_stack.pop_back();
1187 ast_stack.pop_back();
1188 } |
1189 attr TOK_IF '(' expr ')' {
1190 AstNode *node = new AstNode(AST_CASE);
1191 AstNode *block = new AstNode(AST_BLOCK);
1192 AstNode *cond = new AstNode(AST_COND, AstNode::mkconst_int(1, false, 1), block);
1193 ast_stack.back()->children.push_back(node);
1194 node->children.push_back(new AstNode(AST_REDUCE_BOOL, $4));
1195 node->children.push_back(cond);
1196 ast_stack.push_back(node);
1197 ast_stack.push_back(block);
1198 append_attr(node, $1);
1199 } behavioral_stmt optional_else {
1200 ast_stack.pop_back();
1201 ast_stack.pop_back();
1202 } |
1203 case_attr case_type '(' expr ')' {
1204 AstNode *node = new AstNode(AST_CASE, $4);
1205 ast_stack.back()->children.push_back(node);
1206 ast_stack.push_back(node);
1207 append_attr(node, $1);
1208 } opt_synopsys_attr case_body TOK_ENDCASE {
1209 case_type_stack.pop_back();
1210 ast_stack.pop_back();
1211 };
1212
1213 unique_case_attr:
1214 /* empty */ {
1215 $$ = false;
1216 } |
1217 TOK_PRIORITY case_attr {
1218 $$ = $2;
1219 } |
1220 TOK_UNIQUE case_attr {
1221 $$ = true;
1222 };
1223
1224 case_attr:
1225 attr unique_case_attr {
1226 if ($2) (*$1)["\\parallel_case"] = AstNode::mkconst_int(1, false);
1227 $$ = $1;
1228 };
1229
1230 case_type:
1231 TOK_CASE {
1232 case_type_stack.push_back(0);
1233 } |
1234 TOK_CASEX {
1235 case_type_stack.push_back('x');
1236 } |
1237 TOK_CASEZ {
1238 case_type_stack.push_back('z');
1239 };
1240
1241 opt_synopsys_attr:
1242 opt_synopsys_attr TOK_SYNOPSYS_FULL_CASE {
1243 if (ast_stack.back()->attributes.count("\\full_case") == 0)
1244 ast_stack.back()->attributes["\\full_case"] = AstNode::mkconst_int(1, false);
1245 } |
1246 opt_synopsys_attr TOK_SYNOPSYS_PARALLEL_CASE {
1247 if (ast_stack.back()->attributes.count("\\parallel_case") == 0)
1248 ast_stack.back()->attributes["\\parallel_case"] = AstNode::mkconst_int(1, false);
1249 } |
1250 /* empty */;
1251
1252 behavioral_stmt_list:
1253 behavioral_stmt_list behavioral_stmt |
1254 /* empty */;
1255
1256 optional_else:
1257 TOK_ELSE {
1258 AstNode *block = new AstNode(AST_BLOCK);
1259 AstNode *cond = new AstNode(AST_COND, new AstNode(AST_DEFAULT), block);
1260 ast_stack.pop_back();
1261 ast_stack.back()->children.push_back(cond);
1262 ast_stack.push_back(block);
1263 } behavioral_stmt |
1264 /* empty */;
1265
1266 case_body:
1267 case_body case_item |
1268 /* empty */;
1269
1270 case_item:
1271 {
1272 AstNode *node = new AstNode(
1273 case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
1274 case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
1275 ast_stack.back()->children.push_back(node);
1276 ast_stack.push_back(node);
1277 } case_select {
1278 AstNode *block = new AstNode(AST_BLOCK);
1279 ast_stack.back()->children.push_back(block);
1280 ast_stack.push_back(block);
1281 case_type_stack.push_back(0);
1282 } behavioral_stmt {
1283 case_type_stack.pop_back();
1284 ast_stack.pop_back();
1285 ast_stack.pop_back();
1286 };
1287
1288 gen_case_body:
1289 gen_case_body gen_case_item |
1290 /* empty */;
1291
1292 gen_case_item:
1293 {
1294 AstNode *node = new AstNode(
1295 case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
1296 case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
1297 ast_stack.back()->children.push_back(node);
1298 ast_stack.push_back(node);
1299 } case_select {
1300 case_type_stack.push_back(0);
1301 } gen_stmt_or_null {
1302 case_type_stack.pop_back();
1303 ast_stack.pop_back();
1304 };
1305
1306 case_select:
1307 case_expr_list ':' |
1308 TOK_DEFAULT;
1309
1310 case_expr_list:
1311 TOK_DEFAULT {
1312 ast_stack.back()->children.push_back(new AstNode(AST_DEFAULT));
1313 } |
1314 expr {
1315 ast_stack.back()->children.push_back($1);
1316 } |
1317 case_expr_list ',' expr {
1318 ast_stack.back()->children.push_back($3);
1319 };
1320
1321 rvalue:
1322 hierarchical_id '[' expr ']' '.' rvalue {
1323 $$ = new AstNode(AST_PREFIX, $3, $6);
1324 $$->str = *$1;
1325 delete $1;
1326 } |
1327 hierarchical_id range {
1328 $$ = new AstNode(AST_IDENTIFIER, $2);
1329 $$->str = *$1;
1330 delete $1;
1331 if ($2 == nullptr && ($$->str == "\\$initstate" || $$->str == "\\$anyconst" || $$->str == "\\$anyseq"))
1332 $$->type = AST_FCALL;
1333 } |
1334 hierarchical_id non_opt_multirange {
1335 $$ = new AstNode(AST_IDENTIFIER, $2);
1336 $$->str = *$1;
1337 delete $1;
1338 };
1339
1340 lvalue:
1341 rvalue {
1342 $$ = $1;
1343 } |
1344 '{' lvalue_concat_list '}' {
1345 $$ = $2;
1346 };
1347
1348 lvalue_concat_list:
1349 expr {
1350 $$ = new AstNode(AST_CONCAT);
1351 $$->children.push_back($1);
1352 } |
1353 expr ',' lvalue_concat_list {
1354 $$ = $3;
1355 $$->children.push_back($1);
1356 };
1357
1358 opt_arg_list:
1359 '(' arg_list optional_comma ')' |
1360 /* empty */;
1361
1362 arg_list:
1363 arg_list2 |
1364 /* empty */;
1365
1366 arg_list2:
1367 single_arg |
1368 arg_list ',' single_arg;
1369
1370 single_arg:
1371 expr {
1372 ast_stack.back()->children.push_back($1);
1373 };
1374
1375 module_gen_body:
1376 module_gen_body gen_stmt_or_module_body_stmt |
1377 /* empty */;
1378
1379 gen_stmt_or_module_body_stmt:
1380 gen_stmt | module_body_stmt;
1381
1382 // this production creates the obligatory if-else shift/reduce conflict
1383 gen_stmt:
1384 TOK_FOR '(' {
1385 AstNode *node = new AstNode(AST_GENFOR);
1386 ast_stack.back()->children.push_back(node);
1387 ast_stack.push_back(node);
1388 } simple_behavioral_stmt ';' expr {
1389 ast_stack.back()->children.push_back($6);
1390 } ';' simple_behavioral_stmt ')' gen_stmt_block {
1391 ast_stack.pop_back();
1392 } |
1393 TOK_IF '(' expr ')' {
1394 AstNode *node = new AstNode(AST_GENIF);
1395 ast_stack.back()->children.push_back(node);
1396 ast_stack.push_back(node);
1397 ast_stack.back()->children.push_back($3);
1398 } gen_stmt_block opt_gen_else {
1399 ast_stack.pop_back();
1400 } |
1401 case_type '(' expr ')' {
1402 AstNode *node = new AstNode(AST_GENCASE, $3);
1403 ast_stack.back()->children.push_back(node);
1404 ast_stack.push_back(node);
1405 } gen_case_body TOK_ENDCASE {
1406 case_type_stack.pop_back();
1407 ast_stack.pop_back();
1408 } |
1409 TOK_BEGIN opt_label {
1410 AstNode *node = new AstNode(AST_GENBLOCK);
1411 node->str = $2 ? *$2 : std::string();
1412 ast_stack.back()->children.push_back(node);
1413 ast_stack.push_back(node);
1414 } module_gen_body TOK_END opt_label {
1415 if ($2 != NULL)
1416 delete $2;
1417 if ($6 != NULL)
1418 delete $6;
1419 ast_stack.pop_back();
1420 };
1421
1422 gen_stmt_block:
1423 {
1424 AstNode *node = new AstNode(AST_GENBLOCK);
1425 ast_stack.back()->children.push_back(node);
1426 ast_stack.push_back(node);
1427 } gen_stmt_or_module_body_stmt {
1428 ast_stack.pop_back();
1429 };
1430
1431 gen_stmt_or_null:
1432 gen_stmt_block | ';';
1433
1434 opt_gen_else:
1435 TOK_ELSE gen_stmt_or_null | /* empty */;
1436
1437 expr:
1438 basic_expr {
1439 $$ = $1;
1440 } |
1441 basic_expr '?' attr expr ':' expr {
1442 $$ = new AstNode(AST_TERNARY);
1443 $$->children.push_back($1);
1444 $$->children.push_back($4);
1445 $$->children.push_back($6);
1446 append_attr($$, $3);
1447 };
1448
1449 basic_expr:
1450 rvalue {
1451 $$ = $1;
1452 } |
1453 '(' expr ')' TOK_CONSTVAL {
1454 if ($4->substr(0, 1) != "'")
1455 frontend_verilog_yyerror("Syntax error.");
1456 AstNode *bits = $2;
1457 AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
1458 if (val == NULL)
1459 log_error("Value conversion failed: `%s'\n", $4->c_str());
1460 $$ = new AstNode(AST_TO_BITS, bits, val);
1461 delete $4;
1462 } |
1463 hierarchical_id TOK_CONSTVAL {
1464 if ($2->substr(0, 1) != "'")
1465 frontend_verilog_yyerror("Syntax error.");
1466 AstNode *bits = new AstNode(AST_IDENTIFIER);
1467 bits->str = *$1;
1468 AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
1469 if (val == NULL)
1470 log_error("Value conversion failed: `%s'\n", $2->c_str());
1471 $$ = new AstNode(AST_TO_BITS, bits, val);
1472 delete $1;
1473 delete $2;
1474 } |
1475 TOK_CONSTVAL TOK_CONSTVAL {
1476 $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
1477 if ($$ == NULL || (*$2)[0] != '\'')
1478 log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str());
1479 delete $1;
1480 delete $2;
1481 } |
1482 TOK_CONSTVAL {
1483 $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
1484 if ($$ == NULL)
1485 log_error("Value conversion failed: `%s'\n", $1->c_str());
1486 delete $1;
1487 } |
1488 TOK_REALVAL {
1489 $$ = new AstNode(AST_REALVALUE);
1490 char *p = (char*)malloc(GetSize(*$1) + 1), *q;
1491 for (int i = 0, j = 0; j < GetSize(*$1); j++)
1492 if ((*$1)[j] != '_')
1493 p[i++] = (*$1)[j], p[i] = 0;
1494 $$->realvalue = strtod(p, &q);
1495 log_assert(*q == 0);
1496 delete $1;
1497 free(p);
1498 } |
1499 TOK_STRING {
1500 $$ = AstNode::mkconst_str(*$1);
1501 delete $1;
1502 } |
1503 hierarchical_id attr {
1504 AstNode *node = new AstNode(AST_FCALL);
1505 node->str = *$1;
1506 delete $1;
1507 ast_stack.push_back(node);
1508 append_attr(node, $2);
1509 } '(' arg_list optional_comma ')' {
1510 $$ = ast_stack.back();
1511 ast_stack.pop_back();
1512 } |
1513 TOK_TO_SIGNED attr '(' expr ')' {
1514 $$ = new AstNode(AST_TO_SIGNED, $4);
1515 append_attr($$, $2);
1516 } |
1517 TOK_TO_UNSIGNED attr '(' expr ')' {
1518 $$ = new AstNode(AST_TO_UNSIGNED, $4);
1519 append_attr($$, $2);
1520 } |
1521 '(' expr ')' {
1522 $$ = $2;
1523 } |
1524 '(' expr ':' expr ':' expr ')' {
1525 delete $2;
1526 $$ = $4;
1527 delete $6;
1528 } |
1529 '{' concat_list '}' {
1530 $$ = $2;
1531 } |
1532 '{' expr '{' concat_list '}' '}' {
1533 $$ = new AstNode(AST_REPLICATE, $2, $4);
1534 } |
1535 '~' attr basic_expr %prec UNARY_OPS {
1536 $$ = new AstNode(AST_BIT_NOT, $3);
1537 append_attr($$, $2);
1538 } |
1539 basic_expr '&' attr basic_expr {
1540 $$ = new AstNode(AST_BIT_AND, $1, $4);
1541 append_attr($$, $3);
1542 } |
1543 basic_expr OP_NAND attr basic_expr {
1544 $$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_AND, $1, $4));
1545 append_attr($$, $3);
1546 } |
1547 basic_expr '|' attr basic_expr {
1548 $$ = new AstNode(AST_BIT_OR, $1, $4);
1549 append_attr($$, $3);
1550 } |
1551 basic_expr OP_NOR attr basic_expr {
1552 $$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_OR, $1, $4));
1553 append_attr($$, $3);
1554 } |
1555 basic_expr '^' attr basic_expr {
1556 $$ = new AstNode(AST_BIT_XOR, $1, $4);
1557 append_attr($$, $3);
1558 } |
1559 basic_expr OP_XNOR attr basic_expr {
1560 $$ = new AstNode(AST_BIT_XNOR, $1, $4);
1561 append_attr($$, $3);
1562 } |
1563 '&' attr basic_expr %prec UNARY_OPS {
1564 $$ = new AstNode(AST_REDUCE_AND, $3);
1565 append_attr($$, $2);
1566 } |
1567 OP_NAND attr basic_expr %prec UNARY_OPS {
1568 $$ = new AstNode(AST_REDUCE_AND, $3);
1569 append_attr($$, $2);
1570 $$ = new AstNode(AST_LOGIC_NOT, $$);
1571 } |
1572 '|' attr basic_expr %prec UNARY_OPS {
1573 $$ = new AstNode(AST_REDUCE_OR, $3);
1574 append_attr($$, $2);
1575 } |
1576 OP_NOR attr basic_expr %prec UNARY_OPS {
1577 $$ = new AstNode(AST_REDUCE_OR, $3);
1578 append_attr($$, $2);
1579 $$ = new AstNode(AST_LOGIC_NOT, $$);
1580 } |
1581 '^' attr basic_expr %prec UNARY_OPS {
1582 $$ = new AstNode(AST_REDUCE_XOR, $3);
1583 append_attr($$, $2);
1584 } |
1585 OP_XNOR attr basic_expr %prec UNARY_OPS {
1586 $$ = new AstNode(AST_REDUCE_XNOR, $3);
1587 append_attr($$, $2);
1588 } |
1589 basic_expr OP_SHL attr basic_expr {
1590 $$ = new AstNode(AST_SHIFT_LEFT, $1, $4);
1591 append_attr($$, $3);
1592 } |
1593 basic_expr OP_SHR attr basic_expr {
1594 $$ = new AstNode(AST_SHIFT_RIGHT, $1, $4);
1595 append_attr($$, $3);
1596 } |
1597 basic_expr OP_SSHL attr basic_expr {
1598 $$ = new AstNode(AST_SHIFT_SLEFT, $1, $4);
1599 append_attr($$, $3);
1600 } |
1601 basic_expr OP_SSHR attr basic_expr {
1602 $$ = new AstNode(AST_SHIFT_SRIGHT, $1, $4);
1603 append_attr($$, $3);
1604 } |
1605 basic_expr '<' attr basic_expr {
1606 $$ = new AstNode(AST_LT, $1, $4);
1607 append_attr($$, $3);
1608 } |
1609 basic_expr OP_LE attr basic_expr {
1610 $$ = new AstNode(AST_LE, $1, $4);
1611 append_attr($$, $3);
1612 } |
1613 basic_expr OP_EQ attr basic_expr {
1614 $$ = new AstNode(AST_EQ, $1, $4);
1615 append_attr($$, $3);
1616 } |
1617 basic_expr OP_NE attr basic_expr {
1618 $$ = new AstNode(AST_NE, $1, $4);
1619 append_attr($$, $3);
1620 } |
1621 basic_expr OP_EQX attr basic_expr {
1622 $$ = new AstNode(AST_EQX, $1, $4);
1623 append_attr($$, $3);
1624 } |
1625 basic_expr OP_NEX attr basic_expr {
1626 $$ = new AstNode(AST_NEX, $1, $4);
1627 append_attr($$, $3);
1628 } |
1629 basic_expr OP_GE attr basic_expr {
1630 $$ = new AstNode(AST_GE, $1, $4);
1631 append_attr($$, $3);
1632 } |
1633 basic_expr '>' attr basic_expr {
1634 $$ = new AstNode(AST_GT, $1, $4);
1635 append_attr($$, $3);
1636 } |
1637 basic_expr '+' attr basic_expr {
1638 $$ = new AstNode(AST_ADD, $1, $4);
1639 append_attr($$, $3);
1640 } |
1641 basic_expr '-' attr basic_expr {
1642 $$ = new AstNode(AST_SUB, $1, $4);
1643 append_attr($$, $3);
1644 } |
1645 basic_expr '*' attr basic_expr {
1646 $$ = new AstNode(AST_MUL, $1, $4);
1647 append_attr($$, $3);
1648 } |
1649 basic_expr '/' attr basic_expr {
1650 $$ = new AstNode(AST_DIV, $1, $4);
1651 append_attr($$, $3);
1652 } |
1653 basic_expr '%' attr basic_expr {
1654 $$ = new AstNode(AST_MOD, $1, $4);
1655 append_attr($$, $3);
1656 } |
1657 basic_expr OP_POW attr basic_expr {
1658 $$ = new AstNode(AST_POW, $1, $4);
1659 append_attr($$, $3);
1660 } |
1661 '+' attr basic_expr %prec UNARY_OPS {
1662 $$ = new AstNode(AST_POS, $3);
1663 append_attr($$, $2);
1664 } |
1665 '-' attr basic_expr %prec UNARY_OPS {
1666 $$ = new AstNode(AST_NEG, $3);
1667 append_attr($$, $2);
1668 } |
1669 basic_expr OP_LAND attr basic_expr {
1670 $$ = new AstNode(AST_LOGIC_AND, $1, $4);
1671 append_attr($$, $3);
1672 } |
1673 basic_expr OP_LOR attr basic_expr {
1674 $$ = new AstNode(AST_LOGIC_OR, $1, $4);
1675 append_attr($$, $3);
1676 } |
1677 '!' attr basic_expr %prec UNARY_OPS {
1678 $$ = new AstNode(AST_LOGIC_NOT, $3);
1679 append_attr($$, $2);
1680 };
1681
1682 concat_list:
1683 expr {
1684 $$ = new AstNode(AST_CONCAT, $1);
1685 } |
1686 expr ',' concat_list {
1687 $$ = $3;
1688 $$->children.push_back($1);
1689 };
1690