From d84c3a9eac77cd0e34e1c4a0993f897456b52b33 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 22 Nov 2024 07:02:16 +1300 Subject: [PATCH] Backends: More consistent usage of selections Drop use_selection flag from Json and Jny Writers, instead they always operate on selections and if the write_* pass is called without -selected then it pushes the complete selection. rtlil_backend prints differently if it is dumping a portion or whole design, so push the complete selection inside of the dump if needed. Also update `Design::selected_modules()` error message for partially selected modules to match the existing error messages that it replaces. --- backends/cxxrtl/cxxrtl_backend.cc | 17 ++------ backends/intersynth/intersynth.cc | 16 +++----- backends/jny/jny.cc | 24 +++++++---- backends/json/json.cc | 45 +++++++++----------- backends/rtlil/rtlil_backend.cc | 64 ++++++++++++++--------------- backends/verilog/verilog_backend.cc | 9 ++-- kernel/rtlil.cc | 4 +- 7 files changed, 78 insertions(+), 101 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index b72caf119..51450a9c8 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2774,9 +2774,7 @@ struct CxxrtlWorker { RTLIL::Module *top_module = nullptr; std::vector modules; TopoSort topo_design; - for (auto module : design->modules()) { - if (!design->selected_module(module)) - continue; + for (auto module : design->all_selected_modules()) { if (module->get_bool_attribute(ID(cxxrtl_blackbox))) modules.push_back(module); // cxxrtl blackboxes first if (module->get_blackbox_attribute() || module->get_bool_attribute(ID(cxxrtl_blackbox))) @@ -2910,10 +2908,7 @@ struct CxxrtlWorker { bool has_feedback_arcs = false; bool has_buffered_comb_wires = false; - for (auto module : design->modules()) { - if (!design->selected_module(module)) - continue; - + for (auto module : design->all_selected_modules()) { SigMap &sigmap = sigmaps[module]; sigmap.set(module); @@ -3410,16 +3405,10 @@ struct CxxrtlWorker { { has_sync_init = false; - for (auto module : design->modules()) { + for (auto module : design->selected_modules(RTLIL::SELECT_WHOLE_CMDERR, RTLIL::SB_ALL)) { if (module->get_blackbox_attribute() && !module->has_attribute(ID(cxxrtl_blackbox))) continue; - if (!design->selected_whole_module(module)) - if (design->selected_module(module)) - log_cmd_error("Can't handle partially selected module `%s'!\n", id2cstr(module->name)); - if (!design->selected_module(module)) - continue; - for (auto proc : module->processes) for (auto sync : proc.second->syncs) if (sync->type == RTLIL::STi) diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index dcf107de3..008c4a57b 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -122,26 +122,19 @@ struct IntersynthBackend : public Backend { for (auto lib : libs) ct.setup_design(lib); - for (auto module : design->modules()) + if (!selected) design->push_complete_selection(); + for (auto module : design->selected_modules(RTLIL::SELECT_WHOLE_CMDERR, RTLIL::SB_UNBOXED_ONLY)) { SigMap sigmap(module); - if (module->get_blackbox_attribute()) - continue; if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells().size() == 0) continue; - if (selected && !design->selected_whole_module(module->name)) { - if (design->selected_module(module->name)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name)); - continue; - } + if (module->has_memories() || module->has_processes()) + log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n"); log("Generating netlist %s.\n", log_id(module->name)); - if (module->memories.size() != 0 || module->processes.size() != 0) - log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n"); - std::set constcells_code; netlists_code += stringf("# Netlist of module %s\n", log_id(module->name)); netlists_code += stringf("netlist %s\n", log_id(module->name)); @@ -195,6 +188,7 @@ struct IntersynthBackend : public Backend { netlists_code += code; netlists_code += "\n"; } + if (!selected) design->pop_selection(); if (!flag_notypes) { *f << stringf("### Connection Types\n"); diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc index 3897f7553..4b6452917 100644 --- a/backends/jny/jny.cc +++ b/backends/jny/jny.cc @@ -37,7 +37,6 @@ struct JnyWriter { private: std::ostream &f; - bool _use_selection; // XXX(aki): TODO: this needs to be updated to us // dict and then coalesce_cells needs to be updated @@ -112,9 +111,8 @@ struct JnyWriter } public: - JnyWriter(std::ostream &f, bool use_selection, bool connections, bool attributes, bool properties) noexcept: - f(f), _use_selection(use_selection), - _include_connections(connections), _include_attributes(attributes), _include_properties(properties) + JnyWriter(std::ostream &f, bool connections, bool attributes, bool properties) noexcept: + f(f), _include_connections(connections), _include_attributes(attributes), _include_properties(properties) { } void write_metadata(Design *design, uint16_t indent_level = 0, std::string invk = "") @@ -155,7 +153,7 @@ struct JnyWriter f << " \"modules\": [\n"; bool first{true}; - for (auto mod : _use_selection ? design->selected_modules() : design->modules()) { + for (auto mod : design->all_selected_modules()) { if (!first) f << ",\n"; write_module(mod, indent_level + 2); @@ -425,6 +423,9 @@ struct JnyBackend : public Backend { log(" -no-properties\n"); log(" Don't include property information in the netlist output.\n"); log("\n"); + log(" -selected\n"); + log(" only write selected parts of the design.\n"); + log("\n"); log("The JSON schema for JNY output files is located in the \"jny.schema.json\" file\n"); log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\"\n"); log("\n"); @@ -435,6 +436,7 @@ struct JnyBackend : public Backend { bool connections{true}; bool attributes{true}; bool properties{true}; + bool selected{false}; size_t argidx{1}; for (; argidx < args.size(); argidx++) { @@ -453,6 +455,11 @@ struct JnyBackend : public Backend { continue; } + if (args[argidx] == "-selected") { + selected = true; + continue; + } + break; } @@ -469,8 +476,10 @@ struct JnyBackend : public Backend { log_header(design, "Executing jny backend.\n"); - JnyWriter jny_writer(*f, false, connections, attributes, properties); + if (!selected) design->push_complete_selection(); + JnyWriter jny_writer(*f, connections, attributes, properties); jny_writer.write_metadata(design, 0, invk.str()); + if (!selected) design->pop_selection(); } } JnyBackend; @@ -561,8 +570,7 @@ struct JnyPass : public Pass { f = &buf; } - - JnyWriter jny_writer(*f, false, connections, attributes, properties); + JnyWriter jny_writer(*f, connections, attributes, properties); jny_writer.write_metadata(design, 0, invk.str()); if (!empty) { diff --git a/backends/json/json.cc b/backends/json/json.cc index 287c01ead..5556a1834 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -31,7 +31,6 @@ PRIVATE_NAMESPACE_BEGIN struct JsonWriter { std::ostream &f; - bool use_selection; bool aig_mode; bool compat_int_mode; @@ -43,9 +42,8 @@ struct JsonWriter dict sigids; pool aig_models; - JsonWriter(std::ostream &f, bool use_selection, bool aig_mode, bool compat_int_mode) : - f(f), use_selection(use_selection), aig_mode(aig_mode), - compat_int_mode(compat_int_mode) { } + JsonWriter(std::ostream &f, bool aig_mode, bool compat_int_mode) : + f(f), aig_mode(aig_mode), compat_int_mode(compat_int_mode) { } string get_string(string str) { @@ -170,7 +168,7 @@ struct JsonWriter bool first = true; for (auto n : module->ports) { Wire *w = module->wire(n); - if (use_selection && !module->selected(w)) + if (!module->selected(w)) continue; f << stringf("%s\n", first ? "" : ","); f << stringf(" %s: {\n", get_name(n).c_str()); @@ -189,9 +187,7 @@ struct JsonWriter f << stringf(" \"cells\": {"); first = true; - for (auto c : module->cells()) { - if (use_selection && !module->selected(c)) - continue; + for (auto c : module->selected_cells()) { // Eventually we will want to emit $scopeinfo, but currently this // will break JSON netlist consumers like nextpnr if (c->type == ID($scopeinfo)) @@ -239,21 +235,19 @@ struct JsonWriter } f << stringf("\n },\n"); - if (!module->memories.empty()) { + if (module->has_memories()) { f << stringf(" \"memories\": {"); first = true; - for (auto &it : module->memories) { - if (use_selection && !module->selected(it.second)) - continue; + for (auto m : module->selected_memories()) { f << stringf("%s\n", first ? "" : ","); - f << stringf(" %s: {\n", get_name(it.second->name).c_str()); - f << stringf(" \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0"); + f << stringf(" %s: {\n", get_name(m->name).c_str()); + f << stringf(" \"hide_name\": %s,\n", m->name[0] == '$' ? "1" : "0"); f << stringf(" \"attributes\": {"); - write_parameters(it.second->attributes); + write_parameters(m->attributes); f << stringf("\n },\n"); - f << stringf(" \"width\": %d,\n", it.second->width); - f << stringf(" \"start_offset\": %d,\n", it.second->start_offset); - f << stringf(" \"size\": %d\n", it.second->size); + f << stringf(" \"width\": %d,\n", m->width); + f << stringf(" \"start_offset\": %d,\n", m->start_offset); + f << stringf(" \"size\": %d\n", m->size); f << stringf(" }"); first = false; } @@ -262,9 +256,7 @@ struct JsonWriter f << stringf(" \"netnames\": {"); first = true; - for (auto w : module->wires()) { - if (use_selection && !module->selected(w)) - continue; + for (auto w : module->selected_wires()) { f << stringf("%s\n", first ? "" : ","); f << stringf(" %s: {\n", get_name(w->name).c_str()); f << stringf(" \"hide_name\": %s,\n", w->name[0] == '$' ? "1" : "0"); @@ -294,9 +286,8 @@ struct JsonWriter f << stringf("{\n"); f << stringf(" \"creator\": %s,\n", get_string(yosys_version_str).c_str()); f << stringf(" \"modules\": {\n"); - vector modules = use_selection ? design->selected_modules() : design->modules(); bool first_module = true; - for (auto mod : modules) { + for (auto mod : design->all_selected_modules()) { if (!first_module) f << stringf(",\n"); write_module(mod); @@ -354,7 +345,7 @@ struct JsonBackend : public Backend { log(" as JSON numbers (for compatibility with old parsers)\n"); log("\n"); log(" -selected\n"); - log(" output only select module\n"); + log(" only write selected parts of the design.\n"); log("\n"); log("\n"); log("The general syntax of the JSON output created by this command is as follows:\n"); @@ -623,8 +614,10 @@ struct JsonBackend : public Backend { log_header(design, "Executing JSON backend.\n"); - JsonWriter json_writer(*f, use_selection, aig_mode, compat_int_mode); + if (!use_selection) design->push_complete_selection(); + JsonWriter json_writer(*f, aig_mode, compat_int_mode); json_writer.write_design(design); + if (!use_selection) design->pop_selection(); } } JsonBackend; @@ -693,7 +686,7 @@ struct JsonPass : public Pass { f = &buf; } - JsonWriter json_writer(*f, true, aig_mode, compat_int_mode); + JsonWriter json_writer(*f, aig_mode, compat_int_mode); json_writer.write_design(design); if (!empty) { diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index ae60ee6c7..7bd1ec10b 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -335,37 +335,33 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu if (print_body) { - for (auto it : module->wires()) - if (!only_selected || design->selected(module, it)) { - if (only_selected) - f << stringf("\n"); - dump_wire(f, indent + " ", it); - } + for (auto wire : module->selected_wires()) { + if (only_selected) + f << stringf("\n"); + dump_wire(f, indent + " ", wire); + } - for (auto it : module->memories) - if (!only_selected || design->selected(module, it.second)) { - if (only_selected) - f << stringf("\n"); - dump_memory(f, indent + " ", it.second); - } + for (auto memory : module->selected_memories()) { + if (only_selected) + f << stringf("\n"); + dump_memory(f, indent + " ", memory); + } - for (auto it : module->cells()) - if (!only_selected || design->selected(module, it)) { - if (only_selected) - f << stringf("\n"); - dump_cell(f, indent + " ", it); - } + for (auto cell : module->selected_cells()) { + if (only_selected) + f << stringf("\n"); + dump_cell(f, indent + " ", cell); + } - for (auto it : module->processes) - if (!only_selected || design->selected(module, it.second)) { - if (only_selected) - f << stringf("\n"); - dump_proc(f, indent + " ", it.second); - } + for (auto process : module->selected_processes()) { + if (only_selected) + f << stringf("\n"); + dump_proc(f, indent + " ", process); + } bool first_conn_line = true; for (auto it = module->connections().begin(); it != module->connections().end(); ++it) { - bool show_conn = !only_selected || design->selected_whole_module(module->name); + bool show_conn = !only_selected || module->is_selected_whole(); if (!show_conn) { RTLIL::SigSpec sigs = it->first; sigs.append(it->second); @@ -392,12 +388,13 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl { int init_autoidx = autoidx; + if (!only_selected) design->push_complete_selection(); if (!flag_m) { int count_selected_mods = 0; - for (auto module : design->modules()) { - if (design->selected_whole_module(module->name)) + for (auto module : design->all_selected_modules()) { + if (module->is_selected_whole()) flag_m = true; - if (design->selected(module)) + else count_selected_mods++; } if (count_selected_mods > 1) @@ -410,13 +407,12 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl f << stringf("autoidx %d\n", autoidx); } - for (auto module : design->modules()) { - if (!only_selected || design->selected(module)) { - if (only_selected) - f << stringf("\n"); - dump_module(f, "", module, design, only_selected, flag_m, flag_n); - } + for (auto module : design->all_selected_modules()) { + if (only_selected) + f << stringf("\n"); + dump_module(f, "", module, design, only_selected, flag_m, flag_n); } + if (!only_selected) design->pop_selection(); log_assert(init_autoidx == autoidx); } diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a8dd356bc..6481dcd11 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -2590,17 +2590,14 @@ struct VerilogBackend : public Backend { design->sort(); *f << stringf("/* Generated by %s */\n", yosys_version_str); - for (auto module : design->modules()) { + if (!selected) design->push_complete_selection(); + for (auto module : design->selected_modules(RTLIL::SELECT_WHOLE_CMDERR, RTLIL::SB_ALL)) { if (module->get_blackbox_attribute() != blackboxes) continue; - if (selected && !design->selected_whole_module(module->name)) { - if (design->selected_module(module->name)) - log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name)); - continue; - } log("Dumping module `%s'.\n", module->name.c_str()); dump_module(*f, "", module); } + if (!selected) design->pop_selection(); auto_name_map.clear(); reg_wires.clear(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index af1d55bfd..db11b4d1a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1218,10 +1218,10 @@ std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartial log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); break; case RTLIL::SELECT_WHOLE_ERR: - log_error("Unsupported partially selected module %s.\n", log_id(it.first)); + log_error("Can't handle partially selected module %s.\n", log_id(it.first)); break; case RTLIL::SELECT_WHOLE_CMDERR: - log_cmd_error("Unsupported partially selected module %s.\n", log_id(it.first)); + log_cmd_error("Can't handle partially selected module %s.\n", log_id(it.first)); break; default: break;