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