From: Eddie Hung Date: Wed, 13 Feb 2019 00:25:22 +0000 (-0800) Subject: Rip out unused functions in abc9 X-Git-Tag: working-ls180~1237^2~343 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=045f7763ae6adf406c3350c095ed6c224d1972c7;p=yosys.git Rip out unused functions in abc9 --- diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1b4254a53..19b94641b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -117,216 +117,6 @@ bool clk_polarity, en_polarity; RTLIL::SigSpec clk_sig, en_sig; dict pi_map, po_map; -int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1) -{ - assign_map.apply(bit); - - if (signal_map.count(bit) == 0) { - gate_t gate; - gate.id = signal_list.size(); - gate.type = G(NONE); - gate.in1 = -1; - gate.in2 = -1; - gate.in3 = -1; - gate.in4 = -1; - gate.is_port = false; - gate.bit = bit; - if (signal_init.count(bit)) - gate.init = signal_init.at(bit); - else - gate.init = State::Sx; - signal_list.push_back(gate); - signal_map[bit] = gate.id; - } - - gate_t &gate = signal_list[signal_map[bit]]; - - if (gate_type != G(NONE)) - gate.type = gate_type; - if (in1 >= 0) - gate.in1 = in1; - if (in2 >= 0) - gate.in2 = in2; - if (in3 >= 0) - gate.in3 = in3; - if (in4 >= 0) - gate.in4 = in4; - - return gate.id; -} - -void mark_port(RTLIL::SigSpec sig) -{ - for (auto &bit : assign_map(sig)) - if (bit.wire != NULL && signal_map.count(bit) > 0) - signal_list[signal_map[bit]].is_port = true; -} - -void extract_cell(RTLIL::Cell *cell, bool keepff) -{ - if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") - { - if (clk_polarity != (cell->type == "$_DFF_P_")) - return; - if (clk_sig != assign_map(cell->getPort("\\C"))) - return; - if (GetSize(en_sig) != 0) - return; - goto matching_dff; - } - - if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") - { - if (clk_polarity != (cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_")) - return; - if (en_polarity != (cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_")) - return; - if (clk_sig != assign_map(cell->getPort("\\C"))) - return; - if (en_sig != assign_map(cell->getPort("\\E"))) - return; - goto matching_dff; - } - - if (0) { - matching_dff: - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); - - if (keepff) - for (auto &c : sig_q.chunks()) - if (c.wire != NULL) - c.wire->attributes["\\keep"] = 1; - - assign_map.apply(sig_d); - assign_map.apply(sig_q); - - map_signal(sig_q, G(FF), map_signal(sig_d)); - - module->remove(cell); - return; - } - - if (cell->type.in("$_BUF_", "$_NOT_")) - { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - - assign_map.apply(sig_a); - assign_map.apply(sig_y); - - map_signal(sig_y, cell->type == "$_BUF_" ? G(BUF) : G(NOT), map_signal(sig_a)); - - module->remove(cell); - return; - } - - if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) - { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - - assign_map.apply(sig_a); - assign_map.apply(sig_b); - assign_map.apply(sig_y); - - int mapped_a = map_signal(sig_a); - int mapped_b = map_signal(sig_b); - - if (cell->type == "$_AND_") - map_signal(sig_y, G(AND), mapped_a, mapped_b); - else if (cell->type == "$_NAND_") - map_signal(sig_y, G(NAND), mapped_a, mapped_b); - else if (cell->type == "$_OR_") - map_signal(sig_y, G(OR), mapped_a, mapped_b); - else if (cell->type == "$_NOR_") - map_signal(sig_y, G(NOR), mapped_a, mapped_b); - else if (cell->type == "$_XOR_") - map_signal(sig_y, G(XOR), mapped_a, mapped_b); - else if (cell->type == "$_XNOR_") - map_signal(sig_y, G(XNOR), mapped_a, mapped_b); - else if (cell->type == "$_ANDNOT_") - map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b); - else if (cell->type == "$_ORNOT_") - map_signal(sig_y, G(ORNOT), mapped_a, mapped_b); - else - log_abort(); - - module->remove(cell); - return; - } - - if (cell->type == "$_MUX_") - { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_s = cell->getPort("\\S"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - - assign_map.apply(sig_a); - assign_map.apply(sig_b); - assign_map.apply(sig_s); - assign_map.apply(sig_y); - - int mapped_a = map_signal(sig_a); - int mapped_b = map_signal(sig_b); - int mapped_s = map_signal(sig_s); - - map_signal(sig_y, G(MUX), mapped_a, mapped_b, mapped_s); - - module->remove(cell); - return; - } - - if (cell->type.in("$_AOI3_", "$_OAI3_")) - { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_c = cell->getPort("\\C"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - - assign_map.apply(sig_a); - assign_map.apply(sig_b); - assign_map.apply(sig_c); - assign_map.apply(sig_y); - - int mapped_a = map_signal(sig_a); - int mapped_b = map_signal(sig_b); - int mapped_c = map_signal(sig_c); - - map_signal(sig_y, cell->type == "$_AOI3_" ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); - - module->remove(cell); - return; - } - - if (cell->type.in("$_AOI4_", "$_OAI4_")) - { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_c = cell->getPort("\\C"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - - assign_map.apply(sig_a); - assign_map.apply(sig_b); - assign_map.apply(sig_c); - assign_map.apply(sig_d); - assign_map.apply(sig_y); - - int mapped_a = map_signal(sig_a); - int mapped_b = map_signal(sig_b); - int mapped_c = map_signal(sig_c); - int mapped_d = map_signal(sig_d); - - map_signal(sig_y, cell->type == "$_AOI4_" ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); - - module->remove(cell); - return; - } -} - std::string remap_name(RTLIL::IdString abc_name) { std::stringstream sstr; @@ -334,168 +124,6 @@ std::string remap_name(RTLIL::IdString abc_name) return sstr.str(); } -void dump_loop_graph(FILE *f, int &nr, std::map> &edges, std::set &workpool, std::vector &in_counts) -{ - if (f == NULL) - return; - - log("Dumping loop state graph to slide %d.\n", ++nr); - - fprintf(f, "digraph \"slide%d\" {\n", nr); - fprintf(f, " label=\"slide%d\";\n", nr); - fprintf(f, " rankdir=\"TD\";\n"); - - std::set nodes; - for (auto &e : edges) { - nodes.insert(e.first); - for (auto n : e.second) - nodes.insert(n); - } - - for (auto n : nodes) - fprintf(f, " n%d [label=\"%s\\nid=%d, count=%d\"%s];\n", n, log_signal(signal_list[n].bit), - n, in_counts[n], workpool.count(n) ? ", shape=box" : ""); - - for (auto &e : edges) - for (auto n : e.second) - fprintf(f, " n%d -> n%d;\n", e.first, n); - - fprintf(f, "}\n"); -} - -void handle_loops() -{ - // http://en.wikipedia.org/wiki/Topological_sorting - // (Kahn, Arthur B. (1962), "Topological sorting of large networks") - - std::map> edges; - std::vector in_edges_count(signal_list.size()); - std::set workpool; - - FILE *dot_f = NULL; - int dot_nr = 0; - - // uncomment for troubleshooting the loop detection code - // dot_f = fopen("test.dot", "w"); - - for (auto &g : signal_list) { - if (g.type == G(NONE) || g.type == G(FF)) { - workpool.insert(g.id); - } else { - if (g.in1 >= 0) { - edges[g.in1].insert(g.id); - in_edges_count[g.id]++; - } - if (g.in2 >= 0 && g.in2 != g.in1) { - edges[g.in2].insert(g.id); - in_edges_count[g.id]++; - } - if (g.in3 >= 0 && g.in3 != g.in2 && g.in3 != g.in1) { - edges[g.in3].insert(g.id); - in_edges_count[g.id]++; - } - if (g.in4 >= 0 && g.in4 != g.in3 && g.in4 != g.in2 && g.in4 != g.in1) { - edges[g.in4].insert(g.id); - in_edges_count[g.id]++; - } - } - } - - dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); - - while (workpool.size() > 0) - { - int id = *workpool.begin(); - workpool.erase(id); - - // log("Removing non-loop node %d from graph: %s\n", id, log_signal(signal_list[id].bit)); - - for (int id2 : edges[id]) { - log_assert(in_edges_count[id2] > 0); - if (--in_edges_count[id2] == 0) - workpool.insert(id2); - } - edges.erase(id); - - dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); - - while (workpool.size() == 0) - { - if (edges.size() == 0) - break; - - int id1 = edges.begin()->first; - - for (auto &edge_it : edges) { - int id2 = edge_it.first; - RTLIL::Wire *w1 = signal_list[id1].bit.wire; - RTLIL::Wire *w2 = signal_list[id2].bit.wire; - if (w1 == NULL) - id1 = id2; - else if (w2 == NULL) - continue; - else if (w1->name[0] == '$' && w2->name[0] == '\\') - id1 = id2; - else if (w1->name[0] == '\\' && w2->name[0] == '$') - continue; - else if (edges[id1].size() < edges[id2].size()) - id1 = id2; - else if (edges[id1].size() > edges[id2].size()) - continue; - else if (w2->name.str() < w1->name.str()) - id1 = id2; - } - - if (edges[id1].size() == 0) { - edges.erase(id1); - continue; - } - - log_assert(signal_list[id1].bit.wire != NULL); - - std::stringstream sstr; - sstr << "$abcloop$" << (autoidx++); - RTLIL::Wire *wire = module->addWire(sstr.str()); - - bool first_line = true; - for (int id2 : edges[id1]) { - if (first_line) - log("Breaking loop using new signal %s: %s -> %s\n", log_signal(RTLIL::SigSpec(wire)), - log_signal(signal_list[id1].bit), log_signal(signal_list[id2].bit)); - else - log(" %*s %s -> %s\n", int(strlen(log_signal(RTLIL::SigSpec(wire)))), "", - log_signal(signal_list[id1].bit), log_signal(signal_list[id2].bit)); - first_line = false; - } - - int id3 = map_signal(RTLIL::SigSpec(wire)); - signal_list[id1].is_port = true; - signal_list[id3].is_port = true; - log_assert(id3 == int(in_edges_count.size())); - in_edges_count.push_back(0); - workpool.insert(id3); - - for (int id2 : edges[id1]) { - if (signal_list[id2].in1 == id1) - signal_list[id2].in1 = id3; - if (signal_list[id2].in2 == id1) - signal_list[id2].in2 = id3; - if (signal_list[id2].in3 == id1) - signal_list[id2].in3 = id3; - if (signal_list[id2].in4 == id1) - signal_list[id2].in4 = id3; - } - edges[id1].swap(edges[id3]); - - module->connect(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); - dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); - } - } - - if (dot_f != NULL) - fclose(dot_f); -} - std::string add_echos_to_abc_cmd(std::string str) { std::string new_str, token; @@ -675,7 +303,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n", module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); - std::string abc_script = stringf("&read %s/input.xaig; ", tempdir_name.c_str()); + std::string abc_script = stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); if (!liberty_file.empty()) { abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); @@ -729,7 +357,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (size_t pos = abc_script.find("{S}"); pos != std::string::npos; pos = abc_script.find("{S}", pos)) abc_script = abc_script.substr(0, pos) + lutin_shared + abc_script.substr(pos+3); - abc_script += stringf("; &write -v %s/output.xaig", tempdir_name.c_str()); + abc_script += stringf("; &ps; &write -v %s/output.xaig", tempdir_name.c_str()); abc_script = add_echos_to_abc_cmd(abc_script); for (size_t i = 0; i+1 < abc_script.size(); i++) @@ -752,27 +380,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } - for (auto c : cells) - extract_cell(c, keepff); - - for (auto &wire_it : module->wires_) { - if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute("\\keep")) - mark_port(RTLIL::SigSpec(wire_it.second)); - } - - for (auto &cell_it : module->cells_) - for (auto &port_it : cell_it.second->connections()) - mark_port(port_it.second); - - if (clk_sig.size() != 0) - mark_port(clk_sig); - - if (en_sig.size() != 0) - mark_port(en_sig); - - handle_loops(); - - Pass::call(design, stringf("aigmap; write_xaiger %s/input.xaig", tempdir_name.c_str())); + Pass::call(design, stringf("aigmap; write_xaiger -map %s/input.symbols %s/input.xaig; ", tempdir_name.c_str(), tempdir_name.c_str())); log_push(); @@ -865,8 +473,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri bool builtin_lib = liberty_file.empty(); RTLIL::Design *mapped_design = new RTLIL::Design; //parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_", false, sop_mode); - AigerReader reader(mapped_design, ifs, "\\netlist", "\\clk"); - reader.parse_aiger(); + buffer = stringf("%s/%s", tempdir_name.c_str(), "input.symbols"); + AigerReader reader(mapped_design, ifs, "\\netlist", "\\clk", buffer, true /* wideports */); + reader.parse_xaiger(); ifs.close(); @@ -876,7 +485,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_error("ABC output file does not contain a module `netlist'.\n"); for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; - RTLIL::Wire *wire = module->addWire(remap_name(w->name)); + RTLIL::Wire *wire = module->addWire(remap_name(w->name), GetSize(w)); if (markgroups) wire->attributes["\\abcgroup"] = map_autoidx; design->select(module, wire); } @@ -1079,10 +688,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } for (auto conn : mapped_mod->connections()) { - if (!conn.first.is_fully_const()) - conn.first = RTLIL::SigSpec(module->wires_[remap_name(conn.first.as_wire()->name)]); - if (!conn.second.is_fully_const()) - conn.second = RTLIL::SigSpec(module->wires_[remap_name(conn.second.as_wire()->name)]); + if (!conn.first.is_fully_const()) { + auto chunks = conn.first.chunks(); + for (auto &c : chunks) + c.wire = module->wires_[remap_name(c.wire->name)]; + conn.first = std::move(chunks); + } + if (!conn.second.is_fully_const() && conn.second.is_wire()) { + auto chunks = conn.second.chunks(); + for (auto &c : chunks) + c.wire = module->wires_[remap_name(c.wire->name)]; + conn.second = std::move(chunks); + } module->connect(conn); } @@ -1098,23 +715,51 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto &it : cell_stats) log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); int in_wires = 0, out_wires = 0; - for (auto &si : signal_list) - if (si.is_port) { - char buffer[100]; - snprintf(buffer, 100, "\\n%d", si.id); + //for (auto &si : signal_list) + // if (si.is_port) { + // char buffer[100]; + // snprintf(buffer, 100, "\\n%d", si.id); + // RTLIL::SigSig conn; + // if (si.type != G(NONE)) { + // conn.first = si.bit; + // conn.second = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); + // out_wires++; + // } else { + // conn.first = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); + // conn.second = si.bit; + // in_wires++; + // } + // module->connect(conn); + // } + + // FIXME: + module->connections_.clear(); + + for (auto &it : mapped_mod->wires_) { + RTLIL::Wire *w = it.second; + if (!w->port_input && !w->port_output) + continue; + RTLIL::Wire *wire = module->wire(remap_name(w->name)); + if (w->port_input) { RTLIL::SigSig conn; - if (si.type != G(NONE)) { - conn.first = si.bit; - conn.second = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); - out_wires++; - } else { - conn.first = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); - conn.second = si.bit; - in_wires++; - } + conn.first = wire; + conn.second = module->wire(w->name); + if (conn.second.empty()) + log_error("Input port %s not found in original module.\n", w->name.c_str()); + in_wires++; module->connect(conn); } - log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); + else if (w->port_output) { + RTLIL::SigSig conn; + conn.first = module->wire(w->name); + if (conn.first.empty()) + log_error("Output port %s not found in original module.\n", w->name.c_str()); + conn.second = wire; + out_wires++; + module->connect(conn); + } + } + //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); log("ABC RESULTS: input signals: %8d\n", in_wires); log("ABC RESULTS: output signals: %8d\n", out_wires);