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;
std::vector<RTLIL::Module*> modules;
TopoSort<RTLIL::Module*> 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)

View File

@ -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<std::string> 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");

View File

@ -37,7 +37,6 @@ struct JnyWriter
{
private:
std::ostream &f;
bool _use_selection;
// XXX(aki): TODO: this needs to be updated to us
// dict<T, V> 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) {

View File

@ -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<SigBit, string> sigids;
pool<Aig> 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<Module*> 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) {

View File

@ -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);
}

View File

@ -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();

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));
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;