diff options
45 files changed, 1472 insertions, 956 deletions
@@ -115,7 +115,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+1706 +YOSYS_VER := 0.9+2406 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index b6e38c16c..4bdaf7a7f 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -138,9 +138,9 @@ struct BlifDumper { if (!config->gates_mode) return "subckt"; - if (!design->modules_.count(RTLIL::escape_id(cell_type))) + if (design->module(RTLIL::escape_id(cell_type)) == nullptr) return "gate"; - if (design->modules_.at(RTLIL::escape_id(cell_type))->get_blackbox_attribute()) + if (design->module(RTLIL::escape_id(cell_type))->get_blackbox_attribute()) return "gate"; return "subckt"; } @@ -148,7 +148,7 @@ struct BlifDumper void dump_params(const char *command, dict<IdString, Const> ¶ms) { for (auto ¶m : params) { - f << stringf("%s %s ", command, RTLIL::id2cstr(param.first)); + f << stringf("%s %s ", command, log_id(param.first)); if (param.second.flags & RTLIL::CONST_FLAG_STRING) { std::string str = param.second.decode_string(); f << stringf("\""); @@ -172,8 +172,7 @@ struct BlifDumper std::map<int, RTLIL::Wire*> inputs, outputs; - for (auto &wire_it : module->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : module->wires()) { if (wire->port_input) inputs[wire->port_id] = wire; if (wire->port_output) @@ -229,10 +228,8 @@ struct BlifDumper f << stringf(".names $undef\n"); } - for (auto &cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; - if (config->unbuf_types.count(cell->type)) { auto portnames = config->unbuf_types.at(cell->type); f << stringf(".names %s %s\n1 1\n", @@ -649,25 +646,24 @@ struct BlifBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules_) - if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first.str(); + for (auto module : design->modules()) + if (module->get_bool_attribute("\\top")) + top_module_name = module->name.str(); *f << stringf("# Generated by %s\n", yosys_version_str); std::vector<RTLIL::Module*> mod_list; design->sort(); - for (auto module_it : design->modules_) + for (auto module : design->modules()) { - RTLIL::Module *module = module_it.second; if (module->get_blackbox_attribute() && !config.blackbox_mode) continue; if (module->processes.size() != 0) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", log_id(module->name)); if (module->memories.size() != 0) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", log_id(module->name)); if (module->name == RTLIL::escape_id(top_module_name)) { BlifDumper::dump(*f, module, design, config); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index c1da4b127..e68a6a08f 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -39,6 +39,7 @@ struct BtorWorker RTLIL::Module *module; bool verbose; bool single_bad; + bool cover_mode; int next_nid = 1; int initstate_nid = -1; @@ -71,7 +72,11 @@ struct BtorWorker vector<int> bad_properties; dict<SigBit, bool> initbits; pool<Wire*> statewires; - string indent; + pool<string> srcsymbols; + + string indent, info_filename; + vector<string> info_lines; + dict<int, int> info_clocks; void btorf(const char *fmt, ...) { @@ -81,6 +86,40 @@ struct BtorWorker va_end(ap); } + void infof(const char *fmt, ...) + { + va_list ap; + va_start(ap, fmt); + info_lines.push_back(vstringf(fmt, ap)); + va_end(ap); + } + + template<typename T> + string getinfo(T *obj, bool srcsym = false) + { + string infostr = log_id(obj); + if (obj->attributes.count("\\src")) { + string src = obj->attributes.at("\\src").decode_string().c_str(); + if (srcsym && infostr[0] == '$') { + std::replace(src.begin(), src.end(), ' ', '_'); + if (srcsymbols.count(src) || module->count_id("\\" + src)) { + for (int i = 1;; i++) { + string s = stringf("%s-%d", src.c_str(), i); + if (!srcsymbols.count(s) && !module->count_id("\\" + s)) { + src = s; + break; + } + } + } + srcsymbols.insert(src); + infostr = src; + } else { + infostr += " ; " + src; + } + } + return infostr; + } + void btorf_push(const string &id) { if (verbose) { @@ -203,7 +242,7 @@ struct BtorWorker btorf("%d slt %d %d %d\n", nid_b_ltz, sid_bit, nid_b, nid_zero); nid = next_nid++; - btorf("%d ite %d %d %d %d\n", nid, sid, nid_b_ltz, nid_l, nid_r); + btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str()); } else { @@ -211,7 +250,7 @@ struct BtorWorker int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed); nid = next_nid++; - btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b); + btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str()); } SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -246,7 +285,7 @@ struct BtorWorker int sid = get_bv_sid(width); int nid = next_nid++; - btorf("%d %c%s %d %d %d\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b); + btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str()); SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -272,12 +311,12 @@ struct BtorWorker if (cell->type == "$_ANDNOT_") { btorf("%d not %d %d\n", nid1, sid, nid_b); - btorf("%d and %d %d %d\n", nid2, sid, nid_a, nid1); + btorf("%d and %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str()); } if (cell->type == "$_ORNOT_") { btorf("%d not %d %d\n", nid1, sid, nid_b); - btorf("%d or %d %d %d\n", nid2, sid, nid_a, nid1); + btorf("%d or %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str()); } SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -299,13 +338,13 @@ struct BtorWorker if (cell->type == "$_OAI3_") { btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c); - btorf("%d not %d %d\n", nid3, sid, nid2); + btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str()); } if (cell->type == "$_AOI3_") { btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c); - btorf("%d not %d %d\n", nid3, sid, nid2); + btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str()); } SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -330,14 +369,14 @@ struct BtorWorker btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d); btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2); - btorf("%d not %d %d\n", nid4, sid, nid3); + btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str()); } if (cell->type == "$_AOI4_") { btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b); btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d); btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2); - btorf("%d not %d %d\n", nid4, sid, nid3); + btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str()); } SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -369,9 +408,9 @@ struct BtorWorker int nid = next_nid++; if (cell->type.in("$lt", "$le", "$ge", "$gt")) { - btorf("%d %c%s %d %d %d\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b); + btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str()); } else { - btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b); + btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str()); } SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -403,7 +442,7 @@ struct BtorWorker int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed); int nid = next_nid++; - btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a); + btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str()); SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -444,9 +483,9 @@ struct BtorWorker int nid = next_nid++; if (btor_op != "not") - btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b); + btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str()); else - btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a); + btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str()); SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -474,12 +513,14 @@ struct BtorWorker int nid_a = get_sig_nid(cell->getPort("\\A")); int nid = next_nid++; - btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a); if (cell->type == "$reduce_xnor") { int nid2 = next_nid++; + btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str()); btorf("%d not %d %d %d\n", nid2, sid, nid); nid = nid2; + } else { + btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str()); } SigSpec sig = sigmap(cell->getPort("\\Y")); @@ -509,12 +550,14 @@ struct BtorWorker int sid = get_bv_sid(GetSize(sig_y)); int nid = next_nid++; - btorf("%d ite %d %d %d %d\n", nid, sid, nid_s, nid_b, nid_a); if (cell->type == "$_NMUX_") { int tmp = nid; nid = next_nid++; - btorf("%d not %d %d\n", nid, sid, tmp); + btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a); + btorf("%d not %d %d %s\n", nid, sid, tmp, getinfo(cell).c_str()); + } else { + btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str()); } add_nid_sig(nid, sig_y); @@ -536,7 +579,10 @@ struct BtorWorker int nid_b = get_sig_nid(sig_b.extract(i*width, width)); int nid_s = get_sig_nid(sig_s.extract(i)); int nid2 = next_nid++; - btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid); + if (i == GetSize(sig_s)-1) + btorf("%d ite %d %d %d %d %s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str()); + else + btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid); nid = nid2; } @@ -544,11 +590,26 @@ struct BtorWorker goto okay; } - if (cell->type.in("$dff", "$ff", "$_DFF_P_", "$_DFF_N", "$_FF_")) + if (cell->type.in("$dff", "$ff", "$_DFF_P_", "$_DFF_N_", "$_FF_")) { SigSpec sig_d = sigmap(cell->getPort("\\D")); SigSpec sig_q = sigmap(cell->getPort("\\Q")); + if (!info_filename.empty() && cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_")) + { + SigSpec sig_c = sigmap(cell->getPort(cell->type == "$dff" ? "\\CLK" : "\\C")); + int nid = get_sig_nid(sig_c); + bool negedge = false; + + if (cell->type == "$_DFF_N_") + negedge = true; + + if (cell->type == "$dff" && !cell->getParam("\\CLK_POLARITY").as_bool()) + negedge = true; + + info_clocks[nid] |= negedge ? 2 : 1; + } + IdString symbol; if (sig_q.is_wire()) { @@ -983,9 +1044,12 @@ struct BtorWorker return nid; } - BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad) : - f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad) + BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, string info_filename) : + f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), info_filename(info_filename) { + if (!info_filename.empty()) + infof("name %s\n", log_id(module)); + btorf_push("inputs"); for (auto wire : module->wires()) @@ -1004,7 +1068,7 @@ struct BtorWorker int sid = get_bv_sid(GetSize(sig)); int nid = next_nid++; - btorf("%d input %d %s\n", nid, sid, log_id(wire)); + btorf("%d input %d %s\n", nid, sid, getinfo(wire).c_str()); add_nid_sig(nid, sig); } @@ -1028,7 +1092,7 @@ struct BtorWorker btorf_push(stringf("output %s", log_id(wire))); int nid = get_sig_nid(wire); - btorf("%d output %d %s\n", next_nid++, nid, log_id(wire)); + btorf("%d output %d %s\n", next_nid++, nid, getinfo(wire).c_str()); btorf_pop(stringf("output %s", log_id(wire))); } @@ -1066,16 +1130,36 @@ struct BtorWorker btorf("%d not %d %d\n", nid_not_a, sid, nid_a); btorf("%d and %d %d %d\n", nid_en_and_not_a, sid, nid_en, nid_not_a); - if (single_bad) { + if (single_bad && !cover_mode) { bad_properties.push_back(nid_en_and_not_a); } else { - int nid = next_nid++; - string infostr = log_id(cell); - if (infostr[0] == '$' && cell->attributes.count("\\src")) { - infostr = cell->attributes.at("\\src").decode_string().c_str(); - std::replace(infostr.begin(), infostr.end(), ' ', '_'); + if (cover_mode) { + infof("bad %d %s\n", nid_en_and_not_a, getinfo(cell, true).c_str()); + } else { + int nid = next_nid++; + btorf("%d bad %d %s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str()); } - btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str()); + } + + btorf_pop(log_id(cell)); + } + + if (cell->type == "$cover" && cover_mode) + { + btorf_push(log_id(cell)); + + int sid = get_bv_sid(1); + int nid_a = get_sig_nid(cell->getPort("\\A")); + int nid_en = get_sig_nid(cell->getPort("\\EN")); + int nid_en_and_a = next_nid++; + + btorf("%d and %d %d %d\n", nid_en_and_a, sid, nid_en, nid_a); + + if (single_bad) { + bad_properties.push_back(nid_en_and_a); + } else { + int nid = next_nid++; + btorf("%d bad %d %s\n", nid, nid_en_and_a, getinfo(cell, true).c_str()); } btorf_pop(log_id(cell)); @@ -1096,7 +1180,7 @@ struct BtorWorker continue; int this_nid = next_nid++; - btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, log_id(wire)); + btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, getinfo(wire).c_str()); btorf_pop(stringf("wire %s", log_id(wire))); continue; @@ -1167,14 +1251,14 @@ struct BtorWorker } int nid2 = next_nid++; - btorf("%d next %d %d %d\n", nid2, sid, nid, nid_head); + btorf("%d next %d %d %d %s\n", nid2, sid, nid, nid_head, getinfo(cell).c_str()); } else { SigSpec sig = sigmap(cell->getPort("\\D")); int nid_q = get_sig_nid(sig); int sid = get_bv_sid(GetSize(sig)); - btorf("%d next %d %d %d\n", next_nid++, sid, nid, nid_q); + btorf("%d next %d %d %d %s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str()); } btorf_pop(stringf("next %s", log_id(cell))); @@ -1210,6 +1294,35 @@ struct BtorWorker btorf("%d bad %d\n", nid, todo[cursor]); } } + + if (!info_filename.empty()) + { + for (auto &it : info_clocks) + { + switch (it.second) + { + case 1: + infof("posedge %d\n", it.first); + break; + case 2: + infof("negedge %d\n", it.first); + break; + case 3: + infof("event %d\n", it.first); + break; + default: + log_abort(); + } + } + + std::ofstream f; + f.open(info_filename.c_str(), std::ofstream::trunc); + if (f.fail()) + log_error("Can't open file `%s' for writing: %s\n", info_filename.c_str(), strerror(errno)); + for (auto &it : info_lines) + f << it; + f.close(); + } } }; @@ -1229,10 +1342,17 @@ struct BtorBackend : public Backend { log(" -s\n"); log(" Output only a single bad property for all asserts\n"); log("\n"); + log(" -c\n"); + log(" Output cover properties using 'bad' statements instead of asserts\n"); + log("\n"); + log(" -i <filename>\n"); + log(" Create additional info file with auxiliary information\n"); + log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { - bool verbose = false, single_bad = false; + bool verbose = false, single_bad = false, cover_mode = false; + string info_filename; log_header(design, "Executing BTOR backend.\n"); @@ -1247,6 +1367,14 @@ struct BtorBackend : public Backend { single_bad = true; continue; } + if (args[argidx] == "-c") { + cover_mode = true; + continue; + } + if (args[argidx] == "-i" && argidx+1 < args.size()) { + info_filename = args[++argidx]; + continue; + } break; } extra_args(f, filename, args, argidx); @@ -1259,7 +1387,7 @@ struct BtorBackend : public Backend { *f << stringf("; BTOR description generated by %s for module %s.\n", yosys_version_str, log_id(topmod)); - BtorWorker(*f, topmod, verbose, single_bad); + BtorWorker(*f, topmod, verbose, single_bad, cover_mode, info_filename); *f << stringf("; end of yosys output\n"); } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 199560ad0..cb1b4c284 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -171,13 +171,12 @@ struct EdifBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules_) - if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first.str(); + for (auto module : design->modules()) + if (module->get_bool_attribute("\\top")) + top_module_name = module->name.str(); - for (auto module_it : design->modules_) + for (auto module : design->modules()) { - RTLIL::Module *module = module_it.second; if (module->get_blackbox_attribute()) continue; @@ -185,14 +184,13 @@ struct EdifBackend : public Backend { top_module_name = module->name.str(); if (module->processes.size() != 0) - log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name)); + log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", log_id(module->name)); if (module->memories.size() != 0) - log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name)); + log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", log_id(module->name)); - for (auto cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; - if (!design->modules_.count(cell->type) || design->modules_.at(cell->type)->get_blackbox_attribute()) { + if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) { lib_cell_ports[cell->type]; for (auto p : cell->connections()) lib_cell_ports[cell->type][p.first] = GetSize(p.second); @@ -277,11 +275,11 @@ struct EdifBackend : public Backend { // extract module dependencies std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps; - for (auto &mod_it : design->modules_) { - module_deps[mod_it.second] = std::set<RTLIL::Module*>(); - for (auto &cell_it : mod_it.second->cells_) - if (design->modules_.count(cell_it.second->type) > 0) - module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type)); + for (auto module : design->modules()) { + module_deps[module] = std::set<RTLIL::Module*>(); + for (auto cell : module->cells()) + if (design->module(cell->type) != nullptr) + module_deps[module].insert(design->module(cell->type)); } // simple good-enough topological sort @@ -292,12 +290,12 @@ struct EdifBackend : public Backend { for (auto &dep : it.second) if (module_deps.count(dep) > 0) goto not_ready_yet; - // log("Next in topological sort: %s\n", RTLIL::id2cstr(it.first->name)); + // log("Next in topological sort: %s\n", log_id(it.first->name)); sorted_modules.push_back(it.first); not_ready_yet:; } if (sorted_modules_idx == sorted_modules.size()) - log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", RTLIL::id2cstr(module_deps.begin()->first->name)); + log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name)); while (sorted_modules_idx < sorted_modules.size()) module_deps.erase(sorted_modules.at(sorted_modules_idx++)); } @@ -339,8 +337,7 @@ struct EdifBackend : public Backend { *f << stringf(" (view VIEW_NETLIST\n"); *f << stringf(" (viewType NETLIST)\n"); *f << stringf(" (interface\n"); - for (auto &wire_it : module->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : module->wires()) { if (wire->port_id == 0) continue; const char *dir = "INOUT"; @@ -378,8 +375,7 @@ struct EdifBackend : public Backend { *f << stringf(" (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n"); *f << stringf(" (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n"); } - for (auto &cell_it : module->cells_) { - RTLIL::Cell *cell = cell_it.second; + for (auto cell : module->cells()) { *f << stringf(" (instance %s\n", EDIF_DEF(cell->name)); *f << stringf(" (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : ""); @@ -459,8 +455,7 @@ struct EdifBackend : public Backend { add_prop(p.first, p.second); *f << stringf("\n )\n"); } - for (auto &wire_it : module->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : module->wires()) { if (!wire->get_bool_attribute(ID::keep)) continue; for(int i = 0; i < wire->width; i++) { diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index e06786220..5445fad90 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -358,10 +358,10 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl if (!flag_m) { int count_selected_mods = 0; - for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) { - if (design->selected_whole_module(it->first)) + for (auto module : design->modules()) { + if (design->selected_whole_module(module->name)) flag_m = true; - if (design->selected(it->second)) + if (design->selected(module)) count_selected_mods++; } if (count_selected_mods > 1) @@ -374,11 +374,11 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl f << stringf("autoidx %d\n", autoidx); } - for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) { - if (!only_selected || design->selected(it->second)) { + for (auto module : design->modules()) { + if (!only_selected || design->selected(module)) { if (only_selected) f << stringf("\n"); - dump_module(f, "", it->second, design, only_selected, flag_m, flag_n); + dump_module(f, "", module, design, only_selected, flag_m, flag_n); } } diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 809a0fa09..31dce1cca 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -122,70 +122,67 @@ struct IntersynthBackend : public Backend { for (auto lib : libs) ct.setup_design(lib); - for (auto module_it : design->modules_) + for (auto module : design->modules()) { - RTLIL::Module *module = module_it.second; 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; 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", RTLIL::id2cstr(module->name)); + log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name)); continue; } - log("Generating netlist %s.\n", RTLIL::id2cstr(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; - netlists_code += stringf("# Netlist of module %s\n", RTLIL::id2cstr(module->name)); - netlists_code += stringf("netlist %s\n", RTLIL::id2cstr(module->name)); + netlists_code += stringf("# Netlist of module %s\n", log_id(module->name)); + netlists_code += stringf("netlist %s\n", log_id(module->name)); // Module Ports: "std::set<string> celltypes_code" prevents duplicate top level ports - for (auto wire_it : module->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : module->wires()) { if (wire->port_input || wire->port_output) { celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n", - RTLIL::id2cstr(wire->name), wire->width, wire->port_input ? "*" : "", - wire->port_input ? "input" : "output", RTLIL::id2cstr(wire->name), wire->width, RTLIL::id2cstr(wire->name))); - netlists_code += stringf("node %s %s PORT %s\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(wire->name), + log_id(wire->name), wire->width, wire->port_input ? "*" : "", + wire->port_input ? "input" : "output", log_id(wire->name), wire->width, log_id(wire->name))); + netlists_code += stringf("node %s %s PORT %s\n", log_id(wire->name), log_id(wire->name), netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str()); } } // Submodules: "std::set<string> celltypes_code" prevents duplicate cell types - for (auto cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; std::string celltype_code, node_code; if (!ct.cell_known(cell->type)) - log_error("Found unknown cell type %s in module!\n", RTLIL::id2cstr(cell->type)); + log_error("Found unknown cell type %s in module!\n", log_id(cell->type)); - celltype_code = stringf("celltype %s", RTLIL::id2cstr(cell->type)); - node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + celltype_code = stringf("celltype %s", log_id(cell->type)); + node_code = stringf("node %s %s", log_id(cell->name), log_id(cell->type)); for (auto &port : cell->connections()) { RTLIL::SigSpec sig = sigmap(port.second); if (sig.size() != 0) { conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); - celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first)); - node_code += stringf(" %s %s", RTLIL::id2cstr(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str()); + celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first)); + node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str()); } } for (auto ¶m : cell->parameters) { - celltype_code += stringf(" cfg:%d %s", int(param.second.bits.size()), RTLIL::id2cstr(param.first)); + celltype_code += stringf(" cfg:%d %s", int(param.second.bits.size()), log_id(param.first)); if (param.second.bits.size() != 32) { - node_code += stringf(" %s '", RTLIL::id2cstr(param.first)); + node_code += stringf(" %s '", log_id(param.first)); for (int i = param.second.bits.size()-1; i >= 0; i--) node_code += param.second.bits[i] == State::S1 ? "1" : "0"; } else - node_code += stringf(" %s 0x%x", RTLIL::id2cstr(param.first), param.second.as_int()); + node_code += stringf(" %s 0x%x", log_id(param.first), param.second.as_int()); } celltypes_code.insert(celltype_code + "\n"); diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 628765831..eb4826051 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -1523,12 +1523,12 @@ struct Smt2Backend : public Backend { for (auto &dep : it.second) if (module_deps.count(dep) > 0) goto not_ready_yet; - // log("Next in topological sort: %s\n", RTLIL::id2cstr(it.first->name)); + // log("Next in topological sort: %s\n", log_id(it.first->name)); sorted_modules.push_back(it.first); not_ready_yet:; } if (sorted_modules_idx == sorted_modules.size()) - log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", RTLIL::id2cstr(module_deps.begin()->first->name)); + log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name)); while (sorted_modules_idx < sorted_modules.size()) module_deps.erase(sorted_modules.at(sorted_modules_idx++)); } diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 6738a4bbd..9b603a8c5 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -70,14 +70,13 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De idict<IdString, 1> inums; int cell_counter = 0, conn_counter = 0, nc_counter = 0; - for (auto &cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; f << stringf("X%d", cell_counter++); std::vector<RTLIL::SigSpec> port_sigs; - if (design->modules_.count(cell->type) == 0) + if (design->module(cell->type) == nullptr) { log_warning("no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n", log_id(cell->type), log_id(module), log_id(cell)); @@ -88,11 +87,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De } else { - RTLIL::Module *mod = design->modules_.at(cell->type); + RTLIL::Module *mod = design->module(cell->type); std::vector<RTLIL::Wire*> ports; - for (auto wire_it : mod->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : mod->wires()) { if (wire->port_id == 0) continue; while (int(ports.size()) < wire->port_id) @@ -202,16 +200,15 @@ struct SpiceBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules_) - if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first.str(); + for (auto module : design->modules()) + if (module->get_bool_attribute("\\top")) + top_module_name = module->name.str(); *f << stringf("* SPICE netlist generated by %s\n", yosys_version_str); *f << stringf("\n"); - for (auto module_it : design->modules_) + for (auto module : design->modules()) { - RTLIL::Module *module = module_it.second; if (module->get_blackbox_attribute()) continue; @@ -226,8 +223,7 @@ struct SpiceBackend : public Backend { } std::vector<RTLIL::Wire*> ports; - for (auto wire_it : module->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : module->wires()) { if (wire->port_id == 0) continue; while (int(ports.size()) < wire->port_id) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 19541f1c4..e0fd201e1 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -73,12 +73,12 @@ void reset_auto_counter(RTLIL::Module *module) reset_auto_counter_id(module->name, false); - for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it) - reset_auto_counter_id(it->second->name, true); + for (auto w : module->wires()) + reset_auto_counter_id(w->name, true); - for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it) { - reset_auto_counter_id(it->second->name, true); - reset_auto_counter_id(it->second->type, false); + for (auto cell : module->cells()) { + reset_auto_counter_id(cell->name, true); + reset_auto_counter_id(cell->type, false); } for (auto it = module->processes.begin(); it != module->processes.end(); ++it) @@ -1719,9 +1719,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) if (!noexpr) { std::set<std::pair<RTLIL::Wire*,int>> reg_bits; - for (auto &it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = it.second; if (!reg_ct.count(cell->type) || !cell->hasPort("\\Q")) continue; @@ -1734,9 +1733,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) reg_bits.insert(std::pair<RTLIL::Wire*,int>(chunk.wire, chunk.offset+i)); } } - for (auto &it : module->wires_) + for (auto wire : module->wires()) { - RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) if (reg_bits.count(std::pair<RTLIL::Wire*,int>(wire, i)) == 0) goto this_wire_aint_reg; @@ -1751,8 +1749,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) bool keep_running = true; for (int port_id = 1; keep_running; port_id++) { keep_running = false; - for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it) { - RTLIL::Wire *wire = it->second; + for (auto wire : module->wires()) { if (wire->port_id == port_id) { if (port_id != 1) f << stringf(", "); @@ -1764,14 +1761,14 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) } f << stringf(");\n"); - for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it) - dump_wire(f, indent + " ", it->second); + for (auto w : module->wires()) + dump_wire(f, indent + " ", w); for (auto it = module->memories.begin(); it != module->memories.end(); ++it) dump_memory(f, indent + " ", it->second); - for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it) - dump_cell(f, indent + " ", it->second); + for (auto cell : module->cells()) + dump_cell(f, indent + " ", cell); for (auto it = module->processes.begin(); it != module->processes.end(); ++it) dump_process(f, indent + " ", it->second); @@ -1995,16 +1992,16 @@ struct VerilogBackend : public Backend { 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_blackbox_attribute() != blackboxes) + for (auto module : design->modules()) { + if (module->get_blackbox_attribute() != blackboxes) continue; - if (selected && !design->selected_whole_module(it->first)) { - if (design->selected_module(it->first)) - log_cmd_error("Can't handle partially selected module %s!\n", RTLIL::id2cstr(it->first)); + 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", it->first.c_str()); - dump_module(*f, "", it->second); + log("Dumping module `%s'.\n", module->name.c_str()); + dump_module(*f, "", module); } auto_name_map.clear(); diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d1f136fd7..2c1fc25ce 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1320,7 +1320,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule // When an interface instance is found in a module, the whole RTLIL for the module will be rederived again // from AST. The interface members are copied into the AST module with the prefix of the interface. -void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces) +void AstModule::reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module*> &local_interfaces) { loadconfig(); @@ -1408,7 +1408,7 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT // create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces // This method is used to explode the interface when the interface is a port of the module (not instantiated inside) -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool /*mayfail*/) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool /*mayfail*/) { AstNode *new_ast = NULL; std::string modname = derive_common(design, parameters, &new_ast); @@ -1494,7 +1494,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) { bool quiet = lib || attributes.count(ID(blackbox)) || attributes.count(ID(whitebox)); @@ -1514,7 +1514,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module -std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet) +std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet) { std::string stripped_name = name.str(); @@ -1528,18 +1528,18 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString if (child->type != AST_PARAMETER) continue; para_counter++; - std::string para_id = child->str; - if (parameters.count(para_id) > 0) { + auto it = parameters.find(child->str); + if (it != parameters.end()) { if (!quiet) - log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); continue; } - para_id = stringf("$%d", para_counter); - if (parameters.count(para_id) > 0) { + it = parameters.find(stringf("$%d", para_counter)); + if (it != parameters.end()) { if (!quiet) - log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); continue; } } @@ -1559,46 +1559,52 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); loadconfig(); + pool<IdString> rewritten; + rewritten.reserve(GetSize(parameters)); + AstNode *new_ast = ast->clone(); para_counter = 0; for (auto child : new_ast->children) { if (child->type != AST_PARAMETER) continue; para_counter++; - std::string para_id = child->str; - if (parameters.count(para_id) > 0) { + auto it = parameters.find(child->str); + if (it != parameters.end()) { if (!quiet) - log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); + log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second)); goto rewrite_parameter; } - para_id = stringf("$%d", para_counter); - if (parameters.count(para_id) > 0) { + it = parameters.find(stringf("$%d", para_counter)); + if (it != parameters.end()) { if (!quiet) - log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); goto rewrite_parameter; } continue; rewrite_parameter: delete child->children.at(0); - if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { + if ((it->second.flags & RTLIL::CONST_FLAG_REAL) != 0) { child->children[0] = new AstNode(AST_REALVALUE); - child->children[0]->realvalue = std::stod(parameters[para_id].decode_string()); - } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) - child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); + child->children[0]->realvalue = std::stod(it->second.decode_string()); + } else if ((it->second.flags & RTLIL::CONST_FLAG_STRING) != 0) + child->children[0] = AstNode::mkconst_str(it->second.decode_string()); else - child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); - parameters.erase(para_id); + child->children[0] = AstNode::mkconst_bits(it->second.bits, (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0); + rewritten.insert(it->first); } - for (auto param : parameters) { - AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER)); - defparam->children[0]->str = param.first.str(); - if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0) - defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string())); - else - defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); - new_ast->children.push_back(defparam); - } + if (GetSize(rewritten) < GetSize(parameters)) + for (const auto ¶m : parameters) { + if (rewritten.count(param.first)) + continue; + AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER)); + defparam->children[0]->str = param.first.str(); + if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0) + defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string())); + else + defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); + new_ast->children.push_back(defparam); + } (*new_ast_out) = new_ast; return modname; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index e27ab10c2..3dd40238f 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -312,10 +312,10 @@ namespace AST AstNode *ast; bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire; ~AstModule() YS_OVERRIDE; - RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE; - RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE; - std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet = false); - void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE; + RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) YS_OVERRIDE; + RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) YS_OVERRIDE; + std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet = false); + void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) YS_OVERRIDE; RTLIL::Module *clone() const YS_OVERRIDE; void loadconfig() const; }; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 10e9f2683..f801a17e0 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1727,7 +1727,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } did_something = true; newNode = new AstNode(AST_CASE, shift_expr); - for (int i = 0; i <= source_width-result_width; i++) { + for (int i = 0; i < source_width; i++) { int start_bit = children[0]->id2ast->range_right + i; AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true)); AstNode *lvalue = children[0]->clone(); diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index add17c243..fb3db70d2 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -157,7 +157,7 @@ struct RpcServer { struct RpcModule : RTLIL::Module { std::shared_ptr<RpcServer> server; - RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) YS_OVERRIDE { + RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) YS_OVERRIDE { std::string stripped_name = name.str(); if (stripped_name.compare(0, 9, "$abstract") == 0) stripped_name = stripped_name.substr(9); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index be2872e59..3f28f828d 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2522,6 +2522,7 @@ gen_stmt: } simple_behavioral_stmt ';' expr { ast_stack.back()->children.push_back($6); } ';' simple_behavioral_stmt ')' gen_stmt_block { + SET_AST_NODE_LOC(ast_stack.back(), @1, @11); ast_stack.pop_back(); } | TOK_IF '(' expr ')' { @@ -2530,6 +2531,7 @@ gen_stmt: ast_stack.push_back(node); ast_stack.back()->children.push_back($3); } gen_stmt_block opt_gen_else { + SET_AST_NODE_LOC(ast_stack.back(), @1, @7); ast_stack.pop_back(); } | case_type '(' expr ')' { @@ -2538,6 +2540,7 @@ gen_stmt: ast_stack.push_back(node); } gen_case_body TOK_ENDCASE { case_type_stack.pop_back(); + SET_AST_NODE_LOC(ast_stack.back(), @1, @7); ast_stack.pop_back(); } | TOK_BEGIN { @@ -2551,6 +2554,7 @@ gen_stmt: exitTypeScope(); delete $3; delete $7; + SET_AST_NODE_LOC(ast_stack.back(), @1, @7); ast_stack.pop_back(); } | TOK_MSG_TASKS { @@ -2560,6 +2564,7 @@ gen_stmt: ast_stack.back()->children.push_back(node); ast_stack.push_back(node); } opt_arg_list ';'{ + SET_AST_NODE_LOC(ast_stack.back(), @1, @3); ast_stack.pop_back(); }; @@ -2569,6 +2574,7 @@ gen_stmt_block: ast_stack.back()->children.push_back(node); ast_stack.push_back(node); } gen_stmt_or_module_body_stmt { + SET_AST_NODE_LOC(ast_stack.back(), @2, @2); ast_stack.pop_back(); }; diff --git a/kernel/modtools.h b/kernel/modtools.h index 409562eb9..fbc5482ee 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -158,7 +158,7 @@ struct ModIndex : public RTLIL::Monitor #endif } - void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE + void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE { log_assert(module == cell->module); @@ -380,22 +380,15 @@ struct ModWalker } } - ModWalker() : design(NULL), module(NULL) + ModWalker(RTLIL::Design *design) : design(design), module(NULL) { + ct.setup(design); } - ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL) + void setup(RTLIL::Module *module, CellTypes *filter_ct = NULL) { - setup(design, module, filter_ct); - } - - void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL) - { - this->design = design; this->module = module; - ct.clear(); - ct.setup(design); sigmap.set(module); signal_drivers.clear(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 79e50cccd..d04524387 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -85,14 +85,14 @@ RTLIL::Const::Const(RTLIL::State bit, int width) RTLIL::Const::Const(const std::vector<bool> &bits) { flags = RTLIL::CONST_FLAG_NONE; - for (auto b : bits) - this->bits.push_back(b ? State::S1 : State::S0); + for (const auto &b : bits) + this->bits.emplace_back(b ? State::S1 : State::S0); } RTLIL::Const::Const(const RTLIL::Const &c) { flags = c.flags; - for (auto b : c.bits) + for (const auto &b : c.bits) this->bits.push_back(b); } @@ -139,6 +139,7 @@ int RTLIL::Const::as_int(bool is_signed) const std::string RTLIL::Const::as_string() const { std::string ret; + ret.reserve(bits.size()); for (size_t i = bits.size(); i > 0; i--) switch (bits[i-1]) { case S0: ret += "0"; break; @@ -151,9 +152,10 @@ std::string RTLIL::Const::as_string() const return ret; } -RTLIL::Const RTLIL::Const::from_string(std::string str) +RTLIL::Const RTLIL::Const::from_string(const std::string &str) { Const c; + c.bits.reserve(str.size()); for (auto it = str.rbegin(); it != str.rend(); it++) switch (*it) { case '0': c.bits.push_back(State::S0); break; @@ -169,17 +171,16 @@ RTLIL::Const RTLIL::Const::from_string(std::string str) std::string RTLIL::Const::decode_string() const { std::string string; - std::vector<char> string_chars; - for (int i = 0; i < int (bits.size()); i += 8) { + string.reserve(GetSize(bits)/8); + for (int i = 0; i < GetSize(bits); i += 8) { char ch = 0; for (int j = 0; j < 8 && i + j < int (bits.size()); j++) if (bits[i + j] == RTLIL::State::S1) ch |= 1 << j; if (ch != 0) - string_chars.push_back(ch); + string.append({ch}); } - for (int i = int (string_chars.size()) - 1; i >= 0; i--) - string += string_chars[i]; + std::reverse(string.begin(), string.end()); return string; } @@ -187,7 +188,7 @@ bool RTLIL::Const::is_fully_zero() const { cover("kernel.rtlil.const.is_fully_zero"); - for (auto bit : bits) + for (const auto &bit : bits) if (bit != RTLIL::State::S0) return false; @@ -198,7 +199,7 @@ bool RTLIL::Const::is_fully_ones() const { cover("kernel.rtlil.const.is_fully_ones"); - for (auto bit : bits) + for (const auto &bit : bits) if (bit != RTLIL::State::S1) return false; @@ -209,7 +210,7 @@ bool RTLIL::Const::is_fully_def() const { cover("kernel.rtlil.const.is_fully_def"); - for (auto bit : bits) + for (const auto &bit : bits) if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) return false; @@ -220,7 +221,7 @@ bool RTLIL::Const::is_fully_undef() const { cover("kernel.rtlil.const.is_fully_undef"); - for (auto bit : bits) + for (const auto &bit : bits) if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz) return false; @@ -231,11 +232,8 @@ void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value) { if (value) attributes[id] = RTLIL::Const(1); - else { - const auto it = attributes.find(id); - if (it != attributes.end()) - attributes.erase(it); - } + else + attributes.erase(id); } bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const @@ -249,7 +247,7 @@ bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data) { string attrval; - for (auto &s : data) { + for (const auto &s : data) { if (!attrval.empty()) attrval += "|"; attrval += s; @@ -285,8 +283,9 @@ void RTLIL::AttrObject::set_src_attribute(const std::string &src) std::string RTLIL::AttrObject::get_src_attribute() const { std::string src; - if (attributes.count(ID(src))) - src = attributes.at(ID(src)).decode_string(); + const auto it = attributes.find(ID(src)); + if (it != attributes.end()) + src = it->second.decode_string(); return src; } @@ -477,32 +476,33 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) return module; } -void RTLIL::Design::scratchpad_unset(std::string varname) +void RTLIL::Design::scratchpad_unset(const std::string &varname) { scratchpad.erase(varname); } -void RTLIL::Design::scratchpad_set_int(std::string varname, int value) +void RTLIL::Design::scratchpad_set_int(const std::string &varname, int value) { scratchpad[varname] = stringf("%d", value); } -void RTLIL::Design::scratchpad_set_bool(std::string varname, bool value) +void RTLIL::Design::scratchpad_set_bool(const std::string &varname, bool value) { scratchpad[varname] = value ? "true" : "false"; } -void RTLIL::Design::scratchpad_set_string(std::string varname, std::string value) +void RTLIL::Design::scratchpad_set_string(const std::string &varname, std::string value) { - scratchpad[varname] = value; + scratchpad[varname] = std::move(value); } -int RTLIL::Design::scratchpad_get_int(std::string varname, int default_value) const +int RTLIL::Design::scratchpad_get_int(const std::string &varname, int default_value) const { - if (scratchpad.count(varname) == 0) + auto it = scratchpad.find(varname); + if (it == scratchpad.end()) return default_value; - std::string str = scratchpad.at(varname); + const std::string &str = it->second; if (str == "0" || str == "false") return 0; @@ -515,12 +515,13 @@ int RTLIL::Design::scratchpad_get_int(std::string varname, int default_value) co return *endptr ? default_value : parsed_value; } -bool RTLIL::Design::scratchpad_get_bool(std::string varname, bool default_value) const +bool RTLIL::Design::scratchpad_get_bool(const std::string &varname, bool default_value) const { - if (scratchpad.count(varname) == 0) + auto it = scratchpad.find(varname); + if (it == scratchpad.end()) return default_value; - std::string str = scratchpad.at(varname); + const std::string &str = it->second; if (str == "0" || str == "false") return false; @@ -531,11 +532,13 @@ bool RTLIL::Design::scratchpad_get_bool(std::string varname, bool default_value) return default_value; } -std::string RTLIL::Design::scratchpad_get_string(std::string varname, std::string default_value) const +std::string RTLIL::Design::scratchpad_get_string(const std::string &varname, const std::string &default_value) const { - if (scratchpad.count(varname) == 0) + auto it = scratchpad.find(varname); + if (it == scratchpad.end()) return default_value; - return scratchpad.at(varname); + + return it->second; } void RTLIL::Design::remove(RTLIL::Module *module) @@ -723,12 +726,12 @@ void RTLIL::Module::makeblackbox() set_bool_attribute(ID::blackbox); } -void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>) +void RTLIL::Module::reprocess_module(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &) { log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name)); } -RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail) +RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail) { if (mayfail) return RTLIL::IdString(); @@ -736,7 +739,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLI } -RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, dict<RTLIL::IdString, RTLIL::Module*>, dict<RTLIL::IdString, RTLIL::IdString>, bool mayfail) +RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, const dict<RTLIL::IdString, RTLIL::Module*> &, const dict<RTLIL::IdString, RTLIL::IdString> &, bool mayfail) { if (mayfail) return RTLIL::IdString(); @@ -770,16 +773,17 @@ namespace { int param(RTLIL::IdString name) { - if (cell->parameters.count(name) == 0) + auto it = cell->parameters.find(name); + if (it == cell->parameters.end()) error(__LINE__); expected_params.insert(name); - return cell->parameters.at(name).as_int(); + return it->second.as_int(); } int param_bool(RTLIL::IdString name) { int v = param(name); - if (cell->parameters.at(name).bits.size() > 32) + if (GetSize(cell->parameters.at(name)) > 32) error(__LINE__); if (v != 0 && v != 1) error(__LINE__); @@ -797,20 +801,21 @@ namespace { void param_bits(RTLIL::IdString name, int width) { param(name); - if (int(cell->parameters.at(name).bits.size()) != width) + if (GetSize(cell->parameters.at(name).bits) != width) error(__LINE__); } void port(RTLIL::IdString name, int width) { - if (!cell->hasPort(name)) + auto it = cell->connections_.find(name); + if (it == cell->connections_.end()) error(__LINE__); - if (cell->getPort(name).size() != width) + if (GetSize(it->second) != width) error(__LINE__); expected_ports.insert(name); } - void check_expected(bool check_matched_sign = true) + void check_expected(bool check_matched_sign = false) { for (auto ¶ : cell->parameters) if (expected_params.count(para.first) == 0) @@ -819,35 +824,15 @@ namespace { if (expected_ports.count(conn.first) == 0) error(__LINE__); - if (expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) && check_matched_sign) { - bool a_is_signed = param(ID(A_SIGNED)) != 0; - bool b_is_signed = param(ID(B_SIGNED)) != 0; + if (check_matched_sign) { + log_assert(expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) != 0); + bool a_is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool(); + bool b_is_signed = cell->parameters.at(ID(B_SIGNED)).as_bool(); if (a_is_signed != b_is_signed) error(__LINE__); } } - void check_gate(const char *ports) - { - if (cell->parameters.size() != 0) - error(__LINE__); - - for (const char *p = ports; *p; p++) { - char portname[3] = { '\\', *p, 0 }; - if (!cell->hasPort(portname)) - error(__LINE__); - if (cell->getPort(portname).size() != 1) - error(__LINE__); - } - - for (auto &conn : cell->connections()) { - if (conn.first.size() != 2 || conn.first[0] != '\\') - error(__LINE__); - if (strchr(ports, conn.first[1]) == NULL) - error(__LINE__); - } - } - void check() { if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") || @@ -868,7 +853,7 @@ namespace { port(ID::A, param(ID(A_WIDTH))); port(ID::B, param(ID(B_WIDTH))); port(ID::Y, param(ID(Y_WIDTH))); - check_expected(); + check_expected(true); return; } @@ -906,7 +891,7 @@ namespace { port(ID::A, param(ID(A_WIDTH))); port(ID::B, param(ID(B_WIDTH))); port(ID::Y, param(ID(Y_WIDTH))); - check_expected(); + check_expected(true); return; } @@ -949,7 +934,7 @@ namespace { port(ID(X), param(ID(Y_WIDTH))); port(ID::Y, param(ID(Y_WIDTH))); port(ID(CO), param(ID(Y_WIDTH))); - check_expected(); + check_expected(true); return; } @@ -1274,72 +1259,72 @@ namespace { return; } - if (cell->type == ID($_BUF_)) { check_gate("AY"); return; } - if (cell->type == ID($_NOT_)) { check_gate("AY"); return; } - if (cell->type == ID($_AND_)) { check_gate("ABY"); return; } - if (cell->type == ID($_NAND_)) { check_gate("ABY"); return; } - if (cell->type == ID($_OR_)) { check_gate("ABY"); return; } - if (cell->type == ID($_NOR_)) { check_gate("ABY"); return; } - if (cell->type == ID($_XOR_)) { check_gate("ABY"); return; } - if (cell->type == ID($_XNOR_)) { check_gate("ABY"); return; } - if (cell->type == ID($_ANDNOT_)) { check_gate("ABY"); return; } - if (cell->type == ID($_ORNOT_)) { check_gate("ABY"); return; } - if (cell->type == ID($_MUX_)) { check_gate("ABSY"); return; } - if (cell->type == ID($_NMUX_)) { check_gate("ABSY"); return; } - if (cell->type == ID($_AOI3_)) { check_gate("ABCY"); return; } - if (cell->type == ID($_OAI3_)) { check_gate("ABCY"); return; } - if (cell->type == ID($_AOI4_)) { check_gate("ABCDY"); return; } - if (cell->type == ID($_OAI4_)) { check_gate("ABCDY"); return; } - - if (cell->type == ID($_TBUF_)) { check_gate("AYE"); return; } - - if (cell->type == ID($_MUX4_)) { check_gate("ABCDSTY"); return; } - if (cell->type == ID($_MUX8_)) { check_gate("ABCDEFGHSTUY"); return; } - if (cell->type == ID($_MUX16_)) { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; } - - if (cell->type == ID($_SR_NN_)) { check_gate("SRQ"); return; } - if (cell->type == ID($_SR_NP_)) { check_gate("SRQ"); return; } - if (cell->type == ID($_SR_PN_)) { check_gate("SRQ"); return; } - if (cell->type == ID($_SR_PP_)) { check_gate("SRQ"); return; } - - if (cell->type == ID($_FF_)) { check_gate("DQ"); return; } - if (cell->type == ID($_DFF_N_)) { check_gate("DQC"); return; } - if (cell->type == ID($_DFF_P_)) { check_gate("DQC"); return; } - - if (cell->type == ID($_DFFE_NN_)) { check_gate("DQCE"); return; } - if (cell->type == ID($_DFFE_NP_)) { check_gate("DQCE"); return; } - if (cell->type == ID($_DFFE_PN_)) { check_gate("DQCE"); return; } - if (cell->type == ID($_DFFE_PP_)) { check_gate("DQCE"); return; } - - if (cell->type == ID($_DFF_NN0_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_NN1_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_NP0_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_NP1_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_PN0_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_PN1_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_PP0_)) { check_gate("DQCR"); return; } - if (cell->type == ID($_DFF_PP1_)) { check_gate("DQCR"); return; } - - if (cell->type == ID($_DFFSR_NNN_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_NNP_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_NPN_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_NPP_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_PNN_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_PNP_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_PPN_)) { check_gate("CSRDQ"); return; } - if (cell->type == ID($_DFFSR_PPP_)) { check_gate("CSRDQ"); return; } - - if (cell->type == ID($_DLATCH_N_)) { check_gate("EDQ"); return; } - if (cell->type == ID($_DLATCH_P_)) { check_gate("EDQ"); return; } - - if (cell->type == ID($_DLATCHSR_NNN_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_NNP_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_NPN_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_NPP_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_PNN_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_PNP_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_PPN_)) { check_gate("ESRDQ"); return; } - if (cell->type == ID($_DLATCHSR_PPP_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_BUF_)) { port(ID::A,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_NOT_)) { port(ID::A,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_AND_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_NAND_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_OR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_NOR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_XOR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_XNOR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_ANDNOT_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_ORNOT_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_MUX_)) { port(ID::A,1); port(ID::B,1); port(ID(S),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_NMUX_)) { port(ID::A,1); port(ID::B,1); port(ID(S),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_AOI3_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_OAI3_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_AOI4_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID(D),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_OAI4_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID(D),1); port(ID::Y,1); check_expected(); return; } + + if (cell->type == ID($_TBUF_)) { port(ID::A,1); port(ID::Y,1); port(ID(E),1); check_expected(); return; } + + if (cell->type == ID($_MUX4_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID(D),1); port(ID(S),1); port(ID(T),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_MUX8_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID(D),1); port(ID(E),1); port(ID(F),1); port(ID(G),1); port(ID(H),1); port(ID(S),1); port(ID(T),1); port(ID(U),1); port(ID::Y,1); check_expected(); return; } + if (cell->type == ID($_MUX16_)) { port(ID::A,1); port(ID::B,1); port(ID(C),1); port(ID(D),1); port(ID(E),1); port(ID(F),1); port(ID(G),1); port(ID(H),1); port(ID(I),1); port(ID(J),1); port(ID(K),1); port(ID(L),1); port(ID(M),1); port(ID(N),1); port(ID(O),1); port(ID(P),1); port(ID(S),1); port(ID(T),1); port(ID(U),1); port(ID(V),1); port(ID::Y,1); check_expected(); return; } + + if (cell->type == ID($_SR_NN_)) { port(ID(S),1); port(ID(R),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_SR_NP_)) { port(ID(S),1); port(ID(R),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_SR_PN_)) { port(ID(S),1); port(ID(R),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_SR_PP_)) { port(ID(S),1); port(ID(R),1); port(ID(Q),1); check_expected(); return; } + + if (cell->type == ID($_FF_)) { port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFF_N_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); check_expected(); return; } + if (cell->type == ID($_DFF_P_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); check_expected(); return; } + + if (cell->type == ID($_DFFE_NN_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(E),1); check_expected(); return; } + if (cell->type == ID($_DFFE_NP_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(E),1); check_expected(); return; } + if (cell->type == ID($_DFFE_PN_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(E),1); check_expected(); return; } + if (cell->type == ID($_DFFE_PP_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(E),1); check_expected(); return; } + + if (cell->type == ID($_DFF_NN0_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_NN1_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_NP0_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_NP1_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_PN0_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_PN1_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_PP0_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + if (cell->type == ID($_DFF_PP1_)) { port(ID(D),1); port(ID(Q),1); port(ID(C),1); port(ID(R),1); check_expected(); return; } + + if (cell->type == ID($_DFFSR_NNN_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_NNP_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_NPN_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_NPP_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_PNN_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_PNP_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_PPN_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DFFSR_PPP_)) { port(ID(C),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + + if (cell->type == ID($_DLATCH_N_)) { port(ID(E),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCH_P_)) { port(ID(E),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + + if (cell->type == ID($_DLATCHSR_NNN_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_NNP_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_NPN_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_NPP_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_PNN_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_PNP_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_PPN_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } + if (cell->type == ID($_DLATCHSR_PPP_)) { port(ID(E),1); port(ID(S),1); port(ID(R),1); port(ID(D),1); port(ID(Q),1); check_expected(); return; } error(__LINE__); } @@ -1494,11 +1479,10 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RTLIL::Module *mod; void operator()(RTLIL::SigSpec &sig) { - std::vector<RTLIL::SigChunk> chunks = sig.chunks(); - for (auto &c : chunks) + sig.pack(); + for (auto &c : sig.chunks_) if (c.wire != NULL) c.wire = mod->wires_.at(c.wire->name); - sig = chunks; } }; @@ -1588,30 +1572,26 @@ void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires) const pool<RTLIL::Wire*> *wires_p; void operator()(RTLIL::SigSpec &sig) { - std::vector<RTLIL::SigChunk> chunks = sig; - for (auto &c : chunks) + sig.pack(); + for (auto &c : sig.chunks_) if (c.wire != NULL && wires_p->count(c.wire)) { c.wire = module->addWire(NEW_ID, c.width); c.offset = 0; } - sig = chunks; } void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) { log_assert(GetSize(lhs) == GetSize(rhs)); - RTLIL::SigSpec new_lhs, new_rhs; + lhs.unpack(); + rhs.unpack(); for (int i = 0; i < GetSize(lhs); i++) { - RTLIL::SigBit lhs_bit = lhs[i]; - if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) - continue; - RTLIL::SigBit rhs_bit = rhs[i]; - if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire)) - continue; - new_lhs.append(lhs_bit); - new_rhs.append(rhs_bit); + RTLIL::SigBit &lhs_bit = lhs.bits_[i]; + RTLIL::SigBit &rhs_bit = rhs.bits_[i]; + if ((lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) || (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))) { + lhs_bit = State::Sx; + rhs_bit = State::Sx; + } } - lhs = new_lhs; - rhs = new_rhs; } }; @@ -1851,7 +1831,7 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth } #define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters[ID(A_SIGNED)] = is_signed; \ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ @@ -1861,7 +1841,7 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const std::string &src) { \ RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_y, is_signed, src); \ return sig_y; \ @@ -1878,7 +1858,7 @@ DEF_METHOD(LogicNot, 1, ID($logic_not)) #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters[ID(A_SIGNED)] = is_signed; \ cell->parameters[ID(B_SIGNED)] = is_signed; \ @@ -1891,7 +1871,7 @@ DEF_METHOD(LogicNot, 1, ID($logic_not)) cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ return sig_y; \ @@ -1920,7 +1900,7 @@ DEF_METHOD(LogicOr, 1, ID($logic_or)) #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters[ID(A_SIGNED)] = is_signed; \ cell->parameters[ID(B_SIGNED)] = false; \ @@ -1933,7 +1913,7 @@ DEF_METHOD(LogicOr, 1, ID($logic_or)) cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \ RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ return sig_y; \ @@ -1945,7 +1925,7 @@ DEF_METHOD(Sshr, sig_a.size(), ID($sshr)) #undef DEF_METHOD #define DEF_METHOD(_func, _type, _pmux) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters[ID(WIDTH)] = sig_a.size(); \ if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \ @@ -1956,7 +1936,7 @@ DEF_METHOD(Sshr, sig_a.size(), ID($sshr)) cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src) { \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src) { \ RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \ add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \ return sig_y; \ @@ -1966,20 +1946,20 @@ DEF_METHOD(Pmux, ID($pmux), 1) #undef DEF_METHOD #define DEF_METHOD_2(_func, _type, _P1, _P2) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, const std::string &src) { \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const std::string &src) { \ RTLIL::SigBit sig2 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2, src); \ return sig2; \ } #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ @@ -1987,13 +1967,13 @@ DEF_METHOD(Pmux, ID($pmux), 1) cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, const std::string &src) { \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \ RTLIL::SigBit sig3 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, src); \ return sig3; \ } #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ @@ -2002,13 +1982,13 @@ DEF_METHOD(Pmux, ID($pmux), 1) cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, const std::string &src) { \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \ RTLIL::SigBit sig4 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, sig4, src); \ return sig4; \ } #define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, RTLIL::SigBit sig5, const std::string &src) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SigBit &sig5, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ @@ -2018,7 +1998,7 @@ DEF_METHOD(Pmux, ID($pmux), 1) cell->set_src_attribute(src); \ return cell; \ } \ - RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, const std::string &src) { \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \ RTLIL::SigBit sig5 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \ return sig5; \ @@ -2044,7 +2024,7 @@ DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y) #undef DEF_METHOD_4 #undef DEF_METHOD_5 -RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed, const std::string &src) +RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed, bool b_signed, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($pow)); cell->parameters[ID(A_SIGNED)] = a_signed; @@ -2059,7 +2039,7 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R return cell; } -RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src) +RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($slice)); cell->parameters[ID(A_WIDTH)] = sig_a.size(); @@ -2071,7 +2051,7 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, return cell; } -RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src) +RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($concat)); cell->parameters[ID(A_WIDTH)] = sig_a.size(); @@ -2083,7 +2063,7 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a return cell; } -RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src) +RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($lut)); cell->parameters[ID(LUT)] = lut; @@ -2094,7 +2074,7 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, R return cell; } -RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src) +RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($tribuf)); cell->parameters[ID(WIDTH)] = sig_a.size(); @@ -2105,7 +2085,7 @@ RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a return cell; } -RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) +RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($assert)); cell->setPort(ID::A, sig_a); @@ -2114,7 +2094,7 @@ RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a return cell; } -RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) +RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($assume)); cell->setPort(ID::A, sig_a); @@ -2123,7 +2103,7 @@ RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a return cell; } -RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) +RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($live)); cell->setPort(ID::A, sig_a); @@ -2132,7 +2112,7 @@ RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, return cell; } -RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) +RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($fair)); cell->setPort(ID::A, sig_a); @@ -2141,7 +2121,7 @@ RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, return cell; } -RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) +RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($cover)); cell->setPort(ID::A, sig_a); @@ -2150,7 +2130,7 @@ RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, return cell; } -RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src) +RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($equiv)); cell->setPort(ID::A, sig_a); @@ -2160,7 +2140,7 @@ RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, return cell; } -RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($sr)); cell->parameters[ID(SET_POLARITY)] = set_polarity; @@ -2173,7 +2153,7 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, return cell; } -RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src) +RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($ff)); cell->parameters[ID(WIDTH)] = sig_q.size(); @@ -2183,7 +2163,7 @@ RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RT return cell; } -RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dff)); cell->parameters[ID(CLK_POLARITY)] = clk_polarity; @@ -2195,7 +2175,7 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, return cell; } -RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dffe)); cell->parameters[ID(CLK_POLARITY)] = clk_polarity; @@ -2209,8 +2189,8 @@ RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk return cell; } -RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dffsr)); cell->parameters[ID(CLK_POLARITY)] = clk_polarity; @@ -2226,7 +2206,7 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl return cell; } -RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, +RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($adff)); @@ -2242,7 +2222,7 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk return cell; } -RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dlatch)); cell->parameters[ID(EN_POLARITY)] = en_polarity; @@ -2254,8 +2234,8 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e return cell; } -RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dlatchsr)); cell->parameters[ID(EN_POLARITY)] = en_polarity; @@ -2271,7 +2251,7 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig return cell; } -RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src) +RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($_FF_)); cell->setPort(ID(D), sig_d); @@ -2280,7 +2260,7 @@ RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d return cell; } -RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); cell->setPort(ID(C), sig_clk); @@ -2290,7 +2270,7 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_ return cell; } -RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); cell->setPort(ID(C), sig_clk); @@ -2301,8 +2281,8 @@ RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig return cell; } -RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); cell->setPort(ID(C), sig_clk); @@ -2314,7 +2294,7 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si return cell; } -RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, +RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); @@ -2326,7 +2306,7 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig return cell; } -RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); cell->setPort(ID(E), sig_en); @@ -2336,8 +2316,8 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec s return cell; } -RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); cell->setPort(ID(E), sig_en); @@ -2505,14 +2485,9 @@ void RTLIL::Cell::unsetPort(RTLIL::IdString portname) void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal) { - auto conn_it = connections_.find(portname); - - if (conn_it == connections_.end()) { - connections_[portname] = RTLIL::SigSpec(); - conn_it = connections_.find(portname); - log_assert(conn_it != connections_.end()); - } else - if (conn_it->second == signal) + auto r = connections_.insert(portname); + auto conn_it = r.first; + if (!r.second && conn_it->second == signal) return; for (auto mon : module->monitors) @@ -2527,7 +2502,7 @@ void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal) log_backtrace("-X- ", yosys_xtrace-1); } - conn_it->second = signal; + conn_it->second = std::move(signal); } const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const @@ -2585,7 +2560,7 @@ void RTLIL::Cell::unsetParam(RTLIL::IdString paramname) void RTLIL::Cell::setParam(RTLIL::IdString paramname, RTLIL::Const value) { - parameters[paramname] = value; + parameters[paramname] = std::move(value); } const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const @@ -2723,7 +2698,7 @@ RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width) offset = 0; } -RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit) +RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit) { wire = bit.wire; offset = 0; @@ -2734,12 +2709,9 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit) width = 1; } -RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data) +RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) { - wire = sigchunk.wire; - data = sigchunk.data; - width = sigchunk.width; - offset = sigchunk.offset; + *this = sigchunk; } RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const @@ -2805,45 +2777,21 @@ RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts) width_ = 0; hash_ = 0; - std::vector<RTLIL::SigSpec> parts_vec(parts.begin(), parts.end()); - for (auto it = parts_vec.rbegin(); it != parts_vec.rend(); it++) - append(*it); + log_assert(parts.size() > 0); + auto ie = parts.begin(); + auto it = ie + parts.size() - 1; + while (it >= ie) + append(*it--); } -const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other) +RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other) { cover("kernel.rtlil.sigspec.assign"); width_ = other.width_; hash_ = other.hash_; chunks_ = other.chunks_; - bits_.clear(); - - if (!other.bits_.empty()) - { - RTLIL::SigChunk *last = NULL; - int last_end_offset = 0; - - for (auto &bit : other.bits_) { - if (last && bit.wire == last->wire) { - if (bit.wire == NULL) { - last->data.push_back(bit.data); - last->width++; - continue; - } else if (last_end_offset == bit.offset) { - last_end_offset++; - last->width++; - continue; - } - } - chunks_.push_back(bit); - last = &chunks_.back(); - last_end_offset = bit.offset + 1; - } - - check(); - } - + bits_ = other.bits_; return *this; } @@ -2851,7 +2799,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) { cover("kernel.rtlil.sigspec.init.const"); - chunks_.push_back(RTLIL::SigChunk(value)); + chunks_.emplace_back(value); width_ = chunks_.back().width; hash_ = 0; check(); @@ -2861,7 +2809,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) { cover("kernel.rtlil.sigspec.init.chunk"); - chunks_.push_back(chunk); + chunks_.emplace_back(chunk); width_ = chunks_.back().width; hash_ = 0; check(); @@ -2871,7 +2819,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) { cover("kernel.rtlil.sigspec.init.wire"); - chunks_.push_back(RTLIL::SigChunk(wire)); + chunks_.emplace_back(wire); width_ = chunks_.back().width; hash_ = 0; check(); @@ -2881,7 +2829,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) { cover("kernel.rtlil.sigspec.init.wire_part"); - chunks_.push_back(RTLIL::SigChunk(wire, offset, width)); + chunks_.emplace_back(wire, offset, width); width_ = chunks_.back().width; hash_ = 0; check(); @@ -2891,7 +2839,7 @@ RTLIL::SigSpec::SigSpec(const std::string &str) { cover("kernel.rtlil.sigspec.init.str"); - chunks_.push_back(RTLIL::SigChunk(str)); + chunks_.emplace_back(str); width_ = chunks_.back().width; hash_ = 0; check(); @@ -2901,7 +2849,7 @@ RTLIL::SigSpec::SigSpec(int val, int width) { cover("kernel.rtlil.sigspec.init.int"); - chunks_.push_back(RTLIL::SigChunk(val, width)); + chunks_.emplace_back(val, width); width_ = width; hash_ = 0; check(); @@ -2911,18 +2859,18 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) { cover("kernel.rtlil.sigspec.init.state"); - chunks_.push_back(RTLIL::SigChunk(bit, width)); + chunks_.emplace_back(bit, width); width_ = width; hash_ = 0; check(); } -RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) +RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width) { cover("kernel.rtlil.sigspec.init.bit"); if (bit.wire == NULL) - chunks_.push_back(RTLIL::SigChunk(bit.data, width)); + chunks_.emplace_back(bit.data, width); else for (int i = 0; i < width; i++) chunks_.push_back(bit); @@ -2931,47 +2879,47 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) check(); } -RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks) +RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigChunk> &chunks) { cover("kernel.rtlil.sigspec.init.stdvec_chunks"); width_ = 0; hash_ = 0; - for (auto &c : chunks) + for (const auto &c : chunks) append(c); check(); } -RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits) +RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigBit> &bits) { cover("kernel.rtlil.sigspec.init.stdvec_bits"); width_ = 0; hash_ = 0; - for (auto &bit : bits) - append_bit(bit); + for (const auto &bit : bits) + append(bit); check(); } -RTLIL::SigSpec::SigSpec(pool<RTLIL::SigBit> bits) +RTLIL::SigSpec::SigSpec(const pool<RTLIL::SigBit> &bits) { cover("kernel.rtlil.sigspec.init.pool_bits"); width_ = 0; hash_ = 0; - for (auto &bit : bits) - append_bit(bit); + for (const auto &bit : bits) + append(bit); check(); } -RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits) +RTLIL::SigSpec::SigSpec(const std::set<RTLIL::SigBit> &bits) { cover("kernel.rtlil.sigspec.init.stdset_bits"); width_ = 0; hash_ = 0; - for (auto &bit : bits) - append_bit(bit); + for (const auto &bit : bits) + append(bit); check(); } @@ -2981,7 +2929,7 @@ RTLIL::SigSpec::SigSpec(bool bit) width_ = 0; hash_ = 0; - append_bit(bit); + append(SigBit(bit)); check(); } @@ -3034,7 +2982,7 @@ void RTLIL::SigSpec::unpack() const that->bits_.reserve(that->width_); for (auto &c : that->chunks_) for (int i = 0; i < c.width; i++) - that->bits_.push_back(RTLIL::SigBit(c, i)); + that->bits_.emplace_back(c, i); that->chunks_.clear(); that->hash_ = 0; @@ -3299,14 +3247,14 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLI bits_match[i].wire == pattern_chunk.wire && bits_match[i].offset >= pattern_chunk.offset && bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width) - ret.append_bit(bits_other[i]); + ret.append(bits_other[i]); } else { for (int i = 0; i < width_; i++) if (bits_match[i].wire && bits_match[i].wire == pattern_chunk.wire && bits_match[i].offset >= pattern_chunk.offset && bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width) - ret.append_bit(bits_match[i]); + ret.append(bits_match[i]); } } @@ -3330,11 +3278,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const pool<RTLIL::SigBit> &pattern, const std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector(); for (int i = 0; i < width_; i++) if (bits_match[i].wire && pattern.count(bits_match[i])) - ret.append_bit(bits_other[i]); + ret.append(bits_other[i]); } else { for (int i = 0; i < width_; i++) if (bits_match[i].wire && pattern.count(bits_match[i])) - ret.append_bit(bits_match[i]); + ret.append(bits_match[i]); } ret.check(); @@ -3456,7 +3404,7 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) check(); } -void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) +void RTLIL::SigSpec::append(const RTLIL::SigBit &bit) { if (packed()) { @@ -3529,7 +3477,7 @@ void RTLIL::SigSpec::check() const int w = 0; for (size_t i = 0; i < chunks_.size(); i++) { - const RTLIL::SigChunk chunk = chunks_[i]; + const RTLIL::SigChunk &chunk = chunks_[i]; if (chunk.wire == NULL) { if (i > 0) log_assert(chunks_[i-1].wire != NULL); @@ -3768,11 +3716,11 @@ std::string RTLIL::SigSpec::as_string() const pack(); std::string str; + str.reserve(size()); for (size_t i = chunks_.size(); i > 0; i--) { const RTLIL::SigChunk &chunk = chunks_[i-1]; if (chunk.wire != NULL) - for (int j = 0; j < chunk.width; j++) - str += "?"; + str.append(chunk.width, '?'); else str += RTLIL::Const(chunk.data).as_string(); } @@ -3819,24 +3767,30 @@ RTLIL::SigBit RTLIL::SigSpec::as_bit() const return bits_[0]; } -bool RTLIL::SigSpec::match(std::string pattern) const +bool RTLIL::SigSpec::match(const char* pattern) const { cover("kernel.rtlil.sigspec.match"); - pack(); - std::string str = as_string(); - log_assert(pattern.size() == str.size()); + unpack(); + log_assert(int(strlen(pattern)) == GetSize(bits_)); - for (size_t i = 0; i < pattern.size(); i++) { - if (pattern[i] == ' ') + for (auto it = bits_.rbegin(); it != bits_.rend(); it++, pattern++) { + if (*pattern == ' ') continue; - if (pattern[i] == '*') { - if (str[i] != 'z' && str[i] != 'x') + if (*pattern == '*') { + if (*it != State::Sz && *it != State::Sx) return false; continue; } - if (pattern[i] != str[i]) - return false; + if (*pattern == '0') { + if (*it != State::S0) + return false; + } else + if (*pattern == '1') { + if (*it != State::S1) + return false; + } else + log_abort(); } return true; @@ -3860,6 +3814,7 @@ pool<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_pool() const pack(); pool<RTLIL::SigBit> sigbits; + sigbits.reserve(size()); for (auto &c : chunks_) for (int i = 0; i < c.width; i++) sigbits.insert(RTLIL::SigBit(c, i)); @@ -3900,6 +3855,7 @@ dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::S log_assert(width_ == other.width_); dict<RTLIL::SigBit, RTLIL::SigBit> new_map; + new_map.reserve(size()); for (int i = 0; i < width_; i++) new_map[bits_[i]] = other.bits_[i]; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 4afe4304f..a1754c8bd 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -379,13 +379,13 @@ namespace RTLIL extern dict<std::string, std::string> constpad; - static inline std::string escape_id(std::string str) { + static inline std::string escape_id(const std::string &str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') return "\\" + str; return str; } - static inline std::string unescape_id(std::string str) { + static inline std::string unescape_id(const std::string &str) { if (str.size() < 2) return str; if (str[0] != '\\') @@ -401,7 +401,7 @@ namespace RTLIL return unescape_id(str.str()); } - static inline const char *id2cstr(const RTLIL::IdString &str) { + static inline const char *id2cstr(RTLIL::IdString str) { return log_id(str); } @@ -606,7 +606,7 @@ struct RTLIL::Const bool as_bool() const; int as_int(bool is_signed = false) const; std::string as_string() const; - static Const from_string(std::string str); + static Const from_string(const std::string &str); std::string decode_string() const; @@ -678,7 +678,7 @@ struct RTLIL::SigChunk SigChunk(const std::string &str); SigChunk(int val, int width = 32); SigChunk(RTLIL::State bit, int width = 1); - SigChunk(RTLIL::SigBit bit); + SigChunk(const RTLIL::SigBit &bit); SigChunk(const RTLIL::SigChunk &sigchunk); RTLIL::SigChunk &operator =(const RTLIL::SigChunk &other) = default; @@ -758,11 +758,15 @@ private: unpack(); } + // Only used by Module::remove(const pool<Wire*> &wires) + // but cannot be more specific as it isn't yet declared + friend struct RTLIL::Module; + public: SigSpec(); SigSpec(const RTLIL::SigSpec &other); SigSpec(std::initializer_list<RTLIL::SigSpec> parts); - const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other); + RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other); SigSpec(const RTLIL::Const &value); SigSpec(const RTLIL::SigChunk &chunk); @@ -771,11 +775,11 @@ public: SigSpec(const std::string &str); SigSpec(int val, int width = 32); SigSpec(RTLIL::State bit, int width = 1); - SigSpec(RTLIL::SigBit bit, int width = 1); - SigSpec(std::vector<RTLIL::SigChunk> chunks); - SigSpec(std::vector<RTLIL::SigBit> bits); - SigSpec(pool<RTLIL::SigBit> bits); - SigSpec(std::set<RTLIL::SigBit> bits); + SigSpec(const RTLIL::SigBit &bit, int width = 1); + SigSpec(const std::vector<RTLIL::SigChunk> &chunks); + SigSpec(const std::vector<RTLIL::SigBit> &bits); + SigSpec(const pool<RTLIL::SigBit> &bits); + SigSpec(const std::set<RTLIL::SigBit> &bits); SigSpec(bool bit); SigSpec(RTLIL::SigSpec &&other) { @@ -845,7 +849,13 @@ public: RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); } void append(const RTLIL::SigSpec &signal); - void append_bit(const RTLIL::SigBit &bit); + inline void append(Wire *wire) { append(RTLIL::SigSpec(wire)); } + inline void append(const RTLIL::SigChunk &chunk) { append(RTLIL::SigSpec(chunk)); } + inline void append(const RTLIL::Const &const_) { append(RTLIL::SigSpec(const_)); } + + void append(const RTLIL::SigBit &bit); + inline void append(RTLIL::State state) { append(RTLIL::SigBit(state)); } + inline void append(bool bool_) { append(RTLIL::SigBit(bool_)); } void extend_u0(int width, bool is_signed = false); @@ -877,7 +887,7 @@ public: RTLIL::SigChunk as_chunk() const; RTLIL::SigBit as_bit() const; - bool match(std::string pattern) const; + bool match(const char* pattern) const; std::set<RTLIL::SigBit> to_sigbit_set() const; pool<RTLIL::SigBit> to_sigbit_pool() const; @@ -891,7 +901,7 @@ public: operator std::vector<RTLIL::SigChunk>() const { return chunks(); } operator std::vector<RTLIL::SigBit>() const { return bits(); } - RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; } + const RTLIL::SigBit &at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; } unsigned int hash() const { if (!hash_) updhash(); return hash_; }; @@ -946,7 +956,7 @@ struct RTLIL::Monitor virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } - virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, RTLIL::SigSpec&) { } + virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, const RTLIL::SigSpec&) { } virtual void notify_connect(RTLIL::Module*, const RTLIL::SigSig&) { } virtual void notify_connect(RTLIL::Module*, const std::vector<RTLIL::SigSig>&) { } virtual void notify_blackout(RTLIL::Module*) { } @@ -988,15 +998,15 @@ struct RTLIL::Design void remove(RTLIL::Module *module); void rename(RTLIL::Module *module, RTLIL::IdString new_name); - void scratchpad_unset(std::string varname); + void scratchpad_unset(const std::string &varname); - void scratchpad_set_int(std::string varname, int value); - void scratchpad_set_bool(std::string varname, bool value); - void scratchpad_set_string(std::string varname, std::string value); + void scratchpad_set_int(const std::string &varname, int value); + void scratchpad_set_bool(const std::string &varname, bool value); + void scratchpad_set_string(const std::string &varname, std::string value); - int scratchpad_get_int(std::string varname, int default_value = 0) const; - 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; + int scratchpad_get_int(const std::string &varname, int default_value = 0) const; + bool scratchpad_get_bool(const std::string &varname, bool default_value = false) const; + std::string scratchpad_get_string(const std::string &varname, const std::string &default_value = std::string()) const; void sort(); void check(); @@ -1072,10 +1082,10 @@ public: Module(); virtual ~Module(); - virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail = false); - virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail = false); + virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail = false); + virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false); virtual size_t count_id(RTLIL::IdString id); - virtual void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces); + virtual void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces); virtual void sort(); virtual void check(); @@ -1136,166 +1146,166 @@ public: // The add* methods create a cell and return the created cell. All signals must exist in advance. - RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addPos (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addNeg (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - - RTLIL::Cell* addAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - - RTLIL::Cell* addReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - - RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addShift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addShiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - - RTLIL::Cell* addLt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addLe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addEq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addNe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addEqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addNex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addGe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addGt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - - RTLIL::Cell* addAdd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addSub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addMul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addDiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addMod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addPow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = ""); - - RTLIL::Cell* addLogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addLogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - RTLIL::Cell* addLogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = ""); - - RTLIL::Cell* addMux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src = ""); - RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src = ""); - - RTLIL::Cell* addSlice (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src = ""); - RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src = ""); - RTLIL::Cell* addLut (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src = ""); - RTLIL::Cell* addTribuf (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src = ""); - RTLIL::Cell* addAssert (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = ""); - RTLIL::Cell* addAssume (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = ""); - RTLIL::Cell* addLive (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = ""); - RTLIL::Cell* addFair (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = ""); - RTLIL::Cell* addCover (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = ""); - RTLIL::Cell* addEquiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src = ""); - - RTLIL::Cell* addSr (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); - RTLIL::Cell* addFf (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src = ""); - RTLIL::Cell* addDff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDffe (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDffsr (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); - RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, + RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addPos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addNeg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + + RTLIL::Cell* addAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + + RTLIL::Cell* addReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + + RTLIL::Cell* addShl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addShr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addSshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addSshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addShift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addShiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + + RTLIL::Cell* addLt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addLe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addEq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addNe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addEqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addNex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addGe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addGt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + + RTLIL::Cell* addAdd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addSub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addMul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addDiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addMod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = ""); + + RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addLogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + RTLIL::Cell* addLogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = ""); + + RTLIL::Cell* addMux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + RTLIL::Cell* addPmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + + RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = ""); + RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = ""); + RTLIL::Cell* addTribuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + RTLIL::Cell* addAssert (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = ""); + RTLIL::Cell* addAssume (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = ""); + RTLIL::Cell* addLive (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = ""); + RTLIL::Cell* addFair (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = ""); + RTLIL::Cell* addCover (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = ""); + RTLIL::Cell* addEquiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + + RTLIL::Cell* addSr (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = ""); + RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); - - RTLIL::Cell* addBufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addNandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addNorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addXnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = ""); - RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = ""); - - RTLIL::Cell* addFfGate (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src = ""); - RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDffeGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDffsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); - RTLIL::Cell* addAdffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, + RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + + RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addNandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addOrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addNorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addXorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addXnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addAndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addOrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addMuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addNmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addOai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = ""); + + RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = ""); + RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, const std::string &src = ""); - RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, - RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); // The methods without the add* prefix create a cell and an output signal. They return the newly created output signal. - RTLIL::SigSpec Not (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Pos (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Bu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Neg (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - - RTLIL::SigSpec And (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Or (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Xor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Xnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - - RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec ReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec ReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec ReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - - RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Shift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Shiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - - RTLIL::SigSpec Lt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Eq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Ne (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Eqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Nex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Ge (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Gt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - - RTLIL::SigSpec Add (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Sub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Mul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Div (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Mod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Pow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = ""); - - RTLIL::SigSpec LogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec LogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec LogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = ""); - - RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src = ""); - RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src = ""); - - RTLIL::SigBit BufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, const std::string &src = ""); - RTLIL::SigBit NotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, const std::string &src = ""); - RTLIL::SigBit AndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit NandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit OrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit NorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit XorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit XnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); - RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); - RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); - RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = ""); - RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = ""); - RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = ""); - RTLIL::SigBit Oai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = ""); + RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Bu0 (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + + RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Or (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Xor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Xnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + + RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec ReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec ReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec ReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + + RTLIL::SigSpec Shl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Shr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Sshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Sshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Shift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Shiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + + RTLIL::SigSpec Lt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Le (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Eq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Ne (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Eqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Nex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Ge (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Gt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + + RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = ""); + + RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec LogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + RTLIL::SigSpec LogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); + + RTLIL::SigSpec Mux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = ""); + RTLIL::SigSpec Pmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = ""); + + RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = ""); + RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = ""); + RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit NandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit OrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit NorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit XorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit XnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit AndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit OrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = ""); + RTLIL::SigBit MuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = ""); + RTLIL::SigBit NmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = ""); + RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = ""); + RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = ""); + RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = ""); + RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = ""); RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = ""); RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = ""); @@ -1468,7 +1478,7 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } -inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;} +inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){ if (wire) offset = sigbit.offset; } inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const { if (wire == other.wire) diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 2517d6de3..c631fa481 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -39,7 +39,7 @@ struct SigPool bits.clear(); } - void add(RTLIL::SigSpec sig) + void add(const RTLIL::SigSpec &sig) { for (auto &bit : sig) if (bit.wire != NULL) @@ -52,7 +52,7 @@ struct SigPool bits.insert(bit); } - void del(RTLIL::SigSpec sig) + void del(const RTLIL::SigSpec &sig) { for (auto &bit : sig) if (bit.wire != NULL) @@ -65,7 +65,7 @@ struct SigPool bits.erase(bit); } - void expand(RTLIL::SigSpec from, RTLIL::SigSpec to) + void expand(const RTLIL::SigSpec &from, const RTLIL::SigSpec &to) { log_assert(GetSize(from) == GetSize(to)); for (int i = 0; i < GetSize(from); i++) { @@ -75,16 +75,16 @@ struct SigPool } } - RTLIL::SigSpec extract(RTLIL::SigSpec sig) + RTLIL::SigSpec extract(const RTLIL::SigSpec &sig) const { RTLIL::SigSpec result; for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit)) - result.append_bit(bit); + result.append(bit); return result; } - RTLIL::SigSpec remove(RTLIL::SigSpec sig) + RTLIL::SigSpec remove(const RTLIL::SigSpec &sig) const { RTLIL::SigSpec result; for (auto &bit : sig) @@ -93,12 +93,12 @@ struct SigPool return result; } - bool check(RTLIL::SigBit bit) + bool check(const RTLIL::SigBit &bit) const { return bit.wire != NULL && bits.count(bit); } - bool check_any(RTLIL::SigSpec sig) + bool check_any(const RTLIL::SigSpec &sig) const { for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit)) @@ -106,7 +106,7 @@ struct SigPool return false; } - bool check_all(RTLIL::SigSpec sig) + bool check_all(const RTLIL::SigSpec &sig) const { for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit) == 0) @@ -114,14 +114,14 @@ struct SigPool return true; } - RTLIL::SigSpec export_one() + RTLIL::SigSpec export_one() const { for (auto &bit : bits) return RTLIL::SigSpec(bit.first, bit.second); return RTLIL::SigSpec(); } - RTLIL::SigSpec export_all() + RTLIL::SigSpec export_all() const { pool<RTLIL::SigBit> sig; for (auto &bit : bits) @@ -153,67 +153,67 @@ struct SigSet bits.clear(); } - void insert(RTLIL::SigSpec sig, T data) + void insert(const RTLIL::SigSpec &sig, T data) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].insert(data); } - void insert(RTLIL::SigSpec sig, const std::set<T> &data) + void insert(const RTLIL::SigSpec& sig, const std::set<T> &data) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].insert(data.begin(), data.end()); } - void erase(RTLIL::SigSpec sig) + void erase(const RTLIL::SigSpec& sig) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].clear(); } - void erase(RTLIL::SigSpec sig, T data) + void erase(const RTLIL::SigSpec &sig, T data) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].erase(data); } - void erase(RTLIL::SigSpec sig, const std::set<T> &data) + void erase(const RTLIL::SigSpec &sig, const std::set<T> &data) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].erase(data.begin(), data.end()); } - void find(RTLIL::SigSpec sig, std::set<T> &result) + void find(const RTLIL::SigSpec &sig, std::set<T> &result) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) { auto &data = bits[bit]; result.insert(data.begin(), data.end()); } } - void find(RTLIL::SigSpec sig, pool<T> &result) + void find(const RTLIL::SigSpec &sig, pool<T> &result) { - for (auto &bit : sig) + for (const auto &bit : sig) if (bit.wire != NULL) { auto &data = bits[bit]; result.insert(data.begin(), data.end()); } } - std::set<T> find(RTLIL::SigSpec sig) + std::set<T> find(const RTLIL::SigSpec &sig) { std::set<T> result; find(sig, result); return result; } - bool has(RTLIL::SigSpec sig) + bool has(const RTLIL::SigSpec &sig) { for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit)) @@ -262,7 +262,7 @@ struct SigMap add(it.first, it.second); } - void add(RTLIL::SigSpec from, RTLIL::SigSpec to) + void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to) { log_assert(GetSize(from) == GetSize(to)); @@ -287,15 +287,21 @@ struct SigMap } } - void add(RTLIL::SigSpec sig) + void add(const RTLIL::SigBit &bit) { - for (auto &bit : sig) { - RTLIL::SigBit b = database.find(bit); - if (b.wire != nullptr) - database.promote(bit); - } + const auto &b = database.find(bit); + if (b.wire != nullptr) + database.promote(bit); + } + + void add(const RTLIL::SigSpec &sig) + { + for (const auto &bit : sig) + add(bit); } + inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); } + void apply(RTLIL::SigBit &bit) const { bit = database.find(bit); @@ -329,7 +335,7 @@ struct SigMap RTLIL::SigSpec allbits() const { RTLIL::SigSpec sig; - for (auto &bit : database) + for (const auto &bit : database) if (bit.wire != nullptr) sig.append(bit); return sig; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 4cb53f05d..6d64e2e90 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -1098,30 +1098,29 @@ static char *readline_obj_generator(const char *text, int state) if (design->selected_active_module.empty()) { - for (auto &it : design->modules_) - if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); + for (auto mod : design->modules()) + if (RTLIL::unescape_id(mod->name).compare(0, len, text) == 0) + obj_names.push_back(strdup(log_id(mod->name))); } - else - if (design->modules_.count(design->selected_active_module) > 0) + else if (design->module(design->selected_active_module) != nullptr) { - RTLIL::Module *module = design->modules_.at(design->selected_active_module); + RTLIL::Module *module = design->module(design->selected_active_module); - for (auto &it : module->wires_) - if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); + for (auto w : module->wires()) + if (RTLIL::unescape_id(w->name).compare(0, len, text) == 0) + obj_names.push_back(strdup(log_id(w->name))); for (auto &it : module->memories) if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); + obj_names.push_back(strdup(log_id(it.first))); - for (auto &it : module->cells_) - if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); + for (auto cell : module->cells()) + if (RTLIL::unescape_id(cell->name).compare(0, len, text) == 0) + obj_names.push_back(strdup(log_id(cell->name))); for (auto &it : module->processes) if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); + obj_names.push_back(strdup(log_id(it.first))); } std::sort(obj_names.begin(), obj_names.end()); diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 177bcd8a3..8c666ca1f 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -1371,24 +1371,39 @@ int ezSAT::onehot(const std::vector<int> &vec, bool max_only) if (max_only == false) formula.push_back(expression(OpOr, vec)); - // create binary vector - int num_bits = clog2(vec.size()); - std::vector<int> bits; - for (int k = 0; k < num_bits; k++) - bits.push_back(literal()); - - // add at-most-one clauses using binary encoding - for (size_t i = 0; i < vec.size(); i++) - for (int k = 0; k < num_bits; k++) { - std::vector<int> clause; - clause.push_back(NOT(vec[i])); - clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k])); - formula.push_back(expression(OpOr, clause)); - } + if (vec.size() < 8) + { + // fall-back to simple O(n^2) solution for small cases + for (size_t i = 0; i < vec.size(); i++) + for (size_t j = i+1; j < vec.size(); j++) { + std::vector<int> clause; + clause.push_back(NOT(vec[i])); + clause.push_back(NOT(vec[j])); + formula.push_back(expression(OpOr, clause)); + } + } + else + { + // create binary vector + int num_bits = clog2(vec.size()); + std::vector<int> bits; + for (int k = 0; k < num_bits; k++) + bits.push_back(literal()); + + // add at-most-one clauses using binary encoding + for (size_t i = 0; i < vec.size(); i++) + for (int k = 0; k < num_bits; k++) { + std::vector<int> clause; + clause.push_back(NOT(vec[i])); + clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k])); + formula.push_back(expression(OpOr, clause)); + } + } return expression(OpAnd, formula); } +#if 0 int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot) { // many-hot encoding using a simple sorting network @@ -1426,6 +1441,123 @@ int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot) return expression(OpAnd, formula); } +#else +static std::vector<int> lfsr_sym(ezSAT *that, const std::vector<int> &vec, int poly) +{ + std::vector<int> out; + + for (int i = 0; i < int(vec.size()); i++) + if ((poly & (1 << (i+1))) != 0) { + if (out.empty()) + out.push_back(vec.at(i)); + else + out.at(0) = that->XOR(out.at(0), vec.at(i)); + } + + for (int i = 0; i+1 < int(vec.size()); i++) + out.push_back(vec.at(i)); + + return out; +} + +static int lfsr_num(int vec, int poly, int cnt = 1) +{ + int mask = poly >> 1; + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; + + while (cnt-- > 0) { + int bits = vec & (poly >> 1); + bits = ((bits & 0xAAAAAAAA) >> 1) ^ (bits & 0x55555555); + bits = ((bits & 0x44444444) >> 2) ^ (bits & 0x11111111); + bits = ((bits & 0x10101010) >> 4) ^ (bits & 0x01010101); + bits = ((bits & 0x01000100) >> 8) ^ (bits & 0x00010001); + bits = ((bits & 0x00010000) >> 16) ^ (bits & 0x00000001); + vec = ((vec << 1) | bits) & mask; + } + + return vec; +} + +int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot) +{ + // many-hot encoding using LFSR as counter + + int poly = 0; + int nbits = 0; + + if (vec.size() < 3) { + poly = (1 << 2) | (1 << 1) | 1; + nbits = 2; + } else + if (vec.size() < 7) { + poly = (1 << 3) | (1 << 2) | 1; + nbits = 3; + } else + if (vec.size() < 15) { + poly = (1 << 4) | (1 << 3) | 1; + nbits = 4; + } else + if (vec.size() < 31) { + poly = (1 << 5) | (1 << 3) | 1; + nbits = 5; + } else + if (vec.size() < 63) { + poly = (1 << 6) | (1 << 5) | 1; + nbits = 6; + } else + if (vec.size() < 127) { + poly = (1 << 7) | (1 << 6) | 1; + nbits = 7; + } else + // if (vec.size() < 255) { + // poly = (1 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | 1; + // nbits = 8; + // } else + if (vec.size() < 511) { + poly = (1 << 9) | (1 << 5) | 1; + nbits = 9; + } else { + assert(0); + } + + std::vector<int> min_val; + std::vector<int> max_val; + + if (min_hot > 1) + min_val = vec_const_unsigned(lfsr_num(1, poly, min_hot), nbits); + + if (max_hot >= 0) + max_val = vec_const_unsigned(lfsr_num(1, poly, max_hot+1), nbits); + + std::vector<int> state = vec_const_unsigned(1, nbits); + + std::vector<int> match_min; + std::vector<int> match_max; + + if (min_hot == 1) + match_min = vec; + + for (int i = 0; i < int(vec.size()); i++) + { + state = vec_ite(vec[i], lfsr_sym(this, state, poly), state); + + if (!min_val.empty() && i+1 >= min_hot) + match_min.push_back(vec_eq(min_val, state)); + + if (!max_val.empty() && i >= max_hot) + match_max.push_back(vec_eq(max_val, state)); + } + + int min_matched = min_hot ? vec_reduce_or(match_min) : CONST_TRUE; + int max_matched = vec_reduce_or(match_max); + + return AND(min_matched, NOT(max_matched)); +} +#endif int ezSAT::ordered(const std::vector<int> &vec1, const std::vector<int> &vec2, bool allow_equal) { diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index cf3e46ace..8446e27b3 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -35,7 +35,7 @@ struct TraceMonitor : public RTLIL::Monitor log("#TRACE# Module delete: %s\n", log_id(module)); } - void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE + void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE { log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig)); } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index eb912cfd4..b33882595 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -120,8 +120,8 @@ struct MemoryShareWorker for (auto &cond : conditions) { RTLIL::SigSpec sig1, sig2; for (auto &it : cond) { - sig1.append_bit(it.first); - sig2.append_bit(it.second ? RTLIL::State::S1 : RTLIL::State::S0); + sig1.append(it.first); + sig2.append(it.second ? RTLIL::State::S1 : RTLIL::State::S0); } terms.append(module->Ne(NEW_ID, sig1, sig2)); created_conditions++; @@ -284,8 +284,8 @@ struct MemoryShareWorker std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_bits[i], v_mask_bits[i]); if (groups.count(key) == 0) { groups[key].first = grouped_bits.size(); - grouped_bits.append_bit(v_bits[i]); - grouped_mask_bits.append_bit(v_mask_bits[i]); + grouped_bits.append(v_bits[i]); + grouped_mask_bits.append(v_mask_bits[i]); } groups[key].second.push_back(i); } @@ -295,7 +295,7 @@ struct MemoryShareWorker for (int i = 0; i < bits.size(); i++) { std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_bits[i], v_mask_bits[i]); - result.append_bit(grouped_result.at(groups.at(key).first)); + result.append(grouped_result.at(groups.at(key).first)); } return result; @@ -326,7 +326,7 @@ struct MemoryShareWorker for (int i = 0; i < int(v_old_en.size()); i++) { std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_old_en[i], v_next_en[i]); - new_merged_en.append_bit(grouped_new_en.at(groups.at(key))); + new_merged_en.append(grouped_new_en.at(groups.at(key))); } // Create the new merged_data signal. @@ -635,8 +635,8 @@ struct MemoryShareWorker for (int j = 0; j < int(this_en.size()); j++) { std::pair<RTLIL::SigBit, RTLIL::SigBit> key(last_en[j], this_en[j]); if (!groups_en.count(key)) { - grouped_last_en.append_bit(last_en[j]); - grouped_this_en.append_bit(this_en[j]); + grouped_last_en.append(last_en[j]); + grouped_this_en.append(this_en[j]); groups_en[key] = grouped_en->width; grouped_en->width++; } @@ -665,11 +665,17 @@ struct MemoryShareWorker // Setup and run // ------------- - MemoryShareWorker(RTLIL::Design *design, RTLIL::Module *module) : - design(design), module(module), sigmap(module) + MemoryShareWorker(RTLIL::Design *design) : design(design), modwalker(design) {} + + void operator()(RTLIL::Module* module) { std::map<std::string, std::pair<std::vector<RTLIL::Cell*>, std::vector<RTLIL::Cell*>>> memindex; + this->module = module; + sigmap.set(module); + sig_to_mux.clear(); + conditions_logic_cache.clear(); + sigmap_xmux = sigmap; for (auto cell : module->cells()) { @@ -717,7 +723,7 @@ struct MemoryShareWorker cone_ct.cell_types.erase("$shift"); cone_ct.cell_types.erase("$shiftx"); - modwalker.setup(design, module, &cone_ct); + modwalker.setup(module, &cone_ct); for (auto &it : memindex) consolidate_wr_using_sat(it.first, it.second.second); @@ -755,8 +761,10 @@ struct MemorySharePass : public Pass { void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n"); extra_args(args, 1, design); + MemoryShareWorker msw(design); + for (auto module : design->selected_modules()) - MemoryShareWorker(design, module); + msw(module); } } MemorySharePass; diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index cac265a52..07f9ee2a0 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -203,8 +203,8 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPoo return !(w2->port_input && w2->port_output); if (w1->name[0] == '\\' && w2->name[0] == '\\') { - if (regs.check_any(s1) != regs.check_any(s2)) - return regs.check_any(s2); + if (regs.check(s1) != regs.check(s2)) + return regs.check(s2); if (direct_wires.count(w1) != direct_wires.count(w2)) return direct_wires.count(w2) != 0; if (conns.check_any(s1) != conns.check_any(s2)) @@ -358,8 +358,8 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos s2[i] = initval[i]; initval[i] = State::Sx; } - new_conn.first.append_bit(s1[i]); - new_conn.second.append_bit(s2[i]); + new_conn.first.append(s1[i]); + new_conn.second.append(s2[i]); } if (new_conn.first.size() > 0) { if (initval.is_fully_undef()) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 4a2f170b8..f9c5f68f2 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -31,9 +31,8 @@ PRIVATE_NAMESPACE_BEGIN bool did_something; -void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) +void replace_undriven(RTLIL::Module *module, const CellTypes &ct) { - CellTypes ct(design); SigMap sigmap(module); SigPool driven_signals; SigPool used_signals; @@ -193,11 +192,11 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ for (auto &it : grouped_bits[i]) { for (auto &bit : it.second) { - new_conn.first.append_bit(bit); - new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.size())); + new_conn.first.append(bit); + new_conn.second.append(RTLIL::SigBit(new_y, new_a.size())); } - new_a.append_bit(it.first.first); - new_b.append_bit(it.first.second); + new_a.append(it.first.first); + new_b.append(it.first.second); } if (cell->type.in(ID($and), ID($or)) && i == GRP_CONST_A) { @@ -496,6 +495,42 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } + if (cell->type.in(ID($_XOR_), ID($_XNOR_)) || (cell->type.in(ID($xor), ID($xnor)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())) + { + SigBit sig_a = assign_map(cell->getPort(ID::A)); + SigBit sig_b = assign_map(cell->getPort(ID::B)); + if (!sig_a.wire) + std::swap(sig_a, sig_b); + if (sig_b == State::S0 || sig_b == State::S1) { + if (cell->type.in(ID($xor), ID($_XOR_))) { + cover("opt.opt_expr.xor_buffer"); + SigSpec sig_y; + if (cell->type == ID($xor)) + sig_y = (sig_b == State::S1 ? module->Not(NEW_ID, sig_a).as_bit() : sig_a); + else if (cell->type == ID($_XOR_)) + sig_y = (sig_b == State::S1 ? module->NotGate(NEW_ID, sig_a) : sig_a); + else log_abort(); + replace_cell(assign_map, module, cell, "xor_buffer", ID::Y, sig_y); + goto next_cell; + } + if (cell->type.in(ID($xnor), ID($_XNOR_))) { + cover("opt.opt_expr.xnor_buffer"); + SigSpec sig_y; + if (cell->type == ID($xnor)) { + sig_y = (sig_b == State::S1 ? sig_a : module->Not(NEW_ID, sig_a).as_bit()); + int width = cell->getParam(ID(Y_WIDTH)).as_int(); + sig_y.append(RTLIL::Const(State::S1, width-1)); + } + else if (cell->type == ID($_XNOR_)) + sig_y = (sig_b == State::S1 ? sig_a : module->NotGate(NEW_ID, sig_a)); + else log_abort(); + replace_cell(assign_map, module, cell, "xnor_buffer", ID::Y, sig_y); + goto next_cell; + } + log_abort(); + } + } + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor), ID($neg)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) { @@ -651,10 +686,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons int i; for (i = 0; i < GetSize(sig_y); i++) { - if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) - module->connect(sig_y[i], sig_a[i]); - else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) - module->connect(sig_y[i], sig_b[i]); + RTLIL::SigBit b = sig_b.at(i, State::Sx); + RTLIL::SigBit a = sig_a.at(i, State::Sx); + if (b == State::S0 && a != State::Sx) + module->connect(sig_y[i], a); + else if (sub && b == State::S1 && a == State::S1) + module->connect(sig_y[i], State::S0); + else if (!sub && a == State::S0 && b != State::Sx) + module->connect(sig_y[i], b); else break; } @@ -668,7 +707,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (cell->type == "$alu") + if (cell->type == ID($alu)) { RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); @@ -678,9 +717,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons RTLIL::SigSpec sig_y = cell->getPort(ID::Y); RTLIL::SigSpec sig_co = cell->getPort(ID(CO)); - if (sig_ci.wire || sig_bi.wire) - goto next_cell; - bool sub = (sig_ci == State::S1 && sig_bi == State::S1); // If not a subtraction, yet there is a carry or B is inverted @@ -690,14 +726,21 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons int i; for (i = 0; i < GetSize(sig_y); i++) { - if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) { - module->connect(sig_x[i], sub ? module->Not(NEW_ID, sig_a[i]).as_bit() : sig_a[i]); + RTLIL::SigBit b = sig_b.at(i, State::Sx); + RTLIL::SigBit a = sig_a.at(i, State::Sx); + if (b == State::S0 && a != State::Sx) { module->connect(sig_y[i], sig_a[i]); + module->connect(sig_x[i], sub ? module->Not(NEW_ID, a).as_bit() : a); module->connect(sig_co[i], sub ? State::S1 : State::S0); } - else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) { - module->connect(sig_x[i], sig_b[i]); - module->connect(sig_y[i], sig_b[i]); + else if (sub && b == State::S1 && a == State::S1) { + module->connect(sig_y[i], State::S0); + module->connect(sig_x[i], module->Not(NEW_ID, a)); + module->connect(sig_co[i], State::S0); + } + else if (!sub && a == State::S0 && b != State::Sx) { + module->connect(sig_y[i], b); + module->connect(sig_x[i], b); module->connect(sig_co[i], State::S0); } else @@ -842,8 +885,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match("11")) ACTION_DO_Y(0); if (input.match(" *")) ACTION_DO_Y(x); if (input.match("* ")) ACTION_DO_Y(x); - if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1)); - if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } if (cell->type == ID($_MUX_)) { @@ -1032,12 +1073,26 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons bool identity_wrt_b = false; bool arith_inverse = false; - if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor))) + if (cell->type.in(ID($add), ID($sub), ID($alu), ID($or), ID($xor))) { RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); - if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false) + bool sub = cell->type == ID($sub); + + if (cell->type == ID($alu)) { + RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI))); + RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI))); + + sub = (sig_ci == State::S1 && sig_bi == State::S1); + + // If not a subtraction, yet there is a carry or B is inverted + // then no optimisation is possible as carry will not be constant + if (!sub && (sig_ci != State::S0 || sig_bi != State::S0)) + goto next_cell; + } + + if (!sub && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; if (b.is_fully_const() && b.as_bool() == false) @@ -1075,17 +1130,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (identity_wrt_a || identity_wrt_b) { if (identity_wrt_a) - cover_list("opt.opt_expr.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); + cover_list("opt.opt_expr.identwrt.a", "$add", "$sub", "$alu", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); if (identity_wrt_b) - cover_list("opt.opt_expr.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); + cover_list("opt.opt_expr.identwrt.b", "$add", "$sub", "$alu", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); + if (cell->type == ID($alu)) { + int y_width = GetSize(cell->getPort(ID(Y))); + module->connect(cell->getPort(ID(X)), RTLIL::Const(State::S0, y_width)); + module->connect(cell->getPort(ID(CO)), RTLIL::Const(State::S0, y_width)); + cell->unsetPort(ID(BI)); + cell->unsetPort(ID(CI)); + cell->unsetPort(ID(X)); + cell->unsetPort(ID(CO)); + } + if (!identity_wrt_a) { cell->setPort(ID::A, cell->getPort(ID::B)); - cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); - cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); + cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH))); + cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED))); } cell->type = arith_inverse ? ID($neg) : ID($pos); @@ -1590,7 +1655,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } int const_bit_set = get_highest_hot_index(const_sig); - if(const_bit_set >= var_width) + if (const_bit_set >= var_width) { string cmp_name; if (cmp_type == ID($lt) || cmp_type == ID($le)) @@ -1737,13 +1802,14 @@ struct OptExprPass : public Pass { } extra_args(args, argidx, design); + CellTypes ct(design); for (auto module : design->selected_modules()) { log("Optimizing module %s.\n", log_id(module)); if (undriven) { did_something = false; - replace_undriven(design, module); + replace_undriven(module, ct); if (did_something) design->scratchpad_set_bool("opt.did_something", true); } diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 8823a9061..4aa78ff39 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -26,7 +26,6 @@ #include <stdio.h> #include <set> -#define USE_CELL_HASH_CACHE USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -41,9 +40,7 @@ struct OptMergeWorker CellTypes ct; int total_count; -#ifdef USE_CELL_HASH_CACHE - dict<const RTLIL::Cell*, std::string> cell_hash_cache; -#endif + SHA1 checksum; static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn) { @@ -68,7 +65,6 @@ struct OptMergeWorker } } -#ifdef USE_CELL_HASH_CACHE std::string int_to_hash_string(unsigned int v) { if (v == 0) @@ -83,14 +79,9 @@ struct OptMergeWorker std::string hash_cell_parameters_and_connections(const RTLIL::Cell *cell) { - if (cell_hash_cache.count(cell) > 0) - return cell_hash_cache[cell]; - + vector<string> hash_conn_strings; std::string hash_string = cell->type.str() + "\n"; - for (auto &it : cell->parameters) - hash_string += "P " + it.first.str() + "=" + it.second.as_string() + "\n"; - const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections(); dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn; @@ -124,13 +115,22 @@ struct OptMergeWorker conn = &alt_conn; } - vector<string> hash_conn_strings; - for (auto &it : *conn) { - if (cell->output(it.first)) - continue; - RTLIL::SigSpec sig = it.second; - assign_map.apply(sig); + RTLIL::SigSpec sig; + if (cell->output(it.first)) { + if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || + cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || + cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) { + // For the 'Q' output of state elements, + // use its (* init *) attribute value + for (const auto &b : dff_init_map(it.second)) + sig.append(b.wire ? State::Sx : b); + } + else + continue; + } + else + sig = assign_map(it.second); string s = "C " + it.first.str() + "="; for (auto &chunk : sig.chunks()) { if (chunk.wire) @@ -143,50 +143,59 @@ struct OptMergeWorker hash_conn_strings.push_back(s + "\n"); } + for (auto &it : cell->parameters) + hash_conn_strings.push_back("P " + it.first.str() + "=" + it.second.as_string() + "\n"); + std::sort(hash_conn_strings.begin(), hash_conn_strings.end()); for (auto it : hash_conn_strings) hash_string += it; - cell_hash_cache[cell] = sha1(hash_string); - return cell_hash_cache[cell]; + checksum.update(hash_string); + return checksum.final(); } -#endif - bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2, bool <) + bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) { -#ifdef USE_CELL_HASH_CACHE - std::string hash1 = hash_cell_parameters_and_connections(cell1); - std::string hash2 = hash_cell_parameters_and_connections(cell2); - - if (hash1 != hash2) { - lt = hash1 < hash2; - return true; - } -#endif - - if (cell1->parameters != cell2->parameters) { - std::map<RTLIL::IdString, RTLIL::Const> p1(cell1->parameters.begin(), cell1->parameters.end()); - std::map<RTLIL::IdString, RTLIL::Const> p2(cell2->parameters.begin(), cell2->parameters.end()); - lt = p1 < p2; - return true; - } - - dict<RTLIL::IdString, RTLIL::SigSpec> conn1 = cell1->connections(); - dict<RTLIL::IdString, RTLIL::SigSpec> conn2 = cell2->connections(); - - for (auto &it : conn1) { - if (cell1->output(it.first)) - it.second = RTLIL::SigSpec(); - else - assign_map.apply(it.second); - } - - for (auto &it : conn2) { - if (cell2->output(it.first)) - it.second = RTLIL::SigSpec(); - else - assign_map.apply(it.second); + log_assert(cell1 != cell2); + if (cell1->type != cell2->type) return false; + + if (cell1->parameters != cell2->parameters) + return false; + + if (cell1->connections_.size() != cell2->connections_.size()) + return false; + for (const auto &it : cell1->connections_) + if (!cell2->connections_.count(it.first)) + return false; + + decltype(Cell::connections_) conn1, conn2; + conn1.reserve(cell1->connections_.size()); + conn2.reserve(cell1->connections_.size()); + + for (const auto &it : cell1->connections_) { + if (cell1->output(it.first)) { + if (it.first == ID(Q) && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") || + cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") || + cell1->type.in("$adff", "$sr", "$ff", "$_FF_"))) { + // For the 'Q' output of state elements, + // use the (* init *) attribute value + auto &sig1 = conn1[it.first]; + for (const auto &b : dff_init_map(it.second)) + sig1.append(b.wire ? State::Sx : b); + auto &sig2 = conn2[it.first]; + for (const auto &b : dff_init_map(cell2->getPort(it.first))) + sig2.append(b.wire ? State::Sx : b); + } + else { + conn1[it.first] = RTLIL::SigSpec(); + conn2[it.first] = RTLIL::SigSpec(); + } + } + else { + conn1[it.first] = assign_map(it.second); + conn2[it.first] = assign_map(cell2->getPort(it.first)); + } } if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) || @@ -215,54 +224,9 @@ struct OptMergeWorker sort_pmux_conn(conn2); } - if (conn1 != conn2) { - std::map<RTLIL::IdString, RTLIL::SigSpec> c1(conn1.begin(), conn1.end()); - std::map<RTLIL::IdString, RTLIL::SigSpec> c2(conn2.begin(), conn2.end()); - lt = c1 < c2; - return true; - } - - if (conn1.count(ID(Q)) != 0 && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") || - cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") || - cell1->type.in("$adff", "$sr", "$ff", "$_FF_"))) { - std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort(ID(Q))).to_sigbit_vector(); - std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort(ID(Q))).to_sigbit_vector(); - for (size_t i = 0; i < q1.size(); i++) - if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { - lt = q1.at(i) < q2.at(i); - return true; - } - } - - return false; + return conn1 == conn2; } - bool compare_cells(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) - { - if (cell1->type != cell2->type) - return cell1->type < cell2->type; - - if ((!mode_share_all && !ct.cell_known(cell1->type)) || !cell1->known()) - return cell1 < cell2; - - if (cell1->has_keep_attr() || cell2->has_keep_attr()) - return cell1 < cell2; - - bool lt; - if (compare_cell_parameters_and_connections(cell1, cell2, lt)) - return lt; - - return false; - } - - struct CompareCells { - OptMergeWorker *that; - CompareCells(OptMergeWorker *that) : that(that) {} - bool operator()(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) const { - return that->compare_cells(cell1, cell2); - } - }; - OptMergeWorker(RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux, bool mode_share_all) : design(design), module(module), assign_map(module), mode_share_all(mode_share_all) { @@ -299,9 +263,6 @@ struct OptMergeWorker bool did_something = true; while (did_something) { -#ifdef USE_CELL_HASH_CACHE - cell_hash_cache.clear(); -#endif std::vector<RTLIL::Cell*> cells; cells.reserve(module->cells_.size()); for (auto &it : module->cells_) { @@ -312,42 +273,51 @@ struct OptMergeWorker } did_something = false; - std::map<RTLIL::Cell*, RTLIL::Cell*, CompareCells> sharemap(CompareCells(this)); + dict<std::string, RTLIL::Cell*> sharemap; for (auto cell : cells) { - if (sharemap.count(cell) > 0) { - did_something = true; - log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str()); - for (auto &it : cell->connections()) { - if (cell->output(it.first)) { - RTLIL::SigSpec other_sig = sharemap[cell]->getPort(it.first); - log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), - log_signal(it.second), log_signal(other_sig)); - module->connect(RTLIL::SigSig(it.second, other_sig)); - assign_map.add(it.second, other_sig); - - if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || - cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || - cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) { - for (auto c : it.second.chunks()) { - auto jt = c.wire->attributes.find(ID(init)); - if (jt == c.wire->attributes.end()) - continue; - for (int i = c.offset; i < c.offset + c.width; i++) - jt->second[i] = State::Sx; + if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) + continue; + + auto hash = hash_cell_parameters_and_connections(cell); + auto r = sharemap.insert(std::make_pair(hash, cell)); + if (!r.second) { + if (compare_cell_parameters_and_connections(cell, r.first->second)) { + if (cell->has_keep_attr()) { + if (r.first->second->has_keep_attr()) + continue; + std::swap(r.first->second, cell); + } + + + did_something = true; + log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), r.first->second->name.c_str()); + for (auto &it : cell->connections()) { + if (cell->output(it.first)) { + RTLIL::SigSpec other_sig = r.first->second->getPort(it.first); + log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), + log_signal(it.second), log_signal(other_sig)); + module->connect(RTLIL::SigSig(it.second, other_sig)); + assign_map.add(it.second, other_sig); + + if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || + cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || + cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) { + for (auto c : it.second.chunks()) { + auto jt = c.wire->attributes.find(ID(init)); + if (jt == c.wire->attributes.end()) + continue; + for (int i = c.offset; i < c.offset + c.width; i++) + jt->second[i] = State::Sx; + } + dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second))); } - dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second))); } } + log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); + module->remove(cell); + total_count++; } - log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); -#ifdef USE_CELL_HASH_CACHE - cell_hash_cache.erase(cell); -#endif - module->remove(cell); - total_count++; - } else { - sharemap[cell] = cell; } } } diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index f74655d1c..fd734c387 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -192,13 +192,13 @@ struct OptReduceWorker if (all_tuple_bits_same) { - old_sig_conn.first.append_bit(sig_y.at(i)); - old_sig_conn.second.append_bit(sig_a.at(i)); + old_sig_conn.first.append(sig_y.at(i)); + old_sig_conn.second.append(sig_a.at(i)); } else if (consolidated_in_tuples_map.count(in_tuple)) { - old_sig_conn.first.append_bit(sig_y.at(i)); - old_sig_conn.second.append_bit(consolidated_in_tuples_map.at(in_tuple)); + old_sig_conn.first.append(sig_y.at(i)); + old_sig_conn.second.append(consolidated_in_tuples_map.at(in_tuple)); } else { diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 92b5794ac..a7fefc291 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -331,7 +331,7 @@ struct Pmux2ShiftxPass : public Pass { pair<SigSpec, Const> entry; for (auto it : bits) { - entry.first.append_bit(it.first); + entry.first.append(it.first); entry.second.bits.push_back(it.second); } @@ -352,7 +352,7 @@ struct Pmux2ShiftxPass : public Pass { pair<SigSpec, Const> entry; for (auto it : bits) { - entry.first.append_bit(it.first); + entry.first.append(it.first); entry.second.bits.push_back(it.second); } diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 92ce3fd11..c11381138 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -41,7 +41,8 @@ struct ShareWorkerConfig struct ShareWorker { - ShareWorkerConfig config; + const ShareWorkerConfig config; + int limit; pool<RTLIL::IdString> generic_ops; RTLIL::Design *design; @@ -49,7 +50,6 @@ struct ShareWorker CellTypes fwd_ct, cone_ct; ModWalker modwalker; - ModIndex mi; pool<RTLIL::Cell*> cells_to_remove; pool<RTLIL::Cell*> recursion_state; @@ -516,7 +516,7 @@ struct ShareWorker if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A); - new_a.append_bit(RTLIL::State::S0); + new_a.append(RTLIL::State::S0); unsigned_cell->setPort(ID::A, new_a); } unsigned_cell->parameters.at(ID(A_SIGNED)) = true; @@ -588,7 +588,7 @@ struct ShareWorker if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A); - new_a.append_bit(RTLIL::State::S0); + new_a.append(RTLIL::State::S0); unsigned_cell->setPort(ID::A, new_a); } unsigned_cell->parameters.at(ID(A_SIGNED)) = true; @@ -601,7 +601,7 @@ struct ShareWorker if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1; RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B); - new_b.append_bit(RTLIL::State::S0); + new_b.append(RTLIL::State::S0); unsigned_cell->setPort(ID::B, new_b); } unsigned_cell->parameters.at(ID(B_SIGNED)) = true; @@ -790,7 +790,7 @@ struct ShareWorker p.second.bits.clear(); for (auto &it : p_bits) { - p.first.append_bit(it.first); + p.first.append(it.first); p.second.bits.push_back(it.second); } @@ -906,14 +906,14 @@ struct ShareWorker if (used_in_a) for (auto p : c_patterns) { for (int i = 0; i < GetSize(sig_s); i++) - p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0); + p.first.append(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0); if (sort_check_activation_pattern(p)) activation_patterns_cache[cell].insert(p); } for (int idx : used_in_b_parts) for (auto p : c_patterns) { - p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1); + p.first.append(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1); if (sort_check_activation_pattern(p)) activation_patterns_cache[cell].insert(p); } @@ -948,7 +948,7 @@ struct ShareWorker RTLIL::SigSpec signal; for (auto &bit : all_bits) - signal.append_bit(bit); + signal.append(bit); return signal; } @@ -963,7 +963,7 @@ struct ShareWorker for (int i = 0; i < GetSize(p_first); i++) if (filter_bits.count(p_first[i]) == 0) { - new_p.first.append_bit(p_first[i]); + new_p.first.append(p_first[i]); new_p.second.bits.push_back(p.second.bits.at(i)); } @@ -1071,6 +1071,8 @@ struct ShareWorker ct.setup_internals(); ct.setup_stdcells(); + ModIndex mi(module); + pool<RTLIL::Cell*> queue, covered; queue.insert(cell); @@ -1117,13 +1119,9 @@ struct ShareWorker module->remove(cell); } - ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : - config(config), design(design), module(module), mi(module) + ShareWorker(ShareWorkerConfig config, RTLIL::Design* design) : + config(config), design(design), modwalker(design) { - #ifndef NDEBUG - bool before_scc = module_has_scc(); - #endif - generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end()); @@ -1140,8 +1138,27 @@ struct ShareWorker cone_ct.cell_types.erase(ID($shr)); cone_ct.cell_types.erase(ID($sshl)); cone_ct.cell_types.erase(ID($sshr)); + } - modwalker.setup(design, module); + void operator()(RTLIL::Module *module) { + this->module = module; + + #ifndef NDEBUG + bool before_scc = module_has_scc(); + #endif + + limit = config.limit; + modwalker.setup(module); + + cells_to_remove.clear(); + recursion_state.clear(); + topo_cell_drivers.clear(); + topo_bit_drivers.clear(); + exclusive_ctrls.clear(); + terminal_bits.clear(); + shareable_cells.clear(); + forbidden_controls_cache.clear(); + activation_patterns_cache.clear(); find_terminal_bits(); find_shareable_cells(); @@ -1399,8 +1416,8 @@ struct ShareWorker topo_cell_drivers[cell] = { supercell }; topo_cell_drivers[other_cell] = { supercell }; - if (config.limit > 0) - config.limit--; + if (limit > 0) + limit--; break; } @@ -1528,9 +1545,10 @@ struct SharePass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - ShareWorker(config, design, mod_it.second); + ShareWorker sw(config, design); + + for (auto module : design->selected_modules()) + sw(module); } } SharePass; diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 04b882db9..b5451849d 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -98,7 +98,7 @@ struct WreduceWorker SigSpec sig_removed; for (int i = GetSize(bits_removed)-1; i >= 0; i--) - sig_removed.append_bit(bits_removed[i]); + sig_removed.append(bits_removed[i]); if (GetSize(bits_removed) == GetSize(sig_y)) { log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc index d4aee9df0..caf938a74 100644 --- a/passes/proc/proc_prune.cc +++ b/passes/proc/proc_prune.cc @@ -93,7 +93,7 @@ struct PruneWorker for (int i = 0; i < GetSize(lhs); i++) { RTLIL::SigBit lhs_bit = lhs[i]; if (lhs_bit.wire && !assigned[lhs_bit]) { - conn.first.append_bit(lhs_bit); + conn.first.append(lhs_bit); conn.second.append(rhs.extract(i)); } } diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index f9e7783a9..24aba22f3 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -117,11 +117,11 @@ struct Clk2fflogicPass : public Pass { SigSpec clock_edge_pattern; if (clkpol) { - clock_edge_pattern.append_bit(State::S0); - clock_edge_pattern.append_bit(State::S1); + clock_edge_pattern.append(State::S0); + clock_edge_pattern.append(State::S1); } else { - clock_edge_pattern.append_bit(State::S1); - clock_edge_pattern.append_bit(State::S0); + clock_edge_pattern.append(State::S1); + clock_edge_pattern.append(State::S0); } SigSpec clock_edge = module->Eqx(NEW_ID, {clk, SigSpec(past_clk)}, clock_edge_pattern); @@ -257,11 +257,11 @@ struct Clk2fflogicPass : public Pass { SigSpec clock_edge_pattern; if (clkpol) { - clock_edge_pattern.append_bit(State::S0); - clock_edge_pattern.append_bit(State::S1); + clock_edge_pattern.append(State::S0); + clock_edge_pattern.append(State::S1); } else { - clock_edge_pattern.append_bit(State::S1); - clock_edge_pattern.append_bit(State::S0); + clock_edge_pattern.append(State::S1); + clock_edge_pattern.append(State::S0); } SigSpec clock_edge = module->Eqx(NEW_ID, {clk, SigSpec(past_clk)}, clock_edge_pattern); diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index 35d43b106..a7dce9c81 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -113,7 +113,7 @@ struct DeminoutPass : public Pass { { if (bits_numports[bit] > 1 || bits_inout.count(bit)) new_input = true, new_output = true; - if (bit == State::S0 || bit == State::S1) + if (!bit.wire) new_output = true; if (bits_written.count(bit)) { new_output = true; diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc index 11cfddcd9..92c52398c 100644 --- a/passes/techmap/extract_reduce.cc +++ b/passes/techmap/extract_reduce.cc @@ -286,7 +286,7 @@ struct ExtractReducePass : public Pass SigSpec input; for (auto b : input_pool) if (input_pool_intermed.count(b) == 0) - input.append_bit(b); + input.append(b); SigBit output = sigmap(head_cell->getPort(ID::Y)[0]); diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index a2ad87f7d..427b72a6a 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -1405,7 +1405,7 @@ struct FlowmapWorker RTLIL::SigSpec lut_a, lut_y = node; for (auto input_node : input_nodes) - lut_a.append_bit(input_node); + lut_a.append(input_node); lut_a.append(RTLIL::Const(State::Sx, minlut - input_nodes.size())); RTLIL::Cell *lut = module->addLut(NEW_ID, lut_a, lut_y, lut_table); diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 8b1862237..f754aecb8 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -229,11 +229,13 @@ struct IopadmapPass : public Pass { for (auto module : design->selected_modules()) { dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; + pool<SigSig> remove_conns; if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) { dict<SigBit, Cell *> tbuf_bits; pool<SigBit> driven_bits; + dict<SigBit, SigSig> z_conns; // Gather tristate buffers and always-on drivers. for (auto cell : module->cells()) @@ -252,8 +254,10 @@ struct IopadmapPass : public Pass { for (int i = 0; i < GetSize(conn.first); i++) { SigBit dstbit = conn.first[i]; SigBit srcbit = conn.second[i]; - if (!srcbit.wire && srcbit.data == State::Sz) + if (!srcbit.wire && srcbit.data == State::Sz) { + z_conns[dstbit] = conn; continue; + } driven_bits.insert(dstbit); } @@ -302,6 +306,8 @@ struct IopadmapPass : public Pass { // enable. en_sig = SigBit(State::S0); data_sig = SigBit(State::Sx); + if (z_conns.count(wire_bit)) + remove_conns.insert(z_conns[wire_bit]); } if (wire->port_input) @@ -454,6 +460,14 @@ struct IopadmapPass : public Pass { } } + if (!remove_conns.empty()) { + std::vector<SigSig> new_conns; + for (auto &conn : module->connections()) + if (!remove_conns.count(conn)) + new_conns.push_back(conn); + module->new_connections(new_conns); + } + for (auto &it : rewrite_bits) { RTLIL::Wire *wire = it.first; RTLIL::Wire *new_wire = module->addWire( diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 10001baaa..0a67d9dbe 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -906,8 +906,8 @@ struct TechmapWorker RTLIL::SigSig port_conn; for (auto &it : port_connmap) { - port_conn.first.append_bit(it.first); - port_conn.second.append_bit(it.second); + port_conn.first.append(it.first); + port_conn.second.append(it.second); } tpl->connect(port_conn); diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index b8aedaadf..59ada8bae 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -96,9 +96,9 @@ struct SynthIce40Pass : public ScriptPass log(" -abc9\n"); log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); - log(" -flowmap\n"); - log(" use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)\n"); - log("\n"); + log(" -flowmap\n"); + log(" use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); @@ -126,7 +126,7 @@ struct SynthIce40Pass : public ScriptPass abc2 = false; vpr = false; abc9 = false; - flowmap = false; + flowmap = false; device_opt = "hx"; } diff --git a/tests/arch/anlogic/fsm.ys b/tests/arch/anlogic/fsm.ys index 0bcc4e011..eb94177ad 100644 --- a/tests/arch/anlogic/fsm.ys +++ b/tests/arch/anlogic/fsm.ys @@ -10,9 +10,6 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd fsm # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT2 -select -assert-count 5 t:AL_MAP_LUT5 -select -assert-count 1 t:AL_MAP_LUT6 select -assert-count 6 t:AL_MAP_SEQ -select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT5 t:AL_MAP_LUT6 t:AL_MAP_SEQ %% t:* %D +select -assert-none t:AL_MAP_LUT* t:AL_MAP_SEQ %% t:* %D diff --git a/tests/arch/efinix/fsm.ys b/tests/arch/efinix/fsm.ys index a2db2ad98..aef720d46 100644 --- a/tests/arch/efinix/fsm.ys +++ b/tests/arch/efinix/fsm.ys @@ -10,7 +10,6 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd fsm # Constrain all select calls below inside the top module -select -assert-count 1 t:EFX_GBUFCE -select -assert-count 6 t:EFX_FF -select -assert-count 15 t:EFX_LUT4 +select -assert-count 1 t:EFX_GBUFCE +select -assert-count 6 t:EFX_FF select -assert-none t:EFX_GBUFCE t:EFX_FF t:EFX_LUT4 %% t:* %D diff --git a/tests/opt/opt_expr_alu.ys b/tests/opt/opt_expr_alu.ys new file mode 100644 index 000000000..a3361ca43 --- /dev/null +++ b/tests/opt/opt_expr_alu.ys @@ -0,0 +1,63 @@ +read_verilog <<EOT +module test(input a, output [1:0] y); +assign y = {a,1'b0} + 1'b1; +endmodule +EOT + +alumacc +equiv_opt opt_expr -fine +design -load postopt +select -assert-count 1 t:$pos +select -assert-count none t:$pos t:* %D + + +design -reset +read_verilog <<EOT +module test(input a, output [1:0] y); +assign y = {a,1'b1} + 1'b1; +endmodule +EOT + +alumacc +select -assert-count 1 t:$alu +select -assert-count none t:$alu t:* %D + + +design -reset +read_verilog <<EOT +module test(input a, output [1:0] y); +assign y = {a,1'b1} - 1'b1; +endmodule +EOT + +equiv_opt opt_expr -fine +design -load postopt +select -assert-count 1 t:$pos +select -assert-count none t:$pos t:* %D + + +design -reset +read_verilog <<EOT +module test(input a, output [3:0] y); +assign y = {a,3'b101} - 1'b1; +endmodule +EOT + +equiv_opt opt_expr -fine +design -load postopt +select -assert-count 1 t:$pos +select -assert-count none t:$pos t:* %D + + +design -reset +read_verilog <<EOT +module test(input a, output [3:0] y); +assign y = {a,3'b101} - 1'b1; +endmodule +EOT + +alumacc +equiv_opt opt_expr -fine +design -load postopt +select -assert-count 1 t:$pos +select -assert-count none t:$pos t:* %D diff --git a/tests/opt/opt_expr_xor.ys b/tests/opt/opt_expr_xor.ys new file mode 100644 index 000000000..21439fd53 --- /dev/null +++ b/tests/opt/opt_expr_xor.ys @@ -0,0 +1,52 @@ +read_verilog <<EOT +module top(input a, output [3:0] y); +assign y[0] = a^1'b0; +assign y[1] = 1'b1^a; +assign y[2] = a~^1'b0; +assign y[3] = 1'b1^~a; +endmodule +EOT +design -save read +select -assert-count 2 t:$xor +select -assert-count 2 t:$xnor + +equiv_opt opt_expr +design -load postopt +select -assert-none t:$xor +select -assert-none t:$xnor +select -assert-count 2 t:$not + + +design -load read +simplemap +equiv_opt opt_expr +design -load postopt +select -assert-none t:$_XOR_ +select -assert-none t:$_XNOR_ # NB: simplemap does $xnor -> $_XOR_+$_NOT_ +select -assert-count 3 t:$_NOT_ + + +design -reset +read_verilog -icells <<EOT +module top(input a, output [1:0] y); +$_XNOR_ u0(.A(a), .B(1'b0), .Y(y[0])); +$_XNOR_ u1(.A(1'b1), .B(a), .Y(y[1])); +endmodule +EOT +select -assert-count 2 t:$_XNOR_ +equiv_opt opt_expr +design -load postopt +select -assert-none t:$_XNOR_ # NB: simplemap does $xnor -> $_XOR_+$_NOT_ +select -assert-count 1 t:$_NOT_ + + +design -reset +read_verilog <<EOT +module top(input a, output [1:0] w, x, y, z); +assign w = a^1'b0; +assign x = a^1'b1; +assign y = a~^1'b0; +assign z = a~^1'b1; +endmodule +EOT +equiv_opt opt_expr diff --git a/tests/opt/opt_merge_init.ys b/tests/opt/opt_merge_init.ys index a29c29df6..0176f09c7 100644 --- a/tests/opt/opt_merge_init.ys +++ b/tests/opt/opt_merge_init.ys @@ -20,6 +20,7 @@ endmodule EOT opt_merge +select -assert-count 1 t:$dff select -assert-count 1 a:init=1'0 @@ -46,4 +47,31 @@ endmodule EOT opt_merge +select -assert-count 1 t:$dff select -assert-count 1 a:init=2'bx1 + + +design -reset +read_verilog -icells <<EOT +module top(input clk, i, (* init = 1'b0 *) output o, /* NB: no init here! */ output p); + \$dff #( + .CLK_POLARITY(1'h1), + .WIDTH(32'd1) + ) ffo ( + .CLK(clk), + .D(i), + .Q(o) + ); + \$dff #( + .CLK_POLARITY(1'h1), + .WIDTH(32'd1) + ) ffp ( + .CLK(clk), + .D(i), + .Q(p) + ); +endmodule +EOT + +opt_merge +select -assert-count 2 t:$dff diff --git a/tests/opt/opt_merge_keep.ys b/tests/opt/opt_merge_keep.ys new file mode 100644 index 000000000..2a9202901 --- /dev/null +++ b/tests/opt/opt_merge_keep.ys @@ -0,0 +1,64 @@ +read_verilog -icells <<EOT +module top(input clk, i, output o, p); + (* keep *) + \$_DFF_P_ ffo ( + .C(clk), + .D(i), + .Q(o) + ); + \$_DFF_P_ ffp ( + .C(clk), + .D(i), + .Q(p) + ); +endmodule +EOT + +opt_merge +select -assert-count 1 t:$_DFF_P_ +select -assert-count 1 a:keep + + +design -reset +read_verilog -icells <<EOT +module top(input clk, i, output o, p); + \$_DFF_P_ ffo ( + .C(clk), + .D(i), + .Q(o) + ); + (* keep *) + \$_DFF_P_ ffp ( + .C(clk), + .D(i), + .Q(p) + ); +endmodule +EOT + +opt_merge +select -assert-count 1 t:$_DFF_P_ +select -assert-count 1 a:keep + + +design -reset +read_verilog -icells <<EOT +module top(input clk, i, output o, p); + (* keep *) + \$_DFF_P_ ffo ( + .C(clk), + .D(i), + .Q(o) + ); + (* keep *) + \$_DFF_P_ ffp ( + .C(clk), + .D(i), + .Q(p) + ); +endmodule +EOT + +opt_merge +select -assert-count 2 t:$_DFF_P_ +select -assert-count 2 a:keep diff --git a/tests/simple/dynslice.v b/tests/simple/dynslice.v new file mode 100644 index 000000000..7236ac3a5 --- /dev/null +++ b/tests/simple/dynslice.v @@ -0,0 +1,12 @@ +module dynslice ( + input clk , + input [9:0] ctrl , + input [15:0] din , + input [3:0] sel , + output reg [127:0] dout +); +always @(posedge clk) +begin + dout[ctrl*sel+:16] <= din ; +end +endmodule diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys index 25ea94dfc..df029b3a0 100644 --- a/tests/techmap/iopadmap.ys +++ b/tests/techmap/iopadmap.ys @@ -55,13 +55,19 @@ obuf b (.i(i), .o(tmp)); assign o = tmp; endmodule +module k(inout o, o2); +assign o = 1'bz; +endmodule + EOT opt_clean tribuf simplemap -iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j +iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j k opt_clean +hierarchy -check +check select -assert-count 1 a/t:ibuf select -assert-count 1 a/t:obuf @@ -140,6 +146,8 @@ select -assert-count 0 i/t:obuf select -assert-count 1 j/t:ibuf select -assert-count 1 j/t:obuf +select -assert-count 2 k/t:iobuf + # Check that \init attributes get moved from output buffer # to buffer input |