From ec2539480867fcc05c904043747b2f3cba9a9866 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 28 Dec 2019 03:16:28 -0800 Subject: Rename abc9.cc -> abc9_techmap.cc --- passes/techmap/abc9.cc | 1310 ------------------------------------------------ 1 file changed, 1310 deletions(-) delete mode 100644 passes/techmap/abc9.cc (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc deleted file mode 100644 index d03e5da8e..000000000 --- a/passes/techmap/abc9.cc +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * 2019 Eddie Hung - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -// [[CITE]] ABC -// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification -// http://www.eecs.berkeley.edu/~alanmi/abc/ - -#if 0 -// Based on &flow3 - better QoR but more experimental -#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ - "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ - "&mfs; &ps -l" -#else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" -#endif - - -#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/celltypes.h" -#include "kernel/cost.h" -#include "kernel/log.h" -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# include -# include -#endif - -#include "frontends/aiger/aigerparse.h" -#include "kernel/utils.h" - -#ifdef YOSYS_LINK_ABC -extern "C" int Abc_RealMain(int argc, char *argv[]); -#endif - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -bool markgroups; -int map_autoidx; -SigMap assign_map; -RTLIL::Module *module; - -bool clk_polarity, en_polarity; -RTLIL::SigSpec clk_sig, en_sig; - -inline std::string remap_name(RTLIL::IdString abc9_name) -{ - return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1); -} - -void handle_loops(RTLIL::Design *design) -{ - Pass::call(design, "scc -set_attr abc9_scc_id {}"); - - // For every unique SCC found, (arbitrarily) find the first - // cell in the component, and select (and mark) all its output - // wires - pool ids_seen; - for (auto cell : module->cells()) { - auto it = cell->attributes.find(ID(abc9_scc_id)); - if (it != cell->attributes.end()) { - auto r = ids_seen.insert(it->second); - if (r.second) { - for (auto &c : cell->connections_) { - if (c.second.is_fully_const()) continue; - if (cell->output(c.first)) { - SigBit b = c.second.as_bit(); - Wire *w = b.wire; - if (w->port_input) { - // In this case, hopefully the loop break has been already created - // Get the non-prefixed wire - Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); - log_assert(wo != nullptr); - log_assert(wo->port_output); - log_assert(b.offset < GetSize(wo)); - c.second = RTLIL::SigBit(wo, b.offset); - } - else { - // Create a new output/input loop break - w->port_input = true; - w = module->wire(stringf("%s.abco", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); - w->port_output = true; - } - else { - log_assert(w->port_input); - log_assert(b.offset < GetSize(w)); - } - w->set_bool_attribute(ID(abc9_scc_break)); - c.second = RTLIL::SigBit(w, b.offset); - } - } - } - } - cell->attributes.erase(it); - } - } - - module->fixup_ports(); -} - -std::string add_echos_to_abc9_cmd(std::string str) -{ - std::string new_str, token; - for (size_t i = 0; i < str.size(); i++) { - token += str[i]; - if (str[i] == ';') { - while (i+1 < str.size() && str[i+1] == ' ') - i++; - new_str += "echo + " + token + " " + token + " "; - token.clear(); - } - } - - if (!token.empty()) { - if (!new_str.empty()) - new_str += "echo + " + token + "; "; - new_str += token; - } - - return new_str; -} - -std::string fold_abc9_cmd(std::string str) -{ - std::string token, new_str = " "; - int char_counter = 10; - - for (size_t i = 0; i <= str.size(); i++) { - if (i < str.size()) - token += str[i]; - if (i == str.size() || str[i] == ';') { - if (char_counter + token.size() > 75) - new_str += "\n ", char_counter = 14; - new_str += token, char_counter += token.size(); - token.clear(); - } - } - - return new_str; -} - -std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) -{ - if (show_tempdir) - return text; - - while (1) { - size_t pos = text.find(tempdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); - } - - std::string selfdir_name = proc_self_dirname(); - if (selfdir_name != "/") { - while (1) { - size_t pos = text.find(selfdir_name); - if (pos == std::string::npos) - break; - text = text.substr(0, pos) + "/" + text.substr(pos + GetSize(selfdir_name)); - } - } - - return text; -} - -struct abc9_output_filter -{ - bool got_cr; - int escape_seq_state; - std::string linebuf; - std::string tempdir_name; - bool show_tempdir; - - abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) - { - got_cr = false; - escape_seq_state = 0; - } - - void next_char(char ch) - { - if (escape_seq_state == 0 && ch == '\033') { - escape_seq_state = 1; - return; - } - if (escape_seq_state == 1) { - escape_seq_state = ch == '[' ? 2 : 0; - return; - } - if (escape_seq_state == 2) { - if ((ch < '0' || '9' < ch) && ch != ';') - escape_seq_state = 0; - return; - } - escape_seq_state = 0; - if (ch == '\r') { - got_cr = true; - return; - } - if (ch == '\n') { - log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str()); - got_cr = false, linebuf.clear(); - return; - } - if (got_cr) - got_cr = false, linebuf.clear(); - linebuf += ch; - } - - void next_line(const std::string &line) - { - //int pi, po; - //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) { - // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n", - // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???", - // po, po_map.count(po) ? po_map.at(po).c_str() : "???"); - // return; - //} - - for (char ch : line) - next_char(ch); - } -}; - -void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, - bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, - bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay, const dict &box_lookup, bool nomfs -) -{ - module = current_module; - map_autoidx = autoidx++; - - if (clk_str != "$") - { - clk_polarity = true; - clk_sig = RTLIL::SigSpec(); - - en_polarity = true; - en_sig = RTLIL::SigSpec(); - } - - if (!clk_str.empty() && clk_str != "$") - { - if (clk_str.find(',') != std::string::npos) { - int pos = clk_str.find(','); - std::string en_str = clk_str.substr(pos+1); - clk_str = clk_str.substr(0, pos); - if (en_str[0] == '!') { - en_polarity = false; - en_str = en_str.substr(1); - } - if (module->wires_.count(RTLIL::escape_id(en_str)) != 0) - en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0)); - } - if (clk_str[0] == '!') { - clk_polarity = false; - clk_str = clk_str.substr(1); - } - if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); - } - - if (dff_mode && clk_sig.empty()) - log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); - - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; - if (!cleanup) - tempdir_name[0] = tempdir_name[4] = '_'; - tempdir_name = make_temp_dir(tempdir_name); - 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 abc9_script; - - if (!lut_costs.empty()) { - abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); - if (!box_file.empty()) - abc9_script += stringf("read_box -v %s; ", box_file.c_str()); - } - else - if (!lut_file.empty()) { - abc9_script += stringf("read_lut %s; ", lut_file.c_str()); - if (!box_file.empty()) - abc9_script += stringf("read_box -v %s; ", box_file.c_str()); - } - else - log_abort(); - - abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); - - if (!script_file.empty()) { - if (script_file[0] == '+') { - for (size_t i = 1; i < script_file.size(); i++) - if (script_file[i] == '\'') - abc9_script += "'\\''"; - else if (script_file[i] == ',') - abc9_script += " "; - else - abc9_script += script_file[i]; - } else - abc9_script += stringf("source %s", script_file.c_str()); - } else if (!lut_costs.empty() || !lut_file.empty()) { - //bool all_luts_cost_same = true; - //for (int this_cost : lut_costs) - // if (this_cost != lut_costs.front()) - // all_luts_cost_same = false; - abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; - //if (all_luts_cost_same && !fast_mode) - // abc9_script += "; lutpack {S}"; - } else - log_abort(); - - //if (script_file.empty() && !delay_target.empty()) - // for (size_t pos = abc9_script.find("dretime;"); pos != std::string::npos; pos = abc9_script.find("dretime;", pos+1)) - // abc9_script = abc9_script.substr(0, pos) + "dretime; retime -o {D};" + abc9_script.substr(pos+8); - - for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos)) - abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3); - - //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos)) - // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3); - - for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) - abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); - - if (nomfs) - for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos)) - abc9_script = abc9_script.erase(pos, strlen("&mfs")); - - abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); - abc9_script = add_echos_to_abc9_cmd(abc9_script); - - for (size_t i = 0; i+1 < abc9_script.size(); i++) - if (abc9_script[i] == ';' && abc9_script[i+1] == ' ') - abc9_script[i+1] = '\n'; - - FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt"); - fprintf(f, "%s\n", abc9_script.c_str()); - fclose(f); - - if (dff_mode || !clk_str.empty()) - { - if (clk_sig.size() == 0) - log("No%s clock domain found. Not extracting any FF cells.\n", clk_str.empty() ? "" : " matching"); - else { - log("Found%s %s clock domain: %s", clk_str.empty() ? "" : " matching", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig)); - if (en_sig.size() != 0) - log(", enabled by %s%s", en_polarity ? "" : "!", log_signal(en_sig)); - log("\n"); - } - } - - bool count_output = false; - for (auto port_name : module->ports) { - RTLIL::Wire *port_wire = module->wire(port_name); - log_assert(port_wire); - if (port_wire->port_output) { - count_output = true; - break; - } - } - - log_push(); - - if (count_output) - { - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(module); - - handle_loops(design); - - Pass::call(design, "aigmap"); - - //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", - // count_gates, GetSize(signal_list), count_input, count_output); - - Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); - - std::string buffer; - std::ifstream ifs; -#if 0 - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig"); - ifs.open(buffer); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module(ID($__abc9__))); - { - AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); - } - ifs.close(); - Pass::call(design, stringf("write_verilog -noexpr -norename")); - design->remove(design->module(ID($__abc9__))); -#endif - - design->selection_stack.pop_back(); - - log_header(design, "Executing ABC9.\n"); - - if (!lut_costs.empty()) { - buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); - f = fopen(buffer.c_str(), "wt"); - if (f == NULL) - log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); - for (int i = 0; i < GetSize(lut_costs); i++) - fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); - fclose(f); - } - - buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); - log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); - -#ifndef YOSYS_LINK_ABC - abc9_output_filter filt(tempdir_name, show_tempdir); - int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); -#else - // These needs to be mutable, supposedly due to getopt - char *abc9_argv[5]; - string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); - abc9_argv[0] = strdup(exe_file.c_str()); - abc9_argv[1] = strdup("-s"); - abc9_argv[2] = strdup("-f"); - abc9_argv[3] = strdup(tmp_script_name.c_str()); - abc9_argv[4] = 0; - int ret = Abc_RealMain(4, abc9_argv); - free(abc9_argv[0]); - free(abc9_argv[1]); - free(abc9_argv[2]); - free(abc9_argv[3]); -#endif - if (ret != 0) - log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); - - buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig"); - ifs.open(buffer, std::ifstream::binary); - if (ifs.fail()) - log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - - buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module(ID($__abc9__))); - - AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(box_lookup); - ifs.close(); - -#if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename")); -#endif - - log_header(design, "Re-integrating ABC9 results.\n"); - RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); - if (mapped_mod == NULL) - log_error("ABC output file does not contain a module `$__abc9__'.\n"); - - pool output_bits; - for (auto &it : mapped_mod->wires_) { - RTLIL::Wire *w = it.second; - RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); - if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; - if (w->port_output) { - RTLIL::Wire *wire = module->wire(w->name); - log_assert(wire); - for (int i = 0; i < GetSize(w); i++) - output_bits.insert({wire, i}); - } - } - - for (auto &it : module->connections_) { - auto &signal = it.first; - auto bits = signal.bits(); - for (auto &b : bits) - if (output_bits.count(b)) - b = module->addWire(NEW_ID); - signal = std::move(bits); - } - - dict abc9_box; - vector boxes; - for (const auto &it : module->cells_) { - auto cell = it.second; - if (cell->type.in(ID($_AND_), ID($_NOT_))) { - module->remove(cell); - continue; - } - auto jt = abc9_box.find(cell->type); - if (jt == abc9_box.end()) { - RTLIL::Module* box_module = design->module(cell->type); - jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; - } - if (jt->second) - boxes.emplace_back(cell); - } - - dict> bit_drivers, bit_users; - TopoSort toposort; - dict not2drivers; - dict> bit2sinks; - - std::map cell_stats; - for (auto c : mapped_mod->cells()) - { - toposort.node(c->name); - - RTLIL::Cell *cell = nullptr; - if (c->type == ID($_NOT_)) { - RTLIL::SigBit a_bit = c->getPort(ID::A); - RTLIL::SigBit y_bit = c->getPort(ID::Y); - bit_users[a_bit].insert(c->name); - bit_drivers[y_bit].insert(c->name); - - if (!a_bit.wire) { - c->setPort(ID::Y, module->addWire(NEW_ID)); - RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); - log_assert(wire); - module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); - } - else if (!lut_costs.empty() || !lut_file.empty()) { - RTLIL::Cell* driver_lut = nullptr; - // ABC can return NOT gates that drive POs - if (!a_bit.wire->port_input) { - // If it's not a NOT gate that that comes from a PI directly, - // find the driver LUT and clone that to guarantee that we won't - // increase the max logic depth - // (TODO: Optimise by not cloning unless will increase depth) - RTLIL::IdString driver_name; - if (GetSize(a_bit.wire) == 1) - driver_name = stringf("%s$lut", a_bit.wire->name.c_str()); - else - driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); - driver_lut = mapped_mod->cell(driver_name); - } - - if (!driver_lut) { - // If a driver couldn't be found (could be from PI or box CI) - // then implement using a LUT - cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), - RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), - RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), - RTLIL::Const::from_string("01")); - bit2sinks[cell->getPort(ID::A)].push_back(cell); - cell_stats[ID($lut)]++; - } - else - not2drivers[c] = driver_lut; - continue; - } - else - log_abort(); - if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - continue; - } - cell_stats[c->type]++; - - RTLIL::Cell *existing_cell = nullptr; - if (c->type == ID($lut)) { - if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); - module->connect(my_y, my_a); - if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; - log_abort(); - continue; - } - cell = module->addCell(remap_name(c->name), c->type); - } - else { - existing_cell = module->cell(c->name); - log_assert(existing_cell); - cell = module->addCell(remap_name(c->name), c->type); - } - - if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - if (existing_cell) { - cell->parameters = existing_cell->parameters; - cell->attributes = existing_cell->attributes; - } - else { - cell->parameters = c->parameters; - cell->attributes = c->attributes; - } - for (auto &conn : c->connections()) { - RTLIL::SigSpec newsig; - for (auto c : conn.second.chunks()) { - if (c.width == 0) - continue; - //log_assert(c.width == 1); - if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); - newsig.append(c); - } - cell->setPort(conn.first, newsig); - - if (cell->input(conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : conn.second) - bit_users[i].insert(c->name); - } - if (cell->output(conn.first)) - for (auto i : conn.second) - bit_drivers[i].insert(c->name); - } - } - - for (auto existing_cell : boxes) { - Cell *cell = module->cell(remap_name(existing_cell->name)); - if (cell) { - for (auto &conn : existing_cell->connections()) { - if (!conn.second.is_wire()) - continue; - Wire *wire = conn.second.as_wire(); - if (!wire->get_bool_attribute(ID(abc9_padding))) - continue; - cell->unsetPort(conn.first); - log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second)); - } - module->swap_names(cell, existing_cell); - } - module->remove(existing_cell); - } - - // Copy connections (and rename) from mapped_mod to module - for (auto conn : mapped_mod->connections()) { - if (!conn.first.is_fully_const()) { - auto chunks = conn.first.chunks(); - for (auto &c : chunks) - c.wire = module->wires_.at(remap_name(c.wire->name)); - conn.first = std::move(chunks); - } - if (!conn.second.is_fully_const()) { - auto chunks = conn.second.chunks(); - for (auto &c : chunks) - if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); - conn.second = std::move(chunks); - } - module->connect(conn); - } - - 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; - - // Stitch in mapped_mod's inputs/outputs into module - for (auto port : mapped_mod->ports) { - RTLIL::Wire *w = mapped_mod->wire(port); - RTLIL::Wire *wire = module->wire(port); - log_assert(wire); - RTLIL::Wire *remap_wire = module->wire(remap_name(port)); - RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); - log_assert(GetSize(signal) >= GetSize(remap_wire)); - - RTLIL::SigSig conn; - if (w->port_output) { - conn.first = signal; - conn.second = remap_wire; - out_wires++; - module->connect(conn); - } - else if (w->port_input) { - conn.first = remap_wire; - conn.second = signal; - in_wires++; - module->connect(conn); - } - } - - for (auto &it : bit_users) - if (bit_drivers.count(it.first)) - for (auto driver_cell : bit_drivers.at(it.first)) - for (auto user_cell : it.second) - toposort.edge(driver_cell, user_cell); - bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); - log_assert(no_loops); - - for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { - RTLIL::Cell *not_cell = mapped_mod->cell(*ii); - log_assert(not_cell); - if (not_cell->type != ID($_NOT_)) - continue; - auto it = not2drivers.find(not_cell); - if (it == not2drivers.end()) - continue; - RTLIL::Cell *driver_lut = it->second; - RTLIL::SigBit a_bit = not_cell->getPort(ID::A); - RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); - RTLIL::Const driver_mask; - - a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); - y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); - - auto jt = bit2sinks.find(a_bit); - if (jt == bit2sinks.end()) - goto clone_lut; - - for (auto sink_cell : jt->second) - if (sink_cell->type != ID($lut)) - goto clone_lut; - - // Push downstream LUTs past inverter - for (auto sink_cell : jt->second) { - SigSpec A = sink_cell->getPort(ID::A); - RTLIL::Const mask = sink_cell->getParam(ID(LUT)); - int index = 0; - for (; index < GetSize(A); index++) - if (A[index] == a_bit) - break; - log_assert(index < GetSize(A)); - int i = 0; - while (i < GetSize(mask)) { - for (int j = 0; j < (1 << index); j++) - std::swap(mask[i+j], mask[i+j+(1 << index)]); - i += 1 << (index+1); - } - A[index] = y_bit; - sink_cell->setPort(ID::A, A); - sink_cell->setParam(ID(LUT), mask); - } - - // Since we have rewritten all sinks (which we know - // to be only LUTs) to be after the inverter, we can - // go ahead and clone the LUT with the expectation - // that the original driving LUT will become dangling - // and get cleaned away -clone_lut: - driver_mask = driver_lut->getParam(ID(LUT)); - for (auto &b : driver_mask.bits) { - if (b == RTLIL::State::S0) b = RTLIL::State::S1; - else if (b == RTLIL::State::S1) b = RTLIL::State::S0; - } - auto cell = module->addLut(NEW_ID, - driver_lut->getPort(ID::A), - y_bit, - driver_mask); - for (auto &bit : cell->connections_.at(ID::A)) { - bit.wire = module->wires_.at(remap_name(bit.wire->name)); - bit2sinks[bit].push_back(cell); - } - } - - // Now 'unexpose' those wires by undoing - // the expose operation -- remove them from PO/PI - // and re-connecting them back together - for (auto wire : module->wires()) { - auto it = wire->attributes.find(ID(abc9_scc_break)); - if (it != wire->attributes.end()) { - wire->attributes.erase(it); - log_assert(wire->port_output); - wire->port_output = false; - std::string name = wire->name.str(); - RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); - log_assert(i_wire); - log_assert(i_wire->port_input); - i_wire->port_input = false; - module->connect(i_wire, wire); - } - } - module->fixup_ports(); - - //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); - - design->remove(mapped_mod); - } - else - { - log("Don't call ABC as there is nothing to map.\n"); - } - - if (cleanup) - { - log("Removing temp directory.\n"); - remove_directory(tempdir_name); - } - - log_pop(); -} - -struct Abc9Pass : public Pass { - Abc9Pass() : Pass("abc9", "use ABC9 for technology mapping") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" abc9 [options] [selection]\n"); - log("\n"); - log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); - log("library to a target architecture.\n"); - log("\n"); - log(" -exe \n"); -#ifdef ABCEXTERNAL - log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); -#else - log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); -#endif - log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); - log("\n"); - log(" -script \n"); - log(" use the specified ABC script file instead of the default script.\n"); - log("\n"); - log(" if starts with a plus sign (+), then the rest of the filename\n"); - log(" string is interpreted as the command string to be passed to ABC. The\n"); - log(" leading plus sign is removed and all commas (,) in the string are\n"); - log(" replaced with blanks before the string is passed to ABC.\n"); - log("\n"); - log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); - log("\n"); - log(" -fast\n"); - log(" use different default scripts that are slightly faster (at the cost\n"); - log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); - log("\n"); - log(" -D \n"); - log(" set delay target. the string {D} in the default scripts above is\n"); - log(" replaced by this option when used, and an empty string otherwise\n"); - log(" (indicating best possible delay).\n"); -// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); -// log(" default scripts above.\n"); - log("\n"); -// log(" -S \n"); -// log(" maximum number of LUT inputs shared.\n"); -// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); -// log("\n"); - log(" -lut \n"); - log(" generate netlist using luts of (max) the specified width.\n"); - log("\n"); - log(" -lut :\n"); - log(" generate netlist using luts of (max) the specified width . All\n"); - log(" luts with width <= have constant cost. for luts larger than \n"); - log(" the area cost doubles with each additional input bit. the delay cost\n"); - log(" is still constant for all lut widths.\n"); - log("\n"); - log(" -lut \n"); - log(" pass this file with lut library to ABC.\n"); - log("\n"); - log(" -luts ,,,:,..\n"); - log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); - log(" 2, 3, .. inputs.\n"); - log("\n"); -// log(" -dff\n"); -// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); -// log(" clock domains are automatically partitioned in clock domains and each\n"); -// log(" domain is passed through ABC independently.\n"); -// log("\n"); -// log(" -clk [!][,[!]]\n"); -// log(" use only the specified clock domain. this is like -dff, but only FF\n"); -// log(" cells that belong to the specified clock domain are used.\n"); -// log("\n"); -// log(" -keepff\n"); -// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); -// log(" them, for example for equivalence checking.)\n"); -// log("\n"); - log(" -nocleanup\n"); - log(" when this option is used, the temporary files created by this pass\n"); - log(" are not removed. this is useful for debugging.\n"); - log("\n"); - log(" -showtmp\n"); - log(" print the temp dir name in log. usually this is suppressed so that the\n"); - log(" command output is identical across runs.\n"); - log("\n"); - log(" -markgroups\n"); - log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); - log(" this attribute is a unique integer for each ABC process started. This\n"); - log(" is useful for debugging the partitioning of clock domains.\n"); - log("\n"); - log(" -box \n"); - log(" pass this file with box library to ABC. Use with -lut.\n"); - log("\n"); - log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); - log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); - log("ABC on logic snippets extracted from your design. You will not get any useful\n"); - log("output when passing an ABC script that writes a file. Instead write your full\n"); - log("design as BLIF file with write_blif and then load that into ABC externally if\n"); - log("you want to use ABC to convert your design into another format.\n"); - log("\n"); - log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ABC9 pass (technology mapping using ABC9).\n"); - log_push(); - - assign_map.clear(); - -#ifdef ABCEXTERNAL - std::string exe_file = ABCEXTERNAL; -#else - std::string exe_file = proc_self_dirname() + "yosys-abc"; -#endif - std::string script_file, clk_str, box_file, lut_file; - std::string delay_target, lutin_shared = "-S 1", wire_delay; - bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; - bool show_tempdir = false; - bool nomfs = false; - vector lut_costs; - markgroups = false; - -#if 0 - cleanup = false; - show_tempdir = true; -#endif - -#ifdef _WIN32 -#ifndef ABCEXTERNAL - if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) - exe_file = proc_self_dirname() + "..\\yosys-abc"; -#endif -#endif - - size_t argidx; - char pwd [PATH_MAX]; - if (!getcwd(pwd, sizeof(pwd))) { - log_cmd_error("getcwd failed: %s\n", strerror(errno)); - log_abort(); - } - for (argidx = 1; argidx < args.size(); argidx++) { - std::string arg = args[argidx]; - if (arg == "-exe" && argidx+1 < args.size()) { - exe_file = args[++argidx]; - continue; - } - if (arg == "-script" && argidx+1 < args.size()) { - script_file = args[++argidx]; - rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') - script_file = std::string(pwd) + "/" + script_file; - continue; - } - if (arg == "-D" && argidx+1 < args.size()) { - delay_target = "-D " + args[++argidx]; - continue; - } - //if (arg == "-S" && argidx+1 < args.size()) { - // lutin_shared = "-S " + args[++argidx]; - // continue; - //} - if (arg == "-lut" && argidx+1 < args.size()) { - string arg = args[++argidx]; - if (arg.find_first_not_of("0123456789:") == std::string::npos) { - size_t pos = arg.find_first_of(':'); - int lut_mode = 0, lut_mode2 = 0; - if (pos != string::npos) { - lut_mode = atoi(arg.substr(0, pos).c_str()); - lut_mode2 = atoi(arg.substr(pos+1).c_str()); - } else { - lut_mode = atoi(arg.c_str()); - lut_mode2 = lut_mode; - } - lut_costs.clear(); - for (int i = 0; i < lut_mode; i++) - lut_costs.push_back(1); - for (int i = lut_mode; i < lut_mode2; i++) - lut_costs.push_back(2 << (i - lut_mode)); - } - else { - lut_file = arg; - rewrite_filename(lut_file); - if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+') - lut_file = std::string(pwd) + "/" + lut_file; - } - continue; - } - if (arg == "-luts" && argidx+1 < args.size()) { - lut_costs.clear(); - for (auto &tok : split_tokens(args[++argidx], ",")) { - auto parts = split_tokens(tok, ":"); - if (GetSize(parts) == 0 && !lut_costs.empty()) - lut_costs.push_back(lut_costs.back()); - else if (GetSize(parts) == 1) - lut_costs.push_back(atoi(parts.at(0).c_str())); - else if (GetSize(parts) == 2) - while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) - lut_costs.push_back(atoi(parts.at(1).c_str())); - else - log_cmd_error("Invalid -luts syntax.\n"); - } - continue; - } - if (arg == "-fast") { - fast_mode = true; - continue; - } - //if (arg == "-dff") { - // dff_mode = true; - // continue; - //} - //if (arg == "-clk" && argidx+1 < args.size()) { - // clk_str = args[++argidx]; - // dff_mode = true; - // continue; - //} - //if (arg == "-keepff") { - // keepff = true; - // continue; - //} - if (arg == "-nocleanup") { - cleanup = false; - continue; - } - if (arg == "-showtmp") { - show_tempdir = true; - continue; - } - if (arg == "-markgroups") { - markgroups = true; - continue; - } - if (arg == "-box" && argidx+1 < args.size()) { - box_file = args[++argidx]; - continue; - } - if (arg == "-W" && argidx+1 < args.size()) { - wire_delay = "-W " + args[++argidx]; - continue; - } - if (arg == "-nomfs") { - nomfs = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - // ABC expects a box file for XAIG - if (box_file.empty()) - box_file = "+/dummy.box"; - - rewrite_filename(box_file); - if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+') - box_file = std::string(pwd) + "/" + box_file; - - dict box_lookup; - for (auto m : design->modules()) { - auto it = m->attributes.find(ID(abc9_box_id)); - if (it == m->attributes.end()) - continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(id, m->name)); - if (!r.second) - log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); - log_assert(r.second); - - RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; - for (auto p : m->ports) { - auto w = m->wire(p); - log_assert(w); - if (w->attributes.count(ID(abc9_carry))) { - if (w->port_input) { - if (carry_in) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_in = w; - } - else if (w->port_output) { - if (carry_out) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); - carry_out = w; - } - } - } - if (carry_in || carry_out) { - if (carry_in && !carry_out) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); - if (!carry_in && carry_out) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); - // Make carry_in the last PI, and carry_out the last PO - // since ABC requires it this way - auto &ports = m->ports; - for (auto it = ports.begin(); it != ports.end(); ) { - RTLIL::Wire* w = m->wire(*it); - log_assert(w); - if (w == carry_in || w == carry_out) { - it = ports.erase(it); - continue; - } - if (w->port_id > carry_in->port_id) - --w->port_id; - if (w->port_id > carry_out->port_id) - --w->port_id; - log_assert(w->port_input || w->port_output); - log_assert(ports[w->port_id-1] == w->name); - ++it; - } - ports.push_back(carry_in->name); - carry_in->port_id = ports.size(); - ports.push_back(carry_out->name); - carry_out->port_id = ports.size(); - } - } - - for (auto mod : design->selected_modules()) - { - if (mod->attributes.count(ID(abc9_box_id))) - continue; - - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); - continue; - } - - assign_map.set(mod); - - if (!dff_mode || !clk_str.empty()) { - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - continue; - } - - CellTypes ct(design); - - std::vector all_cells = mod->selected_cells(); - std::set unassigned_cells(all_cells.begin(), all_cells.end()); - - std::set expand_queue, next_expand_queue; - std::set expand_queue_up, next_expand_queue_up; - std::set expand_queue_down, next_expand_queue_down; - - typedef tuple clkdomain_t; - std::map> assigned_cells; - std::map assigned_cells_reverse; - - std::map> cell_to_bit, cell_to_bit_up, cell_to_bit_down; - std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; - - for (auto cell : all_cells) - { - clkdomain_t key; - - for (auto &conn : cell->connections()) - for (auto bit : conn.second) { - bit = assign_map(bit); - if (bit.wire != nullptr) { - cell_to_bit[cell].insert(bit); - bit_to_cell[bit].insert(cell); - if (ct.cell_input(cell->type, conn.first)) { - cell_to_bit_up[cell].insert(bit); - bit_to_cell_down[bit].insert(cell); - } - if (ct.cell_output(cell->type, conn.first)) { - cell_to_bit_down[cell].insert(bit); - bit_to_cell_up[bit].insert(cell); - } - } - } - - if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) - { - key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); - } - else - if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) - { - bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); - bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); - } - else - continue; - - unassigned_cells.erase(cell); - expand_queue.insert(cell); - expand_queue_up.insert(cell); - expand_queue_down.insert(cell); - - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - while (!expand_queue_up.empty() || !expand_queue_down.empty()) - { - if (!expand_queue_up.empty()) - { - RTLIL::Cell *cell = *expand_queue_up.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_up.erase(cell); - - for (auto bit : cell_to_bit_up[cell]) - for (auto c : bit_to_cell_up[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (!expand_queue_down.empty()) - { - RTLIL::Cell *cell = *expand_queue_down.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue_down.erase(cell); - - for (auto bit : cell_to_bit_down[cell]) - for (auto c : bit_to_cell_down[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue_up.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - expand_queue.insert(c); - } - } - - if (expand_queue_up.empty() && expand_queue_down.empty()) { - expand_queue_up.swap(next_expand_queue_up); - expand_queue_down.swap(next_expand_queue_down); - } - } - - while (!expand_queue.empty()) - { - RTLIL::Cell *cell = *expand_queue.begin(); - clkdomain_t key = assigned_cells_reverse.at(cell); - expand_queue.erase(cell); - - for (auto bit : cell_to_bit.at(cell)) { - for (auto c : bit_to_cell[bit]) - if (unassigned_cells.count(c)) { - unassigned_cells.erase(c); - next_expand_queue.insert(c); - assigned_cells[key].push_back(c); - assigned_cells_reverse[c] = key; - } - bit_to_cell[bit].clear(); - } - - if (expand_queue.empty()) - expand_queue.swap(next_expand_queue); - } - - clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec()); - for (auto cell : unassigned_cells) { - assigned_cells[key].push_back(cell); - assigned_cells_reverse[cell] = key; - } - - log_header(design, "Summary of detected clock domains:\n"); - for (auto &it : assigned_cells) - log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second), - std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), - std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); - - for (auto &it : assigned_cells) { - clk_polarity = std::get<0>(it.first); - clk_sig = assign_map(std::get<1>(it.first)); - en_polarity = std::get<2>(it.first); - en_sig = assign_map(std::get<3>(it.first)); - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup, nomfs); - assign_map.set(mod); - } - } - - assign_map.clear(); - - log_pop(); - } -} Abc9Pass; - -PRIVATE_NAMESPACE_END -- cgit v1.2.3 From f348ffa44d4ec00537499ffe79ce627beeeefe85 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 28 Dec 2019 05:07:46 -0800 Subject: abc9_techmap -> _map; called from abc9 script pass along with abc9_ops --- passes/techmap/abc9.cc | 231 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 passes/techmap/abc9.cc (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc new file mode 100644 index 000000000..e1cf188ce --- /dev/null +++ b/passes/techmap/abc9.cc @@ -0,0 +1,231 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * (C) 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate + // to one LUT6 (instead of a LUT5 + LUT2) + +struct Abc9Pass : public ScriptPass +{ + Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } + + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" abc9 [options] [selection]\n"); + log("\n"); + log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); + log("library to a target architecture.\n"); + log("\n"); + log(" -exe \n"); +#ifdef ABCEXTERNAL + log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); +#else + log(" use the specified command instead of \"/yosys-abc\" to execute ABC.\n"); +#endif + log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n"); + log("\n"); + log(" -script \n"); + log(" use the specified ABC script file instead of the default script.\n"); + log("\n"); + log(" if starts with a plus sign (+), then the rest of the filename\n"); + log(" string is interpreted as the command string to be passed to ABC. The\n"); + log(" leading plus sign is removed and all commas (,) in the string are\n"); + log(" replaced with blanks before the string is passed to ABC.\n"); + log("\n"); + log(" if no -script parameter is given, the following scripts are used:\n"); + log("\n"); + log(" for -lut/-luts (only one LUT size):\n"); + // FIXME + //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); + log("\n"); + log(" for -lut/-luts (different LUT sizes):\n"); + // FIXME + //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log("\n"); + log(" -fast\n"); + log(" use different default scripts that are slightly faster (at the cost\n"); + log(" of output quality):\n"); + log("\n"); + log(" for -lut/-luts:\n"); + // FIXME + //log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("\n"); + log(" -D \n"); + log(" set delay target. the string {D} in the default scripts above is\n"); + log(" replaced by this option when used, and an empty string otherwise\n"); + log(" (indicating best possible delay).\n"); +// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n"); +// log(" default scripts above.\n"); + log("\n"); +// log(" -S \n"); +// log(" maximum number of LUT inputs shared.\n"); +// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); +// log("\n"); + log(" -lut \n"); + log(" generate netlist using luts of (max) the specified width.\n"); + log("\n"); + log(" -lut :\n"); + log(" generate netlist using luts of (max) the specified width . All\n"); + log(" luts with width <= have constant cost. for luts larger than \n"); + log(" the area cost doubles with each additional input bit. the delay cost\n"); + log(" is still constant for all lut widths.\n"); + log("\n"); + log(" -lut \n"); + log(" pass this file with lut library to ABC.\n"); + log("\n"); + log(" -luts ,,,:,..\n"); + log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); + log(" 2, 3, .. inputs.\n"); + log("\n"); +// log(" -dff\n"); +// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); +// log(" clock domains are automatically partitioned in clock domains and each\n"); +// log(" domain is passed through ABC independently.\n"); +// log("\n"); +// log(" -clk [!][,[!]]\n"); +// log(" use only the specified clock domain. this is like -dff, but only FF\n"); +// log(" cells that belong to the specified clock domain are used.\n"); +// log("\n"); +// log(" -keepff\n"); +// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); +// log(" them, for example for equivalence checking.)\n"); +// log("\n"); + log(" -nocleanup\n"); + log(" when this option is used, the temporary files created by this pass\n"); + log(" are not removed. this is useful for debugging.\n"); + log("\n"); + log(" -showtmp\n"); + log(" print the temp dir name in log. usually this is suppressed so that the\n"); + log(" command output is identical across runs.\n"); + log("\n"); + log(" -markgroups\n"); + log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); + log(" this attribute is a unique integer for each ABC process started. This\n"); + log(" is useful for debugging the partitioning of clock domains.\n"); + log("\n"); + log(" -box \n"); + log(" pass this file with box library to ABC. Use with -lut.\n"); + log("\n"); + log("Note that this is a logic optimization pass within Yosys that is calling ABC\n"); + log("internally. This is not going to \"run ABC on your design\". It will instead run\n"); + log("ABC on logic snippets extracted from your design. You will not get any useful\n"); + log("output when passing an ABC script that writes a file. Instead write your full\n"); + log("design as BLIF file with write_blif and then load that into ABC externally if\n"); + log("you want to use ABC to convert your design into another format.\n"); + log("\n"); + log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); + log("\n"); + help_script(); + log("\n"); + } + + std::stringstream map_cmd; + bool cleanup; + + void clear_flags() YS_OVERRIDE + { + map_cmd.str(""); + map_cmd << "abc9_map"; + cleanup = true; + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + std::string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if ((arg == "-exe" || arg == "-script" || arg == "-D" || + /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || + arg == "-clk" || arg == "-box" || arg == "-W") && + argidx+1 < args.size()) { + map_cmd << " " << arg << " " << args[++argidx]; + continue; + } + if (arg == "-fast" || /*arg == "-dff" ||*/ arg == "-keepff" + /*|| arg == "-nocleanup"*/ || arg == "-showtmp" || arg == "-markgroups" + || arg == "-nomfs") { + map_cmd << " " << arg; + continue; + } + if (arg == "-nocleanup") { + cleanup = false; + continue; + } + break; + } + extra_args(args, argidx, design); + + log_header(design, "Executing ABC9 pass.\n"); + + run_script(design, run_from, run_to); + } + + void script() YS_OVERRIDE + { + auto selected_modules = active_design->selected_modules(); + active_design->selection_stack.emplace_back(false); + + for (auto mod : selected_modules) { + log_push(); + + active_design->selection().select(mod); + + std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; + if (!cleanup) + tempdir_name[0] = tempdir_name[4] = '_'; + tempdir_name = make_temp_dir(tempdir_name); + + run("scc -set_attr abc9_scc_id {}"); + run("abc9_ops -break_scc"); + run("aigmap"); + run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), + "write_xaiger -map /input.sym /input.xaig"); + run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_map [options] -tempdir "); + run("abc9_ops -unbreak_scc"); + + if (cleanup) + { + log("Removing temp directory.\n"); + remove_directory(tempdir_name); + } + + active_design->selection().selected_modules.clear(); + + log_pop(); + } + + active_design->selection_stack.pop_back(); + } +} Abc9Pass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 88b9c8d46ddac513831dc79d370f8abb23ab68fc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 16:29:08 -0800 Subject: Restore count_outputs, move process check to abc --- passes/techmap/abc9.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index d507a6973..ac64ae86d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -164,7 +164,7 @@ struct Abc9Pass : public ScriptPass map_cmd << " " << arg << " " << args[++argidx]; continue; } - if (arg == "-fast" || /*arg == "-dff" ||*/ arg == "-keepff" + if (arg == "-fast" /*|| arg == "-nocleanup"*/ || arg == "-showtmp" || arg == "-markgroups" || arg == "-nomfs") { map_cmd << " " << arg; @@ -189,6 +189,14 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { + if (module->attributes.count(ID(abc9_box_id))) + continue; + + if (module->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(module)); + continue; + } + log_push(); active_design->selection().select(mod); -- cgit v1.2.3 From 16c4ec7edaa3cb66ced2f856d3c48f30d7d2acf1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 16:36:33 -0800 Subject: Add abc9_ops -prep_dff --- passes/techmap/abc9.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index ac64ae86d..cd798cfbe 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -189,11 +189,11 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { - if (module->attributes.count(ID(abc9_box_id))) + if (mod->attributes.count(ID(abc9_box_id))) continue; - if (module->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(module)); + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); continue; } @@ -207,7 +207,7 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); + run("abc9_ops -break_scc -prep_dff"); run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); -- cgit v1.2.3 From b50de28c045e786f3140c95ab23cb2f426918093 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:00:49 -0800 Subject: Add abc9_ops -prep_holes --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index cd798cfbe..e11b15065 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -207,7 +207,7 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc -prep_dff"); + run("abc9_ops -break_scc -prep_dff -prep_holes"); run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); -- cgit v1.2.3 From b42b64e8ed713b0e9810f18db7cafcf356e2b4f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 19:23:54 -0800 Subject: Move Pass::call() out of abc9_ops into abc9 --- passes/techmap/abc9.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e11b15065..7d922df56 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -185,11 +185,21 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { + run("abc9_ops -prep_holes"); + run("select -set abc9_holes A:abc9_holes"); + run("flatten -wb @abc9_holes"); + run("techmap @abc9_holes"); + run("aigmap @abc9_holes"); + run("select -list @abc9_holes"); + run("abc9_ops -prep_dff"); + run("opt -purge @abc9_holes"); + run("setattr -mod -set whitebox 1 @abc9_holes"); + auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { - if (mod->attributes.count(ID(abc9_box_id))) + if (mod->get_blackbox_attribute()) continue; if (mod->processes.size() > 0) { @@ -207,7 +217,7 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc -prep_dff -prep_holes"); + run("abc9_ops -break_scc"); run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); -- cgit v1.2.3 From dacdc6cc941015aff45d1fde4d5365ab5e36e883 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 22:59:14 -0800 Subject: Remove abc9 -clk option --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 9e1318700..f44e3df06 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -150,7 +150,7 @@ struct Abc9Pass : public ScriptPass std::string arg = args[argidx]; if ((arg == "-exe" || arg == "-script" || arg == "-D" || /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || - arg == "-clk" || arg == "-box" || arg == "-W") && + arg == "-box" || arg == "-W") && argidx+1 < args.size()) { map_cmd << " " << arg << " " << args[++argidx]; continue; -- cgit v1.2.3 From 222e5e58ad1ae8845797a2afb63cdcb8c2396401 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 15:58:45 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a7e748ce7..8e17460e1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -190,11 +190,10 @@ struct Abc9Pass : public ScriptPass run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); run("aigmap @abc9_holes"); - run("select -list @abc9_holes"); if (dff_mode) run("abc9_ops -prep_dff"); run("opt -purge @abc9_holes"); - run("setattr -mod -set whitebox 1 @abc9_holes"); + run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); -- cgit v1.2.3 From 7fe268fcdb17d28dbb187d4c5c3b53e648c190ca Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 16:00:26 -0800 Subject: Move scc operations out of inner loop --- passes/techmap/abc9.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8e17460e1..df59ff857 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -189,6 +189,8 @@ struct Abc9Pass : public ScriptPass run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); + run("scc -set_attr abc9_scc_id {}"); + run("abc9_ops -break_scc"); run("aigmap @abc9_holes"); if (dff_mode) run("abc9_ops -prep_dff"); @@ -207,8 +209,6 @@ struct Abc9Pass : public ScriptPass continue; } - log_push(); - active_design->selection().select(mod); std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; @@ -216,14 +216,10 @@ struct Abc9Pass : public ScriptPass tempdir_name[0] = tempdir_name[4] = '_'; tempdir_name = make_temp_dir(tempdir_name); - run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); - run("aigmap"); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), "write_xaiger -map /input.sym /input.xaig"); run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()), "abc9_map [options] -tempdir "); - run("abc9_ops -unbreak_scc"); if (cleanup) { @@ -232,11 +228,11 @@ struct Abc9Pass : public ScriptPass } active_design->selection().selected_modules.clear(); - - log_pop(); } active_design->selection_stack.pop_back(); + + run("abc9_ops -unbreak_scc"); } } Abc9Pass; -- cgit v1.2.3 From 4eaf41505256fc6f20065b3e5a64d74e607b15e7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 2 Jan 2020 16:13:44 -0800 Subject: aigmap everything --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index df59ff857..e7fcb9165 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -191,7 +191,7 @@ struct Abc9Pass : public ScriptPass run("techmap @abc9_holes"); run("scc -set_attr abc9_scc_id {}"); run("abc9_ops -break_scc"); - run("aigmap @abc9_holes"); + run("aigmap"); if (dff_mode) run("abc9_ops -prep_dff"); run("opt -purge @abc9_holes"); -- cgit v1.2.3 From e1f494ab1db523f90cf1e386ba133b1550dcb300 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 13:08:52 -0800 Subject: WIP --- passes/techmap/abc9.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e7fcb9165..6dd4de2e0 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -185,17 +185,17 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { - run("abc9_ops -prep_holes"); - run("select -set abc9_holes A:abc9_holes"); - run("flatten -wb @abc9_holes"); - run("techmap @abc9_holes"); run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); + run("abc9_ops -break_scc"/*" -prep_holes"*/); +// run("select -set abc9_holes A:abc9_holes"); +// run("dump @abc9_holes"); +// run("flatten -wb @abc9_holes"); +// run("techmap @abc9_holes"); run("aigmap"); if (dff_mode) run("abc9_ops -prep_dff"); - run("opt -purge @abc9_holes"); - run("wbflip @abc9_holes"); +// run("opt -purge @abc9_holes"); +// run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); -- cgit v1.2.3 From bb70915fb8adcd7ede7719174dea3bc9c04e613e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 13:21:56 -0800 Subject: WIP --- passes/techmap/abc9.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6dd4de2e0..25fe3fbc8 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -195,7 +195,11 @@ struct Abc9Pass : public ScriptPass if (dff_mode) run("abc9_ops -prep_dff"); // run("opt -purge @abc9_holes"); -// run("wbflip @abc9_holes"); + + run("abc9_ops -prep_holes"); + + run("select -set abc9_holes A:abc9_holes"); + run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); active_design->selection_stack.emplace_back(false); -- cgit v1.2.3 From 559f3379e852f304a0255afcc37714b9d0da59d9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 14:37:58 -0800 Subject: Preserve topo ordering from -prep_holes to write_xaiger --- passes/techmap/abc9.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 25fe3fbc8..af37ecb5c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -187,17 +187,13 @@ struct Abc9Pass : public ScriptPass { run("scc -set_attr abc9_scc_id {}"); run("abc9_ops -break_scc"/*" -prep_holes"*/); -// run("select -set abc9_holes A:abc9_holes"); -// run("dump @abc9_holes"); // run("flatten -wb @abc9_holes"); // run("techmap @abc9_holes"); run("aigmap"); + run("abc9_ops -prep_holes"); if (dff_mode) run("abc9_ops -prep_dff"); // run("opt -purge @abc9_holes"); - - run("abc9_ops -prep_holes"); - run("select -set abc9_holes A:abc9_holes"); run("wbflip @abc9_holes"); -- cgit v1.2.3 From a819656972dd44c479422fa688874926d6239a95 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 14:59:55 -0800 Subject: WIP --- passes/techmap/abc9.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index af37ecb5c..da56f42ea 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -186,15 +186,17 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"/*" -prep_holes"*/); -// run("flatten -wb @abc9_holes"); -// run("techmap @abc9_holes"); + run("abc9_ops -break_scc"); run("aigmap"); + run("abc9_ops -prep_holes"); + run("select -set abc9_holes A:abc9_holes"); + run("flatten -wb @abc9_holes"); + run("techmap @abc9_holes"); + run("aigmap @abc9_holes"); if (dff_mode) run("abc9_ops -prep_dff"); -// run("opt -purge @abc9_holes"); - run("select -set abc9_holes A:abc9_holes"); + run("opt -purge @abc9_holes"); run("wbflip @abc9_holes"); auto selected_modules = active_design->selected_modules(); -- cgit v1.2.3 From 930f03e8830ed8a8023ff88207b97e757ae8496c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 15:38:18 -0800 Subject: Call -prep_holes before aigmap; fix topo ordering --- passes/techmap/abc9.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index da56f42ea..0da815870 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -186,14 +186,11 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc"); - run("aigmap"); - - run("abc9_ops -prep_holes"); + run("abc9_ops -break_scc -prep_holes"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); - run("aigmap @abc9_holes"); + run("aigmap"); if (dff_mode) run("abc9_ops -prep_dff"); run("opt -purge @abc9_holes"); -- cgit v1.2.3 From 6556a1347ab56b022a599835071c6b3059787462 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 4 Jan 2020 09:17:01 -0800 Subject: Fix when -dff not given --- passes/techmap/abc9.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0da815870..d51ed3352 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -186,7 +186,10 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { run("scc -set_attr abc9_scc_id {}"); - run("abc9_ops -break_scc -prep_holes"); + if (help_mode) + run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); + else + run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); -- cgit v1.2.3 From 36ae2e52e49ee510a0bec45e7faa4ed60fdc760d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 12:28:58 -0800 Subject: Fix bad merge --- passes/techmap/abc9.cc | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index d54891167..94eea2983 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -146,23 +146,8 @@ struct Abc9Pass : public ScriptPass clear_flags(); // get arguments from scratchpad first, then override by command arguments - std::string lut_arg, luts_arg; - exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); - script_file = design->scratchpad_get_string("abc9.script", script_file); - if (design->scratchpad.count("abc9.D")) { - delay_target = "-D " + design->scratchpad_get_string("abc9.D"); - } - lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); - luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); - fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode); cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup); - show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); - box_file = design->scratchpad_get_string("abc9.box", box_file); - if (design->scratchpad.count("abc9.W")) { - wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); - } - nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -224,10 +209,10 @@ struct Abc9Pass : public ScriptPass log("Skipping module %s as it contains processes.\n", log_id(mod)); continue; } - log_assert(!module->attributes.count(ID(abc9_box_id))); + log_assert(!mod->attributes.count(ID(abc9_box_id))); - if (!design->selected_whole_module(module)) - log_error("Can't handle partially selected module %s!\n", log_id(module)); + if (!active_design->selected_whole_module(mod)) + log_error("Can't handle partially selected module %s!\n", log_id(mod)); active_design->selection().select(mod); -- cgit v1.2.3 From 2bf442ca011a1495c7c0960e9ea4452fa7e934b5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 13:02:04 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 94eea2983..c7db4f557 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -202,20 +202,17 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { - if (mod->get_blackbox_attribute()) - continue; - if (mod->processes.size() > 0) { log("Skipping module %s as it contains processes.\n", log_id(mod)); continue; } log_assert(!mod->attributes.count(ID(abc9_box_id))); + active_design->selection().select(mod); + if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); - active_design->selection().select(mod); - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; if (!cleanup) tempdir_name[0] = tempdir_name[4] = '_'; -- cgit v1.2.3 From cf3a13746d27fee141700e2c6ea40d528267190f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 15:52:59 -0800 Subject: Add abc9_ops -reintegrate; moved out from now abc9_exe --- passes/techmap/abc9.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c7db4f557..7c261e220 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -129,13 +129,13 @@ struct Abc9Pass : public ScriptPass log("\n"); } - std::stringstream map_cmd; + std::stringstream exe_cmd; bool dff_mode, cleanup; void clear_flags() YS_OVERRIDE { - map_cmd.str(""); - map_cmd << "abc9_map"; + exe_cmd.str(""); + exe_cmd << "abc9_exe"; dff_mode = false; cleanup = true; } @@ -156,13 +156,13 @@ struct Abc9Pass : public ScriptPass /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || arg == "-box" || arg == "-W") && argidx+1 < args.size()) { - map_cmd << " " << arg << " " << args[++argidx]; + exe_cmd << " " << arg << " " << args[++argidx]; continue; } if (arg == "-fast" || /* arg == "-dff" || */ /* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-nomfs") { - map_cmd << " " << arg; + exe_cmd << " " << arg; continue; } if (arg == "-dff") { @@ -219,9 +219,13 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), - "write_xaiger -map /input.sym /input.xaig"); - run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_map [options] -tempdir "); + "write_xaiger -map /input.sym /input.xaig"); + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_exe [options] -cwd "); + + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), + "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run("abc9_ops -reintegrate"); if (cleanup) { -- cgit v1.2.3 From 5d9050a9551628f838ee419404cf1b1d3920a3ed Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 7 Jan 2020 08:00:32 -0800 Subject: abc_exe: move 'count_outputs' check to abc --- passes/techmap/abc9.cc | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7c261e220..0a5454d99 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -219,16 +219,25 @@ struct Abc9Pass : public ScriptPass tempdir_name = make_temp_dir(tempdir_name); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), - "write_xaiger -map /input.sym /input.xaig"); - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); - run("abc9_ops -reintegrate"); + "write_xaiger -map /input.sym /input.xaig"); + + int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); + log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + active_design->scratchpad_get_int("write_xaiger.num_ands"), + active_design->scratchpad_get_int("write_xaiger.num_wires"), + active_design->scratchpad_get_int("write_xaiger.num_inputs"), + num_outputs); + if (num_outputs) { + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_exe [options] -cwd "); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), + "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run("abc9_ops -reintegrate"); + } + else + log("Don't call ABC as there is nothing to map.\n"); - if (cleanup) - { + if (cleanup) { log("Removing temp directory.\n"); remove_directory(tempdir_name); } -- cgit v1.2.3 From 8a47e6ddfdb49ec172f783621a64b3a8906ff5d6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 10:00:50 -0800 Subject: Fix abc9 help, add labels --- passes/techmap/abc9.cc | 129 +++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 58 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0a5454d99..f6627602b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -184,70 +184,83 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { - run("scc -set_attr abc9_scc_id {}"); - if (help_mode) - run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); - else - run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); - run("select -set abc9_holes A:abc9_holes"); - run("flatten -wb @abc9_holes"); - run("techmap @abc9_holes"); - run("aigmap"); - if (dff_mode) - run("abc9_ops -prep_dff"); - run("opt -purge @abc9_holes"); - run("wbflip @abc9_holes"); - - auto selected_modules = active_design->selected_modules(); - active_design->selection_stack.emplace_back(false); - - for (auto mod : selected_modules) { - if (mod->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", log_id(mod)); - continue; - } - log_assert(!mod->attributes.count(ID(abc9_box_id))); - - active_design->selection().select(mod); - - if (!active_design->selected_whole_module(mod)) - log_error("Can't handle partially selected module %s!\n", log_id(mod)); - - std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; - if (!cleanup) - tempdir_name[0] = tempdir_name[4] = '_'; - tempdir_name = make_temp_dir(tempdir_name); - - run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()), - "write_xaiger -map /input.sym /input.xaig"); - - int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); - log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", - active_design->scratchpad_get_int("write_xaiger.num_ands"), - active_design->scratchpad_get_int("write_xaiger.num_wires"), - active_design->scratchpad_get_int("write_xaiger.num_inputs"), - num_outputs); - if (num_outputs) { - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); - run("abc9_ops -reintegrate"); - } + if (check_label("pre")) { + run("scc -set_attr abc9_scc_id {}"); + if (help_mode) + run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); else - log("Don't call ABC as there is nothing to map.\n"); + run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("select -set abc9_holes A:abc9_holes"); + run("flatten -wb @abc9_holes"); + run("techmap @abc9_holes"); + run("aigmap"); + if (dff_mode || help_mode) + run("abc9_ops -prep_dff", "(only if -dff)"); + run("opt -purge @abc9_holes"); + run("wbflip @abc9_holes"); + } - if (cleanup) { - log("Removing temp directory.\n"); - remove_directory(tempdir_name); + if (check_label("map")) { + if (help_mode) { + run("foreach module in selection"); + run(" write_xaiger -map /input.sym /input.xaig"); + run(" abc9_exe [options] -cwd "); + run(" read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run(" abc9_ops -reintegrate"); } + else { + auto selected_modules = active_design->selected_modules(); + active_design->selection_stack.emplace_back(false); - active_design->selection().selected_modules.clear(); - } + for (auto mod : selected_modules) { + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); + continue; + } + log_assert(!mod->attributes.count(ID(abc9_box_id))); + + active_design->selection().select(mod); + + if (!active_design->selected_whole_module(mod)) + log_error("Can't handle partially selected module %s!\n", log_id(mod)); - active_design->selection_stack.pop_back(); + std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; + if (!cleanup) + tempdir_name[0] = tempdir_name[4] = '_'; + tempdir_name = make_temp_dir(tempdir_name); + + run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); + + int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); + log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + active_design->scratchpad_get_int("write_xaiger.num_ands"), + active_design->scratchpad_get_int("write_xaiger.num_wires"), + active_design->scratchpad_get_int("write_xaiger.num_inputs"), + num_outputs); + if (num_outputs) { + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), + "abc9_exe [options] -cwd "); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), + "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run("abc9_ops -reintegrate"); + } + else + log("Don't call ABC as there is nothing to map.\n"); + + if (cleanup) { + log("Removing temp directory.\n"); + remove_directory(tempdir_name); + } + + active_design->selection().selected_modules.clear(); + } + + active_design->selection_stack.pop_back(); + } + } - run("abc9_ops -unbreak_scc"); + if (check_label("post")) + run("abc9_ops -unbreak_scc"); } } Abc9Pass; -- cgit v1.2.3 From 88f14b8bca811a3945aa642ccd50d22ffa0adcbd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 8 Jan 2020 10:02:45 -0800 Subject: Cleanup --- passes/techmap/abc9.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f6627602b..ba5f97626 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -204,7 +204,7 @@ struct Abc9Pass : public ScriptPass if (help_mode) { run("foreach module in selection"); run(" write_xaiger -map /input.sym /input.xaig"); - run(" abc9_exe [options] -cwd "); + run(" abc9_exe -cwd [options]"); run(" read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); run(" abc9_ops -reintegrate"); } @@ -238,10 +238,8 @@ struct Abc9Pass : public ScriptPass active_design->scratchpad_get_int("write_xaiger.num_inputs"), num_outputs); if (num_outputs) { - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str())); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str())); run("abc9_ops -reintegrate"); } else -- cgit v1.2.3 From b2259a920165930261050065d870d03fc7573346 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 10 Jan 2020 11:45:41 -0800 Subject: Add abc9_ops -check, -prep_times, -write_box for required times --- passes/techmap/abc9.cc | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f6627602b..41cfdeece 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -131,6 +131,7 @@ struct Abc9Pass : public ScriptPass std::stringstream exe_cmd; bool dff_mode, cleanup; + std::string box_file; void clear_flags() YS_OVERRIDE { @@ -138,6 +139,7 @@ struct Abc9Pass : public ScriptPass exe_cmd << "abc9_exe"; dff_mode = false; cleanup = true; + box_file.clear(); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -154,7 +156,7 @@ struct Abc9Pass : public ScriptPass std::string arg = args[argidx]; if ((arg == "-exe" || arg == "-script" || arg == "-D" || /* arg == "-S" || */ arg == "-lut" || arg == "-luts" || - arg == "-box" || arg == "-W") && + /*arg == "-box" ||*/ arg == "-W") && argidx+1 < args.size()) { exe_cmd << " " << arg << " " << args[++argidx]; continue; @@ -173,6 +175,10 @@ struct Abc9Pass : public ScriptPass cleanup = false; continue; } + if (arg == "-box" && argidx+1 < args.size()) { + box_file = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -185,11 +191,12 @@ struct Abc9Pass : public ScriptPass void script() YS_OVERRIDE { if (check_label("pre")) { + run("abc9_ops -check"); run("scc -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); + run("abc9_ops -break_scc -prep_times -prep_holes [-dff]", "(option for -dff)"); else - run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("abc9_ops -break_scc -prep_times -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); @@ -203,8 +210,9 @@ struct Abc9Pass : public ScriptPass if (check_label("map")) { if (help_mode) { run("foreach module in selection"); + run(" abc9_ops -write_box [(-box value)|(null)] /input.box"); run(" write_xaiger -map /input.sym /input.xaig"); - run(" abc9_exe [options] -cwd "); + run(" abc9_exe [options] -cwd -box /input.box"); run(" read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); run(" abc9_ops -reintegrate"); } @@ -229,6 +237,10 @@ struct Abc9Pass : public ScriptPass tempdir_name[0] = tempdir_name[4] = '_'; tempdir_name = make_temp_dir(tempdir_name); + if (box_file.empty()) + run(stringf("abc9_ops -write_box (null) %s/input.box", tempdir_name.c_str())); + else + run(stringf("abc9_ops -write_box %s %s/input.box", box_file.c_str(), tempdir_name.c_str())); run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); @@ -238,10 +250,8 @@ struct Abc9Pass : public ScriptPass active_design->scratchpad_get_int("write_xaiger.num_inputs"), num_outputs); if (num_outputs) { - run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()), - "abc9_exe [options] -cwd "); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()), - "read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); + run(stringf("%s -cwd %s -box %s/input.box", exe_cmd.str().c_str(), tempdir_name.c_str(), tempdir_name.c_str())); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str())); run("abc9_ops -reintegrate"); } else -- cgit v1.2.3 From 784fec93c901caa6f9d980388356d120b0cdfea9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 08:42:58 -0800 Subject: abc9: cleanup --- passes/techmap/abc9.cc | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f6627602b..2af0676b1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -26,9 +26,6 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate - // to one LUT6 (instead of a LUT5 + LUT2) - struct Abc9Pass : public ScriptPass { Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } @@ -39,8 +36,9 @@ struct Abc9Pass : public ScriptPass log("\n"); log(" abc9 [options] [selection]\n"); log("\n"); - log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); - log("library to a target architecture. Only fully-selected modules are supported.\n"); + log("This script pass performs a sequence of commands to facilitate the use of the ABC\n"); + log("tool [1] for technology mapping of the current design to a target FPGA\n"); + log("architecture. Only fully-selected modules are supported.\n"); log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL @@ -59,21 +57,13 @@ struct Abc9Pass : public ScriptPass log(" replaced with blanks before the string is passed to ABC.\n"); log("\n"); log(" if no -script parameter is given, the following scripts are used:\n"); - log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - // FIXME - //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - // FIXME + //FIXME: //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); log("\n"); log(" -fast\n"); log(" use different default scripts that are slightly faster (at the cost\n"); log(" of output quality):\n"); - log("\n"); - log(" for -lut/-luts:\n"); - // FIXME + //FIXME: //log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); log("\n"); log(" -D \n"); -- cgit v1.2.3 From 295e241c074ae275e832fdde9fae6fd897170ac8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 17:28:24 -0800 Subject: cleanup --- passes/techmap/abc9.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 30b62dc79..5d6d8904c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -182,12 +182,10 @@ struct Abc9Pass : public ScriptPass run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); -run("dump @abc9_holes"); run("techmap @abc9_holes"); if (dff_mode || help_mode) run("abc9_ops -prep_dff", "(only if -dff)"); run("opt -purge @abc9_holes"); -run("dump @abc9_holes"); run("aigmap"); run("wbflip @abc9_holes"); } -- cgit v1.2.3 From 808b388e34f3cededd450de35555476874cf2799 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 09:43:57 -0800 Subject: abc9: log which module is being operated on --- passes/techmap/abc9.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2ded1c162..2e3df773e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -276,9 +276,11 @@ struct Abc9Pass : public ScriptPass run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs"); - log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n", + + log("Extracted %d AND gates and %d wires from module `%s' to a netlist network with %d inputs and %d outputs.\n", active_design->scratchpad_get_int("write_xaiger.num_ands"), active_design->scratchpad_get_int("write_xaiger.num_wires"), + log_id(mod), active_design->scratchpad_get_int("write_xaiger.num_inputs"), num_outputs); if (num_outputs) { -- cgit v1.2.3 From a2c4d98da70744253ccbe253083ef9df5fa39305 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 19:22:23 -0800 Subject: abc9: add -run option --- passes/techmap/abc9.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2e3df773e..2627ab9ca 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -91,6 +91,11 @@ struct Abc9Pass : public ScriptPass log("tool [1] for technology mapping of the current design to a target FPGA\n"); log("architecture. Only fully-selected modules are supported.\n"); log("\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); log(" -exe \n"); #ifdef ABCEXTERNAL log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n"); @@ -210,13 +215,21 @@ struct Abc9Pass : public ScriptPass } if (arg == "-dff") { dff_mode = true; - exe_cmd << " " << arg; + exe_cmd << " " << arg; continue; } if (arg == "-nocleanup") { cleanup = false; continue; } + if (arg == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } break; } extra_args(args, argidx, design); -- cgit v1.2.3 From 2c65e1abacc4401c4fd3e9b48f52c4de120bc511 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 21:45:27 -0800 Subject: abc9: break SCC by setting (* keep *) on output wires --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2627ab9ca..dad40be63 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -298,7 +298,7 @@ struct Abc9Pass : public ScriptPass num_outputs); if (num_outputs) { run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str())); - run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str())); + run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str())); run("abc9_ops -reintegrate"); } else -- cgit v1.2.3 From 531fddf797a79b46df3e462112ca68ff50e6a18e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 23:42:27 -0800 Subject: abc9_ops: -break_scc -> -mark_scc using (* keep *), remove -unbreak_scc --- passes/techmap/abc9.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index dad40be63..c7fe05795 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -244,9 +244,9 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("scc -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)"); + run("abc9_ops -mark_scc -prep_holes [-dff]", "(option for -dff)"); else - run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("abc9_ops -mark_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); @@ -315,9 +315,6 @@ struct Abc9Pass : public ScriptPass active_design->selection_stack.pop_back(); } } - - if (check_label("post")) - run("abc9_ops -unbreak_scc"); } } Abc9Pass; -- cgit v1.2.3 From 468386d67d902722562e9a0412a76fca79ec4fa2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 12:25:45 -0800 Subject: abc9_ops: -prep_holes -> -prep_xaiger, move padding to write_xaiger --- passes/techmap/abc9.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c7fe05795..6a296bfe7 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -244,9 +244,9 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("scc -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -mark_scc -prep_holes [-dff]", "(option for -dff)"); + run("abc9_ops -mark_scc -prep_xaiger [-dff]", "(option for -dff)"); else - run("abc9_ops -mark_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("abc9_ops -mark_scc -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); -- cgit v1.2.3 From ec95fbb273872ed41e2baadb644a311d31c3ee79 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 13:21:58 -0800 Subject: abc9_ops: -prep_times -> -prep_delays; add doc --- passes/techmap/abc9.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5ba87fa88..dde0a11d4 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -251,9 +251,9 @@ struct Abc9Pass : public ScriptPass run("abc9_ops -check"); run("scc -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -mark_scc -prep_times -prep_xaiger [-dff]", "(option for -dff)"); + run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); else - run("abc9_ops -mark_scc -prep_times -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); + run("abc9_ops -mark_scc -prep_delays -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)"); run("select -set abc9_holes A:abc9_holes"); run("flatten -wb @abc9_holes"); run("techmap @abc9_holes"); @@ -267,7 +267,7 @@ struct Abc9Pass : public ScriptPass if (check_label("map")) { if (help_mode) { run("foreach module in selection"); - run(" abc9_ops -write_box [(-box )|(null)] /input.box"); + run(" abc9_ops -write_box [|(null)] /input.box"); run(" write_xaiger -map /input.sym /input.xaig"); run(" abc9_exe [options] -cwd -box /input.box"); run(" read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig"); -- cgit v1.2.3 From d4e188299ba729756ee689d14c81aab68a7ca1b7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Jan 2020 12:00:14 -0800 Subject: abc9: add some log_{push,pop}() as per @nakengelhardt --- passes/techmap/abc9.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6a296bfe7..f4a89efff 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -235,8 +235,11 @@ struct Abc9Pass : public ScriptPass extra_args(args, argidx, design); log_header(design, "Executing ABC9 pass.\n"); + log_push(); run_script(design, run_from, run_to); + + log_pop(); } void script() YS_OVERRIDE @@ -276,6 +279,7 @@ struct Abc9Pass : public ScriptPass } log_assert(!mod->attributes.count(ID(abc9_box_id))); + log_push(); active_design->selection().select(mod); if (!active_design->selected_whole_module(mod)) @@ -310,6 +314,7 @@ struct Abc9Pass : public ScriptPass } active_design->selection().selected_modules.clear(); + log_pop(); } active_design->selection_stack.pop_back(); -- cgit v1.2.3 From 245873d42d7975b6c303c2d04b75f3cafc6c5697 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 23 Jan 2020 19:08:51 -0800 Subject: abc9: warning message if no modules selected --- passes/techmap/abc9.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'passes/techmap/abc9.cc') diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f4a89efff..2aeda16d6 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -234,6 +234,12 @@ struct Abc9Pass : public ScriptPass } extra_args(args, argidx, design); + log_assert(design); + if (design->selected_modules().empty()) { + log_warning("No modules selected for ABC9 techmapping.\n"); + return; + } + log_header(design, "Executing ABC9 pass.\n"); log_push(); -- cgit v1.2.3