Merge pull request #1163 from whitequark/more-case-attrs
authorClifford Wolf <clifford@clifford.at>
Tue, 9 Jul 2019 14:57:16 +0000 (16:57 +0200)
committerDavid Shah <dave@ds0.me>
Tue, 9 Jul 2019 17:48:47 +0000 (18:48 +0100)
More support for case rule attributes

backends/verilog/verilog_backend.cc
frontends/ast/genrtlil.cc
passes/proc/proc_mux.cc

index 827af5d85c4061c3b7d7a5c08dbca87922d5918c..6288502a549bd6efd445e5a5cb310f95bbda950b 100644 (file)
@@ -364,20 +364,22 @@ void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
        }
 }
 
-void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false)
+void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false, bool as_comment = false)
 {
        if (noattr)
                return;
+       if (attr2comment)
+               as_comment = true;
        for (auto it = attributes.begin(); it != attributes.end(); ++it) {
-               f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str());
+               f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str());
                f << stringf(" = ");
                if (modattr && (it->second == Const(0, 1) || it->second == Const(0)))
                        f << stringf(" 0 ");
                else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
                        f << stringf(" 1 ");
                else
-                       dump_const(f, it->second, -1, 0, false, attr2comment);
-               f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
+                       dump_const(f, it->second, -1, 0, false, as_comment);
+               f << stringf(" %s%c", as_comment ? "*/" : "*)", term);
        }
 }
 
@@ -1492,6 +1494,7 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw
                return;
        }
 
+       dump_attributes(f, indent, sw->attributes);
        f << stringf("%s" "casez (", indent.c_str());
        dump_sigspec(f, sw->signal);
        f << stringf(")\n");
@@ -1511,7 +1514,9 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw
                                dump_sigspec(f, (*it)->compare[i]);
                        }
                }
-               f << stringf(":\n");
+               f << stringf(":");
+               dump_attributes(f, indent, (*it)->attributes, ' ', /*modattr=*/false, /*as_comment=*/true);
+               f << stringf("\n");
                dump_case_body(f, indent + "    ", *it);
        }
 
@@ -1662,7 +1667,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
                }
        }
 
-       dump_attributes(f, indent, module->attributes, '\n', true);
+       dump_attributes(f, indent, module->attributes, '\n', /*attr2comment=*/true);
        f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
        bool keep_running = true;
        for (int port_id = 1; keep_running; port_id++) {
index 079fc11e5dce10168734c2c44e277bc9cbbea6f3..571ddd98886e7c3a4fa9526d37dbd8f0926d6e7e 100644 (file)
@@ -504,6 +504,7 @@ struct AST_INTERNAL::ProcessGenerator
 
                                        RTLIL::CaseRule *backup_case = current_case;
                                        current_case = new RTLIL::CaseRule;
+                                       current_case->attributes["\\src"] = stringf("%s:%d", child->filename.c_str(), child->linenum);
                                        last_generated_case = current_case;
                                        addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
                                        for (auto node : child->children) {
index aac0b121c48b4095920ddc06c73d501fea909723..d029282fd499e6efc79bcc409c022e23f0d494a9 100644 (file)
@@ -144,7 +144,13 @@ struct SnippetSwCache
        }
 };
 
-RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SwitchRule *sw, bool ifxmode)
+void apply_attrs(RTLIL::Cell *cell, const RTLIL::SwitchRule *sw, const RTLIL::CaseRule *cs)
+{
+       cell->attributes = sw->attributes;
+       cell->add_strpool_attribute("\\src", cs->get_strpool_attribute("\\src"));
+}
+
+RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
 {
        std::stringstream sstr;
        sstr << "$procmux$" << (autoidx++);
@@ -173,7 +179,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
                {
                        // create compare cell
                        RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? "$eqx" : "$eq");
-                       eq_cell->attributes = sw->attributes;
+                       apply_attrs(eq_cell, sw, cs);
 
                        eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
                        eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0);
@@ -199,7 +205,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
 
                // reduce cmp vector to one logic signal
                RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or");
-               any_cell->attributes = sw->attributes;
+               apply_attrs(any_cell, sw, cs);
 
                any_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
                any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width);
@@ -212,7 +218,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
        return RTLIL::SigSpec(ctrl_wire);
 }
 
-RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SigSpec when_signal, RTLIL::SigSpec else_signal, RTLIL::Cell *&last_mux_cell, RTLIL::SwitchRule *sw, bool ifxmode)
+RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SigSpec when_signal, RTLIL::SigSpec else_signal, RTLIL::Cell *&last_mux_cell, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
 {
        log_assert(when_signal.size() == else_signal.size());
 
@@ -224,7 +230,7 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
                return when_signal;
 
        // compare results
-       RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, ifxmode);
+       RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
        if (ctrl_sig.size() == 0)
                return when_signal;
        log_assert(ctrl_sig.size() == 1);
@@ -234,7 +240,7 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
 
        // create the multiplexer itself
        RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux");
-       mux_cell->attributes = sw->attributes;
+       apply_attrs(mux_cell, sw, cs);
 
        mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size());
        mux_cell->setPort("\\A", else_signal);
@@ -246,7 +252,7 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
        return RTLIL::SigSpec(result_wire);
 }
 
-void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw, bool ifxmode)
+void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
 {
        log_assert(last_mux_cell != NULL);
        log_assert(when_signal.size() == last_mux_cell->getPort("\\A").size());
@@ -254,7 +260,7 @@ void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::ve
        if (when_signal == last_mux_cell->getPort("\\A"))
                return;
 
-       RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, ifxmode);
+       RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
        log_assert(ctrl_sig.size() == 1);
        last_mux_cell->type = "$pmux";
 
@@ -395,9 +401,9 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
                        RTLIL::CaseRule *cs2 = sw->cases[case_idx];
                        RTLIL::SigSpec value = signal_to_mux_tree(mod, swcache, swpara, cs2, sig, initial_val, ifxmode);
                        if (last_mux_cell && pgroups[case_idx] == pgroups[case_idx+1])
-                               append_pmux(mod, sw->signal, cs2->compare, value, last_mux_cell, sw, ifxmode);
+                               append_pmux(mod, sw->signal, cs2->compare, value, last_mux_cell, sw, cs2, ifxmode);
                        else
-                               result = gen_mux(mod, sw->signal, cs2->compare, value, result, last_mux_cell, sw, ifxmode);
+                               result = gen_mux(mod, sw->signal, cs2->compare, value, result, last_mux_cell, sw, cs2, ifxmode);
                }
        }