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.
This commit is contained in:
Krystine Sherwin 2024-11-22 07:02:16 +13:00
parent 24e54d942a
commit d84c3a9eac
No known key found for this signature in database
7 changed files with 78 additions and 101 deletions

View File

@ -2774,9 +2774,7 @@ struct CxxrtlWorker {
RTLIL::Module *top_module = nullptr; RTLIL::Module *top_module = nullptr;
std::vector<RTLIL::Module*> modules; std::vector<RTLIL::Module*> modules;
TopoSort<RTLIL::Module*> topo_design; TopoSort<RTLIL::Module*> topo_design;
for (auto module : design->modules()) { for (auto module : design->all_selected_modules()) {
if (!design->selected_module(module))
continue;
if (module->get_bool_attribute(ID(cxxrtl_blackbox))) if (module->get_bool_attribute(ID(cxxrtl_blackbox)))
modules.push_back(module); // cxxrtl blackboxes first modules.push_back(module); // cxxrtl blackboxes first
if (module->get_blackbox_attribute() || module->get_bool_attribute(ID(cxxrtl_blackbox))) 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_feedback_arcs = false;
bool has_buffered_comb_wires = false; bool has_buffered_comb_wires = false;
for (auto module : design->modules()) { for (auto module : design->all_selected_modules()) {
if (!design->selected_module(module))
continue;
SigMap &sigmap = sigmaps[module]; SigMap &sigmap = sigmaps[module];
sigmap.set(module); sigmap.set(module);
@ -3410,16 +3405,10 @@ struct CxxrtlWorker {
{ {
has_sync_init = false; 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))) if (module->get_blackbox_attribute() && !module->has_attribute(ID(cxxrtl_blackbox)))
continue; 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 proc : module->processes)
for (auto sync : proc.second->syncs) for (auto sync : proc.second->syncs)
if (sync->type == RTLIL::STi) if (sync->type == RTLIL::STi)

View File

@ -122,26 +122,19 @@ struct IntersynthBackend : public Backend {
for (auto lib : libs) for (auto lib : libs)
ct.setup_design(lib); 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); SigMap sigmap(module);
if (module->get_blackbox_attribute())
continue;
if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells().size() == 0) if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells().size() == 0)
continue; continue;
if (selected && !design->selected_whole_module(module->name)) { if (module->has_memories() || module->has_processes())
if (design->selected_module(module->name)) log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n");
log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name));
continue;
}
log("Generating netlist %s.\n", log_id(module->name)); 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<std::string> constcells_code; std::set<std::string> constcells_code;
netlists_code += stringf("# Netlist of module %s\n", log_id(module->name)); netlists_code += stringf("# Netlist of module %s\n", log_id(module->name));
netlists_code += stringf("netlist %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 += code;
netlists_code += "\n"; netlists_code += "\n";
} }
if (!selected) design->pop_selection();
if (!flag_notypes) { if (!flag_notypes) {
*f << stringf("### Connection Types\n"); *f << stringf("### Connection Types\n");

View File

@ -37,7 +37,6 @@ struct JnyWriter
{ {
private: private:
std::ostream &f; std::ostream &f;
bool _use_selection;
// XXX(aki): TODO: this needs to be updated to us // XXX(aki): TODO: this needs to be updated to us
// dict<T, V> and then coalesce_cells needs to be updated // dict<T, V> and then coalesce_cells needs to be updated
@ -112,9 +111,8 @@ struct JnyWriter
} }
public: public:
JnyWriter(std::ostream &f, bool use_selection, bool connections, bool attributes, bool properties) noexcept: JnyWriter(std::ostream &f, bool connections, bool attributes, bool properties) noexcept:
f(f), _use_selection(use_selection), f(f), _include_connections(connections), _include_attributes(attributes), _include_properties(properties)
_include_connections(connections), _include_attributes(attributes), _include_properties(properties)
{ } { }
void write_metadata(Design *design, uint16_t indent_level = 0, std::string invk = "") void write_metadata(Design *design, uint16_t indent_level = 0, std::string invk = "")
@ -155,7 +153,7 @@ struct JnyWriter
f << " \"modules\": [\n"; f << " \"modules\": [\n";
bool first{true}; bool first{true};
for (auto mod : _use_selection ? design->selected_modules() : design->modules()) { for (auto mod : design->all_selected_modules()) {
if (!first) if (!first)
f << ",\n"; f << ",\n";
write_module(mod, indent_level + 2); write_module(mod, indent_level + 2);
@ -425,6 +423,9 @@ struct JnyBackend : public Backend {
log(" -no-properties\n"); log(" -no-properties\n");
log(" Don't include property information in the netlist output.\n"); log(" Don't include property information in the netlist output.\n");
log("\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("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("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\"\n");
log("\n"); log("\n");
@ -435,6 +436,7 @@ struct JnyBackend : public Backend {
bool connections{true}; bool connections{true};
bool attributes{true}; bool attributes{true};
bool properties{true}; bool properties{true};
bool selected{false};
size_t argidx{1}; size_t argidx{1};
for (; argidx < args.size(); argidx++) { for (; argidx < args.size(); argidx++) {
@ -453,6 +455,11 @@ struct JnyBackend : public Backend {
continue; continue;
} }
if (args[argidx] == "-selected") {
selected = true;
continue;
}
break; break;
} }
@ -469,8 +476,10 @@ struct JnyBackend : public Backend {
log_header(design, "Executing jny backend.\n"); 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()); jny_writer.write_metadata(design, 0, invk.str());
if (!selected) design->pop_selection();
} }
} JnyBackend; } JnyBackend;
@ -561,8 +570,7 @@ struct JnyPass : public Pass {
f = &buf; f = &buf;
} }
JnyWriter jny_writer(*f, connections, attributes, properties);
JnyWriter jny_writer(*f, false, connections, attributes, properties);
jny_writer.write_metadata(design, 0, invk.str()); jny_writer.write_metadata(design, 0, invk.str());
if (!empty) { if (!empty) {

View File

@ -31,7 +31,6 @@ PRIVATE_NAMESPACE_BEGIN
struct JsonWriter struct JsonWriter
{ {
std::ostream &f; std::ostream &f;
bool use_selection;
bool aig_mode; bool aig_mode;
bool compat_int_mode; bool compat_int_mode;
@ -43,9 +42,8 @@ struct JsonWriter
dict<SigBit, string> sigids; dict<SigBit, string> sigids;
pool<Aig> aig_models; pool<Aig> aig_models;
JsonWriter(std::ostream &f, bool use_selection, bool aig_mode, bool compat_int_mode) : JsonWriter(std::ostream &f, bool aig_mode, bool compat_int_mode) :
f(f), use_selection(use_selection), aig_mode(aig_mode), f(f), aig_mode(aig_mode), compat_int_mode(compat_int_mode) { }
compat_int_mode(compat_int_mode) { }
string get_string(string str) string get_string(string str)
{ {
@ -170,7 +168,7 @@ struct JsonWriter
bool first = true; bool first = true;
for (auto n : module->ports) { for (auto n : module->ports) {
Wire *w = module->wire(n); Wire *w = module->wire(n);
if (use_selection && !module->selected(w)) if (!module->selected(w))
continue; continue;
f << stringf("%s\n", first ? "" : ","); f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(n).c_str()); f << stringf(" %s: {\n", get_name(n).c_str());
@ -189,9 +187,7 @@ struct JsonWriter
f << stringf(" \"cells\": {"); f << stringf(" \"cells\": {");
first = true; first = true;
for (auto c : module->cells()) { for (auto c : module->selected_cells()) {
if (use_selection && !module->selected(c))
continue;
// Eventually we will want to emit $scopeinfo, but currently this // Eventually we will want to emit $scopeinfo, but currently this
// will break JSON netlist consumers like nextpnr // will break JSON netlist consumers like nextpnr
if (c->type == ID($scopeinfo)) if (c->type == ID($scopeinfo))
@ -239,21 +235,19 @@ struct JsonWriter
} }
f << stringf("\n },\n"); f << stringf("\n },\n");
if (!module->memories.empty()) { if (module->has_memories()) {
f << stringf(" \"memories\": {"); f << stringf(" \"memories\": {");
first = true; first = true;
for (auto &it : module->memories) { for (auto m : module->selected_memories()) {
if (use_selection && !module->selected(it.second))
continue;
f << stringf("%s\n", first ? "" : ","); f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(it.second->name).c_str()); f << stringf(" %s: {\n", get_name(m->name).c_str());
f << stringf(" \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0"); f << stringf(" \"hide_name\": %s,\n", m->name[0] == '$' ? "1" : "0");
f << stringf(" \"attributes\": {"); f << stringf(" \"attributes\": {");
write_parameters(it.second->attributes); write_parameters(m->attributes);
f << stringf("\n },\n"); f << stringf("\n },\n");
f << stringf(" \"width\": %d,\n", it.second->width); f << stringf(" \"width\": %d,\n", m->width);
f << stringf(" \"start_offset\": %d,\n", it.second->start_offset); f << stringf(" \"start_offset\": %d,\n", m->start_offset);
f << stringf(" \"size\": %d\n", it.second->size); f << stringf(" \"size\": %d\n", m->size);
f << stringf(" }"); f << stringf(" }");
first = false; first = false;
} }
@ -262,9 +256,7 @@ struct JsonWriter
f << stringf(" \"netnames\": {"); f << stringf(" \"netnames\": {");
first = true; first = true;
for (auto w : module->wires()) { for (auto w : module->selected_wires()) {
if (use_selection && !module->selected(w))
continue;
f << stringf("%s\n", first ? "" : ","); f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(w->name).c_str()); f << stringf(" %s: {\n", get_name(w->name).c_str());
f << stringf(" \"hide_name\": %s,\n", w->name[0] == '$' ? "1" : "0"); f << stringf(" \"hide_name\": %s,\n", w->name[0] == '$' ? "1" : "0");
@ -294,9 +286,8 @@ struct JsonWriter
f << stringf("{\n"); f << stringf("{\n");
f << stringf(" \"creator\": %s,\n", get_string(yosys_version_str).c_str()); f << stringf(" \"creator\": %s,\n", get_string(yosys_version_str).c_str());
f << stringf(" \"modules\": {\n"); f << stringf(" \"modules\": {\n");
vector<Module*> modules = use_selection ? design->selected_modules() : design->modules();
bool first_module = true; bool first_module = true;
for (auto mod : modules) { for (auto mod : design->all_selected_modules()) {
if (!first_module) if (!first_module)
f << stringf(",\n"); f << stringf(",\n");
write_module(mod); write_module(mod);
@ -354,7 +345,7 @@ struct JsonBackend : public Backend {
log(" as JSON numbers (for compatibility with old parsers)\n"); log(" as JSON numbers (for compatibility with old parsers)\n");
log("\n"); log("\n");
log(" -selected\n"); log(" -selected\n");
log(" output only select module\n"); log(" only write selected parts of the design.\n");
log("\n"); log("\n");
log("\n"); log("\n");
log("The general syntax of the JSON output created by this command is as follows:\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"); 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); json_writer.write_design(design);
if (!use_selection) design->pop_selection();
} }
} JsonBackend; } JsonBackend;
@ -693,7 +686,7 @@ struct JsonPass : public Pass {
f = &buf; 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); json_writer.write_design(design);
if (!empty) { if (!empty) {

View File

@ -335,37 +335,33 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
if (print_body) if (print_body)
{ {
for (auto it : module->wires()) for (auto wire : module->selected_wires()) {
if (!only_selected || design->selected(module, it)) {
if (only_selected) if (only_selected)
f << stringf("\n"); f << stringf("\n");
dump_wire(f, indent + " ", it); dump_wire(f, indent + " ", wire);
} }
for (auto it : module->memories) for (auto memory : module->selected_memories()) {
if (!only_selected || design->selected(module, it.second)) {
if (only_selected) if (only_selected)
f << stringf("\n"); f << stringf("\n");
dump_memory(f, indent + " ", it.second); dump_memory(f, indent + " ", memory);
} }
for (auto it : module->cells()) for (auto cell : module->selected_cells()) {
if (!only_selected || design->selected(module, it)) {
if (only_selected) if (only_selected)
f << stringf("\n"); f << stringf("\n");
dump_cell(f, indent + " ", it); dump_cell(f, indent + " ", cell);
} }
for (auto it : module->processes) for (auto process : module->selected_processes()) {
if (!only_selected || design->selected(module, it.second)) {
if (only_selected) if (only_selected)
f << stringf("\n"); f << stringf("\n");
dump_proc(f, indent + " ", it.second); dump_proc(f, indent + " ", process);
} }
bool first_conn_line = true; bool first_conn_line = true;
for (auto it = module->connections().begin(); it != module->connections().end(); ++it) { 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) { if (!show_conn) {
RTLIL::SigSpec sigs = it->first; RTLIL::SigSpec sigs = it->first;
sigs.append(it->second); 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; int init_autoidx = autoidx;
if (!only_selected) design->push_complete_selection();
if (!flag_m) { if (!flag_m) {
int count_selected_mods = 0; int count_selected_mods = 0;
for (auto module : design->modules()) { for (auto module : design->all_selected_modules()) {
if (design->selected_whole_module(module->name)) if (module->is_selected_whole())
flag_m = true; flag_m = true;
if (design->selected(module)) else
count_selected_mods++; count_selected_mods++;
} }
if (count_selected_mods > 1) 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); f << stringf("autoidx %d\n", autoidx);
} }
for (auto module : design->modules()) { for (auto module : design->all_selected_modules()) {
if (!only_selected || design->selected(module)) {
if (only_selected) if (only_selected)
f << stringf("\n"); f << stringf("\n");
dump_module(f, "", module, design, only_selected, flag_m, flag_n); dump_module(f, "", module, design, only_selected, flag_m, flag_n);
} }
} if (!only_selected) design->pop_selection();
log_assert(init_autoidx == autoidx); log_assert(init_autoidx == autoidx);
} }

View File

@ -2590,17 +2590,14 @@ struct VerilogBackend : public Backend {
design->sort(); design->sort();
*f << stringf("/* Generated by %s */\n", yosys_version_str); *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) if (module->get_blackbox_attribute() != blackboxes)
continue; 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()); log("Dumping module `%s'.\n", module->name.c_str());
dump_module(*f, "", module); dump_module(*f, "", module);
} }
if (!selected) design->pop_selection();
auto_name_map.clear(); auto_name_map.clear();
reg_wires.clear(); reg_wires.clear();

View File

@ -1218,10 +1218,10 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules(RTLIL::SelectPartial
log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); log_warning("Ignoring partially selected module %s.\n", log_id(it.first));
break; break;
case RTLIL::SELECT_WHOLE_ERR: 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; break;
case RTLIL::SELECT_WHOLE_CMDERR: 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; break;
default: default:
break; break;