From 091bf4a18b2f4bf84fe62b61577c88d961468b3c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:16:37 -0700 Subject: [PATCH] Remove sequential extension --- backends/aiger/xaiger.cc | 299 ++++---------------------------- frontends/aiger/aigerparse.cc | 35 +--- passes/techmap/abc9.cc | 88 +++------- techlibs/xilinx/abc_map.v | 97 ----------- techlibs/xilinx/abc_model.v | 89 ---------- techlibs/xilinx/abc_unmap.v | 119 ------------- techlibs/xilinx/abc_xc7.box | 41 ----- techlibs/xilinx/cells_sim.v | 24 ++- techlibs/xilinx/synth_xilinx.cc | 6 +- 9 files changed, 68 insertions(+), 730 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index d02997da4..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -76,32 +76,25 @@ void aiger_encode(std::ostream &f, int x) struct XAigerWriter { Module *module; - bool zinit_mode; SigMap sigmap; - dict init_map; pool input_bits, output_bits; - dict not_map, ff_map, alias_map; + dict not_map, alias_map; dict> and_map; vector> ci_bits; vector> co_bits; - vector ff_bits; dict arrival_times; vector> aig_gates; - vector aig_latchin, aig_latchinit, aig_outputs; + vector aig_outputs; int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; dict aig_map; dict ordered_outputs; - dict ordered_latches; vector box_list; bool omode = false; - //dict init_inputs; - //int initstate_ff = 0; - int mkgate(int a0, int a1) { aig_m++, aig_a++; @@ -144,7 +137,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool zinit_mode, bool holes_mode=false) : module(module), zinit_mode(zinit_mode), sigmap(module) + XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -167,14 +160,6 @@ struct XAigerWriter for (auto wire : module->wires()) { - if (wire->attributes.count("\\init")) { - SigSpec initsig = sigmap(wire); - Const initval = wire->attributes.at("\\init"); - for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - init_map[initsig[i]] = initval[i] == State::S1; - } - bool keep = wire->attributes.count("\\keep"); for (int i = 0; i < GetSize(wire); i++) @@ -218,12 +203,6 @@ struct XAigerWriter // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; TopoSort toposort; - struct flop_data_t { - IdString d_port; - IdString q_port; - int q_arrival; - }; - dict flop_data; bool abc_box_seen = false; for (auto cell : module->selected_cells()) { @@ -262,86 +241,25 @@ struct XAigerWriter log_assert(!holes_mode); - if (cell->type == "$__ABC_FF_") - { - SigBit D = sigmap(cell->getPort("\\D").as_bit()); - SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); - unused_bits.erase(D); - undriven_bits.erase(Q); - alias_map[Q] = D; - continue; - } - RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module && inst_module->attributes.count("\\abc_box_id")) { abc_box_seen = true; - toposort.node(cell->name); - - auto r = flop_data.insert(std::make_pair(cell->type, flop_data_t{IdString(), IdString(), 0})); - if (r.second && inst_module->attributes.count("\\abc_flop")) { - IdString &abc_flop_d = r.first->second.d_port; - IdString &abc_flop_q = r.first->second.q_port; - for (auto port_name : inst_module->ports) { - auto wire = inst_module->wire(port_name); - log_assert(wire); - if (wire->attributes.count("\\abc_flop_d")) { - if (abc_flop_d != IdString()) - log_error("More than one port has the 'abc_flop_d' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_d = port_name; + if (!holes_mode) { + toposort.node(cell->name); + for (const auto &conn : cell->connections()) { + auto port_wire = inst_module->wire(conn.first); + if (port_wire->port_input) { + // Ignore inout for the sake of topographical ordering + if (port_wire->port_output) continue; + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); } - if (wire->attributes.count("\\abc_flop_q")) { - if (abc_flop_q != IdString()) - log_error("More than one port has the 'abc_flop_q' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_q = port_name; - auto it = wire->attributes.find("\\abc_arrival"); - if (it != wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); - r.first->second.q_arrival = it->second.as_int(); - } - } + if (port_wire->port_output) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } - if (abc_flop_d == IdString()) - log_error("'abc_flop_d' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - if (abc_flop_q == IdString()) - log_error("'abc_flop_q' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - } - - auto abc_flop_d = r.first->second.d_port; - if (abc_flop_d != IdString()) { - SigBit d = cell->getPort(abc_flop_d); - SigBit I = sigmap(d); - if (I != d) - alias_map[I] = d; - unused_bits.erase(d); - - auto abc_flop_q = r.first->second.q_port; - SigBit q = cell->getPort(abc_flop_q); - SigBit O = sigmap(q); - if (O != q) - alias_map[O] = q; - undriven_bits.erase(O); - ff_bits.emplace_back(q); - - auto arrival = r.first->second.q_arrival; - if (arrival) - arrival_times[q] = arrival; - } - - for (const auto &conn : cell->connections()) { - auto port_wire = inst_module->wire(conn.first); - if (port_wire->port_input) { - // Ignore inout for the sake of topographical ordering - if (port_wire->port_output) continue; - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - } - - if (port_wire->port_output) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); } } else { @@ -548,7 +466,6 @@ struct XAigerWriter log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } - init_map.sort(); if (holes_mode) { struct sort_by_port_id { bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { @@ -564,7 +481,6 @@ struct XAigerWriter } not_map.sort(); - ff_map.sort(); and_map.sort(); aig_map[State::S0] = 0; @@ -576,77 +492,12 @@ struct XAigerWriter aig_map[bit] = 2*aig_m; } - for (auto bit : ff_bits) { - aig_m++, aig_i++; - log_assert(!aig_map.count(bit)); - aig_map[bit] = 2*aig_m; - } - - dict ff_aig_map; for (auto &c : ci_bits) { RTLIL::SigBit bit = std::get<0>(c); aig_m++, aig_i++; - auto r = aig_map.insert(std::make_pair(bit, 2*aig_m)); - if (!r.second) - ff_aig_map[bit] = 2*aig_m; + aig_map[bit] = 2*aig_m; } - //if (zinit_mode) - //{ - // for (auto it : ff_map) { - // if (init_map.count(it.first)) - // continue; - // aig_m++, aig_i++; - // init_inputs[it.first] = 2*aig_m; - // } - //} - - //for (auto it : ff_map) { - // aig_m++, aig_l++; - // aig_map[it.first] = 2*aig_m; - // ordered_latches[it.first] = aig_l-1; - // if (init_map.count(it.first) == 0) - // aig_latchinit.push_back(2); - // else - // aig_latchinit.push_back(init_map.at(it.first) ? 1 : 0); - //} - - //if (!init_inputs.empty()) { - // aig_m++, aig_l++; - // initstate_ff = 2*aig_m+1; - // aig_latchinit.push_back(0); - //} - - //if (zinit_mode) - //{ - // for (auto it : ff_map) - // { - // int l = ordered_latches[it.first]; - - // if (aig_latchinit.at(l) == 1) - // aig_map[it.first] ^= 1; - - // if (aig_latchinit.at(l) == 2) - // { - // int gated_ffout = mkgate(aig_map[it.first], initstate_ff^1); - // int gated_initin = mkgate(init_inputs[it.first], initstate_ff); - // aig_map[it.first] = mkgate(gated_ffout^1, gated_initin^1)^1; - // } - // } - //} - - //for (auto it : ff_map) { - // int a = bit2aig(it.second); - // int l = ordered_latches[it.first]; - // if (zinit_mode && aig_latchinit.at(l) == 1) - // aig_latchin.push_back(a ^ 1); - // else - // aig_latchin.push_back(a); - //} - - //if (!init_inputs.empty()) - // aig_latchin.push_back(1); - for (auto &c : co_bits) { RTLIL::SigBit bit = std::get<0>(c); std::get<4>(c) = ordered_outputs[bit] = aig_o++; @@ -658,11 +509,6 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - for (auto bit : ff_bits) { - aig_o++; - aig_outputs.push_back(ff_aig_map.at(bit)); - } - if (output_bits.empty()) { aig_o++; aig_outputs.push_back(0); @@ -677,8 +523,6 @@ struct XAigerWriter int aig_obcjf = aig_obcj; log_assert(aig_m == aig_i + aig_l + aig_a); - log_assert(aig_l == GetSize(aig_latchin)); - log_assert(aig_l == GetSize(aig_latchinit)); log_assert(aig_obcjf == GetSize(aig_outputs)); f << stringf("%s %d %d %d %d %d", ascii_mode ? "aag" : "aig", aig_m, aig_i, aig_l, aig_o, aig_a); @@ -689,15 +533,6 @@ struct XAigerWriter for (int i = 0; i < aig_i; i++) f << stringf("%d\n", 2*i+2); - //for (int i = 0; i < aig_l; i++) { - // if (zinit_mode || aig_latchinit.at(i) == 0) - // f << stringf("%d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 1) - // f << stringf("%d %d 1\n", 2*(aig_i+i)+2, aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 2) - // f << stringf("%d %d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i), 2*(aig_i+i)+2); - //} - for (int i = 0; i < aig_obc; i++) f << stringf("%d\n", aig_outputs.at(i)); @@ -715,15 +550,6 @@ struct XAigerWriter } else { - //for (int i = 0; i < aig_l; i++) { - // if (zinit_mode || aig_latchinit.at(i) == 0) - // f << stringf("%d\n", aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 1) - // f << stringf("%d 1\n", aig_latchin.at(i)); - // else if (aig_latchinit.at(i) == 2) - // f << stringf("%d %d\n", aig_latchin.at(i), 2*(aig_i+i)+2); - //} - for (int i = 0; i < aig_obc; i++) f << stringf("%d\n", aig_outputs.at(i)); @@ -756,14 +582,14 @@ struct XAigerWriter std::stringstream h_buffer; auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); write_h_buffer(1); - log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ff_bits) + GetSize(ci_bits)); - write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size()); - log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(ff_bits) + GetSize(co_bits)); - write_h_buffer(output_bits.size() + GetSize(ff_bits) + GetSize(co_bits)); - log_debug("piNum = %d\n", GetSize(input_bits) + GetSize(ff_bits)); - write_h_buffer(input_bits.size() + ff_bits.size()); - log_debug("poNum = %d\n", GetSize(output_bits) + GetSize(ff_bits)); - write_h_buffer(output_bits.size() + ff_bits.size()); + log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); + write_h_buffer(input_bits.size() + ci_bits.size()); + log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); + write_h_buffer(output_bits.size() + GetSize(co_bits)); + log_debug("piNum = %d\n", GetSize(input_bits)); + write_h_buffer(input_bits.size()); + log_debug("poNum = %d\n", GetSize(output_bits)); + write_h_buffer(output_bits.size()); log_debug("boxNum = %d\n", GetSize(box_list)); write_h_buffer(box_list.size()); @@ -779,7 +605,7 @@ struct XAigerWriter //for (auto bit : output_bits) // write_o_buffer(0); - if (!box_list.empty() || !ff_bits.empty()) { + if (!box_list.empty()) { RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -845,41 +671,13 @@ struct XAigerWriter std::stringstream r_buffer; auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - log_debug("flopNum = %d\n", GetSize(ff_bits)); - write_r_buffer(ff_bits.size()); - int mergeability_class = 1; - for (auto bit : ff_bits) { - write_r_buffer(mergeability_class++); - write_i_buffer(arrival_times.at(bit, 0)); - //write_o_buffer(0); - } - + write_r_buffer(0); f << "r"; std::string buffer_str = r_buffer.str(); int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - std::stringstream s_buffer; - auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1); - write_s_buffer(ff_bits.size()); - for (auto bit : ff_bits) { - auto it = bit.wire->attributes.find("\\init"); - if (it != bit.wire->attributes.end()) { - auto init = it->second[bit.offset]; - if (init == RTLIL::S1) { - write_s_buffer(1); - continue; - } - } - write_s_buffer(0); - } - f << "s"; - buffer_str = s_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - if (holes_module) { log_push(); @@ -915,7 +713,7 @@ struct XAigerWriter Pass::call(holes_design, "clean -purge"); std::stringstream a_buffer; - XAigerWriter writer(holes_module, false /*zinit_mode*/, true /* holes_mode */); + XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); delete holes_design; @@ -953,9 +751,7 @@ struct XAigerWriter void write_map(std::ostream &f, bool verbose_map) { dict input_lines; - dict init_lines; dict output_lines; - dict latch_lines; dict wire_lines; for (auto wire : module->wires()) @@ -976,30 +772,10 @@ struct XAigerWriter if (output_bits.count(b)) { int o = ordered_outputs.at(b); - int init = 2; - auto it = init_map.find(b); - if (it != init_map.end()) - init = it->second ? 1 : 0; - output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); + output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), i, log_id(wire)); continue; } - //if (init_inputs.count(sig[i])) { - // int a = init_inputs.at(sig[i]); - // log_assert((a & 1) == 0); - // init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, i, log_id(wire)); - // continue; - //} - - //if (ordered_latches.count(sig[i])) { - // int l = ordered_latches.at(sig[i]); - // if (zinit_mode && (aig_latchinit.at(l) == 1)) - // latch_lines[l] += stringf("invlatch %d %d %s\n", l, i, log_id(wire)); - // else - // latch_lines[l] += stringf("latch %d %d %s\n", l, i, log_id(wire)); - // continue; - //} - if (verbose_map) { if (aig_map.count(sig[i]) == 0) continue; @@ -1015,10 +791,6 @@ struct XAigerWriter f << it.second; log_assert(input_lines.size() == input_bits.size()); - init_lines.sort(); - for (auto &it : init_lines) - f << it.second; - int box_count = 0; for (auto cell : box_list) f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); @@ -1030,10 +802,6 @@ struct XAigerWriter if (omode && output_bits.empty()) f << "output " << output_lines.size() << " 0 $__dummy__\n"; - latch_lines.sort(); - for (auto &it : latch_lines) - f << it.second; - wire_lines.sort(); for (auto &it : wire_lines) f << it.second; @@ -1054,10 +822,6 @@ struct XAigerBackend : public Backend { log(" -ascii\n"); log(" write ASCII version of AIGER format\n"); log("\n"); - log(" -zinit\n"); - log(" convert FFs to zero-initialized FFs, adding additional inputs for\n"); - log(" uninitialized FFs.\n"); - log("\n"); log(" -map \n"); log(" write an extra file with port and latch symbols\n"); log("\n"); @@ -1068,7 +832,6 @@ struct XAigerBackend : public Backend { void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) YS_OVERRIDE { bool ascii_mode = false; - bool zinit_mode = false; bool verbose_map = false; std::string map_filename; @@ -1081,10 +844,6 @@ struct XAigerBackend : public Backend { ascii_mode = true; continue; } - if (args[argidx] == "-zinit") { - zinit_mode = true; - continue; - } if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) { map_filename = args[++argidx]; continue; @@ -1103,7 +862,7 @@ struct XAigerBackend : public Backend { if (top_module == nullptr) log_error("Can't find top module in current design!\n"); - XAigerWriter writer(top_module, zinit_mode); + XAigerWriter writer(top_module); writer.write_aiger(*f, ascii_mode); if (!map_filename.empty()) { diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 7a467b91e..e8ee487e5 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -732,19 +732,12 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { pool seen_boxes; - pool flops; - unsigned ci_count = 0, co_count = 0, flop_count = 0; + unsigned ci_count = 0, co_count = 0; for (auto cell : boxes) { RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); - bool is_flop = false; if (seen_boxes.insert(cell->type).second) { - if (box_module->attributes.count("\\abc_flop")) { - log_assert(flop_count < flopNum); - flops.insert(cell->type); - is_flop = true; - } auto it = box_module->attributes.find("\\abc_carry"); if (it != box_module->attributes.end()) { RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; @@ -784,8 +777,6 @@ void AigerReader::post_process() carry_out->port_id = ports.size(); } } - else - is_flop = flops.count(cell->type); // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) @@ -812,25 +803,7 @@ void AigerReader::post_process() rhs.append(wire); } - if (!is_flop || port_name != "\\$pastQ") - cell->setPort(port_name, rhs); - } - - if (is_flop) { - RTLIL::Wire *d = outputs[outputs.size() - flopNum + flop_count]; - log_assert(d); - log_assert(d->port_output); - d->port_output = false; - - RTLIL::Wire *q = inputs[piNum - flopNum + flop_count]; - log_assert(q); - log_assert(q->port_input); - q->port_input = false; - - flop_count++; - module->connect(q, d); - cell->set_bool_attribute("\\abc_flop"); - continue; + cell->setPort(port_name, rhs); } } @@ -934,10 +907,6 @@ void AigerReader::post_process() } } log_debug(" -> %s\n", log_id(wire)); - int init; - mf >> init; - if (init < 2) - wire->attributes["\\init"] = init; } else if (type == "box") { RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 29929f80b..919c4ce53 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -551,7 +551,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict abc_box; vector boxes; for (auto cell : module->selected_cells()) { - if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC_FF_))) { + if (cell->type.in(ID($_AND_), ID($_NOT_))) { module->remove(cell); continue; } @@ -651,7 +651,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->attributes = mapped_cell->attributes; } - auto abc_flop = mapped_cell->attributes.count("\\abc_flop"); for (auto &conn : mapped_cell->connections()) { RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { @@ -664,17 +663,15 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } cell->setPort(conn.first, newsig); - if (!abc_flop) { - if (cell->input(conn.first)) { - for (auto i : newsig) - bit2sinks[i].push_back(cell); - for (auto i : conn.second) - bit_users[i].insert(mapped_cell->name); - } - if (cell->output(conn.first)) - for (auto i : conn.second) - bit_drivers[i].insert(mapped_cell->name); + if (cell->input(conn.first)) { + for (auto i : newsig) + bit2sinks[i].push_back(cell); + for (auto i : conn.second) + bit_users[i].insert(mapped_cell->name); } + if (cell->output(conn.first)) + for (auto i : conn.second) + bit_drivers[i].insert(mapped_cell->name); } } @@ -1170,7 +1167,6 @@ struct Abc9Pass : public Pass { assign_map.set(mod); if (!dff_mode || !clk_str.empty()) { - design->selection_stack.emplace_back(false); RTLIL::Selection& sel = design->selection_stack.back(); sel.select(mod); @@ -1198,13 +1194,6 @@ struct Abc9Pass : public Pass { 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; - pool seen_cells; - struct flop_data_t { - IdString clk_port; - IdString en_port; - }; - dict flop_data; - for (auto cell : all_cells) { clkdomain_t key; @@ -1225,57 +1214,20 @@ struct Abc9Pass : public Pass { } } - decltype(flop_data)::iterator it; - if (seen_cells.insert(cell->type).second) { - RTLIL::Module* inst_module = design->module(cell->type); - if (!inst_module) - continue; - - if (!inst_module->attributes.count("\\abc_flop")) - continue; - - IdString abc_flop_clk, abc_flop_en; - for (auto port_name : inst_module->ports) { - auto wire = inst_module->wire(port_name); - log_assert(wire); - if (wire->attributes.count("\\abc_flop_clk")) { - if (abc_flop_clk != IdString()) - log_error("More than one port has the 'abc_flop_clk' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_clk = port_name; - } - if (wire->attributes.count("\\abc_flop_en")) { - if (abc_flop_en != IdString()) - log_error("More than one port has the 'abc_flop_en' attribute set on module '%s'.\n", log_id(cell->type)); - abc_flop_en = port_name; - } - } - - if (abc_flop_clk == IdString()) - log_error("'abc_flop_clk' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - if (abc_flop_en == IdString()) - log_error("'abc_flop_en' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - - it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_en})).first; + 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 { - it = flop_data.find(cell->type); - if (it == flop_data.end()) - continue; + 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; - const auto &data = it->second; - - auto jt = cell->parameters.find("\\CLK_POLARITY"); - if (jt == cell->parameters.end()) - log_error("'CLK_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); - bool this_clk_pol = jt->second.as_bool(); - - jt = cell->parameters.find("\\EN_POLARITY"); - if (jt == cell->parameters.end()) - log_error("'EN_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); - bool this_en_pol = jt->second.as_bool(); - - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.clk_port)), this_en_pol, assign_map(cell->getPort(data.en_port))); unassigned_cells.erase(cell); expand_queue.insert(cell); diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index a760b3d6d..121862692 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -20,103 +20,6 @@ // ============================================================================ -module FDRE (output reg Q, input C, CE, D, R); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_R_INVERTED = 1'b0; - wire \$nextQ ; - \$__ABC_FDRE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_R_INVERTED(IS_R_INVERTED), - .CLK_POLARITY(!IS_C_INVERTED), - .EN_POLARITY(1'b1) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); -endmodule -module FDRE_1 (output reg Q, input C, CE, D, R); - parameter [0:0] INIT = 1'b0; - wire \$nextQ ; - \$__ABC_FDRE_1 #( - .INIT(|0), - .CLK_POLARITY(1'b0), - .EN_POLARITY(1'b1) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); -endmodule - -module FDCE (output reg Q, input C, CE, D, CLR); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - wire \$nextQ , \$currQ ; - \$__ABC_FDCE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_CLR_INVERTED(IS_CLR_INVERTED), - .CLK_POLARITY(!IS_C_INVERTED), - .EN_POLARITY(1'b1) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); -endmodule -module FDCE_1 (output reg Q, input C, CE, D, CLR); - parameter [0:0] INIT = 1'b0; - wire \$nextQ , \$currQ ; - \$__ABC_FDCE_1 #( - .INIT(INIT), - .CLK_POLARITY(1'b0), - .EN_POLARITY(1'b1) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); -endmodule - -module FDPE (output reg Q, input C, CE, D, PRE); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - wire \$nextQ , \$currQ ; - \$__ABC_FDPE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_PRE_INVERTED(IS_PRE_INVERTED), - .CLK_POLARITY(!IS_C_INVERTED), - .EN_POLARITY(1'b1) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); -endmodule -module FDPE_1 (output reg Q, input C, CE, D, PRE); - parameter [0:0] INIT = 1'b0; - wire \$nextQ , \$currQ ; - \$__ABC_FDPE_1 #( - .INIT(INIT), - .CLK_POLARITY(1'b0), - .EN_POLARITY(1'b1) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); -endmodule - module RAM32X1D ( output DPO, SPO, input D, diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index 7162bd213..e3e9686b5 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -26,94 +26,6 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); : (S0 ? I1 : I0); endmodule -module \$__ABC_FF_ (input C, D, output Q); -endmodule - -(* abc_box_id = 1000 *) -module \$__ABC_ASYNC (input A, S, output Y); -endmodule - -(* abc_box_id=1001, lib_whitebox, abc_flop *) -module \$__ABC_FDRE ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_R_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); -endmodule - -(* abc_box_id=1002, lib_whitebox, abc_flop *) -module \$__ABC_FDRE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); -endmodule - -(* abc_box_id=1003, lib_whitebox, abc_flop *) -module \$__ABC_FDCE ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; -endmodule - -(* abc_box_id=1004, lib_whitebox, abc_flop *) -module \$__ABC_FDCE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !CLR) ? D : \$pastQ ; -endmodule - -(* abc_box_id=1005, lib_whitebox, abc_flop *) -module \$__ABC_FDPE ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; -endmodule - -(* abc_box_id=1006, lib_whitebox, abc_flop *) -module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, - (* abc_flop_clk *) input C, - (* abc_flop_en *) input CE, - (* abc_flop_d *) input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = (CE && !PRE) ? D : \$pastQ ; -endmodule - (* abc_box_id=2000 *) module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); endmodule @@ -121,7 +33,6 @@ endmodule module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y); endmodule - module \$__ABC_RAM32X1D ( // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 (* abc_arrival=1153 *) output DPO, SPO, diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v index d00d27e2e..779fc5aac 100644 --- a/techlibs/xilinx/abc_unmap.v +++ b/techlibs/xilinx/abc_unmap.v @@ -20,125 +20,6 @@ // ============================================================================ -module \$__ABC_ASYNC (input A, S, output Y); - assign Y = A; -endmodule - -module \$__ABC_FDRE (output Q, - input C, - input CE, - input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_R_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - - FDRE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_R_INVERTED(IS_R_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .R(R) - ); -endmodule - -module \$__ABC_FDRE_1 (output Q, - input C, - input CE, - input D, - input R, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); - - FDRE_1 #( - .INIT(INIT), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .R(R) - ); -endmodule - -module \$__ABC_FDCE (output Q, - input C, - input CE, - input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_CLR_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - - FDCE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_CLR_INVERTED(IS_CLR_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) - ); -endmodule - -module \$__ABC_FDCE_1 (output Q, - input C, - input CE, - input D, - input CLR, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - - FDCE_1 #( - .INIT(INIT), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) - ); -endmodule - -module \$__ABC_FDPE (output Q, - input C, - input CE, - input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 1'b0; - parameter [0:0] IS_D_INVERTED = 1'b0; - parameter [0:0] IS_PRE_INVERTED = 1'b0; - parameter CLK_POLARITY = !IS_C_INVERTED; - parameter EN_POLARITY = 1'b1; - - FDPE #( - .INIT(INIT), - .IS_C_INVERTED(IS_C_INVERTED), - .IS_D_INVERTED(IS_D_INVERTED), - .IS_PRE_INVERTED(IS_PRE_INVERTED), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) - ); -endmodule - -module \$__ABC_FDPE_1 (output Q, - input C, - input CE, - input D, - input PRE, \$pastQ ); - parameter [0:0] INIT = 1'b0; - parameter CLK_POLARITY = 1'b0; - parameter EN_POLARITY = 1'b1; - - FDPE_1 #( - .INIT(INIT), - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) - ); -endmodule - module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); assign Y = A; endmodule diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index c08af6320..61b89b8af 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -38,47 +38,6 @@ CARRY4 4 1 10 8 592 540 520 356 - 512 548 292 - 228 580 526 507 398 385 508 528 378 380 114 -# Box to emulate async behaviour of FD[CP]* -# Inputs: A S -# Outputs: Y -$__ABC_ASYNC 1000 0 2 1 -0 764 - -# The following FD*.{CE,R,CLR,PRE) are offset by 46ps to -# reflect the -46ps Tsu -# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 -# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 - -# Inputs: C CE D R \$pastQ -# Outputs: Q -FDRE 1001 1 5 1 -0 151 0 446 0 - -# Inputs: C CE D R \$pastQ -# Outputs: Q -FDRE_1 1002 1 5 1 -0 151 0 446 0 - -# Inputs: C CE CLR D \$pastQ -# Outputs: Q -FDCE 1003 1 5 1 -0 151 806 0 0 - -# Inputs: C CE CLR D \$pastQ -# Outputs: Q -FDCE_1 1004 1 5 1 -0 151 806 0 0 - -# Inputs: C CE D PRE \$pastQ -# Outputs: Q -FDPE 1005 1 5 1 -0 151 0 806 0 - -# Inputs: C CE D PRE \$pastQ -# Outputs: Q -FDPE_1 1006 1 5 1 -0 151 0 806 0 - # SLICEM/A6LUT # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} # Inputs: A S0 S1 S2 S3 S4 S5 diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 1ab718ccc..d879a56ee 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -211,7 +211,8 @@ endmodule `endif -module FDRE (output reg Q, input C, CE, D, R); +module FDRE ((* abc_arrival=303 *) output reg Q, + input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -223,7 +224,8 @@ module FDRE (output reg Q, input C, CE, D, R); endcase endgenerate endmodule -module FDSE (output reg Q, input C, CE, D, S); +module FDSE ((* abc_arrival=303 *) output reg Q, + input C, CE, D, S); parameter [0:0] INIT = 1'b1; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -235,7 +237,8 @@ module FDSE (output reg Q, input C, CE, D, S); endcase endgenerate endmodule -module FDCE (output reg Q, input C, CE, D, CLR); +module FDCE ((* abc_arrival=303 *) output reg Q, + input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -249,7 +252,8 @@ module FDCE (output reg Q, input C, CE, D, CLR); endcase endgenerate endmodule -module FDPE (output reg Q, input C, CE, D, PRE); +module FDPE ((* abc_arrival=303 *) output reg Q, + input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -263,25 +267,29 @@ module FDPE (output reg Q, input C, CE, D, PRE); endcase endgenerate endmodule -module FDRE_1 (output reg Q, input C, CE, D, R); +module FDRE_1 ((* abc_arrival=303 *) output reg Q, + input C, CE, D, R); parameter [0:0] INIT = 1'b0; initial Q <= INIT; always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D; endmodule -module FDSE_1 (output reg Q, input C, CE, D, S); +module FDSE_1 ((* abc_arrival=303 *) output reg Q, + input C, CE, D, S); parameter [0:0] INIT = 1'b1; initial Q <= INIT; always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; endmodule -module FDCE_1 (output reg Q, input C, CE, D, CLR); +module FDCE_1 ((* abc_arrival=303 *) output reg Q, + input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; initial Q <= INIT; always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; endmodule -module FDPE_1 (output reg Q, input C, CE, D, PRE); +module FDPE_1 ((* abc_arrival=303 *) output reg Q, + input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; initial Q <= INIT; always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index d28cd2428..b9c4df82f 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -379,8 +379,6 @@ struct SynthXilinxPass : public ScriptPass std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; if (widemux > 0) techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); - if (abc9) - techmap_args += " -map +/xilinx/ff_map.v"; run("techmap " + techmap_args); run("clean"); } @@ -411,11 +409,9 @@ struct SynthXilinxPass : public ScriptPass // has performed any necessary retiming if (!nosrl || help_mode) run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); - std::string techmap_args = "-map +/xilinx/lut_map.v"; + std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/ff_map.v"; if (abc9) techmap_args += " -map +/xilinx/abc_unmap.v"; - else - techmap_args += " -map +/xilinx/ff_map.v"; run("techmap " + techmap_args); run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");