diff options
author | whitequark <whitequark@whitequark.org> | 2019-07-08 11:34:58 +0000 |
---|---|---|
committer | whitequark <whitequark@whitequark.org> | 2019-07-08 11:34:58 +0000 |
commit | 93bc5affd3fc635dafec3a37bf4c5b94c252036f (patch) | |
tree | 0901b0abea7fed10e3fc1f8ec5b37e88e26b6664 | |
parent | 030483ffb909ab38e10d437d09ec922cb0ad2ce8 (diff) | |
download | yosys-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.
-rw-r--r-- | backends/ilang/ilang_backend.cc | 5 | ||||
-rw-r--r-- | frontends/ilang/ilang_parser.y | 13 | ||||
-rw-r--r-- | kernel/rtlil.h | 2 |
3 files changed, 15 insertions, 5 deletions
diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index b4ba2b03f..313af7d5c 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -204,6 +204,11 @@ void ILANG_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) { + for (auto ait = (*it)->attributes.begin(); ait != (*it)->attributes.end(); ++ait) { + f << stringf("%s attribute %s ", indent.c_str(), ait->first.c_str()); + dump_const(f, ait->second); + f << stringf("\n"); + } f << stringf("%s case ", indent.c_str()); for (size_t i = 0; i < (*it)->compare.size(); i++) { if (i > 0) 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; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f4fcf5dcf..82cbfaf28 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1327,7 +1327,7 @@ public: #endif }; -struct RTLIL::CaseRule +struct RTLIL::CaseRule : public RTLIL::AttrObject { std::vector<RTLIL::SigSpec> compare; std::vector<RTLIL::SigSig> actions; |