aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ilang
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2019-07-08 11:34:58 +0000
committerwhitequark <whitequark@whitequark.org>2019-07-08 11:34:58 +0000
commit93bc5affd3fc635dafec3a37bf4c5b94c252036f (patch)
tree0901b0abea7fed10e3fc1f8ec5b37e88e26b6664 /frontends/ilang
parent030483ffb909ab38e10d437d09ec922cb0ad2ce8 (diff)
downloadyosys-93bc5affd3fc635dafec3a37bf4c5b94c252036f.tar.gz
yosys-93bc5affd3fc635dafec3a37bf4c5b94c252036f.tar.bz2
yosys-93bc5affd3fc635dafec3a37bf4c5b94c252036f.zip
Allow attributes on individual switch cases in RTLIL.
The parser changes are slightly awkward. Consider the following IL: process $0 <point 1> switch \foo <point 2> case 1'1 assign \bar \baz <point 3> ... case end end Before this commit, attributes are valid in <point 1>, and <point 3> iff it is immediately followed by a `switch`. (They are essentially attached to the switch.) But, after this commit, and because switch cases do not have an ending delimiter, <point 3> becomes ambiguous: the attribute could attach to either the following `case`, or to the following `switch`. This isn't expressible in LALR(1) and results in a reduce/reduce conflict. To address this, attributes inside processes are now valid anywhere inside the process: in <point 1> and <point 3> a part of case body, and in <point 2> as a separate rule. As a consequence, attributes can now precede `assign`s, which is made illegal in the same way it is illegal to attach attributes to `connect`. Attributes are tracked separately from the parser state, so this does not affect collection of attributes at all, other than allowing them on `case`s. The grammar change serves purely to allow attributes in more syntactic places.
Diffstat (limited to 'frontends/ilang')
-rw-r--r--frontends/ilang/ilang_parser.y13
1 files changed, 9 insertions, 4 deletions
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
index 44c99906a..b4b9693da 100644
--- a/frontends/ilang/ilang_parser.y
+++ b/frontends/ilang/ilang_parser.y
@@ -282,14 +282,14 @@ proc_stmt:
} case_body sync_list TOK_END EOL;
switch_stmt:
- attr_list TOK_SWITCH sigspec EOL {
+ TOK_SWITCH sigspec EOL {
RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
- rule->signal = *$3;
+ rule->signal = *$2;
rule->attributes = attrbuf;
switch_stack.back()->push_back(rule);
attrbuf.clear();
- delete $3;
- } switch_body TOK_END EOL;
+ delete $2;
+ } attr_list switch_body TOK_END EOL;
attr_list:
/* empty */ |
@@ -298,9 +298,11 @@ attr_list:
switch_body:
switch_body TOK_CASE {
RTLIL::CaseRule *rule = new RTLIL::CaseRule;
+ rule->attributes = attrbuf;
switch_stack.back()->back()->cases.push_back(rule);
switch_stack.push_back(&rule->switches);
case_stack.push_back(rule);
+ attrbuf.clear();
} compare_list EOL case_body {
switch_stack.pop_back();
case_stack.pop_back();
@@ -319,12 +321,15 @@ compare_list:
/* empty */;
case_body:
+ case_body attr_stmt |
case_body switch_stmt |
case_body assign_stmt |
/* empty */;
assign_stmt:
TOK_ASSIGN sigspec sigspec EOL {
+ if (attrbuf.size() != 0)
+ rtlil_frontend_ilang_yyerror("dangling attribute");
case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3));
delete $2;
delete $3;