mirror of https://github.com/YosysHQ/yosys.git
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.
This commit is contained in:
parent
030483ffb9
commit
93bc5affd3
|
@ -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 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());
|
f << stringf("%s case ", indent.c_str());
|
||||||
for (size_t i = 0; i < (*it)->compare.size(); i++) {
|
for (size_t i = 0; i < (*it)->compare.size(); i++) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
|
|
|
@ -282,14 +282,14 @@ proc_stmt:
|
||||||
} case_body sync_list TOK_END EOL;
|
} case_body sync_list TOK_END EOL;
|
||||||
|
|
||||||
switch_stmt:
|
switch_stmt:
|
||||||
attr_list TOK_SWITCH sigspec EOL {
|
TOK_SWITCH sigspec EOL {
|
||||||
RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
|
RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
|
||||||
rule->signal = *$3;
|
rule->signal = *$2;
|
||||||
rule->attributes = attrbuf;
|
rule->attributes = attrbuf;
|
||||||
switch_stack.back()->push_back(rule);
|
switch_stack.back()->push_back(rule);
|
||||||
attrbuf.clear();
|
attrbuf.clear();
|
||||||
delete $3;
|
delete $2;
|
||||||
} switch_body TOK_END EOL;
|
} attr_list switch_body TOK_END EOL;
|
||||||
|
|
||||||
attr_list:
|
attr_list:
|
||||||
/* empty */ |
|
/* empty */ |
|
||||||
|
@ -298,9 +298,11 @@ attr_list:
|
||||||
switch_body:
|
switch_body:
|
||||||
switch_body TOK_CASE {
|
switch_body TOK_CASE {
|
||||||
RTLIL::CaseRule *rule = new RTLIL::CaseRule;
|
RTLIL::CaseRule *rule = new RTLIL::CaseRule;
|
||||||
|
rule->attributes = attrbuf;
|
||||||
switch_stack.back()->back()->cases.push_back(rule);
|
switch_stack.back()->back()->cases.push_back(rule);
|
||||||
switch_stack.push_back(&rule->switches);
|
switch_stack.push_back(&rule->switches);
|
||||||
case_stack.push_back(rule);
|
case_stack.push_back(rule);
|
||||||
|
attrbuf.clear();
|
||||||
} compare_list EOL case_body {
|
} compare_list EOL case_body {
|
||||||
switch_stack.pop_back();
|
switch_stack.pop_back();
|
||||||
case_stack.pop_back();
|
case_stack.pop_back();
|
||||||
|
@ -319,12 +321,15 @@ compare_list:
|
||||||
/* empty */;
|
/* empty */;
|
||||||
|
|
||||||
case_body:
|
case_body:
|
||||||
|
case_body attr_stmt |
|
||||||
case_body switch_stmt |
|
case_body switch_stmt |
|
||||||
case_body assign_stmt |
|
case_body assign_stmt |
|
||||||
/* empty */;
|
/* empty */;
|
||||||
|
|
||||||
assign_stmt:
|
assign_stmt:
|
||||||
TOK_ASSIGN sigspec sigspec EOL {
|
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));
|
case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3));
|
||||||
delete $2;
|
delete $2;
|
||||||
delete $3;
|
delete $3;
|
||||||
|
|
|
@ -1327,7 +1327,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RTLIL::CaseRule
|
struct RTLIL::CaseRule : public RTLIL::AttrObject
|
||||||
{
|
{
|
||||||
std::vector<RTLIL::SigSpec> compare;
|
std::vector<RTLIL::SigSpec> compare;
|
||||||
std::vector<RTLIL::SigSig> actions;
|
std::vector<RTLIL::SigSig> actions;
|
||||||
|
|
Loading…
Reference in New Issue