diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 60fb09901..6a6974133 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -113,11 +113,9 @@ void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire) { - std::map sorted_attributes(wire->attributes.begin(), wire->attributes.end()); - - for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); ++it) { - f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); - dump_const(f, it->second); + for (auto &it : wire->attributes) { + f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str()); + dump_const(f, it.second); f << stringf("\n"); } f << stringf("%s" "wire ", indent.c_str()); @@ -138,11 +136,9 @@ void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL:: void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory) { - std::map sorted_attributes(memory->attributes.begin(), memory->attributes.end()); - - for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); ++it) { - f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); - dump_const(f, it->second); + for (auto &it : memory->attributes) { + f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str()); + dump_const(f, it.second); f << stringf("\n"); } f << stringf("%s" "memory ", indent.c_str()); @@ -157,24 +153,20 @@ void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell) { - std::map sorted_attributes(cell->attributes.begin(), cell->attributes.end()); - std::map sorted_parameters(cell->parameters.begin(), cell->parameters.end()); - std::map sorted_connections(cell->connections().begin(), cell->connections().end()); - - for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); ++it) { - f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); - dump_const(f, it->second); + for (auto &it : cell->attributes) { + f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str()); + dump_const(f, it.second); f << stringf("\n"); } f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str()); - for (auto it = sorted_parameters.begin(); it != sorted_parameters.end(); ++it) { - f << stringf("%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str()); - dump_const(f, it->second); + for (auto &it : cell->parameters) { + f << stringf("%s parameter%s %s ", indent.c_str(), (it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it.first.c_str()); + dump_const(f, it.second); f << stringf("\n"); } - for (auto it = sorted_connections.begin(); it != sorted_connections.end(); ++it) { - f << stringf("%s connect %s ", indent.c_str(), it->first.c_str()); - dump_sigspec(f, it->second); + for (auto &it : cell->connections()) { + f << stringf("%s connect %s ", indent.c_str(), it.first.c_str()); + dump_sigspec(f, it.second); f << stringf("\n"); } f << stringf("%s" "end\n", indent.c_str()); @@ -289,52 +281,32 @@ void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu if (print_body) { - std::vector sorted_wires; for (auto it : module->wires()) - sorted_wires.push_back(it); - std::sort(sorted_wires.begin(), sorted_wires.end(), RTLIL::sort_by_name_str()); - - std::vector sorted_memories; - for (auto it : module->memories) - sorted_memories.push_back(it.second); - std::sort(sorted_memories.begin(), sorted_memories.end(), RTLIL::sort_by_name_str()); - - std::vector sorted_cells; - for (auto it : module->cells()) - sorted_cells.push_back(it); - std::sort(sorted_cells.begin(), sorted_cells.end(), RTLIL::sort_by_name_str()); - - std::vector sorted_processes; - for (auto it : module->processes) - sorted_processes.push_back(it.second); - std::sort(sorted_processes.begin(), sorted_processes.end(), RTLIL::sort_by_name_str()); - - for (auto it : sorted_wires) if (!only_selected || design->selected(module, it)) { if (only_selected) f << stringf("\n"); dump_wire(f, indent + " ", it); } - for (auto it : sorted_memories) - if (!only_selected || design->selected(module, it)) { + for (auto it : module->memories) + if (!only_selected || design->selected(module, it.second)) { if (only_selected) f << stringf("\n"); - dump_memory(f, indent + " ", it); + dump_memory(f, indent + " ", it.second); } - for (auto it : sorted_cells) + 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 it : sorted_processes) - if (!only_selected || design->selected(module, it)) { + for (auto it : module->processes) + if (!only_selected || design->selected(module, it.second)) { if (only_selected) f << stringf("\n"); - dump_proc(f, indent + " ", it); + dump_proc(f, indent + " ", it.second); } bool first_conn_line = true; @@ -430,6 +402,8 @@ struct IlangBackend : public Backend { } extra_args(f, filename, args, argidx); + design->sort(); + log("Output filename: %s\n", filename.c_str()); *f << stringf("# Generated by %s\n", yosys_version_str); ILANG_BACKEND::dump_design(*f, design, selected, true, false); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index e9f4691b0..ab0844d72 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1137,6 +1137,8 @@ struct VerilogBackend : public Backend { } extra_args(f, filename, args, argidx); + design->sort(); + *f << stringf("/* Generated by %s */\n", yosys_version_str); for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) { if (it->second->get_bool_attribute("\\blackbox") != blackboxes) diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 52b38a064..8c977de2f 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -457,6 +457,13 @@ public: return entries[i].udata.second; } + template> + void sort(Compare comp = Compare()) + { + std::sort(entries.begin(), entries.end(), [comp](const entry_t &a, const entry_t &b){ return comp(b.udata.first, a.udata.first); }); + do_rehash(); + } + void swap(dict &other) { hashtable.swap(other.hashtable); @@ -760,6 +767,13 @@ public: return i >= 0; } + template> + void sort(Compare comp = Compare()) + { + std::sort(entries.begin(), entries.end(), [comp](const entry_t &a, const entry_t &b){ return comp(b.udata, a.udata); }); + do_rehash(); + } + void swap(pool &other) { hashtable.swap(other.hashtable); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index aea993478..3fb98d1e2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -373,6 +373,14 @@ void RTLIL::Design::remove(RTLIL::Module *module) delete module; } +void RTLIL::Design::sort() +{ + scratchpad.sort(); + modules_.sort(sort_by_id_str()); + for (auto &it : modules_) + it.second->sort(); +} + void RTLIL::Design::check() { #ifndef NDEBUG @@ -976,6 +984,21 @@ namespace { } #endif +void RTLIL::Module::sort() +{ + wires_.sort(sort_by_id_str()); + cells_.sort(sort_by_id_str()); + avail_parameters.sort(sort_by_id_str()); + memories.sort(sort_by_id_str()); + processes.sort(sort_by_id_str()); + for (auto &it : cells_) + it.second->sort(); + for (auto &it : wires_) + it.second->attributes.sort(sort_by_id_str()); + for (auto &it : memories) + it.second->attributes.sort(sort_by_id_str()); +} + void RTLIL::Module::check() { #ifndef NDEBUG @@ -1908,6 +1931,13 @@ const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const return parameters.at(paramname); } +void RTLIL::Cell::sort() +{ + connections_.sort(sort_by_id_str()); + parameters.sort(sort_by_id_str()); + attributes.sort(sort_by_id_str()); +} + void RTLIL::Cell::check() { #ifndef NDEBUG diff --git a/kernel/rtlil.h b/kernel/rtlil.h index dae684d98..d8ebae71d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -788,6 +788,7 @@ struct RTLIL::Design bool scratchpad_get_bool(std::string varname, bool default_value = false) const; std::string scratchpad_get_string(std::string varname, std::string default_value = std::string()) const; + void sort(); void check(); void optimize(); @@ -863,6 +864,8 @@ public: virtual ~Module(); virtual RTLIL::IdString derive(RTLIL::Design *design, dict parameters); virtual size_t count_id(RTLIL::IdString id); + + virtual void sort(); virtual void check(); virtual void optimize(); @@ -1136,6 +1139,7 @@ public: void setParam(RTLIL::IdString paramname, RTLIL::Const value); const RTLIL::Const &getParam(RTLIL::IdString paramname) const; + void sort(); void check(); void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index 38a52d754..01b922043 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -100,6 +100,8 @@ struct EquivInductWorker log(" Proof for induction step failed. %s\n", step != max_seq ? "Extending to next time step." : "Trying to prove individual $equiv from workset."); } + workset.sort(); + for (auto cell : workset) { SigBit bit_a = sigmap(cell->getPort("\\A")).to_single_sigbit(); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c5b25816c..98f83dffc 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -422,6 +422,10 @@ struct CleanPass : public Pass { if (count_rm_cells > 0 || count_rm_wires > 0) log("Removed %d unused cells and %d unused wires.\n", count_rm_cells, count_rm_wires); + design->optimize(); + design->sort(); + design->check(); + ct.clear(); ct_reg.clear(); ct_all.clear();