From 357d36ef4fcc63db8c14b86dbeb10059030cc602 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:07:03 -0700 Subject: [PATCH 001/144] write_xaiger to treat abc_flop boxes as boxff for ABC --- backends/aiger/xaiger.cc | 225 ++++++++++++++++++--------------------- 1 file changed, 104 insertions(+), 121 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index df970e341..4810e0113 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -66,7 +66,6 @@ struct XAigerWriter pool input_bits, output_bits; dict not_map, ff_map, alias_map; dict> and_map; - //pool initstate_bits; vector> ci_bits; vector> co_bits; vector> ff_bits; @@ -97,10 +96,6 @@ struct XAigerWriter { aig_map[bit] = -1; - //if (initstate_bits.count(bit)) { - // log_assert(initstate_ff > 0); - // aig_map[bit] = initstate_ff; - //} else if (not_map.count(bit)) { int a = bit2aig(not_map.at(bit)) ^ 1; aig_map[bit] = a; @@ -207,16 +202,6 @@ struct XAigerWriter continue; } - //if (cell->type.in("$_FF_", "$_DFF_N_", "$_DFF_P_")) - //{ - // SigBit D = sigmap(cell->getPort("\\D").as_bit()); - // SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); - // unused_bits.erase(D); - // undriven_bits.erase(Q); - // ff_map[Q] = D; - // continue; - //} - if (cell->type == "$_AND_") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); @@ -237,61 +222,62 @@ struct XAigerWriter log_assert(!holes_mode); - //if (cell->type == "$initstate") + // FIXME: Should short here, rather than provide $_DFF_[NP]_ + // to ABC as a user cell + //if (cell->type.in(/*"$_FF_",*/ "$_DFF_N_", "$_DFF_P_")) //{ - // SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - // undriven_bits.erase(Y); - // initstate_bits.insert(Y); + // SigBit D = sigmap(cell->getPort("\\D").as_bit()); + // SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); + // alias_map[Q] = D; // continue; //} - RTLIL::Module* inst_module = module->design->module(cell->type); - //bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false; - //if (inst_flop) { - // SigBit d, q; - // for (const auto &c : cell->connections()) { - // auto is_input = cell->input(c.first); - // auto is_output = cell->output(c.first); - // log_assert(is_input || is_output); - // RTLIL::Wire* port = inst_module->wire(c.first); - // for (auto b : c.second.bits()) { - // if (is_input && port->attributes.count("\\abc_flop_d")) { - // d = b; - // SigBit I = sigmap(d); - // if (I != d) - // alias_map[I] = d; - // unused_bits.erase(d); - // } - // if (is_output && port->attributes.count("\\abc_flop_q")) { - // q = b; - // SigBit O = sigmap(q); - // if (O != q) - // alias_map[O] = q; - // undriven_bits.erase(O); - // } - // } - // } - // if (!abc_box_seen) - // abc_box_seen = inst_module->attributes.count("\\abc_box_id"); - // ff_bits.emplace_back(d, q); - //} - /*else*/ if (inst_module && inst_module->attributes.count("\\abc_box_id")) { + RTLIL::Module* inst_module = !holes_mode ? module->design->module(cell->type) : nullptr; + bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false; + if (inst_flop) { + toposort.node(cell->name); + + SigBit d, q; + for (const auto &c : cell->connections()) { + auto is_input = cell->input(c.first); + auto is_output = cell->output(c.first); + log_assert(is_input || is_output); + RTLIL::Wire* port = inst_module->wire(c.first); + if (is_input && port->attributes.count("\\abc_flop_d")) { + d = c.second; + SigBit I = sigmap(d); + if (I != d) + alias_map[I] = d; + unused_bits.erase(d); + } + if (is_output && port->attributes.count("\\abc_flop_q")) { + q = c.second; + SigBit O = sigmap(q); + if (O != q) + alias_map[O] = q; + undriven_bits.erase(O); + } + } + if (!abc_box_seen) + abc_box_seen = inst_module->attributes.count("\\abc_box_id"); + + ff_bits.emplace_back(d, q); + } + else if (inst_module && inst_module->attributes.count("\\abc_box_id")) { abc_box_seen = true; - if (!holes_mode) { - toposort.node(cell->name); - for (const auto &conn : cell->connections()) { - if (cell->input(conn.first)) { - // Ignore inout for the sake of topographical ordering - if (cell->output(conn.first)) continue; - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - } - - if (cell->output(conn.first)) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); + toposort.node(cell->name); + for (const auto &conn : cell->connections()) { + if (cell->input(conn.first)) { + // Ignore inout for the sake of topographical ordering + if (cell->output(conn.first)) continue; + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); } + + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } } else { @@ -555,17 +541,17 @@ struct XAigerWriter // } //} - 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); - } + //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 (!initstate_bits.empty() || !init_inputs.empty()) { + //if (!init_inputs.empty()) { // aig_m++, aig_l++; // initstate_ff = 2*aig_m+1; // aig_latchinit.push_back(0); @@ -589,16 +575,16 @@ struct XAigerWriter // } //} - 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); - } + //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 (!initstate_bits.empty() || !init_inputs.empty()) + //if (!init_inputs.empty()) // aig_latchin.push_back(1); for (auto &c : co_bits) { @@ -617,7 +603,6 @@ struct XAigerWriter RTLIL::SigBit bit = f.second; aig_outputs.push_back(ff_aig_map.at(bit)); } - } void write_aiger(std::ostream &f, bool ascii_mode) @@ -639,14 +624,14 @@ 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_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)); @@ -665,14 +650,14 @@ 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_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)); @@ -789,21 +774,19 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - /*if (!ff_bits.empty())*/ { - std::stringstream r_buffer; - auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - log_debug("flopNum = %zu\n", ff_bits.size()); - write_r_buffer(ff_bits.size()); - //int mergeability_class = 1; - //for (auto cell : ff_bits) - // write_r_buffer(mergeability_class++); + std::stringstream r_buffer; + auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); + log_debug("flopNum = %zu\n", ff_bits.size()); + write_r_buffer(ff_bits.size()); + int mergeability_class = 1; + for (auto cell : ff_bits) + write_r_buffer(mergeability_class++); - 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()); - } + f << "r"; + buffer_str = r_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) { // NB: fixup_ports() will sort ports by name @@ -885,14 +868,14 @@ struct XAigerWriter // 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 (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) From 2ef2aa997cbe75732535946b25c35dcb3fe5eec4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:07:53 -0700 Subject: [PATCH 002/144] read_aiger to not require clk_name for latches, plus debug --- frontends/aiger/aigerparse.cc | 58 ++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index d378a07b7..281e1cc9d 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -495,8 +495,7 @@ void AigerReader::parse_aiger_ascii() // Parse latches RTLIL::Wire *clk_wire = nullptr; - if (L > 0) { - log_assert(clk_name != ""); + if (L > 0 && !clk_name.empty()) { clk_wire = module->wire(clk_name); log_assert(!clk_wire); log_debug("Creating %s\n", clk_name.c_str()); @@ -512,7 +511,10 @@ void AigerReader::parse_aiger_ascii() RTLIL::Wire *q_wire = createWireIfNotExists(module, l1); RTLIL::Wire *d_wire = createWireIfNotExists(module, l2); - module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire); + if (clk_wire) + module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire); + else + module->addFfGate(NEW_ID, d_wire, q_wire); // Reset logic is optional in AIGER 1.9 if (f.peek() == ' ') { @@ -620,8 +622,7 @@ void AigerReader::parse_aiger_binary() // Parse latches RTLIL::Wire *clk_wire = nullptr; - if (L > 0) { - log_assert(clk_name != ""); + if (L > 0 && !clk_name.empty()) { clk_wire = module->wire(clk_name); log_assert(!clk_wire); log_debug("Creating %s\n", clk_name.c_str()); @@ -637,7 +638,10 @@ void AigerReader::parse_aiger_binary() RTLIL::Wire *q_wire = createWireIfNotExists(module, l1); RTLIL::Wire *d_wire = createWireIfNotExists(module, l2); - module->addDff(NEW_ID, clk_wire, d_wire, q_wire); + if (clk_wire) + module->addDff(NEW_ID, clk_wire, d_wire, q_wire); + else + module->addFf(NEW_ID, d_wire, q_wire); // Reset logic is optional in AIGER 1.9 if (f.peek() == ' ') { @@ -731,7 +735,14 @@ void AigerReader::post_process() RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); - if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) { + RTLIL::Module* flop_module = nullptr; + if (box_module->attributes.count("\\abc_flop")) { + log_assert(flop_count < flopNum); + log_assert(box_module->name.begins_with("$__ABC_")); + flop_module = design->module("\\" + box_module->name.substr(7)); + log_assert(flop_module); + } + else if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) { RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr; RTLIL::Wire* last_in = nullptr, *last_out = nullptr; for (const auto &port_name : box_module->ports) { @@ -766,39 +777,36 @@ void AigerReader::post_process() } } - bool flop = box_module->attributes.count("\\abc_flop"); - log_assert(!flop || flop_count < flopNum); - // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) for (auto port_name : box_module->ports) { - RTLIL::Wire* w = box_module->wire(port_name); - log_assert(w); + RTLIL::Wire* port = box_module->wire(port_name); + log_assert(port); RTLIL::SigSpec rhs; RTLIL::Wire* wire = nullptr; - for (int i = 0; i < GetSize(w); i++) { - if (w->port_input) { + for (int i = 0; i < GetSize(port); i++) { + if (port->port_input) { log_assert(co_count < outputs.size()); wire = outputs[co_count++]; log_assert(wire); log_assert(wire->port_output); wire->port_output = false; - if (flop && w->attributes.count("\\abc_flop_d")) { + if (flop_module && port->attributes.count("\\abc_flop_d")) { RTLIL::Wire* d = outputs[outputs.size() - flopNum + flop_count]; log_assert(d); log_assert(d->port_output); d->port_output = false; } } - if (w->port_output) { + if (port->port_output) { log_assert((piNum + ci_count) < inputs.size()); wire = inputs[piNum + ci_count++]; log_assert(wire); log_assert(wire->port_input); wire->port_input = false; - if (flop && w->attributes.count("\\abc_flop_q")) { + if (flop_module && port->attributes.count("\\abc_flop_q")) { wire = inputs[piNum - flopNum + flop_count]; log_assert(wire); log_assert(wire->port_input); @@ -807,10 +815,14 @@ void AigerReader::post_process() } rhs.append(wire); } - cell->setPort(port_name, rhs); + if (!flop_module || !port->attributes.count("\\abc_discard")) + cell->setPort(port_name, rhs); } - if (flop) flop_count++; + if (flop_module) { + flop_count++; + cell->type = flop_module->name; + } } dict wideports_cache; @@ -826,6 +838,7 @@ void AigerReader::post_process() RTLIL::Wire* wire = inputs[variable]; log_assert(wire); log_assert(wire->port_input); + log_debug("Renaming input %s", log_id(wire)); if (index == 0) { // Cope with the fact that a CI might be identical @@ -852,12 +865,14 @@ void AigerReader::post_process() wire->port_input = false; } } + log_debug(" -> %s\n", log_id(wire)); } else if (type == "output") { log_assert(static_cast(variable + co_count) < outputs.size()); RTLIL::Wire* wire = outputs[variable + co_count]; log_assert(wire); log_assert(wire->port_output); + log_debug("Renaming output %s", log_id(wire)); if (index == 0) { // Cope with the fact that a CO might be identical @@ -904,6 +919,7 @@ void AigerReader::post_process() wire->port_output = false; } } + log_debug(" -> %s\n", log_id(wire)); } else if (type == "box") { RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); @@ -1009,8 +1025,8 @@ struct AigerFrontend : public Frontend { log(" Name of module to be created (default: )\n"); log("\n"); log(" -clk_name \n"); - log(" AIGER latches to be transformed into posedge DFFs clocked by wire of"); - log(" this name (default: clk)\n"); + log(" If specified, AIGER latches to be transformed into $_DFF_P_ cells\n" + log(" clocked by wire of this name. Otherwise, $_FF_ cells will be used.\n"); log("\n"); log(" -map \n"); log(" read file with port and latch symbols\n"); From da487c4f31fd2d97c0d7110010e7379e5445ceb0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:08:18 -0700 Subject: [PATCH 003/144] For now, short $_DFF_[NP]_ from ff_map.v at re-integration --- passes/techmap/abc9.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f7f2e862a..69b0c1192 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -511,6 +511,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // Remove all AND, NOT, and ABC box instances // in preparation for stitching mapped_mod in + // Short $_DFF_[NP]_ cells used by ABC (FIXME) dict erased_boxes; for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { RTLIL::Cell* cell = it->second; @@ -518,6 +519,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri it = module->cells_.erase(it); continue; } + else if (cell->type.in("$_DFF_N_", "$_DFF_P_")) { + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + module->connect(Q, D); + it = module->cells_.erase(it); + continue; + } RTLIL::Module* box_module = design->module(cell->type); if (box_module && box_module->attributes.count("\\abc_box_id")) { erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters))); From 295bb23ae06d36acc8ced4825ece6003470cd357 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:08:56 -0700 Subject: [PATCH 004/144] Wrap FDRE with $__ABC_FDRE containing comb --- techlibs/xilinx/Makefile.inc | 1 + techlibs/xilinx/abc_xc7.box | 8 ++++---- techlibs/xilinx/ff_map.v | 10 +++++++++- techlibs/xilinx/synth_xilinx.cc | 22 +++++++++++++++------- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index 1a652eb27..12ec20053 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -30,6 +30,7 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_ff.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut)) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 8a48bad4e..653f6bcb3 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -41,10 +41,10 @@ RAM128X1D 5 0 17 2 - - - - - - - - 314 314 314 314 314 314 292 - - 347 347 347 347 347 347 296 - - - - - - - - - - -# Inputs: C CE D R -# Outputs: Q -FDRE 6 0 4 1 -- - - - +# Inputs: C CE D R Q_past +# Outputs: Q_next +FDRE 6 1 5 1 +- - - - - # Inputs: C CE D S # Outputs: Q diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index 13beaa6ae..ba34425d6 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -23,7 +23,15 @@ `ifndef _NO_FFS module \$_DFF_N_ (input D, C, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule -module \$_DFF_P_ (input D, C, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule +module \$_DFF_P_ (input D, C, output Q); +`ifndef _ABC + FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); +`else + wire Q_next; + \$__ABC_FDRE #(/*.INIT(|0)*/) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); + \$_DFF_P_ abc_dff (.D(Q_next), .Q(Q), .C(C)); +`endif +endmodule module \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule module \$_DFFE_PP_ (input D, C, E, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index a11648873..b9da4e6a6 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -276,25 +276,33 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_cells")) { run("techmap -map +/techmap.v -map +/xilinx/cells_map.v"); + if (abc == "abc9") + run("techmap -max_iter 1 -D _ABC -map +/xilinx/ff_map.v"); run("clean"); } if (check_label("map_luts")) { - if (abc == "abc9") - run(abc + " -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + XC7_WIRE_DELAY + string(retime ? " -dff" : "")); - else if (help_mode) + if (abc == "abc9") { + run("read_verilog -icells -lib +/xilinx/abc_ff.v"); + run(abc + " -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + XC7_WIRE_DELAY + string(retime ? " -retime" : "")); + } + else if (help_mode) { run(abc + " -luts 2:2,3,6:5,10,20 [-dff]"); - else + 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"); + } + else { run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + 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"); + } run("clean"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming if (!nosrl || help_mode) run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); - run("techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); - 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"); + run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v"); run("clean"); } From 7a3c403ba0e411c990be59da44e1decb6aafc8f8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:10:01 -0700 Subject: [PATCH 005/144] Missing close bracket --- frontends/aiger/aigerparse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 281e1cc9d..d0d2ffdba 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -1025,7 +1025,7 @@ struct AigerFrontend : public Frontend { log(" Name of module to be created (default: )\n"); log("\n"); log(" -clk_name \n"); - log(" If specified, AIGER latches to be transformed into $_DFF_P_ cells\n" + log(" If specified, AIGER latches to be transformed into $_DFF_P_ cells\n"); log(" clocked by wire of this name. Otherwise, $_FF_ cells will be used.\n"); log("\n"); log(" -map \n"); From ac18a76bebad001fc3e617a7cefebe13610abcb8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:34:48 -0700 Subject: [PATCH 006/144] Map to $_FF_ instead of $_DFF_P_ to prevent recursion issues --- passes/techmap/abc9.cc | 26 +++++++++++++------------- techlibs/xilinx/ff_map.v | 2 +- techlibs/xilinx/synth_xilinx.cc | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 69b0c1192..4bb4058b1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -242,7 +242,7 @@ struct abc_output_filter }; 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 cleanup, vector lut_costs, bool retime_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) @@ -285,7 +285,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); } - if (dff_mode && clk_sig.empty()) + if (retime_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"; @@ -359,7 +359,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri fprintf(f, "%s\n", abc_script.c_str()); fclose(f); - if (dff_mode || !clk_str.empty()) + if (retime_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"); @@ -511,7 +511,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // Remove all AND, NOT, and ABC box instances // in preparation for stitching mapped_mod in - // Short $_DFF_[NP]_ cells used by ABC (FIXME) + // Short $_FF_ cells used by ABC (FIXME) dict erased_boxes; for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { RTLIL::Cell* cell = it->second; @@ -519,7 +519,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri it = module->cells_.erase(it); continue; } - else if (cell->type.in("$_DFF_N_", "$_DFF_P_")) { + else if (cell->type.in("$_FF_")) { SigBit D = cell->getPort("\\D"); SigBit Q = cell->getPort("\\Q"); module->connect(Q, D); @@ -842,7 +842,7 @@ struct Abc9Pass : public Pass { #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 fast_mode = false, retime_mode = false, keepff = false, cleanup = true; bool show_tempdir = false; vector lut_costs; markgroups = false; @@ -933,13 +933,13 @@ struct Abc9Pass : public Pass { fast_mode = true; continue; } - //if (arg == "-dff") { - // dff_mode = true; - // continue; - //} + if (arg == "-retime") { + retime_mode = true; + continue; + } //if (arg == "-clk" && argidx+1 < args.size()) { // clk_str = args[++argidx]; - // dff_mode = true; + // retime_mode = true; // continue; //} //if (arg == "-keepff") { @@ -1003,8 +1003,8 @@ struct Abc9Pass : public Pass { } } - if (!dff_mode || !clk_str.empty()) { - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, + if (!retime_mode || !clk_str.empty()) { + abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, retime_mode, clk_str, keepff, delay_target, lutin_shared, fast_mode, show_tempdir, box_file, lut_file, wire_delay); continue; diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index ba34425d6..8688c1c3b 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -29,7 +29,7 @@ module \$_DFF_P_ (input D, C, output Q); `else wire Q_next; \$__ABC_FDRE #(/*.INIT(|0)*/) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); - \$_DFF_P_ abc_dff (.D(Q_next), .Q(Q), .C(C)); + \$_FF_ abc_dff (.D(Q_next), .Q(Q)); `endif endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b9da4e6a6..375ab7af1 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -277,7 +277,7 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_cells")) { run("techmap -map +/techmap.v -map +/xilinx/cells_map.v"); if (abc == "abc9") - run("techmap -max_iter 1 -D _ABC -map +/xilinx/ff_map.v"); + run("techmap -D _ABC -map +/xilinx/ff_map.v t:$_DFF*"); run("clean"); } From 6d74b3e004455a98d785bd27c4276b787af637a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:36:02 -0700 Subject: [PATCH 007/144] Update comment --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4810e0113..09f80fee8 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -224,7 +224,7 @@ struct XAigerWriter // FIXME: Should short here, rather than provide $_DFF_[NP]_ // to ABC as a user cell - //if (cell->type.in(/*"$_FF_",*/ "$_DFF_N_", "$_DFF_P_")) + //if (cell->type.in("$_FF_" /*, "$_DFF_N_", "$_DFF_P_"*/)) //{ // SigBit D = sigmap(cell->getPort("\\D").as_bit()); // SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); From a76c8a7ffdfb879971c8c3d1b1f7e8392ddf2c91 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 09:46:35 -0700 Subject: [PATCH 008/144] Fix initialisation of flops --- passes/techmap/abc9.cc | 5 +++-- techlibs/xilinx/ff_map.v | 2 +- techlibs/xilinx/synth_xilinx.cc | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 4bb4058b1..51bea4d57 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -520,8 +520,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri continue; } else if (cell->type.in("$_FF_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); + RTLIL::Wire *D = cell->getPort("\\D").as_wire(); + RTLIL::Wire *Q = cell->getPort("\\Q").as_wire(); + Q->attributes.swap(D->attributes); module->connect(Q, D); it = module->cells_.erase(it); continue; diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index 8688c1c3b..1f0635614 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -28,7 +28,7 @@ module \$_DFF_P_ (input D, C, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); `else wire Q_next; - \$__ABC_FDRE #(/*.INIT(|0)*/) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); + \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); \$_FF_ abc_dff (.D(Q_next), .Q(Q)); `endif endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 375ab7af1..db43e13c1 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -275,9 +275,10 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("map_cells")) { - run("techmap -map +/techmap.v -map +/xilinx/cells_map.v"); if (abc == "abc9") - run("techmap -D _ABC -map +/xilinx/ff_map.v t:$_DFF*"); + run("techmap -map +/techmap.v -map +/xilinx/cells_map.v -D _ABC -map +/xilinx/ff_map.v"); + else + run("techmap -map +/techmap.v -map +/xilinx/cells_map.v"); run("clean"); } @@ -286,23 +287,22 @@ struct SynthXilinxPass : public ScriptPass run("read_verilog -icells -lib +/xilinx/abc_ff.v"); run(abc + " -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + XC7_WIRE_DELAY + string(retime ? " -retime" : "")); } - else if (help_mode) { + else if (help_mode) run(abc + " -luts 2:2,3,6:5,10,20 [-dff]"); - 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"); - } - else { + else run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); - 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"); - } run("clean"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming if (!nosrl || help_mode) run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); - run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v"); + if (abc == "abc9") + run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v"); + else + run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/ff_map.v"); + 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"); run("clean"); } From 65c7bafc64682276d6c1f3cc53b97aa04d8c9039 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 10:19:05 -0700 Subject: [PATCH 009/144] Re-order alphabetically --- techlibs/xilinx/abc_xc7.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 653f6bcb3..42f563898 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -41,7 +41,7 @@ RAM128X1D 5 0 17 2 - - - - - - - - 314 314 314 314 314 314 292 - - 347 347 347 347 347 347 296 - - - - - - - - - - -# Inputs: C CE D R Q_past +# Inputs: C CE D Q_past R # Outputs: Q_next FDRE 6 1 5 1 - - - - - From b706ae82de2fa82b68c327740820c03cc203a217 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 12:42:18 -0700 Subject: [PATCH 010/144] Fix log_debug messages --- frontends/aiger/aigerparse.cc | 40 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index d0d2ffdba..833c0023b 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -429,6 +429,7 @@ void AigerReader::parse_xaiger() else if (c == 'r') { uint32_t dataSize = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); + log_debug("flopNum: %u\n", flopNum); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); f.ignore(flopNum * sizeof(uint32_t)); } @@ -450,7 +451,7 @@ void AigerReader::parse_xaiger() uint32_t poNum = parse_xaiger_literal(f); log_debug("poNum = %u\n", poNum); uint32_t boxNum = parse_xaiger_literal(f); - log_debug("boxNum = %u\n", poNum); + log_debug("boxNum = %u\n", boxNum); for (unsigned i = 0; i < boxNum; i++) { f.ignore(2*sizeof(uint32_t)); uint32_t boxUniqueId = parse_xaiger_literal(f); @@ -777,51 +778,56 @@ void AigerReader::post_process() } } + RTLIL::Wire *d = nullptr; + RTLIL::Wire *q = nullptr; // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) for (auto port_name : box_module->ports) { RTLIL::Wire* port = box_module->wire(port_name); log_assert(port); RTLIL::SigSpec rhs; - RTLIL::Wire* wire = nullptr; for (int i = 0; i < GetSize(port); i++) { + RTLIL::Wire* wire = nullptr; if (port->port_input) { + if (flop_module && port->attributes.count("\\abc_flop_d")) { + log_assert(!d); + d = outputs[outputs.size() - flopNum + flop_count]; + log_assert(d); + log_assert(d->port_output); + d->port_output = false; + } + log_assert(co_count < outputs.size()); wire = outputs[co_count++]; log_assert(wire); log_assert(wire->port_output); wire->port_output = false; - - if (flop_module && port->attributes.count("\\abc_flop_d")) { - RTLIL::Wire* d = outputs[outputs.size() - flopNum + flop_count]; - log_assert(d); - log_assert(d->port_output); - d->port_output = false; - } } if (port->port_output) { + if (flop_module && port->attributes.count("\\abc_flop_q")) { + log_assert(!q); + q = inputs[piNum - flopNum + flop_count]; + log_assert(q); + log_assert(q->port_input); + q->port_input = false; + } + log_assert((piNum + ci_count) < inputs.size()); wire = inputs[piNum + ci_count++]; log_assert(wire); log_assert(wire->port_input); wire->port_input = false; - - if (flop_module && port->attributes.count("\\abc_flop_q")) { - wire = inputs[piNum - flopNum + flop_count]; - log_assert(wire); - log_assert(wire->port_input); - wire->port_input = false; - } } rhs.append(wire); } if (!flop_module || !port->attributes.count("\\abc_discard")) cell->setPort(port_name, rhs); } - if (flop_module) { flop_count++; cell->type = flop_module->name; + //module->addFfGate(NEW_ID, d1 q); + module->connect(q, d); } } From c04921c3a8391d2335fab42ef354bb2bb2f3ac2a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 18:13:44 -0700 Subject: [PATCH 011/144] Fix debug message --- frontends/aiger/aigerparse.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 833c0023b..d2657c9da 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -900,6 +900,7 @@ void AigerReader::post_process() else { wire->port_output = false; module->connect(wire, existing); + wire = existing; } } else if (index > 0) { From c2f3f116d041b97b0d8b6ed28c87810bf6c2630e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 18:16:14 -0700 Subject: [PATCH 012/144] Use $__ABC_FF_ instead of $_FF_ --- backends/aiger/xaiger.cc | 4 ++-- passes/techmap/abc9.cc | 34 +++++++++++++++++++++------------- techlibs/xilinx/ff_map.v | 12 ++++++++++-- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 09f80fee8..c3a4e69c2 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -222,8 +222,8 @@ struct XAigerWriter log_assert(!holes_mode); - // FIXME: Should short here, rather than provide $_DFF_[NP]_ - // to ABC as a user cell + // FIXME: Should short here, rather than provide $__ABC_FF_ + // to ABC like a user cell //if (cell->type.in("$_FF_" /*, "$_DFF_N_", "$_DFF_P_"*/)) //{ // SigBit D = sigmap(cell->getPort("\\D").as_bit()); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 51bea4d57..cedbc9273 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -399,6 +399,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri //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); +#if 0 + Pass::call(design, stringf("write_verilog -noexpr -norename %s/before.xaig", tempdir_name.c_str())); +#endif Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); std::string buffer; @@ -513,25 +516,22 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // in preparation for stitching mapped_mod in // Short $_FF_ cells used by ABC (FIXME) dict erased_boxes; + std::vector abc_dff; for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { RTLIL::Cell* cell = it->second; if (cell->type.in("$_AND_", "$_NOT_")) { it = module->cells_.erase(it); continue; } - else if (cell->type.in("$_FF_")) { - RTLIL::Wire *D = cell->getPort("\\D").as_wire(); - RTLIL::Wire *Q = cell->getPort("\\Q").as_wire(); - Q->attributes.swap(D->attributes); - module->connect(Q, D); - it = module->cells_.erase(it); - continue; - } - RTLIL::Module* box_module = design->module(cell->type); - if (box_module && box_module->attributes.count("\\abc_box_id")) { - erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters))); - it = module->cells_.erase(it); - continue; + if (cell->type.in("$__ABC_FF_")) + abc_dff.emplace_back(cell); + else { + RTLIL::Module* box_module = design->module(cell->type); + if (box_module && box_module->attributes.count("\\abc_box_id")) { + erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters))); + it = module->cells_.erase(it); + continue; + } } ++it; } @@ -671,6 +671,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri int in_wires = 0, out_wires = 0; // Stitch in mapped_mod's inputs/outputs into module + // TODO: iterate using ports for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; if (!w->port_input && !w->port_output) @@ -697,6 +698,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } + for (auto cell : abc_dff) { + RTLIL::SigBit D = cell->getPort("\\D"); + RTLIL::SigBit Q = cell->getPort("\\Q"); + module->connect(Q, D); + module->remove(cell); + } + //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); diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index 1f0635614..bfd4c6998 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -29,12 +29,20 @@ module \$_DFF_P_ (input D, C, output Q); `else wire Q_next; \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); - \$_FF_ abc_dff (.D(Q_next), .Q(Q)); + \$__ABC_FF_ abc_dff (.D(Q_next), .Q(Q)); `endif endmodule module \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); +`ifndef _ABC + FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); +`else + wire Q_next; + \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(E), .R(1'b0)); + \$__ABC_FF_ abc_dff (.D(Q_next), .Q(Q)); +`endif +endmodule module \$_DFF_NN0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule module \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule From cdfb634977b3ee005c5635f7902ea21dd45f7311 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 18:18:56 -0700 Subject: [PATCH 013/144] Cleanup --- passes/techmap/abc9.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index cedbc9273..e13cd0eef 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -671,26 +671,23 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri int in_wires = 0, out_wires = 0; // Stitch in mapped_mod's inputs/outputs into module - // TODO: iterate using ports - for (auto &it : mapped_mod->wires_) { - RTLIL::Wire *w = it.second; - if (!w->port_input && !w->port_output) - continue; - RTLIL::Wire *wire = module->wire(w->name); + for (auto port_name : mapped_mod->ports) { + RTLIL::Wire *port = mapped_mod->wire(port_name); + log_assert(port); + RTLIL::Wire *wire = module->wire(port->name); log_assert(wire); - RTLIL::Wire *remap_wire = module->wire(remap_name(w->name)); + RTLIL::Wire *remap_wire = module->wire(remap_name(port->name)); RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); log_assert(GetSize(signal) >= GetSize(remap_wire)); - log_assert(w->port_input || w->port_output); RTLIL::SigSig conn; - if (w->port_input) { + if (port->port_input) { conn.first = remap_wire; conn.second = signal; in_wires++; module->connect(conn); } - if (w->port_output) { + if (port->port_output) { conn.first = signal; conn.second = remap_wire; out_wires++; From 0debea25a731d83449b08152c7c6158e37e63d75 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 18:24:04 -0700 Subject: [PATCH 014/144] Update comment --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c3a4e69c2..ce2f6e571 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -224,7 +224,7 @@ struct XAigerWriter // FIXME: Should short here, rather than provide $__ABC_FF_ // to ABC like a user cell - //if (cell->type.in("$_FF_" /*, "$_DFF_N_", "$_DFF_P_"*/)) + //if (cell->type == "$__ABC_FF_") //{ // SigBit D = sigmap(cell->getPort("\\D").as_bit()); // SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); From 9ec57b46c2f37ca9eafca8e0e919d676c74f99d8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 19:36:37 -0700 Subject: [PATCH 015/144] Fix spacing --- techlibs/xilinx/ff_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index bfd4c6998..bd36c78fc 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -27,7 +27,7 @@ module \$_DFF_P_ (input D, C, output Q); `ifndef _ABC FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); `else - wire Q_next; + wire Q_next; \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); \$__ABC_FF_ abc_dff (.D(Q_next), .Q(Q)); `endif From 2309459605b262040f7bea84e6d935d2838686d5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 19:36:55 -0700 Subject: [PATCH 016/144] Do not treat $__ABC_FF_ as a user cell --- backends/aiger/xaiger.cc | 18 +++++++++--------- passes/techmap/abc9.cc | 27 ++++++--------------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ce2f6e571..923ba3da8 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -222,15 +222,15 @@ struct XAigerWriter log_assert(!holes_mode); - // FIXME: Should short here, rather than provide $__ABC_FF_ - // to ABC like a user cell - //if (cell->type == "$__ABC_FF_") - //{ - // SigBit D = sigmap(cell->getPort("\\D").as_bit()); - // SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); - // alias_map[Q] = D; - // continue; - //} + 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 = !holes_mode ? module->design->module(cell->type) : nullptr; bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index e13cd0eef..decf5a6aa 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -512,26 +512,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } - // Remove all AND, NOT, and ABC box instances - // in preparation for stitching mapped_mod in - // Short $_FF_ cells used by ABC (FIXME) dict erased_boxes; - std::vector abc_dff; for (auto it = module->cells_.begin(); it != module->cells_.end(); ) { RTLIL::Cell* cell = it->second; - if (cell->type.in("$_AND_", "$_NOT_")) { + if (cell->type.in("$_AND_", "$_NOT_", "$__ABC_FF_")) { it = module->cells_.erase(it); continue; } - if (cell->type.in("$__ABC_FF_")) - abc_dff.emplace_back(cell); - else { - RTLIL::Module* box_module = design->module(cell->type); - if (box_module && box_module->attributes.count("\\abc_box_id")) { - erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters))); - it = module->cells_.erase(it); - continue; - } + RTLIL::Module* box_module = design->module(cell->type); + if (box_module && box_module->attributes.count("\\abc_box_id")) { + erased_boxes.insert(std::make_pair(it->first, std::move(cell->parameters))); + it = module->cells_.erase(it); + continue; } ++it; } @@ -695,13 +687,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } - for (auto cell : abc_dff) { - RTLIL::SigBit D = cell->getPort("\\D"); - RTLIL::SigBit Q = cell->getPort("\\Q"); - module->connect(Q, D); - module->remove(cell); - } - //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); From bd2690e9b940c055a4aa3443e7f1435d66d875f4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 22:41:13 -0700 Subject: [PATCH 017/144] Preserve init of flops, and write into XAIG --- backends/aiger/xaiger.cc | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 923ba3da8..8210d013e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -258,8 +258,8 @@ struct XAigerWriter undriven_bits.erase(O); } } - if (!abc_box_seen) - abc_box_seen = inst_module->attributes.count("\\abc_box_id"); + log_assert(inst_module->attributes.count("\\abc_box_id")); + abc_box_seen = true; ff_bits.emplace_back(d, q); } @@ -696,7 +696,7 @@ struct XAigerWriter log_debug("ciNum = %zu\n", input_bits.size() + ff_bits.size() + ci_bits.size()); write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size()); log_debug("coNum = %zu\n", output_bits.size() + ff_bits.size() + co_bits.size()); - write_h_buffer(output_bits.size() + ff_bits.size()+ co_bits.size()); + write_h_buffer(output_bits.size() + ff_bits.size() + co_bits.size()); log_debug("piNum = %zu\n", input_bits.size() + ff_bits.size()); write_h_buffer(input_bits.size()+ ff_bits.size()); log_debug("poNum = %zu\n", output_bits.size() + ff_bits.size()); @@ -780,7 +780,7 @@ struct XAigerWriter write_r_buffer(ff_bits.size()); int mergeability_class = 1; for (auto cell : ff_bits) - write_r_buffer(mergeability_class++); + write_r_buffer(mergeability_class); f << "r"; buffer_str = r_buffer.str(); @@ -788,6 +788,27 @@ struct XAigerWriter 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 &f : ff_bits) { + RTLIL::SigBit q = f.second; + auto it = q.wire->attributes.find("\\init"); + if (it != q.wire->attributes.end()) { + auto init = it->second[q.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) { // NB: fixup_ports() will sort ports by name //holes_module->fixup_ports(); @@ -857,7 +878,11 @@ struct XAigerWriter if (output_bits.count(b)) { int o = ordered_outputs.at(b); - output_lines[o] += stringf("output %lu %d %s\n", o - co_bits.size(), i, log_id(wire)); + int init = 2; + auto it = init_map.find(b); + if (it != init_map.end()) + init = it->second ? 1 : 0; + output_lines[o] += stringf("output %lu %d %s %d\n", o - co_bits.size(), i, log_id(wire), init); continue; } From d969a9060eb337007e9246301fff906db5a8283e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 22:41:29 -0700 Subject: [PATCH 018/144] Add +/xilinx/abc_ff --- techlibs/xilinx/abc_ff.v | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 techlibs/xilinx/abc_ff.v diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v new file mode 100644 index 000000000..abf4ac093 --- /dev/null +++ b/techlibs/xilinx/abc_ff.v @@ -0,0 +1,33 @@ +/* + * 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. + * + */ + +// ============================================================================ + +module \$__ABC_FF_ (input C, D, output Q); +endmodule + +(* abc_box_id = 6, lib_whitebox, abc_flop *) +module \$__ABC_FDRE ((* abc_flop_q *) output Q, input C, CE, (* abc_flop_d *) input D, (* abc_flop_q_past, abc_discard *) input Q_past, input 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; + assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : Q_past); +endmodule From 3d1185b835e16cc0613aa7a31e810dd6da69599f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 22:41:42 -0700 Subject: [PATCH 019/144] Read init from outputs --- frontends/aiger/aigerparse.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index d2657c9da..5a6db8481 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -927,6 +927,10 @@ 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)); From 416312b9ed027b062c4e043b6265b73b25eb299a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 22:44:45 -0700 Subject: [PATCH 020/144] abc9 to recover_init by default --- passes/techmap/abc9.cc | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index decf5a6aa..aea5e478d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -67,7 +67,6 @@ SigMap assign_map; RTLIL::Module *module; std::map signal_map; std::map signal_init; -bool recover_init; bool clk_polarity, en_polarity; RTLIL::SigSpec clk_sig, en_sig; @@ -253,7 +252,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri signal_map.clear(); pi_map.clear(); po_map.clear(); - recover_init = false; if (clk_str != "$") { @@ -510,6 +508,12 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (int i = 0; i < GetSize(wire); i++) output_bits.insert({wire, i}); } + + auto jt = w->attributes.find("\\init"); + if (jt != w->attributes.end()) { + auto r = remap_wire->attributes.insert(std::make_pair("\\init", jt->second)); + log_assert(r.second); + } } dict erased_boxes; @@ -649,15 +653,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri module->connect(conn); } - if (recover_init) - for (auto wire : mapped_mod->wires()) { - if (wire->attributes.count("\\init")) { - Wire *w = module->wires_[remap_name(wire->name)]; - log_assert(w->attributes.count("\\init") == 0); - w->attributes["\\init"] = wire->attributes.at("\\init"); - } - } - 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; From 3ed95dae8d7661256003f5294f6aa7168b87c5a8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 22:48:16 -0700 Subject: [PATCH 021/144] Cleanup --- passes/techmap/abc9.cc | 47 +++++++----------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index aea5e478d..4e7bdfa8f 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -65,12 +65,9 @@ bool markgroups; int map_autoidx; SigMap assign_map; RTLIL::Module *module; -std::map signal_map; -std::map signal_init; bool clk_polarity, en_polarity; RTLIL::SigSpec clk_sig, en_sig; -dict pi_map, po_map; std::string remap_name(RTLIL::IdString abc_name) { @@ -227,13 +224,13 @@ struct abc_output_filter 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; - } + //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); @@ -249,10 +246,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri module = current_module; map_autoidx = autoidx++; - signal_map.clear(); - pi_map.clear(); - po_map.clear(); - if (clk_str != "$") { clk_polarity = true; @@ -816,10 +809,6 @@ struct Abc9Pass : public Pass { log_push(); assign_map.clear(); - signal_map.clear(); - signal_init.clear(); - pi_map.clear(); - po_map.clear(); #ifdef ABCEXTERNAL std::string exe_file = ABCEXTERNAL; @@ -970,24 +959,6 @@ struct Abc9Pass : public Pass { } assign_map.set(mod); - signal_init.clear(); - - for (Wire *wire : mod->wires()) - if (wire->attributes.count("\\init")) { - SigSpec initsig = assign_map(wire); - Const initval = wire->attributes.at("\\init"); - for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) - switch (initval[i]) { - case State::S0: - signal_init[initsig[i]] = State::S0; - break; - case State::S1: - signal_init[initsig[i]] = State::S0; - break; - default: - break; - } - } if (!retime_mode || !clk_str.empty()) { abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, retime_mode, clk_str, keepff, @@ -1146,10 +1117,6 @@ struct Abc9Pass : public Pass { Pass::call(design, "clean"); assign_map.clear(); - signal_map.clear(); - signal_init.clear(); - pi_map.clear(); - po_map.clear(); log_pop(); } From 6852c83bbe5c1c862527b78910e7d29dc73a6ee5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 15 Jun 2019 22:50:15 -0700 Subject: [PATCH 022/144] Cleanup write_xaiger --- backends/aiger/xaiger.cc | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8210d013e..dbf9b9750 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -68,7 +68,7 @@ struct XAigerWriter dict> and_map; vector> ci_bits; vector> co_bits; - vector> ff_bits; + vector ff_bits; vector> aig_gates; vector aig_latchin, aig_latchinit, aig_outputs; @@ -237,31 +237,29 @@ struct XAigerWriter if (inst_flop) { toposort.node(cell->name); - SigBit d, q; for (const auto &c : cell->connections()) { auto is_input = cell->input(c.first); auto is_output = cell->output(c.first); log_assert(is_input || is_output); RTLIL::Wire* port = inst_module->wire(c.first); if (is_input && port->attributes.count("\\abc_flop_d")) { - d = c.second; + SigBit d = c.second; SigBit I = sigmap(d); if (I != d) alias_map[I] = d; unused_bits.erase(d); } if (is_output && port->attributes.count("\\abc_flop_q")) { - q = c.second; + SigBit q = c.second; SigBit O = sigmap(q); if (O != q) alias_map[O] = q; undriven_bits.erase(O); + ff_bits.emplace_back(q); } } log_assert(inst_module->attributes.count("\\abc_box_id")); abc_box_seen = true; - - ff_bits.emplace_back(d, q); } else if (inst_module && inst_module->attributes.count("\\abc_box_id")) { abc_box_seen = true; @@ -515,8 +513,7 @@ struct XAigerWriter aig_map[bit] = 2*aig_m; } - for (auto &f : ff_bits) { - RTLIL::SigBit bit = f.second; + for (auto bit : ff_bits) { aig_m++, aig_i++; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; @@ -598,9 +595,8 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - for (auto &f : ff_bits) { + for (auto bit : ff_bits) { aig_o++; - RTLIL::SigBit bit = f.second; aig_outputs.push_back(ff_aig_map.at(bit)); } } @@ -791,11 +787,10 @@ struct XAigerWriter 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 &f : ff_bits) { - RTLIL::SigBit q = f.second; - auto it = q.wire->attributes.find("\\init"); - if (it != q.wire->attributes.end()) { - auto init = it->second[q.offset]; + 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; From 0c59bc0b75ba2985e6ae0806d410fe2fa1c94e37 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 16 Jun 2019 10:42:00 -0700 Subject: [PATCH 023/144] Cleanup --- backends/aiger/xaiger.cc | 67 +++++++++++++++-------------------- frontends/aiger/aigerparse.cc | 41 ++++++++++----------- techlibs/xilinx/abc_ff.v | 6 ++-- techlibs/xilinx/abc_xc7.box | 4 +-- techlibs/xilinx/ff_map.v | 12 +++---- 5 files changed, 58 insertions(+), 72 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index dbf9b9750..87dca014d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -233,49 +233,40 @@ struct XAigerWriter } RTLIL::Module* inst_module = !holes_mode ? module->design->module(cell->type) : nullptr; - bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false; - if (inst_flop) { - toposort.node(cell->name); + if (inst_module && inst_module->attributes.count("\\abc_box_id")) { + abc_box_seen = true; - for (const auto &c : cell->connections()) { - auto is_input = cell->input(c.first); - auto is_output = cell->output(c.first); - log_assert(is_input || is_output); - RTLIL::Wire* port = inst_module->wire(c.first); - if (is_input && port->attributes.count("\\abc_flop_d")) { - SigBit d = c.second; - SigBit I = sigmap(d); - if (I != d) - alias_map[I] = d; - unused_bits.erase(d); - } - if (is_output && port->attributes.count("\\abc_flop_q")) { - SigBit q = c.second; - SigBit O = sigmap(q); - if (O != q) - alias_map[O] = q; - undriven_bits.erase(O); - ff_bits.emplace_back(q); + toposort.node(cell->name); + auto abc_flop_d = inst_module->attributes.at("\\abc_flop_d", RTLIL::Const()); + if (abc_flop_d.size() == 0) { + for (const auto &conn : cell->connections()) { + if (cell->input(conn.first)) { + // Ignore inout for the sake of topographical ordering + if (cell->output(conn.first)) continue; + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); + } + + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } } - log_assert(inst_module->attributes.count("\\abc_box_id")); - abc_box_seen = true; - } - else if (inst_module && inst_module->attributes.count("\\abc_box_id")) { - abc_box_seen = true; + else { + auto abc_flop_q = inst_module->attributes.at("\\abc_flop_q"); - toposort.node(cell->name); - for (const auto &conn : cell->connections()) { - if (cell->input(conn.first)) { - // Ignore inout for the sake of topographical ordering - if (cell->output(conn.first)) continue; - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - } + SigBit d = cell->getPort(RTLIL::escape_id(abc_flop_d.decode_string())); + SigBit I = sigmap(d); + if (I != d) + alias_map[I] = d; + unused_bits.erase(d); - if (cell->output(conn.first)) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); + SigBit q = cell->getPort(RTLIL::escape_id(abc_flop_q.decode_string())); + SigBit O = sigmap(q); + if (O != q) + alias_map[O] = q; + undriven_bits.erase(O); + ff_bits.emplace_back(q); } } else { diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 5a6db8481..60cbde857 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -737,11 +737,13 @@ void AigerReader::post_process() log_assert(box_module); RTLIL::Module* flop_module = nullptr; - if (box_module->attributes.count("\\abc_flop")) { + auto flop_module_name = box_module->attributes.at("\\abc_flop", RTLIL::Const()); + RTLIL::IdString flop_past_q; + if (flop_module_name.size() > 0) { log_assert(flop_count < flopNum); - log_assert(box_module->name.begins_with("$__ABC_")); - flop_module = design->module("\\" + box_module->name.substr(7)); + flop_module = design->module(RTLIL::escape_id(flop_module_name.decode_string())); log_assert(flop_module); + flop_past_q = box_module->attributes.at("\\abc_flop_past_q").decode_string(); } else if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) { RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr; @@ -778,8 +780,6 @@ void AigerReader::post_process() } } - RTLIL::Wire *d = nullptr; - RTLIL::Wire *q = nullptr; // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) for (auto port_name : box_module->ports) { @@ -789,14 +789,6 @@ void AigerReader::post_process() for (int i = 0; i < GetSize(port); i++) { RTLIL::Wire* wire = nullptr; if (port->port_input) { - if (flop_module && port->attributes.count("\\abc_flop_d")) { - log_assert(!d); - d = outputs[outputs.size() - flopNum + flop_count]; - log_assert(d); - log_assert(d->port_output); - d->port_output = false; - } - log_assert(co_count < outputs.size()); wire = outputs[co_count++]; log_assert(wire); @@ -804,14 +796,6 @@ void AigerReader::post_process() wire->port_output = false; } if (port->port_output) { - if (flop_module && port->attributes.count("\\abc_flop_q")) { - log_assert(!q); - q = inputs[piNum - flopNum + flop_count]; - log_assert(q); - log_assert(q->port_input); - q->port_input = false; - } - log_assert((piNum + ci_count) < inputs.size()); wire = inputs[piNum + ci_count++]; log_assert(wire); @@ -820,13 +804,24 @@ void AigerReader::post_process() } rhs.append(wire); } - if (!flop_module || !port->attributes.count("\\abc_discard")) + + if (!flop_module || port_name != flop_past_q) cell->setPort(port_name, rhs); } + if (flop_module) { + 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++; cell->type = flop_module->name; - //module->addFfGate(NEW_ID, d1 q); module->connect(q, d); } } diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index abf4ac093..e95602ab2 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -23,11 +23,11 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule -(* abc_box_id = 6, lib_whitebox, abc_flop *) -module \$__ABC_FDRE ((* abc_flop_q *) output Q, input C, CE, (* abc_flop_d *) input D, (* abc_flop_q_past, abc_discard *) input Q_past, input R); +(* abc_box_id = 6, lib_whitebox, abc_flop = "FDRE", abc_flop_q = "Q", abc_flop_d = "D", abc_flop_past_q = "\\$pastQ" *) +module \$__ABC_FDRE (output Q, input C, CE, D, 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; - assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : Q_past); + assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); endmodule diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 42f563898..9aef37545 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -41,8 +41,8 @@ RAM128X1D 5 0 17 2 - - - - - - - - 314 314 314 314 314 314 292 - - 347 347 347 347 347 347 296 - - - - - - - - - - -# Inputs: C CE D Q_past R -# Outputs: Q_next +# Inputs: C CE D R \$pastQ +# Outputs: Q FDRE 6 1 5 1 - - - - - diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index bd36c78fc..5ad73aa63 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -27,9 +27,9 @@ module \$_DFF_P_ (input D, C, output Q); `ifndef _ABC FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); `else - wire Q_next; - \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(1'b1), .R(1'b0)); - \$__ABC_FF_ abc_dff (.D(Q_next), .Q(Q)); + wire \$nextQ ; + \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(1'b1), .R(1'b0)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); `endif endmodule @@ -38,9 +38,9 @@ module \$_DFFE_PP_ (input D, C, E, output Q); `ifndef _ABC FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); `else - wire Q_next; - \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q_next), .Q_past(Q), .C(C), .CE(E), .R(1'b0)); - \$__ABC_FF_ abc_dff (.D(Q_next), .Q(Q)); + wire \$nextQ ; + \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(E), .R(1'b0)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); `endif endmodule From d80678e581899315791706ee1703bf700b0f9c15 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 17 Jun 2019 15:10:33 -0700 Subject: [PATCH 024/144] Cleanup --- passes/techmap/abc9.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 776bceb3b..f56350b1d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -527,7 +527,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } RTLIL::Module* box_module = design->module(cell->type); if (box_module && box_module->attributes.count("\\abc_box_id")) - boxes.emplace_back(it->second); + boxes.emplace_back(cell); ++it; } @@ -629,8 +629,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } - for (auto cell : boxes) - module->remove(cell); + for (auto cell : boxes) + module->remove(cell); // Copy connections (and rename) from mapped_mod to module for (auto conn : mapped_mod->connections()) { From 8a86f9bb6259d335a250868c6f060936a482be8a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 17 Jun 2019 15:13:05 -0700 Subject: [PATCH 025/144] Add box delays for FD* --- techlibs/xilinx/abc_xc7.box | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 9aef37545..4caf69320 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -44,19 +44,19 @@ RAM128X1D 5 0 17 2 # Inputs: C CE D R \$pastQ # Outputs: Q FDRE 6 1 5 1 -- - - - - +- 109 -46 358 0 -# Inputs: C CE D S +# Inputs: C CE D S \$pastQ # Outputs: Q -FDSE 7 0 4 1 -- - - - +FDSE 7 0 5 1 +- 109 -46 358 0 -# Inputs: C CE CLR D +# Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE 8 0 4 1 -- - - - +FDCE 8 0 5 1 +- 109 - -46 0 -# Inputs: C CE D PRE +# Inputs: C CE D PRE \$pastQ # Outputs: Q -FDPE 9 0 4 1 -- - - - +FDPE 9 0 5 1 +- 109 -46 - 0 From 659c04a68d15b20a9421ea5d154b259265f39494 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 1 Jul 2019 10:47:14 -0700 Subject: [PATCH 026/144] Update abc_box_id numbering --- techlibs/xilinx/abc_ff.v | 2 +- techlibs/xilinx/abc_xc7.box | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index e95602ab2..9f6f9c47e 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -23,7 +23,7 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule -(* abc_box_id = 6, lib_whitebox, abc_flop = "FDRE", abc_flop_q = "Q", abc_flop_d = "D", abc_flop_past_q = "\\$pastQ" *) +(* abc_box_id = 7, lib_whitebox, abc_flop = "FDRE", abc_flop_q = "Q", abc_flop_d = "D", abc_flop_past_q = "\\$pastQ" *) module \$__ABC_FDRE (output Q, input C, CE, D, R, \$pastQ ); parameter [0:0] INIT = 1'b0; //parameter [0:0] IS_C_INVERTED = 1'b0; diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index bb9258e78..633e2d484 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -54,20 +54,20 @@ RAM128X1D 6 0 17 2 # Inputs: C CE D R \$pastQ # Outputs: Q -FDRE 6 1 5 1 +FDRE 7 1 5 1 - 109 -46 358 0 # Inputs: C CE D S \$pastQ # Outputs: Q -FDSE 7 0 5 1 +FDSE 8 0 5 1 - 109 -46 358 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE 8 0 5 1 +FDCE 9 0 5 1 - 109 - -46 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q -FDPE 9 0 5 1 +FDPE 10 0 5 1 - 109 -46 - 0 From ef757002dbc8280a65d25618e57b20d3dbadd64a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 1 Jul 2019 10:55:24 -0700 Subject: [PATCH 027/144] Also remove $__ABC_FF_ --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2eee43739..30df8e3ef 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -566,7 +566,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri vector boxes; for (const auto &it : module->cells_) { auto cell = it.second; - if (cell->type.in("$_AND_", "$_NOT_")) { + if (cell->type.in("$_AND_", "$_NOT_", "$__ABC_FF_")) { module->remove(cell); continue; } From ac5f3d500db46a4312d77f43fded2feb25545a3a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 1 Jul 2019 11:10:44 -0700 Subject: [PATCH 028/144] Fix spacing --- frontends/aiger/aigerparse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 7f81a4c89..57a164f1b 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -756,7 +756,7 @@ void AigerReader::post_process() log_assert(flop_module); flop_past_q = box_module->attributes.at("\\abc_flop_past_q").decode_string(); } - else if (seen_boxes.insert(cell->type).second) { + else if (seen_boxes.insert(cell->type).second) { auto it = box_module->attributes.find("\\abc_carry"); if (it != box_module->attributes.end()) { RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; From 5466121ffb055c81946f8a729724febb8f93d4ef Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 1 Jul 2019 11:50:14 -0700 Subject: [PATCH 029/144] Capture all data in one "abc_flop" attribute --- techlibs/xilinx/abc_ff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 9f6f9c47e..a91720260 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -23,7 +23,7 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule -(* abc_box_id = 7, lib_whitebox, abc_flop = "FDRE", abc_flop_q = "Q", abc_flop_d = "D", abc_flop_past_q = "\\$pastQ" *) +(* abc_box_id = 7, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) module \$__ABC_FDRE (output Q, input C, CE, D, R, \$pastQ ); parameter [0:0] INIT = 1'b0; //parameter [0:0] IS_C_INVERTED = 1'b0; From a31e17182d7f9437fb78f5018dfccbd66d9704ea Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 1 Jul 2019 11:50:34 -0700 Subject: [PATCH 030/144] Refactor and cope with new abc_flop format --- backends/aiger/xaiger.cc | 58 ++++++++++++++++++++++++----------- frontends/aiger/aigerparse.cc | 30 ++++++++++++------ 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8a35e06fa..19e6c8369 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -211,6 +211,7 @@ struct XAigerWriter // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; TopoSort toposort; + dict> flop_data; bool abc_box_seen = false; for (auto cell : module->selected_cells()) { @@ -264,8 +265,45 @@ struct XAigerWriter abc_box_seen = true; toposort.node(cell->name); - auto abc_flop_d = inst_module->attributes.at("\\abc_flop_d", RTLIL::Const()); - if (abc_flop_d.size() == 0) { + + auto r = flop_data.insert(std::make_pair(cell->type, std::make_pair(IdString(), IdString()))); + if (r.second) { + auto it = inst_module->attributes.find("\\abc_flop"); + if (it != inst_module->attributes.end()) { + std::string abc_flop = it->second.decode_string(); + size_t start, end; + end = abc_flop.find(','); // Ignore original module + log_assert(end != std::string::npos); + start = end + 1; + end = abc_flop.find(',', start + 1); + log_assert(start != std::string::npos && end != std::string::npos); + auto abc_flop_d = RTLIL::escape_id(abc_flop.substr(start, end-start)); + start = end + 1; + end = abc_flop.find(',', start + 1); + log_assert(start != std::string::npos && end != std::string::npos); + auto abc_flop_q = RTLIL::escape_id(abc_flop.substr(start, end-start)); + r.first->second = std::make_pair(abc_flop_d, abc_flop_q); + } + } + + auto abc_flop_d = r.first->second.first; + 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.second; + 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); + + } + else { for (const auto &conn : cell->connections()) { if (cell->input(conn.first)) { // Ignore inout for the sake of topographical ordering @@ -279,22 +317,6 @@ struct XAigerWriter bit_drivers[bit].insert(cell->name); } } - else { - auto abc_flop_q = inst_module->attributes.at("\\abc_flop_q"); - - SigBit d = cell->getPort(RTLIL::escape_id(abc_flop_d.decode_string())); - SigBit I = sigmap(d); - if (I != d) - alias_map[I] = d; - unused_bits.erase(d); - - SigBit q = cell->getPort(RTLIL::escape_id(abc_flop_q.decode_string())); - SigBit O = sigmap(q); - if (O != q) - alias_map[O] = q; - undriven_bits.erase(O); - ff_bits.emplace_back(q); - } } else { for (const auto &c : cell->connections()) { diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 57a164f1b..30e35da01 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -742,22 +742,29 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { pool seen_boxes; + dict> flop_data; unsigned ci_count = 0, co_count = 0, flop_count = 0; for (auto cell : boxes) { RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); RTLIL::Module* flop_module = nullptr; - auto flop_module_name = box_module->attributes.at("\\abc_flop", RTLIL::Const()); RTLIL::IdString flop_past_q; - if (flop_module_name.size() > 0) { - log_assert(flop_count < flopNum); - flop_module = design->module(RTLIL::escape_id(flop_module_name.decode_string())); - log_assert(flop_module); - flop_past_q = box_module->attributes.at("\\abc_flop_past_q").decode_string(); - } - else if (seen_boxes.insert(cell->type).second) { - auto it = box_module->attributes.find("\\abc_carry"); + if (seen_boxes.insert(cell->type).second) { + auto it = box_module->attributes.find("\\abc_flop"); + if (it != box_module->attributes.end()) { + log_assert(flop_count < flopNum); + std::string abc_flop = it->second.decode_string(); + auto pos = abc_flop.find(','); + log_assert(pos != std::string::npos); + flop_module = design->module(RTLIL::escape_id(abc_flop.substr(0, pos))); + log_assert(flop_module); + pos = abc_flop.rfind(','); + log_assert(pos != std::string::npos); + flop_past_q = RTLIL::escape_id(abc_flop.substr(pos+1)); + flop_data[cell->type] = std::make_pair(flop_module, flop_past_q); + } + it = box_module->attributes.find("\\abc_carry"); if (it != box_module->attributes.end()) { RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; auto carry_in_out = it->second.decode_string(); @@ -796,6 +803,11 @@ void AigerReader::post_process() carry_out->port_id = ports.size(); } } + else { + auto it = flop_data.find(cell->type); + if (it != flop_data.end()) + std::tie(flop_module,flop_past_q) = it->second; + } // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) From 69f4c039ce615c6a6c788e7b0da53e37467d32f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 2 Jul 2019 12:21:03 -0700 Subject: [PATCH 031/144] Safe side: all flops have different mergeability class --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 19e6c8369..632a5c8d5 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -843,7 +843,7 @@ struct XAigerWriter write_r_buffer(ff_bits.size()); int mergeability_class = 1; for (auto cell : ff_bits) - write_r_buffer(mergeability_class); + write_r_buffer(mergeability_class++); f << "r"; buffer_str = r_buffer.str(); From 73c8f1a59e69c5c2f06827d365afc6504fdfad82 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 16:12:33 -0700 Subject: [PATCH 032/144] Fix box numbering --- techlibs/xilinx/abc_ff.v | 2 +- techlibs/xilinx/abc_xc7.box | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index a91720260..8bbdff6f4 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -23,7 +23,7 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule -(* abc_box_id = 7, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) +(* abc_box_id = 8, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) module \$__ABC_FDRE (output Q, input C, CE, D, R, \$pastQ ); parameter [0:0] INIT = 1'b0; //parameter [0:0] IS_C_INVERTED = 1'b0; diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 69ff9aeab..1e1afbc1d 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -59,20 +59,20 @@ RAM128X1D 7 0 17 2 # Inputs: C CE D R \$pastQ # Outputs: Q -FDRE 7 1 5 1 +FDRE 8 1 5 1 - 109 -46 358 0 # Inputs: C CE D S \$pastQ # Outputs: Q -FDSE 8 0 5 1 +FDSE 9 0 5 1 - 109 -46 358 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE 9 0 5 1 +FDCE 10 0 5 1 - 109 - -46 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q -FDPE 10 0 5 1 +FDPE 11 0 5 1 - 109 -46 - 0 From 838ae1a14cddf25919bb2a68e74220a07db4a06e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 16:15:57 -0700 Subject: [PATCH 033/144] synth_xilinx's map_cells stage to techmap ff_map.v --- techlibs/xilinx/synth_xilinx.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2455c2885..45be9a318 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -361,6 +361,8 @@ struct SynthXilinxPass : public ScriptPass std::string techmap_args = "-map +/techmap.v -D _ABC -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"); } From 0ab8f28bc7b6fefc1b4acd4e5c1cb437af878806 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 16:23:15 -0700 Subject: [PATCH 034/144] Uncomment IS_C_INVERTED parameter --- techlibs/xilinx/abc_ff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 8bbdff6f4..d81f828e9 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -26,7 +26,7 @@ endmodule (* abc_box_id = 8, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) module \$__ABC_FDRE (output Q, input C, CE, D, R, \$pastQ ); parameter [0:0] INIT = 1'b0; - //parameter [0:0] IS_C_INVERTED = 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; assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); From 7b2599cb94a718d3c3d6fa4b5eb3ad4824ed13c4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 17:06:05 -0700 Subject: [PATCH 035/144] Move ABC FF stuff to abc_ff.v; add support for other FD* types --- techlibs/xilinx/abc_ff.v | 114 +++++++++++++++++++++++++++++++- techlibs/xilinx/abc_xc7.box | 25 +++++-- techlibs/xilinx/ff_map.v | 21 +----- techlibs/xilinx/synth_xilinx.cc | 2 +- 4 files changed, 135 insertions(+), 27 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index d81f828e9..f823bd731 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -20,14 +20,124 @@ // ============================================================================ +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_CLR_INVERTED = 1'b0; + wire \$nextQ ; + \$__ABC_FDRE #(.INIT(|0)) _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)) _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(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b0), .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(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); + \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b0), .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_FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + generate + if (IS_PRE_INVERTED) + \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); + else + \$__ABC_MUX_ abc_async_mux (.A(1'b1), .B(\$currQ ), .S(PRE), .Y(Q)); + endgenerate +endmodule +module FDPE_1 (output reg Q, input C, CE, D, CLR); + parameter [0:0] INIT = 1'b0; + wire \$nextQ , \$currQ ; + \$__ABC_FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); +endmodule + +`ifndef _ABC module \$__ABC_FF_ (input C, D, output Q); endmodule -(* abc_box_id = 8, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) +(* abc_box_id = 1000 *) +module \$__ABC_FD_ASYNC_MUX_ (input A, B, S, output Q); +// assign Q = S ? B : A; +endmodule + +(* abc_box_id = 1001, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) module \$__ABC_FDRE (output Q, input C, CE, D, R, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter [0:0] IS_C_INVERTED = 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; assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); endmodule + +(* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1,D,Q,\\$pastQ" *) +module \$__ABC_FDRE_1 (output Q, input C, CE, D, 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; + assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); +endmodule + +(* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE,D,Q,\\$pastQ" *) +module \$__ABC_FDCE (output Q, input C, CE, D, 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; + assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1,D,Q,\\$pastQ" *) +module \$__ABC_FDCE_1 (output Q, input C, CE, D, 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; + assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id = 1005, lib_whitebox, abc_flop = "FDPE,D,Q,\\$pastQ" *) +module \$__ABC_FDPE (output Q, input C, CE, D, 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; + assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id = 1006, lib_whitebox, abc_flop = "FDPE_1,D,Q,\\$pastQ" *) +module \$__ABC_FDPE_1 (output Q, input C, CE, D, 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; + assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +`endif diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 1e1afbc1d..ed283deac 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -57,22 +57,37 @@ RAM128X1D 7 0 17 2 - - - - - - - - 1009 998 839 774 605 494 450 - - 1047 1036 877 812 643 532 478 - - - - - - - - - - +# Inputs: A B S +# Outputs: Y +$__ABC_FD_ASYNC_MUX_ 1000 0 3 1 +0 0 764 + # Inputs: C CE D R \$pastQ # Outputs: Q -FDRE 8 1 5 1 +FDRE 1001 1 5 1 - 109 -46 358 0 -# Inputs: C CE D S \$pastQ +# Inputs: C CE D R \$pastQ # Outputs: Q -FDSE 9 0 5 1 +FDRE_1 1002 1 5 1 - 109 -46 358 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE 10 0 5 1 +FDCE 1003 1 5 1 +- 109 - -46 0 + +# Inputs: C CE CLR D \$pastQ +# Outputs: Q +FDCE_1004 11 1 5 1 - 109 - -46 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q -FDPE 11 0 5 1 +FDPE 1005 1 5 1 +- 109 -46 - 0 + +# Inputs: C CE D PRE \$pastQ +# Outputs: Q +FDPE_1 1006 1 5 1 - 109 -46 - 0 diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index 5ad73aa63..b12b0ed7d 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -23,26 +23,9 @@ `ifndef _NO_FFS module \$_DFF_N_ (input D, C, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule -module \$_DFF_P_ (input D, C, output Q); -`ifndef _ABC - FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); -`else - wire \$nextQ ; - \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(1'b1), .R(1'b0)); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); -`endif -endmodule - +module \$_DFF_P_ (input D, C, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule module \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); -`ifndef _ABC - FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); -`else - wire \$nextQ ; - \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(E), .R(1'b0)); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); -`endif -endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule module \$_DFF_NN0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule module \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 45be9a318..d5ae124e0 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -362,7 +362,7 @@ struct SynthXilinxPass : public ScriptPass if (widemux > 0) techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); if (abc9) - techmap_args += " -map +/xilinx/ff_map.v"; + techmap_args += " -map +/xilinx/ff_map.v -D _ABC -map +/xilinx/abc_ff.v"; run("techmap " + techmap_args); run("clean"); } From 0372c900e8dbf6c3d46cdb9438b46d5ddf970e18 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 17:15:49 -0700 Subject: [PATCH 036/144] Fix typo, and have !{PRE,CLR} behave as CE --- techlibs/xilinx/abc_ff.v | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index f823bd731..015211988 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -44,14 +44,14 @@ module FDCE (output reg Q, input C, CE, D, CLR); wire \$nextQ , \$currQ ; \$__ABC_FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR)); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); - \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .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(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR)); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); endmodule module FDPE (output reg Q, input C, CE, D, PRE); @@ -64,9 +64,9 @@ module FDPE (output reg Q, input C, CE, D, PRE); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); generate if (IS_PRE_INVERTED) - \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); else - \$__ABC_MUX_ abc_async_mux (.A(1'b1), .B(\$currQ ), .S(PRE), .Y(Q)); + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(1'b1), .B(\$currQ ), .S(PRE), .Y(Q)); endgenerate endmodule module FDPE_1 (output reg Q, input C, CE, D, CLR); @@ -74,7 +74,7 @@ module FDPE_1 (output reg Q, input C, CE, D, CLR); wire \$nextQ , \$currQ ; \$__ABC_FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE)); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); - \$__ABC_MUX_ abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); endmodule `ifndef _ABC @@ -82,7 +82,7 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule (* abc_box_id = 1000 *) -module \$__ABC_FD_ASYNC_MUX_ (input A, B, S, output Q); +module \$__ABC_FD_ASYNC_MUX (input A, B, S, output Q); // assign Q = S ? B : A; endmodule @@ -109,8 +109,8 @@ module \$__ABC_FDCE (output Q, input C, CE, D, 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; - assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule (* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1,D,Q,\\$pastQ" *) @@ -118,8 +118,8 @@ module \$__ABC_FDCE_1 (output Q, input C, CE, D, 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; - assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule (* abc_box_id = 1005, lib_whitebox, abc_flop = "FDPE,D,Q,\\$pastQ" *) @@ -127,8 +127,8 @@ module \$__ABC_FDPE (output Q, input C, CE, D, 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; - assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule (* abc_box_id = 1006, lib_whitebox, abc_flop = "FDPE_1,D,Q,\\$pastQ" *) @@ -136,8 +136,8 @@ module \$__ABC_FDPE_1 (output Q, input C, CE, D, 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; - assign Q = CE ? (D ^ IS_D_INVERTED) : \$pastQ ; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule `endif From 3bb48facb21032eb49ca40150827358e2d35a9c8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 17:17:54 -0700 Subject: [PATCH 037/144] Remove params from FD*_1 variants --- techlibs/xilinx/abc_ff.v | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 015211988..1d9a25ba7 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -98,10 +98,7 @@ endmodule (* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1,D,Q,\\$pastQ" *) module \$__ABC_FDRE_1 (output Q, input C, CE, D, 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; - assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); + assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); endmodule (* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE,D,Q,\\$pastQ" *) @@ -116,10 +113,7 @@ endmodule (* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1,D,Q,\\$pastQ" *) module \$__ABC_FDCE_1 (output Q, input C, CE, D, 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; - assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; + assign Q = (CE && !CLR) ? D : \$pastQ ; endmodule (* abc_box_id = 1005, lib_whitebox, abc_flop = "FDPE,D,Q,\\$pastQ" *) @@ -134,10 +128,7 @@ endmodule (* abc_box_id = 1006, lib_whitebox, abc_flop = "FDPE_1,D,Q,\\$pastQ" *) module \$__ABC_FDPE_1 (output Q, input C, CE, D, 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; - assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; + assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule `endif From a092c48f036b71cc4014ec6f2865297d49589d40 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 17:34:51 -0700 Subject: [PATCH 038/144] Use split_tokens() --- backends/aiger/xaiger.cc | 28 +++++++++++----------------- frontends/aiger/aigerparse.cc | 16 ++++++++-------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index a1085addf..ba0e36ce1 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -276,18 +276,12 @@ struct XAigerWriter if (r.second) { auto it = inst_module->attributes.find("\\abc_flop"); if (it != inst_module->attributes.end()) { - std::string abc_flop = it->second.decode_string(); - size_t start, end; - end = abc_flop.find(','); // Ignore original module - log_assert(end != std::string::npos); - start = end + 1; - end = abc_flop.find(',', start + 1); - log_assert(start != std::string::npos && end != std::string::npos); - auto abc_flop_d = RTLIL::escape_id(abc_flop.substr(start, end-start)); - start = end + 1; - end = abc_flop.find(',', start + 1); - log_assert(start != std::string::npos && end != std::string::npos); - auto abc_flop_q = RTLIL::escape_id(abc_flop.substr(start, end-start)); + auto abc_flop = it->second.decode_string(); + auto tokens = split_tokens(abc_flop, ","); + if (tokens.size() != 4) + log_error("'abc_flop' attribute on module '%s' does not contain exactly four comma-separated tokens.\n", log_id(cell->type)); + auto abc_flop_d = RTLIL::escape_id(tokens[1]); + auto abc_flop_q = RTLIL::escape_id(tokens[2]); r.first->second = std::make_pair(abc_flop_d, abc_flop_q); } } @@ -404,15 +398,15 @@ struct XAigerWriter if (it != box_module->attributes.end()) { RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; auto carry_in_out = it->second.decode_string(); - auto pos = carry_in_out.find(','); - if (pos == std::string::npos) - log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type)); - auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos)); + auto tokens = split_tokens(carry_in_out, ","); + if (tokens.size() != 2) + log_error("'abc_carry' attribute on module '%s' does not contain exactly two comma-separated tokens.\n", log_id(cell->type)); + auto carry_in_name = RTLIL::escape_id(tokens[0]); carry_in = box_module->wire(carry_in_name); if (!carry_in || !carry_in->port_input) log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str()); - auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1)); + auto carry_out_name = RTLIL::escape_id(tokens[1]); carry_out = box_module->wire(carry_out_name); if (!carry_out || !carry_out->port_output) log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str()); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 30e35da01..35b7f6a97 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -754,14 +754,14 @@ void AigerReader::post_process() auto it = box_module->attributes.find("\\abc_flop"); if (it != box_module->attributes.end()) { log_assert(flop_count < flopNum); - std::string abc_flop = it->second.decode_string(); - auto pos = abc_flop.find(','); - log_assert(pos != std::string::npos); - flop_module = design->module(RTLIL::escape_id(abc_flop.substr(0, pos))); - log_assert(flop_module); - pos = abc_flop.rfind(','); - log_assert(pos != std::string::npos); - flop_past_q = RTLIL::escape_id(abc_flop.substr(pos+1)); + auto abc_flop = it->second.decode_string(); + auto tokens = split_tokens(abc_flop, ","); + if (tokens.size() != 4) + log_error("'abc_flop' attribute on module '%s' does not contain exactly four comma-separated tokens.\n", log_id(cell->type)); + flop_module = design->module(RTLIL::escape_id(tokens[0])); + if (!flop_module) + log_error("First token '%s' in 'abc_flop' attribute on module '%s' is not a valid module.\n", tokens[0].c_str(), log_id(cell->type)); + flop_past_q = RTLIL::escape_id(tokens[3]); flop_data[cell->type] = std::make_pair(flop_module, flop_past_q); } it = box_module->attributes.find("\\abc_carry"); From 4a995c5d80735baf1431a088c2faf81eb75fdaf6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 17:54:56 -0700 Subject: [PATCH 039/144] Change how to specify flops to ABC again --- backends/aiger/xaiger.cc | 30 ++++++++++++++------- frontends/aiger/aigerparse.cc | 16 +++++------ techlibs/xilinx/abc_ff.v | 50 ++++++++++++++++++++++++++--------- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ba0e36ce1..53b6ff97a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -273,17 +273,27 @@ struct XAigerWriter toposort.node(cell->name); auto r = flop_data.insert(std::make_pair(cell->type, std::make_pair(IdString(), IdString()))); - if (r.second) { - auto it = inst_module->attributes.find("\\abc_flop"); - if (it != inst_module->attributes.end()) { - auto abc_flop = it->second.decode_string(); - auto tokens = split_tokens(abc_flop, ","); - if (tokens.size() != 4) - log_error("'abc_flop' attribute on module '%s' does not contain exactly four comma-separated tokens.\n", log_id(cell->type)); - auto abc_flop_d = RTLIL::escape_id(tokens[1]); - auto abc_flop_q = RTLIL::escape_id(tokens[2]); - r.first->second = std::make_pair(abc_flop_d, abc_flop_q); + if (r.second && inst_module->attributes.count("\\abc_flop")) { + IdString abc_flop_d, abc_flop_q; + 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 (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; + } } + 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)); + r.first->second = std::make_pair(abc_flop_d, abc_flop_q); } auto abc_flop_d = r.first->second.first; diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 35b7f6a97..11c5e3570 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -742,27 +742,23 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { pool seen_boxes; - dict> flop_data; + dict flop_data; unsigned ci_count = 0, co_count = 0, flop_count = 0; for (auto cell : boxes) { RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); RTLIL::Module* flop_module = nullptr; - RTLIL::IdString flop_past_q; + const RTLIL::IdString flop_past_q = RTLIL::escape_id("\\$pastQ"); if (seen_boxes.insert(cell->type).second) { auto it = box_module->attributes.find("\\abc_flop"); if (it != box_module->attributes.end()) { log_assert(flop_count < flopNum); auto abc_flop = it->second.decode_string(); - auto tokens = split_tokens(abc_flop, ","); - if (tokens.size() != 4) - log_error("'abc_flop' attribute on module '%s' does not contain exactly four comma-separated tokens.\n", log_id(cell->type)); - flop_module = design->module(RTLIL::escape_id(tokens[0])); + flop_module = design->module(RTLIL::escape_id(abc_flop)); if (!flop_module) - log_error("First token '%s' in 'abc_flop' attribute on module '%s' is not a valid module.\n", tokens[0].c_str(), log_id(cell->type)); - flop_past_q = RTLIL::escape_id(tokens[3]); - flop_data[cell->type] = std::make_pair(flop_module, flop_past_q); + log_error("'abc_flop' attribute value '%s' on module '%s' is not a valid module.\n", abc_flop.c_str(), log_id(cell->type)); + flop_data[cell->type] = flop_module; } it = box_module->attributes.find("\\abc_carry"); if (it != box_module->attributes.end()) { @@ -806,7 +802,7 @@ void AigerReader::post_process() else { auto it = flop_data.find(cell->type); if (it != flop_data.end()) - std::tie(flop_module,flop_past_q) = it->second; + flop_module = it->second; } // NB: Assume box_module->ports are sorted alphabetically diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 1d9a25ba7..db63232b7 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -86,23 +86,35 @@ module \$__ABC_FD_ASYNC_MUX (input A, B, S, output Q); // assign Q = S ? B : A; endmodule -(* abc_box_id = 1001, lib_whitebox, abc_flop = "FDRE,D,Q,\\$pastQ" *) -module \$__ABC_FDRE (output Q, input C, CE, D, R, \$pastQ ); +(* abc_box_id = 1001, lib_whitebox, abc_flop = "FDRE" *) +module \$__ABC_FDRE ((* abc_flop_q *) 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; + (* abc_flop_clk_inv *) parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); endmodule -(* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1,D,Q,\\$pastQ" *) -module \$__ABC_FDRE_1 (output Q, input C, CE, D, R, \$pastQ ); +(* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1" *) +module \$__ABC_FDRE_1 ((* abc_flop_q *) 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; assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); endmodule -(* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE,D,Q,\\$pastQ" *) -module \$__ABC_FDCE (output Q, input C, CE, D, CLR, \$pastQ ); +(* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE" *) +module \$__ABC_FDCE ((* abc_flop_q *) 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; @@ -110,14 +122,22 @@ module \$__ABC_FDCE (output Q, input C, CE, D, CLR, \$pastQ ); assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule -(* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1,D,Q,\\$pastQ" *) -module \$__ABC_FDCE_1 (output Q, input C, CE, D, CLR, \$pastQ ); +(* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1" *) +module \$__ABC_FDCE_1 ((* abc_flop_q *) 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; assign Q = (CE && !CLR) ? D : \$pastQ ; endmodule -(* abc_box_id = 1005, lib_whitebox, abc_flop = "FDPE,D,Q,\\$pastQ" *) -module \$__ABC_FDPE (output Q, input C, CE, D, PRE, \$pastQ ); +(* abc_box_id = 1005, lib_whitebox, abc_flop = "FDPE" *) +module \$__ABC_FDPE ((* abc_flop_q *) 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; @@ -125,8 +145,12 @@ module \$__ABC_FDPE (output Q, input C, CE, D, PRE, \$pastQ ); assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule -(* abc_box_id = 1006, lib_whitebox, abc_flop = "FDPE_1,D,Q,\\$pastQ" *) -module \$__ABC_FDPE_1 (output Q, input C, CE, D, PRE, \$pastQ ); +(* abc_box_id = 1006, lib_whitebox, abc_flop = "FDPE_1" *) +module \$__ABC_FDPE_1 ((* abc_flop_q *) 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; assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule From f8f0ffe786eabd016e0f9a0e4f4de10743638cdf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 18:56:50 -0700 Subject: [PATCH 040/144] Small opt --- frontends/aiger/aigerparse.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 11c5e3570..b599160cf 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -749,7 +749,6 @@ void AigerReader::post_process() log_assert(box_module); RTLIL::Module* flop_module = nullptr; - const RTLIL::IdString flop_past_q = RTLIL::escape_id("\\$pastQ"); if (seen_boxes.insert(cell->type).second) { auto it = box_module->attributes.find("\\abc_flop"); if (it != box_module->attributes.end()) { @@ -830,7 +829,7 @@ void AigerReader::post_process() rhs.append(wire); } - if (!flop_module || port_name != flop_past_q) + if (!flop_module || port_name != "\\$pastQ") cell->setPort(port_name, rhs); } From f030be3f1c384f457b5700aef99d21c34258f64e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 18:57:11 -0700 Subject: [PATCH 041/144] Preserve all parameters, plus some extra ones for clk/en polarity --- techlibs/xilinx/abc_ff.v | 76 ++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index db63232b7..d0087501d 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -24,15 +24,29 @@ 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_CLR_INVERTED = 1'b0; + parameter [0:0] IS_R_INVERTED = 1'b0; wire \$nextQ ; - \$__ABC_FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R)); + \$__ABC_FDRE #( + .INIT(|0), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_R_INVERTED(IS_R_INVERTED), + .\$abc_flop_clk_pol (!IS_C_INVERTED), + .\$abc_flop_en_pol (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)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R)); + \$__ABC_FDRE_1 #(.INIT(|0), + .\$abc_flop_clk_pol (1'b1), + .\$abc_flop_en_pol (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 @@ -42,14 +56,29 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR)); + \$__ABC_FDCE #( + .INIT(|0), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_CLR_INVERTED(IS_CLR_INVERTED), + .\$abc_flop_clk_pol (!IS_C_INVERTED), + .\$abc_flop_en_pol (1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) + ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .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(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR)); + \$__ABC_FDCE_1 #( + .INIT(|0), + .\$abc_flop_clk_pol (1'b1), + .\$abc_flop_en_pol (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_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); endmodule @@ -60,7 +89,16 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE)); + \$__ABC_FDCE #( + .INIT(|0), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_PRE_INVERTED(IS_PRE_INVERTED), + .\$abc_flop_clk_pol (!IS_C_INVERTED), + .\$abc_flop_en_pol (1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) + ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); generate if (IS_PRE_INVERTED) @@ -72,7 +110,13 @@ endmodule module FDPE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE)); + \$__ABC_FDPE_1 #( + .INIT(|0), + .\$abc_flop_clk_pol (1'b1), + .\$abc_flop_en_pol (1'b1) + ) _TECHMAP_REPLACE_ ( + .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) + ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); endmodule @@ -93,9 +137,11 @@ module \$__ABC_FDRE ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input R, \$pastQ ); parameter [0:0] INIT = 1'b0; - (* abc_flop_clk_inv *) parameter [0:0] IS_C_INVERTED = 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 \$abc_flop_clk_pol = ~IS_C_INVERTED; + parameter \$abc_flop_en_pol = 1'b1; assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); endmodule @@ -106,6 +152,8 @@ module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input R, \$pastQ ); parameter [0:0] INIT = 1'b0; + parameter \$abc_flop_clk_pol = 1'b1; + parameter \$abc_flop_en_pol = 1'b1; assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); endmodule @@ -116,9 +164,11 @@ module \$__ABC_FDCE ((* abc_flop_q *) output Q, (* 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_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter \$abc_flop_clk_pol = ~IS_C_INVERTED; + parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule @@ -129,6 +179,8 @@ module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input CLR, \$pastQ ); parameter [0:0] INIT = 1'b0; + parameter \$abc_flop_clk_pol = 1'b1; + parameter \$abc_flop_en_inv = 1'b1; assign Q = (CE && !CLR) ? D : \$pastQ ; endmodule @@ -139,9 +191,11 @@ module \$__ABC_FDPE ((* abc_flop_q *) output Q, (* 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_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; + parameter \$abc_flop_clk_pol = ~IS_C_INVERTED; + parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule @@ -152,6 +206,8 @@ module \$__ABC_FDPE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input PRE, \$pastQ ); parameter [0:0] INIT = 1'b0; + parameter \$abc_flop_clk_pol = ~IS_C_INVERTED; + parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule From 71acd3ddcfc9083f23ee624de1c16be6b8dbe4d6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 18:57:44 -0700 Subject: [PATCH 042/144] Remove -retime from abc9, revert to abc behav with separate clock/en domains --- passes/techmap/abc9.cc | 90 ++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 30df8e3ef..6e57ab7f3 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -285,7 +285,7 @@ struct abc_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool retime_mode, std::string clk_str, + bool cleanup, vector lut_costs, bool /*retime_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) @@ -323,8 +323,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); } - if (retime_mode && clk_sig.empty()) - log_cmd_error("Clock domain %s not found.\n", clk_str.c_str()); + //if (retime_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) @@ -397,7 +397,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri fprintf(f, "%s\n", abc_script.c_str()); fclose(f); - if (retime_mode || !clk_str.empty()) + if (/*retime_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"); @@ -874,7 +874,7 @@ struct Abc9Pass : public Pass { #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, retime_mode = false, keepff = false, cleanup = true; + bool fast_mode = false, /*retime_mode = false,*/ keepff = false, cleanup = true; bool show_tempdir = false; vector lut_costs; markgroups = false; @@ -965,10 +965,10 @@ struct Abc9Pass : public Pass { fast_mode = true; continue; } - if (arg == "-retime") { - retime_mode = true; - continue; - } + //if (arg == "-retime") { + // retime_mode = true; + // continue; + //} //if (arg == "-clk" && argidx+1 < args.size()) { // clk_str = args[++argidx]; // retime_mode = true; @@ -1017,13 +1017,6 @@ struct Abc9Pass : public Pass { assign_map.set(mod); - if (!retime_mode || !clk_str.empty()) { - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, retime_mode, clk_str, keepff, - delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay); - continue; - } - CellTypes ct(design); std::vector all_cells = mod->selected_cells(); @@ -1040,8 +1033,10 @@ 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; - for (auto cell : all_cells) - { + pool seen_cells; + dict> flop_data; + + for (auto cell : all_cells) { clkdomain_t key; for (auto &conn : cell->connections()) @@ -1061,19 +1056,56 @@ struct Abc9Pass : public Pass { } } - if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") - { - key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); + 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, std::make_pair(abc_flop_clk, abc_flop_en))).first; } - else - if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") - { - bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_"; - bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_"; - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); + else { + it = flop_data.find(cell->type); + if (it == flop_data.end()) + continue; } - else - continue; + + auto jt = cell->parameters.find("\\$abc_flop_clk_pol"); + if (jt == cell->parameters.end()) + log_error("'$abc_flop_clk_pol' parameter not found on module '%s'.\n", log_id(cell->type)); + cell->parameters.erase(jt); + bool this_clk_pol = jt->second.as_bool(); + jt = cell->parameters.find("\\$abc_flop_en_pol"); + if (jt == cell->parameters.end()) + log_error("'$abc_flop_en_pol' parameter not found on module '%s'.\n", log_id(cell->type)); + bool this_en_pol = jt->second.as_bool(); + cell->parameters.erase(jt); + + const auto &data = it->second; + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.first)), this_en_pol, assign_map(cell->getPort(data.second))); unassigned_cells.erase(cell); expand_queue.insert(cell); From f3511e4f9358b0eb053893877ab615b66325da39 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 19:01:13 -0700 Subject: [PATCH 043/144] Use \$currQ --- techlibs/xilinx/abc_ff.v | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index d0087501d..96cbb1e04 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -66,8 +66,13 @@ module FDCE (output reg Q, input C, CE, D, CLR); ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); + generate + if (IS_PRE_INVERTED) + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); + else + \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(1'b0), .B(\$currQ ), .S(CLR), .Y(Q)); + endgenerate endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; @@ -99,7 +104,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); generate if (IS_PRE_INVERTED) \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); @@ -117,7 +122,7 @@ module FDPE_1 (output reg Q, input C, CE, D, CLR); ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); + \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); endmodule From e603d719d650722e4fcd1b65b46c64da19c92f81 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 19:04:22 -0700 Subject: [PATCH 044/144] Fix spacing --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 53b6ff97a..9a448c2a0 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -679,7 +679,7 @@ struct XAigerWriter aig_o++; aig_outputs.push_back(0); omode = true; - } + } } void write_aiger(std::ostream &f, bool ascii_mode) From ad35b509de55df1ab5c6a360adec1e3777ba2410 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 19:05:53 -0700 Subject: [PATCH 045/144] Another typo --- techlibs/xilinx/abc_ff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 96cbb1e04..91cfbc4c4 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -68,7 +68,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); generate - if (IS_PRE_INVERTED) + if (IS_CLR_INVERTED) \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); else \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(1'b0), .B(\$currQ ), .S(CLR), .Y(Q)); From 7899a06ed64c55e8d804ef2970ad983e3d112013 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 19:59:24 -0700 Subject: [PATCH 046/144] Another typo --- techlibs/xilinx/abc_ff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 91cfbc4c4..6f9011ef1 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -94,7 +94,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - \$__ABC_FDCE #( + \$__ABC_FDPE #( .INIT(|0), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), From ea6ffea2cd580542cbb5cc349f5268af0700e292 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 20:10:20 -0700 Subject: [PATCH 047/144] Fix clk_pol for FD*_1 --- backends/aiger/xaiger.cc | 1 - techlibs/xilinx/abc_ff.v | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 9a448c2a0..82c28549c 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -311,7 +311,6 @@ struct XAigerWriter alias_map[O] = q; undriven_bits.erase(O); ff_bits.emplace_back(q); - } else { for (const auto &conn : cell->connections()) { diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 6f9011ef1..8e0b578ab 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -157,7 +157,7 @@ module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input R, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter \$abc_flop_clk_pol = 1'b1; + parameter \$abc_flop_clk_pol = 1'b0; parameter \$abc_flop_en_pol = 1'b1; assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); endmodule @@ -184,7 +184,7 @@ module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input CLR, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter \$abc_flop_clk_pol = 1'b1; + parameter \$abc_flop_clk_pol = 1'b0; parameter \$abc_flop_en_inv = 1'b1; assign Q = (CE && !CLR) ? D : \$pastQ ; endmodule @@ -211,7 +211,7 @@ module \$__ABC_FDPE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input PRE, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter \$abc_flop_clk_pol = ~IS_C_INVERTED; + parameter \$abc_flop_clk_pol = 1'b0; parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule From 9f608d6be30c9302c0e3810525457e39f57b0334 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 20:25:59 -0700 Subject: [PATCH 048/144] write_verilog with *.v extension --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 6e57ab7f3..330361f65 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -435,7 +435,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // count_gates, GetSize(signal_list), count_input, count_output); #if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename %s/before.xaig", tempdir_name.c_str())); + Pass::call(design, stringf("write_verilog -noexpr -norename %s/before.v", tempdir_name.c_str())); #endif Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); From 375fcbe5113db80a92b950e5aca7df17add67acf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 20:26:09 -0700 Subject: [PATCH 049/144] abc_flop to also get topologically sorted --- backends/aiger/xaiger.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 82c28549c..5eeae3b82 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -312,19 +312,18 @@ struct XAigerWriter undriven_bits.erase(O); ff_bits.emplace_back(q); } - else { - for (const auto &conn : cell->connections()) { - if (cell->input(conn.first)) { - // Ignore inout for the sake of topographical ordering - if (cell->output(conn.first)) continue; - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - } - if (cell->output(conn.first)) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); + for (const auto &conn : cell->connections()) { + if (cell->input(conn.first)) { + // Ignore inout for the sake of topographical ordering + if (cell->output(conn.first)) continue; + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); } + + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } } else { From f984e0cb345c7cec85eb9b90a13faacffa2e3fa2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 22:33:35 -0700 Subject: [PATCH 050/144] Another typo --- techlibs/xilinx/abc_ff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 8e0b578ab..e4937f646 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -112,7 +112,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(1'b1), .B(\$currQ ), .S(PRE), .Y(Q)); endgenerate endmodule -module FDPE_1 (output reg Q, input C, CE, D, CLR); +module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; \$__ABC_FDPE_1 #( From d357431df175719ed7653d2e3724473aece36b78 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 22:54:39 -0700 Subject: [PATCH 051/144] Restore from master --- techlibs/xilinx/ff_map.v | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index b12b0ed7d..13beaa6ae 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -24,6 +24,7 @@ module \$_DFF_N_ (input D, C, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule module \$_DFF_P_ (input D, C, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule + module \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule module \$_DFFE_PP_ (input D, C, E, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule From 33862d04451ba58ce2b51c1e11abf86b65c3f018 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 09:22:52 -0700 Subject: [PATCH 052/144] WIP for fixing partitioning, temporarily do not partition --- passes/techmap/abc9.cc | 46 +++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 330361f65..4347c3789 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -86,7 +86,7 @@ void handle_loops(RTLIL::Design *design) // cell in the component, and select (and mark) all its output // wires pool ids_seen; - for (auto cell : module->cells()) { + for (auto cell : module->selected_cells()) { auto it = cell->attributes.find("\\abc_scc_id"); if (it != cell->attributes.end()) { auto r = ids_seen.insert(it->second); @@ -423,10 +423,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (count_output) { - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(module); - Pass::call(design, "aigmap"); handle_loops(design); @@ -457,8 +453,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri design->remove(design->module("$__abc9__")); #endif - design->selection_stack.pop_back(); - // Now 'unexpose' those wires by undoing // the expose operation -- remove them from PO/PI // and re-connecting them back together @@ -477,7 +471,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } module->fixup_ports(); - log_header(design, "Executing ABC9.\n"); if (!lut_costs.empty()) { @@ -564,8 +557,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict abc_box; vector boxes; - for (const auto &it : module->cells_) { - auto cell = it.second; + for (auto cell : module->selected_cells()) { if (cell->type.in("$_AND_", "$_NOT_", "$__ABC_FF_")) { module->remove(cell); continue; @@ -663,6 +655,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (existing_cell) { cell->parameters = existing_cell->parameters; cell->attributes = existing_cell->attributes; + + auto it = cell->parameters.find("\\$abc_flop_clk_pol"); + if (it != cell->parameters.end()) + cell->parameters.erase(it); + it = cell->parameters.find("\\$abc_flop_en_pol"); + if (it != cell->parameters.end()) + cell->parameters.erase(it); } else { cell->parameters = c->parameters; @@ -1017,6 +1016,20 @@ struct Abc9Pass : public Pass { assign_map.set(mod); + if (true || /*!dff_mode ||*/ !clk_str.empty()) { + + design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = design->selection_stack.back(); + sel.select(mod); + + abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, false, clk_str, keepff, + delay_target, lutin_shared, fast_mode, show_tempdir, + box_file, lut_file, wire_delay); + + design->selection_stack.pop_back(); + continue; + } + CellTypes ct(design); std::vector all_cells = mod->selected_cells(); @@ -1096,13 +1109,11 @@ struct Abc9Pass : public Pass { auto jt = cell->parameters.find("\\$abc_flop_clk_pol"); if (jt == cell->parameters.end()) log_error("'$abc_flop_clk_pol' parameter not found on module '%s'.\n", log_id(cell->type)); - cell->parameters.erase(jt); bool this_clk_pol = jt->second.as_bool(); jt = cell->parameters.find("\\$abc_flop_en_pol"); if (jt == cell->parameters.end()) log_error("'$abc_flop_en_pol' parameter not found on module '%s'.\n", log_id(cell->type)); bool this_en_pol = jt->second.as_bool(); - cell->parameters.erase(jt); const auto &data = it->second; key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.first)), this_en_pol, assign_map(cell->getPort(data.second))); @@ -1191,16 +1202,27 @@ struct Abc9Pass : public Pass { std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); + design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = design->selection_stack.back(); + 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)); + + pool assigned_names; + for (auto i : it.second) + assigned_names.insert(i->name); + sel.selected_members[mod->name] = std::move(assigned_names); + 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); assign_map.set(mod); } + + design->selection_stack.pop_back(); } Pass::call(design, "clean"); From 0c3ed73dade2488d0add1a3e6e82b148171f2d66 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 09:55:14 -0700 Subject: [PATCH 053/144] Count $_NOT_ cells turned into $luts --- passes/techmap/abc9.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 4347c3789..53b0b8bbe 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -584,7 +584,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_assert(wire); module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1); } - else if (!lut_costs.empty() || !lut_file.empty()) { + else { RTLIL::Cell* driving_lut = nullptr; // ABC can return NOT gates that drive POs if (!a_bit.wire->port_input) { @@ -622,12 +622,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), driver_lut); } - } - else { - cell = module->addCell(remap_name(c->name), "$_NOT_"); - cell->setPort("\\A", RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset)); - cell->setPort("\\Y", RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset)); - cell_stats[RTLIL::unescape_id(c->type)]++; + cell_stats["$lut"]++; } if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; continue; From 237d8651a5b91bf4fa1de69d0930fdcbba049e40 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 09:58:00 -0700 Subject: [PATCH 054/144] Error out if abc9 not called with -lut or -luts --- passes/techmap/abc9.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 53b0b8bbe..b9eb71cf1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -999,6 +999,9 @@ struct Abc9Pass : public Pass { } extra_args(args, argidx, design); + if (lut_costs.empty() && lut_file.empty()) + log_cmd_error("abc9 must be called with '-lut' or '-luts'\n"); + for (auto mod : design->selected_modules()) { if (mod->attributes.count("\\abc_box_id")) From bd198aa803bdfc3b21bfa920822805df992e3120 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 10:07:14 -0700 Subject: [PATCH 055/144] Missing debug message --- frontends/aiger/aigerparse.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index b599160cf..77ef75cd5 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -901,6 +901,7 @@ void AigerReader::post_process() wire->port_output = false; continue; } + log_debug("Renaming output %s", log_id(wire)); if (index == 0) { // Cope with the fact that a CO might be identical From 93fbd56db1c72403881281aa2c3e61bf6e622344 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 10:25:59 -0700 Subject: [PATCH 056/144] $__ABC_FD_ASYNC_MUX.Q -> Y --- techlibs/xilinx/abc_ff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index e4937f646..81696ddb5 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -131,7 +131,7 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule (* abc_box_id = 1000 *) -module \$__ABC_FD_ASYNC_MUX (input A, B, S, output Q); +module \$__ABC_FD_ASYNC_MUX (input A, B, S, output Y); // assign Q = S ? B : A; endmodule From 8fef4c359419998eb4b068b019cbeb7faae331b7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 10:52:33 -0700 Subject: [PATCH 057/144] Simplify to $__ABC_ASYNC box --- techlibs/xilinx/abc_ff.v | 21 +++++---------------- techlibs/xilinx/abc_xc7.box | 6 +++--- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 81696ddb5..69013f475 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -67,12 +67,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - generate - if (IS_CLR_INVERTED) - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); - else - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(1'b0), .B(\$currQ ), .S(CLR), .Y(Q)); - endgenerate + \$__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; @@ -85,7 +80,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b0), .S(CLR), .Y(Q)); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); endmodule module FDPE (output reg Q, input C, CE, D, PRE); @@ -105,12 +100,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - generate - if (IS_PRE_INVERTED) - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); - else - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(1'b1), .B(\$currQ ), .S(PRE), .Y(Q)); - endgenerate + \$__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; @@ -123,7 +113,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) ); \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); - \$__ABC_FD_ASYNC_MUX abc_async_mux (.A(\$currQ ), .B(1'b1), .S(PRE), .Y(Q)); + \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); endmodule `ifndef _ABC @@ -131,8 +121,7 @@ module \$__ABC_FF_ (input C, D, output Q); endmodule (* abc_box_id = 1000 *) -module \$__ABC_FD_ASYNC_MUX (input A, B, S, output Y); -// assign Q = S ? B : A; +module \$__ABC_ASYNC (input A, S, output Y); endmodule (* abc_box_id = 1001, lib_whitebox, abc_flop = "FDRE" *) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index ed283deac..df16c3af1 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -57,10 +57,10 @@ RAM128X1D 7 0 17 2 - - - - - - - - 1009 998 839 774 605 494 450 - - 1047 1036 877 812 643 532 478 - - - - - - - - - - -# Inputs: A B S +# Inputs: A S # Outputs: Y -$__ABC_FD_ASYNC_MUX_ 1000 0 3 1 -0 0 764 +$__ABC_ASYNC 1000 0 2 1 +0 764 # Inputs: C CE D R \$pastQ # Outputs: Q From a314565ad448c1d5a76604bbd25ac2c901c08f8f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 10:52:45 -0700 Subject: [PATCH 058/144] Short out async box --- frontends/aiger/aigerparse.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 77ef75cd5..b984e846a 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -741,6 +741,9 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { + const RTLIL::Wire* n0 = module->wire("\\__0__"); + const RTLIL::Wire* n1 = module->wire("\\__1__"); + pool seen_boxes; dict flop_data; unsigned ci_count = 0, co_count = 0, flop_count = 0; @@ -847,6 +850,17 @@ void AigerReader::post_process() flop_count++; cell->type = flop_module->name; module->connect(q, d); + continue; + } + + // Remove the async mux by shorting out its input and output + if (cell->type == "$__ABC_ASYNC") { + RTLIL::Wire* A = cell->getPort("\\A").as_wire(); + if (A == n0 || A == n1) A = nullptr; + auto it = cell->connections_.find("\\Y"); + log_assert(it != cell->connections_.end()); + module->connect(it->second, A); + cell->connections_.erase(it); } } From 021f8e549266fb500d19f7a3b7747cad6eda22c2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 13:23:07 -0700 Subject: [PATCH 059/144] Fix typo --- techlibs/xilinx/abc_xc7.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index df16c3af1..24512ecf7 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -79,7 +79,7 @@ FDCE 1003 1 5 1 # Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE_1004 11 1 5 1 +FDCE_1004 1 1 5 1 - 109 - -46 0 # Inputs: C CE D PRE \$pastQ From 8f9d529929f43e6ba98f06159ae9533984c6264f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 13:54:40 -0700 Subject: [PATCH 060/144] $pastQ should be first input --- techlibs/xilinx/abc_xc7.box | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 24512ecf7..5dc93e508 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -62,32 +62,32 @@ RAM128X1D 7 0 17 2 $__ABC_ASYNC 1000 0 2 1 0 764 -# Inputs: C CE D R \$pastQ +# Inputs: $pastQ C CE D R # Outputs: Q FDRE 1001 1 5 1 -- 109 -46 358 0 +0 - 0 0 0 -# Inputs: C CE D R \$pastQ +# Inputs: $pastQ C CE D R # Outputs: Q FDRE_1 1002 1 5 1 -- 109 -46 358 0 +0 - 109 -46 358 -# Inputs: C CE CLR D \$pastQ +# Inputs: $pastQ C CE CLR D # Outputs: Q FDCE 1003 1 5 1 -- 109 - -46 0 +0 - 109 - -46 -# Inputs: C CE CLR D \$pastQ +# Inputs: $pastQ C CE CLR D # Outputs: Q -FDCE_1004 1 1 5 1 -- 109 - -46 0 +FDCE_1 1004 1 5 1 +0 - 109 - -46 -# Inputs: C CE D PRE \$pastQ +# Inputs: $pastQ C CE D PRE # Outputs: Q FDPE 1005 1 5 1 -- 109 -46 - 0 +0 - 109 -46 - -# Inputs: C CE D PRE \$pastQ +# Inputs: $pastQ C CE D PRE # Outputs: Q FDPE_1 1006 1 5 1 -- 109 -46 - 0 +0 - 109 -46 - From 854333f2af53626e09de693f5d5c7fa107d81c74 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 13:55:47 -0700 Subject: [PATCH 061/144] Propagate INIT attr --- techlibs/xilinx/abc_ff.v | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 69013f475..19f86365a 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -27,7 +27,7 @@ module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] IS_R_INVERTED = 1'b0; wire \$nextQ ; \$__ABC_FDRE #( - .INIT(|0), + .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_R_INVERTED(IS_R_INVERTED), @@ -57,7 +57,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_CLR_INVERTED = 1'b0; wire \$nextQ , \$currQ ; \$__ABC_FDCE #( - .INIT(|0), + .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_CLR_INVERTED(IS_CLR_INVERTED), @@ -73,7 +73,7 @@ module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; \$__ABC_FDCE_1 #( - .INIT(|0), + .INIT(INIT), .\$abc_flop_clk_pol (1'b1), .\$abc_flop_en_pol (1'b1) ) _TECHMAP_REPLACE_ ( @@ -90,7 +90,7 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_PRE_INVERTED = 1'b0; wire \$nextQ , \$currQ ; \$__ABC_FDPE #( - .INIT(|0), + .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .IS_PRE_INVERTED(IS_PRE_INVERTED), @@ -106,7 +106,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; \$__ABC_FDPE_1 #( - .INIT(|0), + .INIT(INIT), .\$abc_flop_clk_pol (1'b1), .\$abc_flop_en_pol (1'b1) ) _TECHMAP_REPLACE_ ( From 1ada5681340aca5132e4a7bf8fa2d4a6e80adc59 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 14:23:45 -0700 Subject: [PATCH 062/144] Revert "$pastQ should be first input" This reverts commit 8f9d529929f43e6ba98f06159ae9533984c6264f. --- techlibs/xilinx/abc_xc7.box | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 5dc93e508..24512ecf7 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -62,32 +62,32 @@ RAM128X1D 7 0 17 2 $__ABC_ASYNC 1000 0 2 1 0 764 -# Inputs: $pastQ C CE D R +# Inputs: C CE D R \$pastQ # Outputs: Q FDRE 1001 1 5 1 -0 - 0 0 0 +- 109 -46 358 0 -# Inputs: $pastQ C CE D R +# Inputs: C CE D R \$pastQ # Outputs: Q FDRE_1 1002 1 5 1 -0 - 109 -46 358 +- 109 -46 358 0 -# Inputs: $pastQ C CE CLR D +# Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE 1003 1 5 1 -0 - 109 - -46 +- 109 - -46 0 -# Inputs: $pastQ C CE CLR D +# Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE_1 1004 1 5 1 -0 - 109 - -46 +FDCE_1004 1 1 5 1 +- 109 - -46 0 -# Inputs: $pastQ C CE D PRE +# Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE 1005 1 5 1 -0 - 109 -46 - +- 109 -46 - 0 -# Inputs: $pastQ C CE D PRE +# Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE_1 1006 1 5 1 -0 - 109 -46 - +- 109 -46 - 0 From 3ef927647c04bccce1d72751f6fb95ac4ac7e98b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 14:25:47 -0700 Subject: [PATCH 063/144] Fix FDCE_1 box --- techlibs/xilinx/abc_xc7.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 24512ecf7..73f532711 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -79,7 +79,7 @@ FDCE 1003 1 5 1 # Inputs: C CE CLR D \$pastQ # Outputs: Q -FDCE_1004 1 1 5 1 +FDCE_1 1004 1 5 1 - 109 - -46 0 # Inputs: C CE D PRE \$pastQ From d386177e6d99ea2b3ef4b798653c0b1d7786e6b8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 17:09:17 -0700 Subject: [PATCH 064/144] ABC doesn't like negative delays in flop boxes... --- techlibs/xilinx/abc_xc7.box | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 73f532711..f59cdcde8 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -65,29 +65,29 @@ $__ABC_ASYNC 1000 0 2 1 # Inputs: C CE D R \$pastQ # Outputs: Q FDRE 1001 1 5 1 -- 109 -46 358 0 +0 109 0 358 0 # Inputs: C CE D R \$pastQ # Outputs: Q FDRE_1 1002 1 5 1 -- 109 -46 358 0 +0 109 0 358 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE 1003 1 5 1 -- 109 - -46 0 +0 109 764 0 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE_1 1004 1 5 1 -- 109 - -46 0 +0 109 764 0 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE 1005 1 5 1 -- 109 -46 - 0 +0 109 0 764 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE_1 1006 1 5 1 -- 109 -46 - 0 +0 109 0 764 0 From 1c9f3fadb9f60653fc9d1d7d72ba22033e077468 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 11 Jul 2019 17:17:26 -0700 Subject: [PATCH 065/144] Add Tsu offset to boxes, and comments --- techlibs/xilinx/abc_xc7.box | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index f59cdcde8..044ed1bff 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -14,6 +14,7 @@ F7MUX 1 1 3 1 MUXF8 2 1 3 1 104 94 273 +# Box containing MUXF7.[AB] + MUXF8 # Inputs: I0 I1 I2 I3 S0 S1 # Outputs: O $__MUXF78 3 1 6 1 @@ -57,37 +58,41 @@ RAM128X1D 7 0 17 2 - - - - - - - - 1009 998 839 774 605 494 450 - - 1047 1036 877 812 643 532 478 - - - - - - - - - - +# 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 + # Inputs: C CE D R \$pastQ # Outputs: Q FDRE 1001 1 5 1 -0 109 0 358 0 +0 155 0 404 0 # Inputs: C CE D R \$pastQ # Outputs: Q FDRE_1 1002 1 5 1 -0 109 0 358 0 +0 155 0 404 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE 1003 1 5 1 -0 109 764 0 0 +0 155 810 0 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE_1 1004 1 5 1 -0 109 764 0 0 +0 155 810 0 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE 1005 1 5 1 -0 109 0 764 0 +0 155 0 810 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE_1 1006 1 5 1 -0 109 0 764 0 +0 155 0 810 0 From 10c69f71e9dd03780364402f5c470be33f6cfca5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 09:16:20 -0700 Subject: [PATCH 066/144] Use %d --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 5d3677ab3..0a2445593 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -808,7 +808,7 @@ struct XAigerWriter std::stringstream r_buffer; auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - log_debug("flopNum = %zu\n", ff_bits.size()); + log_debug("flopNum = %d\n", GetSize(ff_bits)); write_r_buffer(ff_bits.size()); int mergeability_class = 1; for (auto cell : ff_bits) From 9bfe924e17a87fac8a35fcb7ff5e067f6c520e07 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 09:40:01 -0700 Subject: [PATCH 067/144] Set abc_flop and use it in toposort --- frontends/aiger/aigerparse.cc | 1 + passes/techmap/abc9.cc | 82 ++++++++++++++++++++++------------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index f2b38da67..6fd9e0432 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -840,6 +840,7 @@ void AigerReader::post_process() flop_count++; cell->type = flop_module->name; module->connect(q, d); + cell->set_bool_attribute("\\abc_flop"); continue; } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 50a6e0fe5..df62b4fa5 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -443,6 +443,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri design->remove(design->module(ID($__abc9__))); #endif + design->selection_stack.pop_back(); + // Now 'unexpose' those wires by undoing // the expose operation -- remove them from PO/PI // and re-connecting them back together @@ -568,19 +570,17 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict> bit2sinks; std::map cell_stats; - for (auto c : mapped_mod->cells()) + for (auto mapped_cell : mapped_mod->cells()) { - toposort.node(c->name); + toposort.node(mapped_cell->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 (mapped_cell->type == ID($_NOT_)) { + RTLIL::SigBit a_bit = mapped_cell->getPort(ID(A)); + RTLIL::SigBit y_bit = mapped_cell->getPort(ID(Y)); if (!a_bit.wire) { - c->setPort(ID(Y), module->addWire(NEW_ID)); + mapped_cell->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); @@ -604,38 +604,40 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (!driving_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())), + cell = module->addLut(remap_name(stringf("%s$lut", mapped_cell->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)]++; + bit_users[a_bit].insert(mapped_cell->name); + bit_drivers[y_bit].insert(mapped_cell->name); } else - not2drivers[c] = driving_lut; + not2drivers[mapped_cell] = driving_lut; continue; } if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; continue; } - cell_stats[c->type]++; + cell_stats[mapped_cell->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)); + if (mapped_cell->type == ID($lut)) { + if (GetSize(mapped_cell->getPort(ID(A))) == 1 && mapped_cell->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + SigSpec my_a = module->wires_.at(remap_name(mapped_cell->getPort(ID(A)).as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(mapped_cell->getPort(ID(Y)).as_wire()->name)); module->connect(my_y, my_a); - if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; + if (markgroups) mapped_cell->attributes[ID(abcgroup)] = map_autoidx; log_abort(); continue; } - cell = module->addCell(remap_name(c->name), c->type); + cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); } else { - existing_cell = module->cell(c->name); + existing_cell = module->cell(mapped_cell->name); log_assert(existing_cell); - cell = module->addCell(remap_name(c->name), c->type); + cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); module->swap_names(cell, existing_cell); } @@ -652,10 +654,12 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->parameters.erase(it); } else { - cell->parameters = c->parameters; - cell->attributes = c->attributes; + cell->parameters = mapped_cell->parameters; + cell->attributes = mapped_cell->attributes; } - for (auto &conn : c->connections()) { + + auto abc_flop = mapped_cell->attributes.count("\\abc_flop"); + for (auto &conn : mapped_cell->connections()) { RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { if (c.width == 0) @@ -667,15 +671,17 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } 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 (!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->output(conn.first)) - for (auto i : conn.second) - bit_drivers[i].insert(c->name); } } @@ -701,7 +707,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } for (auto &it : cell_stats) - log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); + log("ABC RESULTS: %15s cells: %8d\n", log_id(it.first), it.second); int in_wires = 0, out_wires = 0; // Stitch in mapped_mod's inputs/outputs into module @@ -734,7 +740,21 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto driver_cell : bit_drivers.at(it.first)) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); +#if 0 + toposort.analyze_loops = true; +#endif bool no_loops = toposort.sort(); +#if 0 + unsigned i = 0; + for (auto &it : toposort.loops) { + log(" loop %d\n", i++); + for (auto cell_name : it) { + auto cell = mapped_mod->cell(cell_name); + log_assert(cell); + log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str()); + } + } +#endif log_assert(no_loops); for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { From e301440a0bae76dcff159c77274c91aad40021c0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 09:51:49 -0700 Subject: [PATCH 068/144] Use attributes instead of params --- passes/techmap/abc9.cc | 36 +++++++++++++++++++++++----------- techlibs/xilinx/abc_ff.v | 42 ++++++++++++---------------------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index df62b4fa5..d52be1836 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -646,12 +646,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->parameters = existing_cell->parameters; cell->attributes = existing_cell->attributes; - auto it = cell->parameters.find("\\$abc_flop_clk_pol"); - if (it != cell->parameters.end()) - cell->parameters.erase(it); - it = cell->parameters.find("\\$abc_flop_en_pol"); - if (it != cell->parameters.end()) - cell->parameters.erase(it); + cell->attributes.erase("\\abc_flop_clk_pol"); + cell->attributes.erase("\\abc_flop_en_pol"); } else { cell->parameters = mapped_cell->parameters; @@ -1265,14 +1261,32 @@ struct Abc9Pass : public Pass { continue; } - auto jt = cell->parameters.find("\\$abc_flop_clk_pol"); + auto jt = cell->attributes.find("\\abc_flop_clk_pol"); if (jt == cell->parameters.end()) - log_error("'$abc_flop_clk_pol' parameter not found on module '%s'.\n", log_id(cell->type)); - bool this_clk_pol = jt->second.as_bool(); + log_error("'abc_flop_clk_pol' attribute not found on module '%s'.\n", log_id(cell->type)); + bool this_clk_pol; + if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { + auto param = jt->second.decode_string(); + auto kt = cell->parameters.find(param); + if (kt == cell->parameters.end()) + log_error("'abc_flop_clk_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); + this_clk_pol = kt->second.as_bool(); + } + else + this_clk_pol = jt->second.as_bool(); jt = cell->parameters.find("\\$abc_flop_en_pol"); if (jt == cell->parameters.end()) - log_error("'$abc_flop_en_pol' parameter not found on module '%s'.\n", log_id(cell->type)); - bool this_en_pol = jt->second.as_bool(); + log_error("'abc_flop_en_pol' attribute not found on module '%s'.\n", log_id(cell->type)); + bool this_en_pol; + if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { + auto param = jt->second.decode_string(); + auto kt = cell->parameters.find(param); + if (kt == cell->parameters.end()) + log_error("'abc_flop_en_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); + this_en_pol = kt->second.as_bool(); + } + else + this_en_pol = jt->second.as_bool(); const auto &data = it->second; key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.first)), this_en_pol, assign_map(cell->getPort(data.second))); diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 19f86365a..1d308fa96 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -26,13 +26,12 @@ module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; wire \$nextQ ; + (* abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) \$__ABC_FDRE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), - .IS_R_INVERTED(IS_R_INVERTED), - .\$abc_flop_clk_pol (!IS_C_INVERTED), - .\$abc_flop_en_pol (1'b1) + .IS_R_INVERTED(IS_R_INVERTED) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) ); @@ -41,9 +40,8 @@ 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), - .\$abc_flop_clk_pol (1'b1), - .\$abc_flop_en_pol (1'b1) + (* abc_flop_clk_pol=1, abc_flop_en_pol=1 *) + \$__ABC_FDRE_1 #(.INIT(|0) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) ); @@ -56,13 +54,12 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; wire \$nextQ , \$currQ ; + (* abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) \$__ABC_FDCE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), - .IS_CLR_INVERTED(IS_CLR_INVERTED), - .\$abc_flop_clk_pol (!IS_C_INVERTED), - .\$abc_flop_en_pol (1'b1) + .IS_CLR_INVERTED(IS_CLR_INVERTED) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) ); @@ -72,10 +69,9 @@ endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; + (* abc_flop_clk_pol=1, abc_flop_en_pol=1 *) \$__ABC_FDCE_1 #( - .INIT(INIT), - .\$abc_flop_clk_pol (1'b1), - .\$abc_flop_en_pol (1'b1) + .INIT(INIT) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) ); @@ -89,13 +85,12 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; wire \$nextQ , \$currQ ; + (* abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) \$__ABC_FDPE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), - .IS_PRE_INVERTED(IS_PRE_INVERTED), - .\$abc_flop_clk_pol (!IS_C_INVERTED), - .\$abc_flop_en_pol (1'b1) + .IS_PRE_INVERTED(IS_PRE_INVERTED) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) ); @@ -105,10 +100,9 @@ endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; + (* abc_flop_clk_pol=1, abc_flop_en_pol=1 *) \$__ABC_FDPE_1 #( - .INIT(INIT), - .\$abc_flop_clk_pol (1'b1), - .\$abc_flop_en_pol (1'b1) + .INIT(INIT) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) ); @@ -134,8 +128,6 @@ module \$__ABC_FDRE ((* abc_flop_q *) output Q, 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 \$abc_flop_clk_pol = ~IS_C_INVERTED; - parameter \$abc_flop_en_pol = 1'b1; assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); endmodule @@ -146,8 +138,6 @@ module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input R, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter \$abc_flop_clk_pol = 1'b0; - parameter \$abc_flop_en_pol = 1'b1; assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); endmodule @@ -161,8 +151,6 @@ module \$__ABC_FDCE ((* abc_flop_q *) output Q, 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 \$abc_flop_clk_pol = ~IS_C_INVERTED; - parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule @@ -173,8 +161,6 @@ module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input CLR, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter \$abc_flop_clk_pol = 1'b0; - parameter \$abc_flop_en_inv = 1'b1; assign Q = (CE && !CLR) ? D : \$pastQ ; endmodule @@ -188,8 +174,6 @@ module \$__ABC_FDPE ((* abc_flop_q *) output Q, 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 \$abc_flop_clk_pol = ~IS_C_INVERTED; - parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule @@ -200,8 +184,6 @@ module \$__ABC_FDPE_1 ((* abc_flop_q *) output Q, (* abc_flop_d *) input D, input PRE, \$pastQ ); parameter [0:0] INIT = 1'b0; - parameter \$abc_flop_clk_pol = 1'b0; - parameter \$abc_flop_en_pol = 1'b1; assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule From ba2261e21a18b969473f228b5f55bd5612558ed8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 11:18:33 -0700 Subject: [PATCH 069/144] Move from cell attr to module attr --- passes/techmap/abc9.cc | 100 +++++++++++++++++++++++++++------------ techlibs/xilinx/abc_ff.v | 18 +++---- 2 files changed, 76 insertions(+), 42 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 398df190c..be2a8d50b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1202,7 +1202,15 @@ struct Abc9Pass : public Pass { std::map> bit_to_cell, bit_to_cell_up, bit_to_cell_down; pool seen_cells; - dict> flop_data; + struct flop_data_t { + IdString clk_port; + IdString clk_pol_param; + bool clk_pol; + IdString en_port; + IdString en_pol_param; + bool en_pol; + }; + dict flop_data; for (auto cell : all_cells) { clkdomain_t key; @@ -1253,7 +1261,40 @@ struct Abc9Pass : public Pass { 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, std::make_pair(abc_flop_clk, abc_flop_en))).first; + + auto jt = inst_module->attributes.find("\\abc_flop_clk_pol"); + if (jt == inst_module->attributes.end()) + log_error("'abc_flop_clk_pol' attribute not found on module '%s'.\n", log_id(inst_module)); + IdString abc_flop_clk_pol_param; + bool abc_flop_clk_pol; + if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { + auto param = jt->second.decode_string(); + abc_flop_clk_pol = (param[0] == '!'); + if (abc_flop_clk_pol) + abc_flop_clk_pol_param = RTLIL::escape_id(param.substr(1)); + else + abc_flop_clk_pol_param = RTLIL::escape_id(param); + } + else + abc_flop_clk_pol = !jt->second.as_bool(); + jt = inst_module->attributes.find("\\abc_flop_en_pol"); + if (jt == inst_module->attributes.end()) + log_error("'abc_flop_en_pol' attribute not found on module '%s'.\n", log_id(inst_module)); + IdString abc_flop_en_pol_param; + bool abc_flop_en_pol; + if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { + auto param = jt->second.decode_string(); + abc_flop_en_pol = (param[0] == '!'); + if (abc_flop_en_pol) + abc_flop_en_pol_param = RTLIL::escape_id(param.substr(1)); + else + abc_flop_en_pol_param = RTLIL::escape_id(param); + } + else + abc_flop_en_pol = !jt->second.as_bool(); + + it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_clk_pol_param, abc_flop_clk_pol, + abc_flop_en, abc_flop_en_pol_param, abc_flop_en_pol})).first; } else { it = flop_data.find(cell->type); @@ -1261,35 +1302,34 @@ struct Abc9Pass : public Pass { continue; } - auto jt = cell->attributes.find("\\abc_flop_clk_pol"); - if (jt == cell->parameters.end()) - log_error("'abc_flop_clk_pol' attribute not found on module '%s'.\n", log_id(cell->type)); - bool this_clk_pol; - if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { - auto param = jt->second.decode_string(); - auto kt = cell->parameters.find(param); - if (kt == cell->parameters.end()) - log_error("'abc_flop_clk_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); - this_clk_pol = kt->second.as_bool(); - } - else - this_clk_pol = jt->second.as_bool(); - jt = cell->parameters.find("\\$abc_flop_en_pol"); - if (jt == cell->parameters.end()) - log_error("'abc_flop_en_pol' attribute not found on module '%s'.\n", log_id(cell->type)); - bool this_en_pol; - if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { - auto param = jt->second.decode_string(); - auto kt = cell->parameters.find(param); - if (kt == cell->parameters.end()) - log_error("'abc_flop_en_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); - this_en_pol = kt->second.as_bool(); - } - else - this_en_pol = jt->second.as_bool(); - const auto &data = it->second; - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.first)), this_en_pol, assign_map(cell->getPort(data.second))); + + bool this_clk_pol; + if (data.clk_pol_param == IdString()) + this_clk_pol = data.clk_pol; + else { + auto param = data.clk_pol_param; + auto jt = cell->parameters.find(param); + if (jt == cell->parameters.end()) + log_error("'abc_flop_clk_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); + this_clk_pol = jt->second.as_bool(); + if (data.clk_pol) + this_clk_pol = !this_clk_pol; + } + bool this_en_pol; + if (data.en_pol_param == IdString()) + this_en_pol = data.en_pol; + else { + auto param = data.en_pol_param; + auto jt = cell->parameters.find(param); + if (jt == cell->parameters.end()) + log_error("'abc_flop_en_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); + this_en_pol = jt->second.as_bool(); + if (data.en_pol) + this_en_pol = !this_en_pol; + } + + 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_ff.v b/techlibs/xilinx/abc_ff.v index 1d308fa96..117820f0d 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -26,7 +26,6 @@ module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_R_INVERTED = 1'b0; wire \$nextQ ; - (* abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) \$__ABC_FDRE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), @@ -40,7 +39,6 @@ endmodule module FDRE_1 (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; wire \$nextQ ; - (* abc_flop_clk_pol=1, abc_flop_en_pol=1 *) \$__ABC_FDRE_1 #(.INIT(|0) ) _TECHMAP_REPLACE_ ( .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) @@ -54,7 +52,6 @@ module FDCE (output reg Q, input C, CE, D, CLR); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - (* abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) \$__ABC_FDCE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), @@ -69,7 +66,6 @@ endmodule module FDCE_1 (output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; - (* abc_flop_clk_pol=1, abc_flop_en_pol=1 *) \$__ABC_FDCE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( @@ -85,7 +81,6 @@ module FDPE (output reg Q, input C, CE, D, PRE); parameter [0:0] IS_D_INVERTED = 1'b0; parameter [0:0] IS_PRE_INVERTED = 1'b0; wire \$nextQ , \$currQ ; - (* abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) \$__ABC_FDPE #( .INIT(INIT), .IS_C_INVERTED(IS_C_INVERTED), @@ -100,7 +95,6 @@ endmodule module FDPE_1 (output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; wire \$nextQ , \$currQ ; - (* abc_flop_clk_pol=1, abc_flop_en_pol=1 *) \$__ABC_FDPE_1 #( .INIT(INIT) ) _TECHMAP_REPLACE_ ( @@ -118,7 +112,7 @@ endmodule module \$__ABC_ASYNC (input A, S, output Y); endmodule -(* abc_box_id = 1001, lib_whitebox, abc_flop = "FDRE" *) +(* abc_box_id=1001, lib_whitebox, abc_flop="FDRE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) module \$__ABC_FDRE ((* abc_flop_q *) output Q, (* abc_flop_clk *) input C, (* abc_flop_en *) input CE, @@ -131,7 +125,7 @@ module \$__ABC_FDRE ((* abc_flop_q *) output Q, assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); endmodule -(* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1" *) +(* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, (* abc_flop_clk *) input C, (* abc_flop_en *) input CE, @@ -141,7 +135,7 @@ module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); endmodule -(* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE" *) +(* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) module \$__ABC_FDCE ((* abc_flop_q *) output Q, (* abc_flop_clk *) input C, (* abc_flop_en *) input CE, @@ -154,7 +148,7 @@ module \$__ABC_FDCE ((* abc_flop_q *) output Q, assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule -(* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1" *) +(* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, (* abc_flop_clk *) input C, (* abc_flop_en *) input CE, @@ -164,7 +158,7 @@ module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, assign Q = (CE && !CLR) ? D : \$pastQ ; endmodule -(* abc_box_id = 1005, lib_whitebox, abc_flop = "FDPE" *) +(* abc_box_id=1005, lib_whitebox, abc_flop="FDPE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) module \$__ABC_FDPE ((* abc_flop_q *) output Q, (* abc_flop_clk *) input C, (* abc_flop_en *) input CE, @@ -177,7 +171,7 @@ module \$__ABC_FDPE ((* abc_flop_q *) output Q, assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; endmodule -(* abc_box_id = 1006, lib_whitebox, abc_flop = "FDPE_1" *) +(* abc_box_id=1006, lib_whitebox, abc_flop="FDPE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) module \$__ABC_FDPE_1 ((* abc_flop_q *) output Q, (* abc_flop_clk *) input C, (* abc_flop_en *) input CE, From f25837f8e8482036a761fc631f7f79e5a2c777c5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 11:31:40 -0700 Subject: [PATCH 070/144] Update box timings --- techlibs/xilinx/abc_xc7.box | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 044ed1bff..16040662c 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -1,4 +1,5 @@ # Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf +# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf # NB: Inputs/Outputs must be ordered alphabetically # (with exceptions for carry in/out) @@ -66,33 +67,35 @@ $__ABC_ASYNC 1000 0 2 1 # 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 155 0 404 0 +0 151 0 446 0 # Inputs: C CE D R \$pastQ # Outputs: Q FDRE_1 1002 1 5 1 -0 155 0 404 0 +0 151 0 446 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE 1003 1 5 1 -0 155 810 0 0 +0 151 806 0 0 # Inputs: C CE CLR D \$pastQ # Outputs: Q FDCE_1 1004 1 5 1 -0 155 810 0 0 +0 151 806 0 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE 1005 1 5 1 -0 155 0 810 0 +0 151 0 806 0 # Inputs: C CE D PRE \$pastQ # Outputs: Q FDPE_1 1006 1 5 1 -0 155 0 810 0 +0 151 0 806 0 From d02ef8c73f90b345b56f2e1f5f8a3f96a92bdf74 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 11:32:18 -0700 Subject: [PATCH 071/144] Add 'abc_arrival' attribute for flop outputs --- techlibs/xilinx/abc_ff.v | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 117820f0d..66d9573d3 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -113,7 +113,7 @@ module \$__ABC_ASYNC (input A, S, output Y); endmodule (* abc_box_id=1001, lib_whitebox, abc_flop="FDRE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) -module \$__ABC_FDRE ((* abc_flop_q *) output Q, +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, @@ -126,7 +126,7 @@ module \$__ABC_FDRE ((* abc_flop_q *) output Q, endmodule (* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) -module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, +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, @@ -136,7 +136,7 @@ module \$__ABC_FDRE_1 ((* abc_flop_q *) output Q, endmodule (* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) -module \$__ABC_FDCE ((* abc_flop_q *) output Q, +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, @@ -149,7 +149,7 @@ module \$__ABC_FDCE ((* abc_flop_q *) output Q, endmodule (* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) -module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, +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, @@ -159,7 +159,7 @@ module \$__ABC_FDCE_1 ((* abc_flop_q *) output Q, endmodule (* abc_box_id=1005, lib_whitebox, abc_flop="FDPE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) -module \$__ABC_FDPE ((* abc_flop_q *) output Q, +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, @@ -172,7 +172,7 @@ module \$__ABC_FDPE ((* abc_flop_q *) output Q, endmodule (* abc_box_id=1006, lib_whitebox, abc_flop="FDPE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) -module \$__ABC_FDPE_1 ((* abc_flop_q *) output Q, +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, From 91687d3feae8df0e315232d3989a445e7d452d1f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 12:33:24 -0700 Subject: [PATCH 072/144] Add (* abc_arrival *) attribute --- backends/aiger/xaiger.cc | 75 +++++++++++++++++++++++++++++++++++----- passes/techmap/abc9.cc | 2 +- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f6b51b787..6f91e34bd 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -86,6 +86,7 @@ struct XAigerWriter vector> ci_bits; vector> co_bits; vector ff_bits; + dict arrival_times; vector> aig_gates; vector aig_latchin, aig_latchinit, aig_outputs; @@ -217,7 +218,12 @@ struct XAigerWriter // box ordering, but not individual AIG cells dict> bit_drivers, bit_users; TopoSort toposort; - dict> flop_data; + 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()) { @@ -272,9 +278,10 @@ struct XAigerWriter toposort.node(cell->name); - auto r = flop_data.insert(std::make_pair(cell->type, std::make_pair(IdString(), IdString()))); + 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, abc_flop_q; + 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); @@ -287,16 +294,22 @@ struct XAigerWriter 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 (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)); - r.first->second = std::make_pair(abc_flop_d, abc_flop_q); } - auto abc_flop_d = r.first->second.first; + 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); @@ -304,13 +317,17 @@ struct XAigerWriter alias_map[I] = d; unused_bits.erase(d); - auto abc_flop_q = r.first->second.second; + 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()) { @@ -330,12 +347,22 @@ struct XAigerWriter bool cell_known = cell->known(); for (const auto &c : cell->connections()) { if (c.second.is_fully_const()) continue; - auto is_input = !cell_known || cell->input(c.first); - auto is_output = !cell_known || cell->output(c.first); + auto port_wire = inst_module->wire(c.first); + log_assert(port_wire); + auto is_input = !cell_known || port_wire->port_input; + auto is_output = !cell_known || port_wire->port_output; if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); if (is_input) { + int arrival = 0; + auto it = port_wire->attributes.find("\\abc_arrival"); + if (it != port_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(port_wire), log_id(cell->type)); + arrival = it->second.as_int(); + } + for (auto b : c.second.bits()) { Wire *w = b.wire; if (!w) continue; @@ -349,6 +376,8 @@ struct XAigerWriter if (!cell_known) keep_bits.insert(b); } + if (arrival) + arrival_times[b] = arrival; } } if (is_output) { @@ -362,6 +391,8 @@ struct XAigerWriter undriven_bits.erase(O); } } + + } } @@ -722,6 +753,9 @@ struct XAigerWriter int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); }; + auto write_buffer_float = [](std::stringstream &buffer, float f32) { + buffer.write(reinterpret_cast(&f32), sizeof(f32)); + }; std::stringstream h_buffer; auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); @@ -806,13 +840,25 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + std::stringstream i_buffer; + auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); + for (auto i : input_bits) + write_i_buffer(arrival_times.at(i, 0)); + //std::stringstream o_buffer; + //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); + //for (auto o : output_bits) + // write_o_buffer(0); + 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 cell : ff_bits) + for (auto i : ff_bits) { write_r_buffer(mergeability_class++); + write_i_buffer(arrival_times.at(i, 0)); + //write_o_buffer(0); + } f << "r"; buffer_str = r_buffer.str(); @@ -820,6 +866,17 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + f << "i"; + buffer_str = i_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()); + //f << "o"; + //buffer_str = o_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()); + 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()); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index be2a8d50b..9156381fa 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -965,7 +965,7 @@ struct Abc9Pass : public Pass { vector lut_costs; markgroups = false; -#if 0 +#if 1 cleanup = false; show_tempdir = true; #endif From 2f863660870e9ef66c5fcccbf711cf9eb46849c0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 12:39:22 -0700 Subject: [PATCH 073/144] Add reference to source of Tclktoq timing --- techlibs/xilinx/abc_ff.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v index 66d9573d3..36e1a08e4 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_ff.v @@ -20,6 +20,8 @@ // ============================================================================ +// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 + module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; From e29df7d5fa507657994e974630e89511a205ff1e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 12:44:43 -0700 Subject: [PATCH 074/144] Remove debug --- passes/techmap/abc9.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 9156381fa..be2a8d50b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -965,7 +965,7 @@ struct Abc9Pass : public Pass { vector lut_costs; markgroups = false; -#if 1 +#if 0 cleanup = false; show_tempdir = true; #endif From b71212ddeaf099fbbf78d65cf64b3f6f75f80aea Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 12:46:35 -0700 Subject: [PATCH 075/144] Add BRAM arrival times --- techlibs/xilinx/xc7_brams_bb.v | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/xc7_brams_bb.v b/techlibs/xilinx/xc7_brams_bb.v index a682ba4a7..0e8cb406c 100644 --- a/techlibs/xilinx/xc7_brams_bb.v +++ b/techlibs/xilinx/xc7_brams_bb.v @@ -1,3 +1,5 @@ +// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147 + module RAMB18E1 ( input CLKARDCLK, input CLKBWRCLK, @@ -19,10 +21,10 @@ module RAMB18E1 ( input [1:0] WEA, input [3:0] WEBWE, - output [15:0] DOADO, - output [15:0] DOBDO, - output [1:0] DOPADOP, - output [1:0] DOPBDOP + (* abc_arrival=2454 *) output [15:0] DOADO, + (* abc_arrival=2454 *) output [15:0] DOBDO, + (* abc_arrival=2454 *) output [1:0] DOPADOP, + (* abc_arrival=2454 *) output [1:0] DOPBDOP ); parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -143,10 +145,10 @@ module RAMB36E1 ( input [3:0] WEA, input [7:0] WEBWE, - output [31:0] DOADO, - output [31:0] DOBDO, - output [3:0] DOPADOP, - output [3:0] DOPBDOP + (* abc_arrival=2454 *) output [31:0] DOADO, + (* abc_arrival=2454 *) output [31:0] DOBDO, + (* abc_arrival=2454 *) output [3:0] DOPADOP, + (* abc_arrival=2454 *) output [3:0] DOPBDOP ); parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; From 45d4b33f0c2140d764a3a16b14286f6651fbbae6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 13:17:31 -0700 Subject: [PATCH 076/144] Output i/o/h extensions even if no boxes or flops --- backends/aiger/xaiger.cc | 131 ++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 6f91e34bd..2be88b884 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -344,25 +344,16 @@ struct XAigerWriter } } else { - bool cell_known = cell->known(); + bool cell_known = inst_module; for (const auto &c : cell->connections()) { if (c.second.is_fully_const()) continue; - auto port_wire = inst_module->wire(c.first); - log_assert(port_wire); + auto port_wire = inst_module ? inst_module->wire(c.first) : nullptr; auto is_input = !cell_known || port_wire->port_input; auto is_output = !cell_known || port_wire->port_output; if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); if (is_input) { - int arrival = 0; - auto it = port_wire->attributes.find("\\abc_arrival"); - if (it != port_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(port_wire), log_id(cell->type)); - arrival = it->second.as_int(); - } - for (auto b : c.second.bits()) { Wire *w = b.wire; if (!w) continue; @@ -376,11 +367,19 @@ struct XAigerWriter if (!cell_known) keep_bits.insert(b); } - if (arrival) - arrival_times[b] = arrival; } } if (is_output) { + int arrival = 0; + if (port_wire) { + auto it = port_wire->attributes.find("\\abc_arrival"); + if (it != port_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(port_wire), log_id(cell->type)); + arrival = it->second.as_int(); + } + } + for (auto b : c.second.bits()) { Wire *w = b.wire; if (!w) continue; @@ -389,6 +388,9 @@ struct XAigerWriter if (O != b) alias_map[O] = b; undriven_bits.erase(O); + + if (arrival) + arrival_times[b] = arrival; } } @@ -748,29 +750,37 @@ struct XAigerWriter f << "c"; + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + 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("boxNum = %d\n", GetSize(box_list)); + write_h_buffer(box_list.size()); + + auto write_buffer_float = [](std::stringstream &buffer, float f32) { + buffer.write(reinterpret_cast(&f32), sizeof(f32)); + }; + std::stringstream i_buffer; + auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); + for (auto bit : input_bits) + write_i_buffer(arrival_times.at(bit, 0)); + //std::stringstream o_buffer; + //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); + //for (auto bit : output_bits) + // write_o_buffer(0); + if (!box_list.empty() || !ff_bits.empty()) { - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - auto write_buffer_float = [](std::stringstream &buffer, float f32) { - buffer.write(reinterpret_cast(&f32), sizeof(f32)); - }; - - 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("boxNum = %d\n", GetSize(box_list)); - write_h_buffer(box_list.size()); - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -834,49 +844,23 @@ struct XAigerWriter write_h_buffer(box_count++); } - f << "h"; - std::string buffer_str = h_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 i_buffer; - auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); - for (auto i : input_bits) - write_i_buffer(arrival_times.at(i, 0)); - //std::stringstream o_buffer; - //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); - //for (auto o : output_bits) - // write_o_buffer(0); - 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 i : ff_bits) { + for (auto bit : ff_bits) { write_r_buffer(mergeability_class++); - write_i_buffer(arrival_times.at(i, 0)); + write_i_buffer(arrival_times.at(bit, 0)); //write_o_buffer(0); } f << "r"; - buffer_str = r_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); + 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()); - f << "i"; - buffer_str = i_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()); - //f << "o"; - //buffer_str = o_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()); - 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()); @@ -947,6 +931,23 @@ struct XAigerWriter } } + f << "h"; + std::string buffer_str = h_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()); + + f << "i"; + buffer_str = i_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()); + //f << "o"; + //buffer_str = o_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()); + f << stringf("Generated by %s\n", yosys_version_str); } From 526e0813427aae24b9df2eacbbb8c067bdfd5eec Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 15:15:43 -0700 Subject: [PATCH 077/144] Add arrival times for SRL outputs --- techlibs/xilinx/cells_sim.v | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 910d0e246..e5d9f480b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -353,7 +353,8 @@ module RAM128X1D ( endmodule module SRL16E ( - output Q, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, input A0, A1, A2, A3, CE, CLK, D ); parameter [15:0] INIT = 16'h0000; @@ -371,8 +372,9 @@ module SRL16E ( endmodule module SRLC32E ( - output Q, - output Q31, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, + (* abc_arrival=1114 *) output Q31, input [4:0] A, input CE, CLK, D ); From be9e4f1b674ef4fb3f02e99efcfda04ea27b2a68 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 12:39:11 -0700 Subject: [PATCH 078/144] Use abc_{map,unmap,model}.v --- frontends/aiger/aigerparse.cc | 41 ++---- techlibs/xilinx/Makefile.inc | 4 +- techlibs/xilinx/abc_map.v | 120 ++++++++++++++++++ techlibs/xilinx/{abc_ff.v => abc_model.v} | 148 ++++++++-------------- techlibs/xilinx/abc_unmap.v | 140 ++++++++++++++++++++ techlibs/xilinx/cells_map.v | 2 - techlibs/xilinx/cells_sim.v | 8 -- techlibs/xilinx/synth_xilinx.cc | 12 +- 8 files changed, 334 insertions(+), 141 deletions(-) create mode 100644 techlibs/xilinx/abc_map.v rename techlibs/xilinx/{abc_ff.v => abc_model.v} (51%) create mode 100644 techlibs/xilinx/abc_unmap.v diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index cb4ec6183..7a467b91e 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -731,28 +731,21 @@ void AigerReader::parse_aiger_binary() void AigerReader::post_process() { - const RTLIL::Wire* n0 = module->wire("\\__0__"); - const RTLIL::Wire* n1 = module->wire("\\__1__"); - pool seen_boxes; - dict flop_data; + pool flops; unsigned ci_count = 0, co_count = 0, flop_count = 0; for (auto cell : boxes) { RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); - RTLIL::Module* flop_module = nullptr; + bool is_flop = false; if (seen_boxes.insert(cell->type).second) { - auto it = box_module->attributes.find("\\abc_flop"); - if (it != box_module->attributes.end()) { + if (box_module->attributes.count("\\abc_flop")) { log_assert(flop_count < flopNum); - auto abc_flop = it->second.decode_string(); - flop_module = design->module(RTLIL::escape_id(abc_flop)); - if (!flop_module) - log_error("'abc_flop' attribute value '%s' on module '%s' is not a valid module.\n", abc_flop.c_str(), log_id(cell->type)); - flop_data[cell->type] = flop_module; + flops.insert(cell->type); + is_flop = true; } - it = box_module->attributes.find("\\abc_carry"); + auto it = box_module->attributes.find("\\abc_carry"); if (it != box_module->attributes.end()) { RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; auto carry_in_out = it->second.decode_string(); @@ -791,11 +784,8 @@ void AigerReader::post_process() carry_out->port_id = ports.size(); } } - else { - auto it = flop_data.find(cell->type); - if (it != flop_data.end()) - flop_module = it->second; - } + else + is_flop = flops.count(cell->type); // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) @@ -822,11 +812,11 @@ void AigerReader::post_process() rhs.append(wire); } - if (!flop_module || port_name != "\\$pastQ") + if (!is_flop || port_name != "\\$pastQ") cell->setPort(port_name, rhs); } - if (flop_module) { + if (is_flop) { RTLIL::Wire *d = outputs[outputs.size() - flopNum + flop_count]; log_assert(d); log_assert(d->port_output); @@ -838,21 +828,10 @@ void AigerReader::post_process() q->port_input = false; flop_count++; - cell->type = flop_module->name; module->connect(q, d); cell->set_bool_attribute("\\abc_flop"); continue; } - - // Remove the async mux by shorting out its input and output - if (cell->type == "$__ABC_ASYNC") { - RTLIL::Wire* A = cell->getPort("\\A").as_wire(); - if (A == n0 || A == n1) A = nullptr; - auto it = cell->connections_.find("\\Y"); - log_assert(it != cell->connections_.end()); - module->connect(it->second, A); - cell->connections_.erase(it); - } } dict wideports_cache; diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index a9e0c5c7b..a11880c4d 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -39,7 +39,9 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_ff.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_unmap.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_model.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7_nowide.lut)) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v new file mode 100644 index 000000000..99e1fe127 --- /dev/null +++ b/techlibs/xilinx/abc_map.v @@ -0,0 +1,120 @@ +/* + * 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. + * + */ + +// ============================================================================ + +// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 + +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 diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_model.v similarity index 51% rename from techlibs/xilinx/abc_ff.v rename to techlibs/xilinx/abc_model.v index 36e1a08e4..41c232650 100644 --- a/techlibs/xilinx/abc_ff.v +++ b/techlibs/xilinx/abc_model.v @@ -20,93 +20,12 @@ // ============================================================================ -// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 - -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) - ) _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) - ) _TECHMAP_REPLACE_ ( - .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) - ); - \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +(* abc_box_id = 3, lib_whitebox *) +module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); + assign O = S1 ? (S0 ? I3 : I2) + : (S0 ? I1 : I0); 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) - ) _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) - ) _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) - ) _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) - ) _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 - -`ifndef _ABC module \$__ABC_FF_ (input C, D, output Q); endmodule @@ -114,7 +33,7 @@ endmodule module \$__ABC_ASYNC (input A, S, output Y); endmodule -(* abc_box_id=1001, lib_whitebox, abc_flop="FDRE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) +(* 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, @@ -124,20 +43,24 @@ module \$__ABC_FDRE ((* abc_flop_q, abc_arrival=303 *) output Q, 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 = "FDRE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) +(* 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 = "FDCE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) +(* 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, @@ -147,20 +70,24 @@ module \$__ABC_FDCE ((* abc_flop_q, abc_arrival=303 *) output Q, 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 = "FDCE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) +(* 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="FDPE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) +(* 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, @@ -170,17 +97,52 @@ module \$__ABC_FDPE ((* abc_flop_q, abc_arrival=303 *) output Q, 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="FDPE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) +(* 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 [0:0] INIT = 1'b0; + parameter CLK_POLARITY = 1'b0; + parameter EN_POLARITY = 1'b1; assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule -`endif +module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); + output O; + input I0, I1, I2, I3, S0, S1; + wire T0, T1; + parameter _TECHMAP_BITS_CONNMAP_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I0_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I1_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I2_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I3_ = 0; + parameter _TECHMAP_CONSTMSK_S0_ = 0; + parameter _TECHMAP_CONSTVAL_S0_ = 0; + parameter _TECHMAP_CONSTMSK_S1_ = 0; + parameter _TECHMAP_CONSTVAL_S1_ = 0; + if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1) + assign T0 = I1; + else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_) + assign T0 = I0; + else + MUXF7 mux7a (.I0(I0), .I1(I1), .S(S0), .O(T0)); + if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1) + assign T1 = I3; + else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_) + assign T1 = I2; + else + MUXF7 mux7b (.I0(I2), .I1(I3), .S(S0), .O(T1)); + if (_TECHMAP_CONSTMSK_S1_ && _TECHMAP_CONSTVAL_S1_ === 1'b1) + assign O = T1; + else if (_TECHMAP_CONSTMSK_S1_ || (_TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_ && _TECHMAP_CONNMAP_I1_ === _TECHMAP_CONNMAP_I2_ && _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_)) + assign O = T0; + else + MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); +endmodule diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v new file mode 100644 index 000000000..6de766e76 --- /dev/null +++ b/techlibs/xilinx/abc_unmap.v @@ -0,0 +1,140 @@ +/* + * 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. + * + */ + +// ============================================================================ + +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 diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index b8e5bafc7..a15884ec4 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -331,7 +331,6 @@ module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y) endmodule `endif -`ifndef _ABC module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); output O; input I0, I1, I2, I3, S0, S1; @@ -364,4 +363,3 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); else MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); endmodule -`endif diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index dd5a76752..614fd8eef 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -169,14 +169,6 @@ module MUXF8(output O, input I0, I1, S); assign O = S ? I1 : I0; endmodule -`ifdef _ABC -(* abc_box_id = 3, lib_whitebox *) -module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); - assign O = S1 ? (S0 ? I3 : I2) - : (S0 ? I1 : I0); -endmodule -`endif - module XORCY(output O, input CI, LI); assign O = CI ^ LI; endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 6456dbdf4..3525e4de9 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -230,9 +230,9 @@ struct SynthXilinxPass : public ScriptPass { if (check_label("begin")) { if (vpr) - run("read_verilog -lib -icells -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); + run("read_verilog -lib -icells -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); else - run("read_verilog -lib -icells -D _ABC +/xilinx/cells_sim.v"); + run("read_verilog -lib -icells +/xilinx/cells_sim.v"); run("read_verilog -lib +/xilinx/cells_xtra.v"); @@ -373,11 +373,11 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("map_cells")) { - std::string techmap_args = "-map +/techmap.v -D _ABC -map +/xilinx/cells_map.v"; + 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 -D _ABC -map +/xilinx/abc_ff.v"; + techmap_args += " -map +/xilinx/ff_map.v -map +/xilinx/abc_map.v"; run("techmap " + techmap_args); run("clean"); } @@ -389,7 +389,7 @@ struct SynthXilinxPass : public ScriptPass else if (abc9) { if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); - run("read_verilog -icells -lib +/xilinx/abc_ff.v"); + run("read_verilog -icells -lib +/xilinx/abc_model.v"); if (nowidelut) run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); else @@ -408,7 +408,7 @@ struct SynthXilinxPass : public ScriptPass if (!nosrl || help_mode) run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); if (abc9) - run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v"); + run("techmap -map +/xilinx/lut_map.v -map +/xilinx/abc_unmap.v"); else run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/ff_map.v"); run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " From 5eda5fc7eb889b738739270f67349b1027951443 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 12:41:11 -0700 Subject: [PATCH 079/144] Remove -icells --- techlibs/xilinx/synth_xilinx.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 3525e4de9..d4874af45 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -230,9 +230,9 @@ struct SynthXilinxPass : public ScriptPass { if (check_label("begin")) { if (vpr) - run("read_verilog -lib -icells -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); + run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); else - run("read_verilog -lib -icells +/xilinx/cells_sim.v"); + run("read_verilog -lib +/xilinx/cells_sim.v"); run("read_verilog -lib +/xilinx/cells_xtra.v"); From 8d0cffaf20c55c733bb5d286b5de1ed85cde77f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 13:11:39 -0700 Subject: [PATCH 080/144] Remove mapping rules --- techlibs/xilinx/abc_model.v | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index 41c232650..243a93403 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -113,36 +113,3 @@ module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, parameter EN_POLARITY = 1'b1; assign Q = (CE && !PRE) ? D : \$pastQ ; endmodule - -module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); - output O; - input I0, I1, I2, I3, S0, S1; - wire T0, T1; - parameter _TECHMAP_BITS_CONNMAP_ = 0; - parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I0_ = 0; - parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I1_ = 0; - parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I2_ = 0; - parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I3_ = 0; - parameter _TECHMAP_CONSTMSK_S0_ = 0; - parameter _TECHMAP_CONSTVAL_S0_ = 0; - parameter _TECHMAP_CONSTMSK_S1_ = 0; - parameter _TECHMAP_CONSTVAL_S1_ = 0; - if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1) - assign T0 = I1; - else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_) - assign T0 = I0; - else - MUXF7 mux7a (.I0(I0), .I1(I1), .S(S0), .O(T0)); - if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1) - assign T1 = I3; - else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_) - assign T1 = I2; - else - MUXF7 mux7b (.I0(I2), .I1(I3), .S(S0), .O(T1)); - if (_TECHMAP_CONSTMSK_S1_ && _TECHMAP_CONSTVAL_S1_ === 1'b1) - assign O = T1; - else if (_TECHMAP_CONSTMSK_S1_ || (_TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_ && _TECHMAP_CONNMAP_I1_ === _TECHMAP_CONNMAP_I2_ && _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_)) - assign O = T0; - else - MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); -endmodule From 505d062daf0e2600dacf04cf18d97b279bd58d72 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 13:33:31 -0700 Subject: [PATCH 081/144] Fix use of {CLK,EN}_POLARITY, also add a FIXME --- passes/techmap/abc9.cc | 78 +++++++----------------------------------- 1 file changed, 13 insertions(+), 65 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 576fb8542..c7dc67c62 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -645,9 +645,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (existing_cell) { cell->parameters = existing_cell->parameters; cell->attributes = existing_cell->attributes; - - cell->attributes.erase("\\abc_flop_clk_pol"); - cell->attributes.erase("\\abc_flop_en_pol"); } else { cell->parameters = mapped_cell->parameters; @@ -1204,11 +1201,7 @@ struct Abc9Pass : public Pass { pool seen_cells; struct flop_data_t { IdString clk_port; - IdString clk_pol_param; - bool clk_pol; IdString en_port; - IdString en_pol_param; - bool en_pol; }; dict flop_data; @@ -1262,39 +1255,7 @@ struct Abc9Pass : public Pass { if (abc_flop_en == IdString()) log_error("'abc_flop_en' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); - auto jt = inst_module->attributes.find("\\abc_flop_clk_pol"); - if (jt == inst_module->attributes.end()) - log_error("'abc_flop_clk_pol' attribute not found on module '%s'.\n", log_id(inst_module)); - IdString abc_flop_clk_pol_param; - bool abc_flop_clk_pol; - if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { - auto param = jt->second.decode_string(); - abc_flop_clk_pol = (param[0] == '!'); - if (abc_flop_clk_pol) - abc_flop_clk_pol_param = RTLIL::escape_id(param.substr(1)); - else - abc_flop_clk_pol_param = RTLIL::escape_id(param); - } - else - abc_flop_clk_pol = !jt->second.as_bool(); - jt = inst_module->attributes.find("\\abc_flop_en_pol"); - if (jt == inst_module->attributes.end()) - log_error("'abc_flop_en_pol' attribute not found on module '%s'.\n", log_id(inst_module)); - IdString abc_flop_en_pol_param; - bool abc_flop_en_pol; - if (jt->second.flags == RTLIL::ConstFlags::CONST_FLAG_STRING) { - auto param = jt->second.decode_string(); - abc_flop_en_pol = (param[0] == '!'); - if (abc_flop_en_pol) - abc_flop_en_pol_param = RTLIL::escape_id(param.substr(1)); - else - abc_flop_en_pol_param = RTLIL::escape_id(param); - } - else - abc_flop_en_pol = !jt->second.as_bool(); - - it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_clk_pol_param, abc_flop_clk_pol, - abc_flop_en, abc_flop_en_pol_param, abc_flop_en_pol})).first; + it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_en})).first; } else { it = flop_data.find(cell->type); @@ -1304,30 +1265,15 @@ struct Abc9Pass : public Pass { const auto &data = it->second; - bool this_clk_pol; - if (data.clk_pol_param == IdString()) - this_clk_pol = data.clk_pol; - else { - auto param = data.clk_pol_param; - auto jt = cell->parameters.find(param); - if (jt == cell->parameters.end()) - log_error("'abc_flop_clk_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); - this_clk_pol = jt->second.as_bool(); - if (data.clk_pol) - this_clk_pol = !this_clk_pol; - } - bool this_en_pol; - if (data.en_pol_param == IdString()) - this_en_pol = data.en_pol; - else { - auto param = data.en_pol_param; - auto jt = cell->parameters.find(param); - if (jt == cell->parameters.end()) - log_error("'abc_flop_en_pol' value '%s' is not a parameter on module '%s'.\n", param.c_str(), log_id(cell->type)); - this_en_pol = jt->second.as_bool(); - if (data.en_pol) - this_en_pol = !this_en_pol; - } + 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))); @@ -1416,9 +1362,10 @@ struct Abc9Pass : public Pass { std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); for (auto &it : assigned_cells) { + // FIXME: abc9_module calls below can delete cells, + // leaving a dangling pointer here... clk_polarity = std::get<0>(it.first); clk_sig = assign_map(std::get<1>(it.first)); en_polarity = std::get<2>(it.first); @@ -1427,6 +1374,7 @@ struct Abc9Pass : public Pass { pool assigned_names; for (auto i : it.second) assigned_names.insert(i->name); + RTLIL::Selection& sel = design->selection_stack.back(); sel.selected_members[mod->name] = std::move(assigned_names); abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", From 0079e9b4a677de66372e5c5c9cb011ce74184258 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 13:53:38 -0700 Subject: [PATCH 082/144] Add LUTRAM delays --- techlibs/xilinx/cells_sim.v | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 614fd8eef..fa0a8fea0 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -289,7 +289,8 @@ endmodule (* abc_box_id = 5 *) module RAM32X1D ( - output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output DPO, SPO, (* abc_scc_break *) input D, input WCLK, (* abc_scc_break *) input WE, @@ -309,7 +310,8 @@ endmodule (* abc_box_id = 6 *) module RAM64X1D ( - output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output DPO, SPO, (* abc_scc_break *) input D, input WCLK, (* abc_scc_break *) input WE, @@ -329,7 +331,8 @@ endmodule (* abc_box_id = 7 *) module RAM128X1D ( - output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output DPO, SPO, (* abc_scc_break *) input D, input WCLK, (* abc_scc_break *) input WE, From c00d72cdb30382d1e4d63f64e2b6ee2d1e312092 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 14:47:58 -0700 Subject: [PATCH 083/144] Minor refactor --- backends/aiger/xaiger.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2be88b884..ad2a778fa 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -331,14 +331,15 @@ struct XAigerWriter } for (const auto &conn : cell->connections()) { - if (cell->input(conn.first)) { + auto port_wire = inst_module->wire(conn.first); + if (port_wire->port_input) { // Ignore inout for the sake of topographical ordering - if (cell->output(conn.first)) continue; + if (port_wire->port_output) continue; for (auto bit : sigmap(conn.second)) bit_users[bit].insert(cell->name); } - if (cell->output(conn.first)) + if (port_wire->port_output) for (auto bit : sigmap(conn.second)) bit_drivers[bit].insert(cell->name); } @@ -354,7 +355,7 @@ struct XAigerWriter log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); if (is_input) { - for (auto b : c.second.bits()) { + for (auto b : sigmap(c.second)) { Wire *w = b.wire; if (!w) continue; if (!w->port_output || !cell_known) { @@ -380,7 +381,7 @@ struct XAigerWriter } } - for (auto b : c.second.bits()) { + for (auto b : sigmap(c.second)) { Wire *w = b.wire; if (!w) continue; input_bits.insert(b); @@ -393,8 +394,6 @@ struct XAigerWriter arrival_times[b] = arrival; } } - - } } From 808f07630fc79bf5f6e44986985dd07f83bb9d46 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 14:49:11 -0700 Subject: [PATCH 084/144] Wrap LUTRAMs in order to capture comb/seq behaviour --- techlibs/xilinx/abc_map.v | 69 +++++++++++++++++++++++++++++++++++++ techlibs/xilinx/abc_model.v | 44 +++++++++++++++++++++++ techlibs/xilinx/abc_unmap.v | 64 ++++++++++++++++++++++++++++++++++ techlibs/xilinx/abc_xc7.box | 35 ++++++++----------- techlibs/xilinx/cells_sim.v | 24 +++++-------- 5 files changed, 200 insertions(+), 36 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 99e1fe127..0d69e8c08 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -118,3 +118,72 @@ module FDPE_1 (output reg Q, input C, CE, D, 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, + input WCLK, + input WE, + input A0, A1, A2, A3, A4, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 +); + parameter INIT = 32'h0; + parameter IS_WCLK_INVERTED = 1'b0; + wire \$DPO , \$SPO ; + \$__ABC_RAM32X1D #( + .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .DPO(\$DPO ), .SPO(\$SPO ), + .D(D), .WCLK(WCLK), .WE(WE), + .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), + .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4) + ); + \$__ABC_LUTMUX dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO)); + \$__ABC_LUTMUX spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO)); +endmodule + +module RAM64X1D ( + output DPO, SPO, + input D, + input WCLK, + input WE, + input A0, A1, A2, A3, A4, A5, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 +); + parameter INIT = 64'h0; + parameter IS_WCLK_INVERTED = 1'b0; + wire \$DPO , \$SPO ; + \$__ABC_RAM64X1D #( + .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .DPO(\$DPO ), .SPO(\$SPO ), + .D(D), .WCLK(WCLK), .WE(WE), + .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5), + .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5) + ); + \$__ABC_LUTMUX6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO)); + \$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO)); +endmodule + +module \$__ABC_RAM128X1D ( + output DPO, SPO, + input D, + input WCLK, + input WE, + input [6:0] A, DPRA +); + parameter INIT = 128'h0; + parameter IS_WCLK_INVERTED = 1'b0; + wire \$DPO , \$SPO ; + \$__ABC_RAM128X1D #( + .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .DPO(\$DPO ), .SPO(\$SPO ), + .D(D), .WCLK(WCLK), .WE(WE), + .A(A), + .DPRA(DPRA) + ); + \$__ABC_LUTMUX7 dpo (.A(\$DPO ), .S(A), .Y(DPO)); + \$__ABC_LUTMUX7 spo (.A(\$SPO ), .S(A), .Y(SPO)); + +endmodule diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index 243a93403..76ef41a91 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -113,3 +113,47 @@ module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, 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 +(* abc_box_id=2001 *) +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#L904-L905 + (* abc_arrival=1472 *) output DPO, SPO, + input D, + input WCLK, + input WE, + input A0, A1, A2, A3, A4, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 +); +endmodule + +module \$__ABC_RAM64X1D ( + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output DPO, SPO, + input D, + input WCLK, + input WE, + input A0, A1, A2, A3, A4, A5, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 +); + parameter INIT = 64'h0; + parameter IS_WCLK_INVERTED = 1'b0; +endmodule + +module \$__ABC_RAM128X1D ( + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output DPO, SPO, + input D, + input WCLK, + input WE, + input [6:0] A, DPRA +); + parameter INIT = 128'h0; + parameter IS_WCLK_INVERTED = 1'b0; +endmodule diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v index 6de766e76..f2708b477 100644 --- a/techlibs/xilinx/abc_unmap.v +++ b/techlibs/xilinx/abc_unmap.v @@ -138,3 +138,67 @@ module \$__ABC_FDPE_1 (output Q, .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) ); endmodule + +module \$__ABC_LUTMUX (input A, input [5:0] S, output Y); + assign Y = A; +endmodule + +module \$__ABC_RAM32X1D ( + output DPO, SPO, + input D, + input WCLK, + input WE, + input A0, A1, A2, A3, A4, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 +); + parameter INIT = 32'h0; + parameter IS_WCLK_INVERTED = 1'b0; + RAM32X1D #( + .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .DPO(DPO), .SPO(SPO), + .D(D), .WCLK(WCLK), .WE(WE), + .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), + .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4) + ); +endmodule + +module \$__ABC_RAM64X1D ( + output DPO, SPO, + input D, + input WCLK, + input WE, + input A0, A1, A2, A3, A4, A5, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 +); + parameter INIT = 64'h0; + parameter IS_WCLK_INVERTED = 1'b0; + RAM64X1D #( + .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .DPO(DPO), .SPO(SPO), + .D(D), .WCLK(WCLK), .WE(WE), + .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5), + .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5) + ); +endmodule + +module \$__ABC_RAM128X1D ( + output DPO, SPO, + input D, + input WCLK, + input WE, + input A, + input DPRA, +); + parameter INIT = 128'h0; + parameter IS_WCLK_INVERTED = 1'b0; + RAM128X1D #( + .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .DPO(DPO), .SPO(SPO), + .D(D), .WCLK(WCLK), .WE(WE), + .A(A), + .DPRA(DPRA) + ); +endmodule diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 16040662c..c08af6320 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -38,27 +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 -# SLICEM/A6LUT -# Inputs: A0 A1 A2 A3 A4 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 WCLK WE -# Outputs: DPO SPO -RAM32X1D 5 0 13 2 -- - - - - - 631 472 407 238 127 - - -631 472 407 238 127 - - - - - - - - - -# SLICEM/A6LUT -# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE -# Outputs: DPO SPO -RAM64X1D 6 0 15 2 -- - - - - - - 642 631 472 407 238 127 - - -642 631 472 407 238 127 - - - - - - - - - - -# SLICEM/A6LUT + F7[AB]MUX -# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE -# Outputs: DPO SPO -RAM128X1D 7 0 17 2 -- - - - - - - - 1009 998 839 774 605 494 450 - - -1047 1036 877 812 643 532 478 - - - - - - - - - - - # Box to emulate async behaviour of FD[CP]* # Inputs: A S # Outputs: Y @@ -99,3 +78,17 @@ FDPE 1005 1 5 1 # 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 +# Outputs: Y +$__ABC_LUTRAM6 2000 0 7 1 +0 642 631 472 407 238 127 + +# SLICEM/A6LUT + F7BMUX +# Box to emulate comb/seq behaviour of RAMD128 +# Inputs: A S0 S1 S2 S3 S4 S5 S6 +# Outputs: DPO SPO +$__ABC_LUTRAM7 2001 0 8 1 +0 1047 1036 877 812 643 532 478 diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index fa0a8fea0..e5261de1c 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -287,13 +287,11 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; endmodule -(* abc_box_id = 5 *) module RAM32X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output DPO, SPO, - (* abc_scc_break *) input D, + output DPO, SPO, + input D, input WCLK, - (* abc_scc_break *) input WE, + input WE, input A0, A1, A2, A3, A4, input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 ); @@ -308,13 +306,11 @@ module RAM32X1D ( always @(posedge clk) if (WE) mem[a] <= D; endmodule -(* abc_box_id = 6 *) module RAM64X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output DPO, SPO, - (* abc_scc_break *) input D, + output DPO, SPO, + input D, input WCLK, - (* abc_scc_break *) input WE, + input WE, input A0, A1, A2, A3, A4, A5, input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 ); @@ -329,13 +325,11 @@ module RAM64X1D ( always @(posedge clk) if (WE) mem[a] <= D; endmodule -(* abc_box_id = 7 *) module RAM128X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output DPO, SPO, - (* abc_scc_break *) input D, + output DPO, SPO, + input D, input WCLK, - (* abc_scc_break *) input WE, + input WE, input [6:0] A, DPRA ); parameter INIT = 128'h0; From e273ed52758599cb156cf3c309905da70826fe2d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 15:09:38 -0700 Subject: [PATCH 085/144] Wrap SRL{16,32} too --- techlibs/xilinx/abc_map.v | 38 ++++++++++++++++++++++++++++++++++++- techlibs/xilinx/abc_model.v | 32 +++++++++++++++++++++++++------ techlibs/xilinx/abc_unmap.v | 37 +++++++++++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 0d69e8c08..56b4fe7f9 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -185,5 +185,41 @@ module \$__ABC_RAM128X1D ( ); \$__ABC_LUTMUX7 dpo (.A(\$DPO ), .S(A), .Y(DPO)); \$__ABC_LUTMUX7 spo (.A(\$SPO ), .S(A), .Y(SPO)); - +endmodule + +module SRL16E ( + output Q, + input A0, A1, A2, A3, CE, CLK, D +); + parameter [15:0] INIT = 16'h0000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; + wire \$Q ; + \$__ABC_SRL16E #( + .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .Q(\$Q ), + .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D) + ); + // TODO: Check if SRL uses fast inputs or slow inputs + \$__ABC_LUTMUX6 q (.A(\$Q ), .S({A0, A1, A2, A3, 1'b0, 1'b0}), .Y(Q)); +endmodule + +module SRLC32E ( + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, + (* abc_arrival=1114 *) output Q31, + input [4:0] A, + input CE, CLK, D +); + parameter [31:0] INIT = 32'h00000000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; + wire \$Q ; + \$__ABC_SRLC32E #( + .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .Q(\$Q ), .Q31(Q31), + .A(A), .CE(CE), .CLK(CLK), .D(D) + ); + // TODO: Check if SRL uses fast inputs or slow inputs + \$__ABC_LUTMUX6 q (.A(\$Q ), .S({A, 1'b0}), .Y(Q)); endmodule diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index 76ef41a91..7162bd213 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -123,8 +123,8 @@ endmodule module \$__ABC_RAM32X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc_arrival=1153 *) output DPO, SPO, input D, input WCLK, input WE, @@ -134,8 +134,8 @@ module \$__ABC_RAM32X1D ( endmodule module \$__ABC_RAM64X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc_arrival=1153 *) output DPO, SPO, input D, input WCLK, input WE, @@ -147,8 +147,8 @@ module \$__ABC_RAM64X1D ( endmodule module \$__ABC_RAM128X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc_arrival=1153 *) output DPO, SPO, input D, input WCLK, input WE, @@ -157,3 +157,23 @@ module \$__ABC_RAM128X1D ( parameter INIT = 128'h0; parameter IS_WCLK_INVERTED = 1'b0; endmodule + +module SRL16E ( + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, + input A0, A1, A2, A3, CE, CLK, D +); + parameter [15:0] INIT = 16'h0000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; +endmodule + +module SRLC32E ( + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, + (* abc_arrival=1114 *) output Q31, + input [4:0] A, + input CE, CLK, D +); + parameter [31:0] INIT = 32'h00000000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; +endmodule diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v index f2708b477..d00d27e2e 100644 --- a/techlibs/xilinx/abc_unmap.v +++ b/techlibs/xilinx/abc_unmap.v @@ -139,7 +139,10 @@ module \$__ABC_FDPE_1 (output Q, ); endmodule -module \$__ABC_LUTMUX (input A, input [5:0] S, output Y); +module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); + assign Y = A; +endmodule +module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y); assign Y = A; endmodule @@ -202,3 +205,35 @@ module \$__ABC_RAM128X1D ( .DPRA(DPRA) ); endmodule + +module \$__ABC_SRL16E ( + output Q, + input A0, A1, A2, A3, CE, CLK, D +); + parameter [15:0] INIT = 16'h0000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; + + SRL16E #( + .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .Q(Q), + .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D) + ); +endmodule + +module \$__ABC_SRLC32E ( + output Q, + output Q31, + input [4:0] A, + input CE, CLK, D +); + parameter [31:0] INIT = 32'h00000000; + parameter [0:0] IS_CLK_INVERTED = 1'b0; + + SRLC32E #( + .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) + ) _TECHMAP_REPLACE_ ( + .Q(Q), .Q31(Q31), + .A(A), .CE(CE), .CLK(CLK), .D(D) + ); +endmodule From 0ca397f087287307d13daac57f60c24c6f2a982e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 15:10:01 -0700 Subject: [PATCH 086/144] Deprecate `abc_scc_break` attribute --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 56f428548..fe30348eb 100644 --- a/README.md +++ b/README.md @@ -409,14 +409,6 @@ Verilog Attributes and non-standard features blackbox or whitebox definition to a corresponding entry in a `abc9` box-file. -- The port attribute ``abc_scc_break`` indicates a module input port that will - be treated as a primary output during `abc9` techmapping. Doing so eliminates - the possibility of a strongly-connected component (i.e. a combinatorial loop) - existing. Typically, this is specified for sequential inputs on otherwise - combinatorial boxes -- for example, applying ``abc_scc_break`` onto the `D` - port of a LUTRAM cell prevents `abc9` from interpreting any `Q` -> `D` paths - as a combinatorial loop. - - The port attribute ``abc_carry`` marks the carry-in (if an input port) and carry-out (if output port) ports of a box. This information is necessary for `abc9` to preserve the integrity of carry-chains. Specifying this attribute From 1b5d2de1d4212bd93f9b0ca0d5173e4c8a4dd4e8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 15:23:26 -0700 Subject: [PATCH 087/144] Do not sigmap! --- backends/aiger/xaiger.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ad2a778fa..d02997da4 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -355,7 +355,7 @@ struct XAigerWriter log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); if (is_input) { - for (auto b : sigmap(c.second)) { + for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; if (!w->port_output || !cell_known) { @@ -381,7 +381,7 @@ struct XAigerWriter } } - for (auto b : sigmap(c.second)) { + for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; input_bits.insert(b); From 96f00e9147967b587ee3b0118b944464b06da0b6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 17:51:50 -0700 Subject: [PATCH 088/144] Typo --- techlibs/xilinx/abc_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 56b4fe7f9..dc5032d23 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -165,7 +165,7 @@ module RAM64X1D ( \$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO)); endmodule -module \$__ABC_RAM128X1D ( +module RAM128X1D ( output DPO, SPO, input D, input WCLK, From 54284aaa986800b8623d401fd93cf92d25d13713 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 17:52:27 -0700 Subject: [PATCH 089/144] Remove delays from abc_map.v --- techlibs/xilinx/abc_map.v | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index dc5032d23..1d8604ddb 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -20,8 +20,6 @@ // ============================================================================ -// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 - module FDRE (output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; @@ -205,9 +203,8 @@ module SRL16E ( endmodule module SRLC32E ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, - (* abc_arrival=1114 *) output Q31, + output Q, + output Q31, input [4:0] A, input CE, CLK, D ); From 3b52d6e29ccc95fd4d102d9a59bb34125521c648 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 17:55:12 -0700 Subject: [PATCH 090/144] Move `techmap abc_map.v` into map_luts --- techlibs/xilinx/synth_xilinx.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index d6ff91e13..a2ec6a9c9 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -380,7 +380,7 @@ struct SynthXilinxPass : public ScriptPass if (widemux > 0) techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); if (abc9) - techmap_args += " -map +/xilinx/ff_map.v -map +/xilinx/abc_map.v"; + techmap_args += " -map +/xilinx/ff_map.v"; run("techmap " + techmap_args); run("clean"); } @@ -393,6 +393,7 @@ struct SynthXilinxPass : public ScriptPass if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); run("read_verilog -icells -lib +/xilinx/abc_model.v"); + run("techmap -map +/xilinx/abc_map.v"; if (nowidelut) run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); else From 30a379b5b6600f0e0e99f0c99ad7bc1d4d08cd90 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 17:59:31 -0700 Subject: [PATCH 091/144] Cleanup techmap in map_luts --- techlibs/xilinx/synth_xilinx.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index a2ec6a9c9..d28cd2428 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -393,7 +393,7 @@ struct SynthXilinxPass : public ScriptPass if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); run("read_verilog -icells -lib +/xilinx/abc_model.v"); - run("techmap -map +/xilinx/abc_map.v"; + run("techmap -map +/xilinx/abc_map.v"); if (nowidelut) run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); else @@ -411,10 +411,12 @@ 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"; if (abc9) - run("techmap -map +/xilinx/lut_map.v -map +/xilinx/abc_unmap.v"); + techmap_args += " -map +/xilinx/abc_unmap.v"; else - run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/ff_map.v"); + 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"); run("clean"); From aa2d3af6319d475e589acd1efc83d07c11257229 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:08:07 -0700 Subject: [PATCH 092/144] LUTMUX -> LUTMUX6 --- techlibs/xilinx/abc_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 1d8604ddb..a760b3d6d 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -136,8 +136,8 @@ module RAM32X1D ( .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4) ); - \$__ABC_LUTMUX dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO)); - \$__ABC_LUTMUX spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO)); + \$__ABC_LUTMUX6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO)); + \$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO)); endmodule module RAM64X1D ( From fad15d276dd9746b41a2d3e1592285ad4362fe21 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:08:58 -0700 Subject: [PATCH 093/144] retime_mode -> dff_mode --- passes/techmap/abc9.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c7dc67c62..29929f80b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -269,7 +269,7 @@ struct abc_output_filter }; void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - bool cleanup, vector lut_costs, bool /*retime_mode*/, std::string clk_str, + 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, @@ -309,7 +309,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); } - //if (retime_mode && clk_sig.empty()) + //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"; @@ -383,7 +383,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri fprintf(f, "%s\n", abc_script.c_str()); fclose(f); - if (/*retime_mode ||*/ !clk_str.empty()) + 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"); @@ -957,7 +957,7 @@ struct Abc9Pass : public Pass { #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, /*retime_mode = false,*/ keepff = false, cleanup = true; + bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false; vector lut_costs; markgroups = false; @@ -1049,12 +1049,12 @@ struct Abc9Pass : public Pass { continue; } //if (arg == "-retime") { - // retime_mode = true; + // dff_mode = true; // continue; //} //if (arg == "-clk" && argidx+1 < args.size()) { // clk_str = args[++argidx]; - // retime_mode = true; + // dff_mode = true; // continue; //} //if (arg == "-keepff") { @@ -1169,7 +1169,7 @@ struct Abc9Pass : public Pass { assign_map.set(mod); - if (true || /*!dff_mode ||*/ !clk_str.empty()) { + if (!dff_mode || !clk_str.empty()) { design->selection_stack.emplace_back(false); RTLIL::Selection& sel = design->selection_stack.back(); From bbab6086918f8af3a8a09c2be56208fc29ef7068 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:14:40 -0700 Subject: [PATCH 094/144] Remove SRL* delays from cells_sim.v --- techlibs/xilinx/cells_sim.v | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index e5261de1c..1ab718ccc 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -342,8 +342,7 @@ module RAM128X1D ( endmodule module SRL16E ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, + output Q, input A0, A1, A2, A3, CE, CLK, D ); parameter [15:0] INIT = 16'h0000; @@ -361,9 +360,8 @@ module SRL16E ( endmodule module SRLC32E ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, - (* abc_arrival=1114 *) output Q31, + output Q, + output Q31, input [4:0] A, input CE, CLK, D ); From 091bf4a18b2f4bf84fe62b61577c88d961468b3c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:16:37 -0700 Subject: [PATCH 095/144] 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"); From 343039496baf434beca8c2fb3c275a60365f9496 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:22:58 -0700 Subject: [PATCH 096/144] Add reference to FD* timing --- techlibs/xilinx/cells_sim.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index d879a56ee..6aba5a4b2 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -211,6 +211,8 @@ endmodule `endif +// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250 + module FDRE ((* abc_arrival=303 *) output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; From 4cd1d21bfe412e9c6edb8aa74c19ee57370c56c4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:27:16 -0700 Subject: [PATCH 097/144] Add (* abc_arrival= *) doc --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index fe30348eb..63cefaf26 100644 --- a/README.md +++ b/README.md @@ -414,6 +414,11 @@ Verilog Attributes and non-standard features `abc9` to preserve the integrity of carry-chains. Specifying this attribute onto a bus port will affect only its most significant bit. +- The port attribute ``abc_arrival`` specifies an integer (for output ports + only) to be used as the arrival time of this sequential port. It can be used, + for example, to specify the clk-to-Q delay of a flip-flop for consideration + during techmapping. + Non-standard or SystemVerilog features for formal verification ============================================================== From 55acf3120fa47bb95be8a6551738f4f9b1c70a21 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 18:59:03 -0700 Subject: [PATCH 098/144] ecp5 to use abc_map.v and _unmap.v --- techlibs/ecp5/Makefile.inc | 3 +++ techlibs/ecp5/abc_5g.box | 16 ++++++++-------- techlibs/ecp5/abc_map.v | 24 ++++++++++++++++++++++++ techlibs/ecp5/abc_model.v | 18 ++++++++++++++++++ techlibs/ecp5/abc_unmap.v | 25 +++++++++++++++++++++++++ techlibs/ecp5/cells_sim.v | 7 +++---- techlibs/ecp5/synth_ecp5.cc | 8 +++++++- 7 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 techlibs/ecp5/abc_map.v create mode 100644 techlibs/ecp5/abc_model.v create mode 100644 techlibs/ecp5/abc_unmap.v diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 73e18112f..cffd5c3a4 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -11,6 +11,9 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_map.v)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_unmap.v)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_model.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.box)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.lut)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g_nowide.lut)) diff --git a/techlibs/ecp5/abc_5g.box b/techlibs/ecp5/abc_5g.box index c757d137d..66ebe196a 100644 --- a/techlibs/ecp5/abc_5g.box +++ b/techlibs/ecp5/abc_5g.box @@ -15,16 +15,16 @@ CCU2C 1 1 9 3 630 379 630 379 526 275 392 141 273 516 516 516 516 412 412 278 278 43 -# Box 2 : TRELLIS_DPR16X4 (16x4 dist ram) +# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram) # Outputs: DO0, DO1, DO2, DO3 -# name ID w/b ins outs -TRELLIS_DPR16X4 2 0 14 4 +# name ID w/b ins outs +$__ABC_RAM16X2_COMB 2 0 8 4 -#DI0 DI1 DI2 DI3 RAD0 RAD1 RAD2 RAD3 WAD0 WAD1 WAD2 WAD3 WCK WRE -- - - - 141 379 275 379 - - - - - - -- - - - 141 379 275 379 - - - - - - -- - - - 141 379 275 379 - - - - - - -- - - - 141 379 275 379 - - - - - - +#A0 A1 A2 A3 RAD0 RAD1 RAD2 RAD3 +0 0 0 0 141 379 275 379 +0 0 0 0 141 379 275 379 +0 0 0 0 141 379 275 379 +0 0 0 0 141 379 275 379 # Box 3 : PFUMX (MUX2) # Outputs: Z diff --git a/techlibs/ecp5/abc_map.v b/techlibs/ecp5/abc_map.v new file mode 100644 index 000000000..e8187ed18 --- /dev/null +++ b/techlibs/ecp5/abc_map.v @@ -0,0 +1,24 @@ +// --------------------------------------- + +module TRELLIS_DPR16X4 ( + input [3:0] DI, + input [3:0] WAD, + input WRE, + input WCK, + input [3:0] RAD, + output [3:0] DO +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter [63:0] INITVAL = 64'h0000000000000000; + wire [3:0] \$DO ; + + \$__ABC_DPR16X4_SEQ #( + .WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL) + ) _TECHMAP_REPLACE_ ( + .DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK), + .RAD(RAD), .DO(\$DO ) + ); + + \$__ABC_DPR16X4_COMB do (.A(\$DO ), .S(RAD), .Y(DO)); +endmodule diff --git a/techlibs/ecp5/abc_model.v b/techlibs/ecp5/abc_model.v new file mode 100644 index 000000000..4eb923cb1 --- /dev/null +++ b/techlibs/ecp5/abc_model.v @@ -0,0 +1,18 @@ +// --------------------------------------- + +(* abc_box_id=2 *) +module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y); +endmodule + +module \$__ABC_DPR16X4_SEQ ( + input [3:0] DI, + input [3:0] WAD, + input WRE, + input WCK, + input [3:0] RAD, + output [3:0] DO +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter [63:0] INITVAL = 64'h0000000000000000; +endmodule diff --git a/techlibs/ecp5/abc_unmap.v b/techlibs/ecp5/abc_unmap.v new file mode 100644 index 000000000..0f918c202 --- /dev/null +++ b/techlibs/ecp5/abc_unmap.v @@ -0,0 +1,25 @@ +// --------------------------------------- + +module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y); + assign Y = A; +endmodule + +module \$__ABC_DPR16X4_SEQ ( + input [3:0] DI, + input [3:0] WAD, + input WRE, + input WCK, + input [3:0] RAD, + output [3:0] DO +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter [63:0] INITVAL = 64'h0000000000000000; + + TRELLIS_DPR16X4 #( + .WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL) + ) _TECHMAP_REPLACE_ ( + .DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK), + .RAD(RAD), .DO(DO) + ); +endmodule diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 2fcb0369e..f79a27312 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -107,11 +107,10 @@ module PFUMX (input ALUT, BLUT, C0, output Z); endmodule // --------------------------------------- -//(* abc_box_id=2 *) module TRELLIS_DPR16X4 ( - (* abc_scc_break *) input [3:0] DI, - (* abc_scc_break *) input [3:0] WAD, - (* abc_scc_break *) input WRE, + input [3:0] DI, + input [3:0] WAD, + input WRE, input WCK, input [3:0] RAD, output [3:0] DO diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 143d1f95c..93e1cd5b5 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -278,12 +278,18 @@ struct SynthEcp5Pass : public ScriptPass if (abc2 || help_mode) { run("abc", " (only if -abc2)"); } - run("techmap -map +/ecp5/latches_map.v"); + std::string techmap_args = "-map +/ecp5/latches_map.v"; + if (abc9) + techmap_args += " -map +/ecp5/abc_map.v"; + run("techmap " + techmap_args); + if (abc9) { + run("read_verilog -icells -lib +/ecp5/abc_model.v"); if (nowidelut) run("abc9 -lut +/ecp5/abc_5g_nowide.lut -box +/ecp5/abc_5g.box -W 200"); else run("abc9 -lut +/ecp5/abc_5g.lut -box +/ecp5/abc_5g.box -W 200"); + run("techmap -map +/ecp5/abc_unmap.v"); } else { if (nowidelut) run("abc -lut 4 -dress"); From d46dc9c5b4362c1e333979cbbac4f3567904fee5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 19:18:36 -0700 Subject: [PATCH 099/144] ecp5 to use -max_iter 1 --- techlibs/ecp5/abc_map.v | 2 +- techlibs/ecp5/cells_sim.v | 2 +- techlibs/ecp5/synth_ecp5.cc | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/techlibs/ecp5/abc_map.v b/techlibs/ecp5/abc_map.v index e8187ed18..ffd25f06d 100644 --- a/techlibs/ecp5/abc_map.v +++ b/techlibs/ecp5/abc_map.v @@ -13,7 +13,7 @@ module TRELLIS_DPR16X4 ( parameter [63:0] INITVAL = 64'h0000000000000000; wire [3:0] \$DO ; - \$__ABC_DPR16X4_SEQ #( + TRELLIS_DPR16X4 #( .WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL) ) _TECHMAP_REPLACE_ ( .DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK), diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index f79a27312..24de0c3c2 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -113,7 +113,7 @@ module TRELLIS_DPR16X4 ( input WRE, input WCK, input [3:0] RAD, - output [3:0] DO + /* (* abc_arrival= *) */ output [3:0] DO ); parameter WCKMUX = "WCK"; parameter WREMUX = "WRE"; diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 93e1cd5b5..b1d3160ba 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -280,11 +280,10 @@ struct SynthEcp5Pass : public ScriptPass } std::string techmap_args = "-map +/ecp5/latches_map.v"; if (abc9) - techmap_args += " -map +/ecp5/abc_map.v"; + techmap_args += " -map +/ecp5/abc_map.v -max_iter 1"; run("techmap " + techmap_args); if (abc9) { - run("read_verilog -icells -lib +/ecp5/abc_model.v"); if (nowidelut) run("abc9 -lut +/ecp5/abc_5g_nowide.lut -box +/ecp5/abc_5g.box -W 200"); else From 6b1b03d9f771addbd54358299faad181b589c9f8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 19:20:17 -0700 Subject: [PATCH 100/144] ecp5: remove DPR16X4 from abc_unmap.v --- techlibs/ecp5/abc_unmap.v | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/techlibs/ecp5/abc_unmap.v b/techlibs/ecp5/abc_unmap.v index 0f918c202..d43cdd93f 100644 --- a/techlibs/ecp5/abc_unmap.v +++ b/techlibs/ecp5/abc_unmap.v @@ -3,23 +3,3 @@ module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y); assign Y = A; endmodule - -module \$__ABC_DPR16X4_SEQ ( - input [3:0] DI, - input [3:0] WAD, - input WRE, - input WCK, - input [3:0] RAD, - output [3:0] DO -); - parameter WCKMUX = "WCK"; - parameter WREMUX = "WRE"; - parameter [63:0] INITVAL = 64'h0000000000000000; - - TRELLIS_DPR16X4 #( - .WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL) - ) _TECHMAP_REPLACE_ ( - .DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK), - .RAD(RAD), .DO(DO) - ); -endmodule From c26c5563845d81048dea35c4aef5f4678e177b23 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 19:47:11 -0700 Subject: [PATCH 101/144] xilinx to use abc_map.v with -max_iter 1 --- techlibs/xilinx/abc_map.v | 26 ++++----- techlibs/xilinx/abc_model.v | 60 +-------------------- techlibs/xilinx/abc_unmap.v | 96 +-------------------------------- techlibs/xilinx/abc_xc7.box | 4 +- techlibs/xilinx/cells_sim.v | 9 ++-- techlibs/xilinx/synth_xilinx.cc | 2 +- 6 files changed, 26 insertions(+), 171 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index 121862692..c3701b1a8 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -31,7 +31,7 @@ module RAM32X1D ( parameter INIT = 32'h0; parameter IS_WCLK_INVERTED = 1'b0; wire \$DPO , \$SPO ; - \$__ABC_RAM32X1D #( + RAM32X1D #( .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) ) _TECHMAP_REPLACE_ ( .DPO(\$DPO ), .SPO(\$SPO ), @@ -39,8 +39,8 @@ module RAM32X1D ( .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4) ); - \$__ABC_LUTMUX6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO)); - \$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO)); + \$__ABC_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO)); + \$__ABC_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO)); endmodule module RAM64X1D ( @@ -54,7 +54,7 @@ module RAM64X1D ( parameter INIT = 64'h0; parameter IS_WCLK_INVERTED = 1'b0; wire \$DPO , \$SPO ; - \$__ABC_RAM64X1D #( + RAM64X1D #( .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) ) _TECHMAP_REPLACE_ ( .DPO(\$DPO ), .SPO(\$SPO ), @@ -62,8 +62,8 @@ module RAM64X1D ( .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5), .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5) ); - \$__ABC_LUTMUX6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO)); - \$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO)); + \$__ABC_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO)); + \$__ABC_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO)); endmodule module RAM128X1D ( @@ -76,7 +76,7 @@ module RAM128X1D ( parameter INIT = 128'h0; parameter IS_WCLK_INVERTED = 1'b0; wire \$DPO , \$SPO ; - \$__ABC_RAM128X1D #( + RAM128X1D #( .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) ) _TECHMAP_REPLACE_ ( .DPO(\$DPO ), .SPO(\$SPO ), @@ -84,8 +84,8 @@ module RAM128X1D ( .A(A), .DPRA(DPRA) ); - \$__ABC_LUTMUX7 dpo (.A(\$DPO ), .S(A), .Y(DPO)); - \$__ABC_LUTMUX7 spo (.A(\$SPO ), .S(A), .Y(SPO)); + \$__ABC_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO)); + \$__ABC_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO)); endmodule module SRL16E ( @@ -95,14 +95,14 @@ module SRL16E ( parameter [15:0] INIT = 16'h0000; parameter [0:0] IS_CLK_INVERTED = 1'b0; wire \$Q ; - \$__ABC_SRL16E #( + SRL16E #( .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) ) _TECHMAP_REPLACE_ ( .Q(\$Q ), .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D) ); // TODO: Check if SRL uses fast inputs or slow inputs - \$__ABC_LUTMUX6 q (.A(\$Q ), .S({A0, A1, A2, A3, 1'b0, 1'b0}), .Y(Q)); + \$__ABC_LUT6 q (.A(\$Q ), .S({A0, A1, A2, A3, 1'b0, 1'b0}), .Y(Q)); endmodule module SRLC32E ( @@ -114,12 +114,12 @@ module SRLC32E ( parameter [31:0] INIT = 32'h00000000; parameter [0:0] IS_CLK_INVERTED = 1'b0; wire \$Q ; - \$__ABC_SRLC32E #( + SRLC32E #( .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) ) _TECHMAP_REPLACE_ ( .Q(\$Q ), .Q31(Q31), .A(A), .CE(CE), .CLK(CLK), .D(D) ); // TODO: Check if SRL uses fast inputs or slow inputs - \$__ABC_LUTMUX6 q (.A(\$Q ), .S({A, 1'b0}), .Y(Q)); + \$__ABC_LUT6 q (.A(\$Q ), .S({A, 1'b0}), .Y(Q)); endmodule diff --git a/techlibs/xilinx/abc_model.v b/techlibs/xilinx/abc_model.v index e3e9686b5..655b993f6 100644 --- a/techlibs/xilinx/abc_model.v +++ b/techlibs/xilinx/abc_model.v @@ -27,64 +27,8 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); endmodule (* abc_box_id=2000 *) -module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); +module \$__ABC_LUT6 (input A, input [5:0] S, output Y); endmodule (* abc_box_id=2001 *) -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, - input D, - input WCLK, - input WE, - input A0, A1, A2, A3, A4, - input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 -); -endmodule - -module \$__ABC_RAM64X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc_arrival=1153 *) output DPO, SPO, - input D, - input WCLK, - input WE, - input A0, A1, A2, A3, A4, A5, - input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 -); - parameter INIT = 64'h0; - parameter IS_WCLK_INVERTED = 1'b0; -endmodule - -module \$__ABC_RAM128X1D ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc_arrival=1153 *) output DPO, SPO, - input D, - input WCLK, - input WE, - input [6:0] A, DPRA -); - parameter INIT = 128'h0; - parameter IS_WCLK_INVERTED = 1'b0; -endmodule - -module SRL16E ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, - input A0, A1, A2, A3, CE, CLK, D -); - parameter [15:0] INIT = 16'h0000; - parameter [0:0] IS_CLK_INVERTED = 1'b0; -endmodule - -module SRLC32E ( - // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, - (* abc_arrival=1114 *) output Q31, - input [4:0] A, - input CE, CLK, D -); - parameter [31:0] INIT = 32'h00000000; - parameter [0:0] IS_CLK_INVERTED = 1'b0; +module \$__ABC_LUT7 (input A, input [6:0] S, output Y); endmodule diff --git a/techlibs/xilinx/abc_unmap.v b/techlibs/xilinx/abc_unmap.v index 779fc5aac..f101a22d0 100644 --- a/techlibs/xilinx/abc_unmap.v +++ b/techlibs/xilinx/abc_unmap.v @@ -20,101 +20,9 @@ // ============================================================================ -module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); +module \$__ABC_LUT6 (input A, input [5:0] S, output Y); assign Y = A; endmodule -module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y); +module \$__ABC_LUT7 (input A, input [6:0] S, output Y); assign Y = A; endmodule - -module \$__ABC_RAM32X1D ( - output DPO, SPO, - input D, - input WCLK, - input WE, - input A0, A1, A2, A3, A4, - input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 -); - parameter INIT = 32'h0; - parameter IS_WCLK_INVERTED = 1'b0; - RAM32X1D #( - .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) - ) _TECHMAP_REPLACE_ ( - .DPO(DPO), .SPO(SPO), - .D(D), .WCLK(WCLK), .WE(WE), - .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), - .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4) - ); -endmodule - -module \$__ABC_RAM64X1D ( - output DPO, SPO, - input D, - input WCLK, - input WE, - input A0, A1, A2, A3, A4, A5, - input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 -); - parameter INIT = 64'h0; - parameter IS_WCLK_INVERTED = 1'b0; - RAM64X1D #( - .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) - ) _TECHMAP_REPLACE_ ( - .DPO(DPO), .SPO(SPO), - .D(D), .WCLK(WCLK), .WE(WE), - .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5), - .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5) - ); -endmodule - -module \$__ABC_RAM128X1D ( - output DPO, SPO, - input D, - input WCLK, - input WE, - input A, - input DPRA, -); - parameter INIT = 128'h0; - parameter IS_WCLK_INVERTED = 1'b0; - RAM128X1D #( - .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED) - ) _TECHMAP_REPLACE_ ( - .DPO(DPO), .SPO(SPO), - .D(D), .WCLK(WCLK), .WE(WE), - .A(A), - .DPRA(DPRA) - ); -endmodule - -module \$__ABC_SRL16E ( - output Q, - input A0, A1, A2, A3, CE, CLK, D -); - parameter [15:0] INIT = 16'h0000; - parameter [0:0] IS_CLK_INVERTED = 1'b0; - - SRL16E #( - .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) - ) _TECHMAP_REPLACE_ ( - .Q(Q), - .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D) - ); -endmodule - -module \$__ABC_SRLC32E ( - output Q, - output Q31, - input [4:0] A, - input CE, CLK, D -); - parameter [31:0] INIT = 32'h00000000; - parameter [0:0] IS_CLK_INVERTED = 1'b0; - - SRLC32E #( - .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED) - ) _TECHMAP_REPLACE_ ( - .Q(Q), .Q31(Q31), - .A(A), .CE(CE), .CLK(CLK), .D(D) - ); -endmodule diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 61b89b8af..554cc0cf0 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -42,12 +42,12 @@ CARRY4 4 1 10 8 # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} # Inputs: A S0 S1 S2 S3 S4 S5 # Outputs: Y -$__ABC_LUTRAM6 2000 0 7 1 +$__ABC_LUT6 2000 0 7 1 0 642 631 472 407 238 127 # SLICEM/A6LUT + F7BMUX # Box to emulate comb/seq behaviour of RAMD128 # Inputs: A S0 S1 S2 S3 S4 S5 S6 # Outputs: DPO SPO -$__ABC_LUTRAM7 2001 0 8 1 +$__ABC_LUT7 2001 0 8 1 0 1047 1036 877 812 643 532 478 diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 6aba5a4b2..3a58f32fa 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -298,7 +298,8 @@ module FDPE_1 ((* abc_arrival=303 *) output reg Q, endmodule module RAM32X1D ( - output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc_arrival=11530 *) output DPO, SPO, input D, input WCLK, input WE, @@ -317,7 +318,8 @@ module RAM32X1D ( endmodule module RAM64X1D ( - output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc_arrival=1153 *) output DPO, SPO, input D, input WCLK, input WE, @@ -336,7 +338,8 @@ module RAM64X1D ( endmodule module RAM128X1D ( - output DPO, SPO, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 + (* abc_arrival=1153 *) output DPO, SPO, input D, input WCLK, input WE, diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b9c4df82f..263788fec 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -391,7 +391,7 @@ struct SynthXilinxPass : public ScriptPass if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); run("read_verilog -icells -lib +/xilinx/abc_model.v"); - run("techmap -map +/xilinx/abc_map.v"); + run("techmap -map +/xilinx/abc_map.v -max_iter 1"); if (nowidelut) run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); else From 57493e328ad69b749619bc692130e28ab5c212ee Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 19:48:16 -0700 Subject: [PATCH 102/144] techmap -max_iter to apply to each module individually --- passes/techmap/techmap.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index b271c8781..a6c1214a7 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -943,7 +943,8 @@ struct TechmapPass : public Pass { log(" instead of inlining them.\n"); log("\n"); log(" -max_iter \n"); - log(" only run the specified number of iterations.\n"); + log(" only run the specified number of iterations for each module.\n"); + log(" default: unlimited\n"); log("\n"); log(" -recursive\n"); log(" instead of the iterative breadth-first algorithm use a recursive\n"); @@ -1157,15 +1158,16 @@ struct TechmapPass : public Pass { RTLIL::Module *module = *worker.module_queue.begin(); worker.module_queue.erase(module); + int module_max_iter = max_iter; bool did_something = true; std::set handled_cells; while (did_something) { did_something = false; - if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) - did_something = true; + if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) + did_something = true; if (did_something) module->check(); - if (max_iter > 0 && --max_iter == 0) + if (module_max_iter > 0 && --module_max_iter == 0) break; } } From 64d62710de4f1db0d59d7fa04b3fb4d51c8dff2e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:07:38 -0700 Subject: [PATCH 103/144] Oops --- techlibs/xilinx/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 3a58f32fa..80211619b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -299,7 +299,7 @@ endmodule module RAM32X1D ( // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 - (* abc_arrival=11530 *) output DPO, SPO, + (* abc_arrival=1153 *) output DPO, SPO, input D, input WCLK, input WE, From 7b646101e936cacd20938c20ddfbaa63ee268fb2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:57:13 -0700 Subject: [PATCH 104/144] Only xaig if GetSize(output_bits) > 0 --- backends/aiger/xaiger.cc | 306 ++++++++++++++++++++------------------- 1 file changed, 154 insertions(+), 152 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..c1ab59600 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,176 +575,178 @@ struct XAigerWriter f << "c"; - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - 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(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()); + if (GetSize(output_bits) > 0) { + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + 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(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()); - auto write_buffer_float = [](std::stringstream &buffer, float f32) { - buffer.write(reinterpret_cast(&f32), sizeof(f32)); - }; - std::stringstream i_buffer; - auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); - for (auto bit : input_bits) - write_i_buffer(arrival_times.at(bit, 0)); - //std::stringstream o_buffer; - //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); - //for (auto bit : output_bits) - // write_o_buffer(0); + auto write_buffer_float = [](std::stringstream &buffer, float f32) { + buffer.write(reinterpret_cast(&f32), sizeof(f32)); + }; + std::stringstream i_buffer; + auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); + for (auto bit : input_bits) + write_i_buffer(arrival_times.at(bit, 0)); + //std::stringstream o_buffer; + //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); + //for (auto bit : output_bits) + // write_o_buffer(0); - if (!box_list.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); - log_assert(holes_module); + if (!box_list.empty()) { + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + log_assert(holes_module); - int port_id = 1; - int box_count = 0; - for (auto cell : box_list) { - RTLIL::Module* box_module = module->design->module(cell->type); - int box_inputs = 0, box_outputs = 0; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - } + int port_id = 1; + int box_count = 0; + for (auto cell : box_list) { + RTLIL::Module* box_module = module->design->module(cell->type); + int box_inputs = 0, box_outputs = 0; + Cell *holes_cell = nullptr; + if (box_module->get_bool_attribute("\\whitebox")) { + holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell->parameters = cell->parameters; + } - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) - for (const auto &port_name : box_module->ports) { - RTLIL::Wire *w = box_module->wire(port_name); - log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { - for (int i = 0; i < GetSize(w); i++) { - box_inputs++; - holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; + // NB: Assume box_module->ports are sorted alphabetically + // (as RTLIL::Module::fixup_ports() would do) + for (const auto &port_name : box_module->ports) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_wire; + if (w->port_input) { + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + } + if (holes_cell) + port_wire.append(holes_wire); + } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); + } + if (w->port_output) { + box_outputs += GetSize(w); + for (int i = 0; i < GetSize(w); i++) { + if (GetSize(w) == 1) + holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + else + holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); + holes_wire->port_output = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_wire.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); } - if (holes_cell) - port_wire.append(holes_wire); + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } - if (w->port_output) { - box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); - else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_wire.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); - } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); } + + write_h_buffer(box_inputs); + write_h_buffer(box_outputs); + write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); + write_h_buffer(box_count++); } - write_h_buffer(box_inputs); - write_h_buffer(box_outputs); - write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); - write_h_buffer(box_count++); - } - - std::stringstream r_buffer; - auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - 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()); - - if (holes_module) { - log_push(); - - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); - - holes_module->design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = holes_module->design->selection_stack.back(); - sel.select(holes_module); - - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); - - Pass::call(holes_module->design, "flatten -wb"); - - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call - Pass::call(holes_module->design, "techmap"); - Pass::call(holes_module->design, "aigmap"); - for (auto cell : holes_module->cells()) - if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - - holes_module->design->selection_stack.pop_back(); - - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - holes_module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - Pass::call(holes_design, "clean -purge"); - - std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); - writer.write_aiger(a_buffer, false /*ascii_mode*/); - - delete holes_design; - - f << "a"; - std::string buffer_str = a_buffer.str(); + std::stringstream r_buffer; + auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); + 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()); - log_pop(); + if (holes_module) { + log_push(); + + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); + + holes_module->design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = holes_module->design->selection_stack.back(); + sel.select(holes_module); + + // TODO: Should not need to opt_merge if we only instantiate + // each box type once... + Pass::call(holes_module->design, "opt_merge -share_all"); + + Pass::call(holes_module->design, "flatten -wb"); + + // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, + // instead of per write_xaiger call + Pass::call(holes_module->design, "techmap"); + Pass::call(holes_module->design, "aigmap"); + for (auto cell : holes_module->cells()) + if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + + holes_module->design->selection_stack.pop_back(); + + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + holes_module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "clean -purge"); + + std::stringstream a_buffer; + XAigerWriter writer(holes_module, true /* holes_mode */); + writer.write_aiger(a_buffer, false /*ascii_mode*/); + + delete holes_design; + + f << "a"; + std::string buffer_str = a_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()); + + log_pop(); + } } + + f << "h"; + std::string buffer_str = h_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()); + + f << "i"; + buffer_str = i_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()); + //f << "o"; + //buffer_str = o_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()); } - f << "h"; - std::string buffer_str = h_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()); - - f << "i"; - buffer_str = i_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()); - //f << "o"; - //buffer_str = o_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()); - f << stringf("Generated by %s\n", yosys_version_str); } From 4d123b7638b7036da70de169d16d2ae21b89b8e2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 21:22:38 -0700 Subject: [PATCH 105/144] Revert "Only xaig if GetSize(output_bits) > 0" This reverts commit 7b646101e936cacd20938c20ddfbaa63ee268fb2. --- backends/aiger/xaiger.cc | 304 +++++++++++++++++++-------------------- 1 file changed, 151 insertions(+), 153 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c1ab59600..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,178 +575,176 @@ struct XAigerWriter f << "c"; - if (GetSize(output_bits) > 0) { - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - 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(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()); + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + 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(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()); - auto write_buffer_float = [](std::stringstream &buffer, float f32) { - buffer.write(reinterpret_cast(&f32), sizeof(f32)); - }; - std::stringstream i_buffer; - auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); - for (auto bit : input_bits) - write_i_buffer(arrival_times.at(bit, 0)); - //std::stringstream o_buffer; - //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); - //for (auto bit : output_bits) - // write_o_buffer(0); + auto write_buffer_float = [](std::stringstream &buffer, float f32) { + buffer.write(reinterpret_cast(&f32), sizeof(f32)); + }; + std::stringstream i_buffer; + auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); + for (auto bit : input_bits) + write_i_buffer(arrival_times.at(bit, 0)); + //std::stringstream o_buffer; + //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); + //for (auto bit : output_bits) + // write_o_buffer(0); - if (!box_list.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); - log_assert(holes_module); + if (!box_list.empty()) { + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + log_assert(holes_module); - int port_id = 1; - int box_count = 0; - for (auto cell : box_list) { - RTLIL::Module* box_module = module->design->module(cell->type); - int box_inputs = 0, box_outputs = 0; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - } + int port_id = 1; + int box_count = 0; + for (auto cell : box_list) { + RTLIL::Module* box_module = module->design->module(cell->type); + int box_inputs = 0, box_outputs = 0; + Cell *holes_cell = nullptr; + if (box_module->get_bool_attribute("\\whitebox")) { + holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell->parameters = cell->parameters; + } - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) - for (const auto &port_name : box_module->ports) { - RTLIL::Wire *w = box_module->wire(port_name); - log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { - for (int i = 0; i < GetSize(w); i++) { - box_inputs++; - holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - if (holes_cell) - port_wire.append(holes_wire); - } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } - if (w->port_output) { - box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); - else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); - holes_wire->port_output = true; + // NB: Assume box_module->ports are sorted alphabetically + // (as RTLIL::Module::fixup_ports() would do) + for (const auto &port_name : box_module->ports) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_wire; + if (w->port_input) { + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_wire.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); + if (holes_cell) + port_wire.append(holes_wire); } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); + } + if (w->port_output) { + box_outputs += GetSize(w); + for (int i = 0; i < GetSize(w); i++) { + if (GetSize(w) == 1) + holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + else + holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); + holes_wire->port_output = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_wire.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); + } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); } - - write_h_buffer(box_inputs); - write_h_buffer(box_outputs); - write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); - write_h_buffer(box_count++); } - std::stringstream r_buffer; - auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - 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()); - - if (holes_module) { - log_push(); - - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); - - holes_module->design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = holes_module->design->selection_stack.back(); - sel.select(holes_module); - - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); - - Pass::call(holes_module->design, "flatten -wb"); - - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call - Pass::call(holes_module->design, "techmap"); - Pass::call(holes_module->design, "aigmap"); - for (auto cell : holes_module->cells()) - if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - - holes_module->design->selection_stack.pop_back(); - - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - holes_module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - Pass::call(holes_design, "clean -purge"); - - std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); - writer.write_aiger(a_buffer, false /*ascii_mode*/); - - delete holes_design; - - f << "a"; - std::string buffer_str = a_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()); - - log_pop(); - } + write_h_buffer(box_inputs); + write_h_buffer(box_outputs); + write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); + write_h_buffer(box_count++); } - f << "h"; - std::string buffer_str = h_buffer.str(); + std::stringstream r_buffer; + auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); + 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()); - f << "i"; - buffer_str = i_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()); - //f << "o"; - //buffer_str = o_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(); + + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); + + holes_module->design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = holes_module->design->selection_stack.back(); + sel.select(holes_module); + + // TODO: Should not need to opt_merge if we only instantiate + // each box type once... + Pass::call(holes_module->design, "opt_merge -share_all"); + + Pass::call(holes_module->design, "flatten -wb"); + + // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, + // instead of per write_xaiger call + Pass::call(holes_module->design, "techmap"); + Pass::call(holes_module->design, "aigmap"); + for (auto cell : holes_module->cells()) + if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + + holes_module->design->selection_stack.pop_back(); + + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + holes_module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "clean -purge"); + + std::stringstream a_buffer; + XAigerWriter writer(holes_module, true /* holes_mode */); + writer.write_aiger(a_buffer, false /*ascii_mode*/); + + delete holes_design; + + f << "a"; + std::string buffer_str = a_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()); + + log_pop(); + } } + f << "h"; + std::string buffer_str = h_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()); + + f << "i"; + buffer_str = i_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()); + //f << "o"; + //buffer_str = o_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()); + f << stringf("Generated by %s\n", yosys_version_str); } From 8182cb9d91555d5be52abbfeeb5d22af05342d8a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 21:30:16 -0700 Subject: [PATCH 106/144] Fix omode which inserts an output if none exists (otherwise abc9 breaks) --- backends/aiger/xaiger.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..8c8ff2f7e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -504,16 +504,16 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } + if (output_bits.empty()) { + output_bits.insert(State::S0); + omode = true; + } + for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - aig_o++; - aig_outputs.push_back(0); - omode = true; - } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -575,6 +575,7 @@ struct XAigerWriter f << "c"; + log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -796,11 +797,11 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); + if (omode) + output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); - if (omode && output_bits.empty()) - f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) From 584c68069194f7c776755c108801a56898e19fff Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:27:42 -0700 Subject: [PATCH 107/144] Add abc_arrival to SRL* --- techlibs/xilinx/cells_sim.v | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 80211619b..65c59759a 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -355,7 +355,8 @@ module RAM128X1D ( endmodule module SRL16E ( - output Q, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, input A0, A1, A2, A3, CE, CLK, D ); parameter [15:0] INIT = 16'h0000; @@ -373,8 +374,9 @@ module SRL16E ( endmodule module SRLC32E ( - output Q, - output Q31, + // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 + (* abc_arrival=1472 *) output Q, + (* abc_arrival=1114 *) output Q31, input [4:0] A, input CE, CLK, D ); From 8f0c1232d7c511a6473f4581e4c27a90088cedb7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:29:40 -0700 Subject: [PATCH 108/144] Revert "Fix omode which inserts an output if none exists (otherwise abc9 breaks)" This reverts commit 8182cb9d91555d5be52abbfeeb5d22af05342d8a. --- backends/aiger/xaiger.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8c8ff2f7e..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -504,16 +504,16 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - output_bits.insert(State::S0); - omode = true; - } - for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } + if (output_bits.empty()) { + aig_o++; + aig_outputs.push_back(0); + omode = true; + } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -575,7 +575,6 @@ struct XAigerWriter f << "c"; - log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -797,11 +796,11 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); - if (omode) - output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); + if (omode && output_bits.empty()) + f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) From 399ac760ff2bf4a7d438ed388820e7bfb511de6b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:31:18 -0700 Subject: [PATCH 109/144] Output "h" extension only if boxes --- backends/aiger/xaiger.cc | 60 +++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..b66706ffa 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,24 +575,6 @@ struct XAigerWriter f << "c"; - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - 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(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()); - auto write_buffer_float = [](std::stringstream &buffer, float f32) { buffer.write(reinterpret_cast(&f32), sizeof(f32)); }; @@ -606,6 +588,24 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty()) { + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + 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(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()); + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -669,12 +669,18 @@ struct XAigerWriter write_h_buffer(box_count++); } + f << "h"; + std::string buffer_str = h_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 r_buffer; auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); write_r_buffer(0); f << "r"; - std::string buffer_str = r_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); + buffer_str = r_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()); @@ -727,16 +733,14 @@ struct XAigerWriter log_pop(); } } - - f << "h"; - std::string buffer_str = h_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()); + else { + log_debug("piNum = %d\n", GetSize(input_bits)); + log_debug("poNum = %d\n", GetSize(output_bits)); + } f << "i"; - buffer_str = i_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); + std::string buffer_str = i_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()); //f << "o"; From 5d0f6cbd540e1be4525563329dabd2f2aaf7069e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:47:06 -0700 Subject: [PATCH 110/144] techmap before read --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 263788fec..218192315 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -390,8 +390,8 @@ struct SynthXilinxPass : public ScriptPass else if (abc9) { if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); - run("read_verilog -icells -lib +/xilinx/abc_model.v"); run("techmap -map +/xilinx/abc_map.v -max_iter 1"); + run("read_verilog -icells -lib +/xilinx/abc_model.v"); if (nowidelut) run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); else From c7af71ecde65ad310e487a296b957678412fca74 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:47:17 -0700 Subject: [PATCH 111/144] Use semicolon --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 218192315..8d0cf84f3 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -386,7 +386,7 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_luts")) { run("opt_expr -mux_undef"); if (help_mode) - run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut', option for '-retime')"); + run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut'; option for '-retime')"); else if (abc9) { if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); From e658d472c89d0fef820f2a9ddc6184b566cc0d9b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 11:31:20 -0700 Subject: [PATCH 112/144] Put attributes above port --- techlibs/xilinx/cells_sim.v | 65 ++++++++++++++++++++++++---------- techlibs/xilinx/xc7_brams_bb.v | 24 ++++++++----- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 21ac19300..e2ec4e525 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -215,8 +215,11 @@ endmodule // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250 -module FDRE ((* abc_arrival=303 *) 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; @@ -228,8 +231,11 @@ module FDRE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDSE ((* abc_arrival=303 *) 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; @@ -241,8 +247,11 @@ module FDSE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDCE ((* abc_arrival=303 *) 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; @@ -256,8 +265,11 @@ module FDCE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDPE ((* abc_arrival=303 *) 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; @@ -271,29 +283,41 @@ module FDPE ((* abc_arrival=303 *) output reg Q, endcase endgenerate endmodule -module FDRE_1 ((* abc_arrival=303 *) 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 ((* abc_arrival=303 *) 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 ((* abc_arrival=303 *) 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 ((* abc_arrival=303 *) 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; @@ -361,7 +385,8 @@ endmodule module SRL16E ( // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, + (* abc_arrival=1472 *) + output Q, input A0, A1, A2, A3, CE, CLK, D ); parameter [15:0] INIT = 16'h0000; @@ -380,8 +405,10 @@ endmodule module SRLC32E ( // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 - (* abc_arrival=1472 *) output Q, - (* abc_arrival=1114 *) output Q31, + (* abc_arrival=1472 *) + output Q, + (* abc_arrival=1114 *) + output Q31, input [4:0] A, input CE, CLK, D ); diff --git a/techlibs/xilinx/xc7_brams_bb.v b/techlibs/xilinx/xc7_brams_bb.v index 0e8cb406c..56939089c 100644 --- a/techlibs/xilinx/xc7_brams_bb.v +++ b/techlibs/xilinx/xc7_brams_bb.v @@ -21,10 +21,14 @@ module RAMB18E1 ( input [1:0] WEA, input [3:0] WEBWE, - (* abc_arrival=2454 *) output [15:0] DOADO, - (* abc_arrival=2454 *) output [15:0] DOBDO, - (* abc_arrival=2454 *) output [1:0] DOPADOP, - (* abc_arrival=2454 *) output [1:0] DOPBDOP + (* abc_arrival=2454 *) + output [15:0] DOADO, + (* abc_arrival=2454 *) + output [15:0] DOBDO, + (* abc_arrival=2454 *) + output [1:0] DOPADOP, + (* abc_arrival=2454 *) + output [1:0] DOPBDOP ); parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -145,10 +149,14 @@ module RAMB36E1 ( input [3:0] WEA, input [7:0] WEBWE, - (* abc_arrival=2454 *) output [31:0] DOADO, - (* abc_arrival=2454 *) output [31:0] DOBDO, - (* abc_arrival=2454 *) output [3:0] DOPADOP, - (* abc_arrival=2454 *) output [3:0] DOPBDOP + (* abc_arrival=2454 *) + output [31:0] DOADO, + (* abc_arrival=2454 *) + output [31:0] DOBDO, + (* abc_arrival=2454 *) + output [3:0] DOPADOP, + (* abc_arrival=2454 *) + output [3:0] DOPBDOP ); parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; From 85d39653ac62fa4f1f809fb71b0df82a8bd01dfc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 13:20:29 -0700 Subject: [PATCH 113/144] Remove unused model --- techlibs/ecp5/abc_model.v | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/techlibs/ecp5/abc_model.v b/techlibs/ecp5/abc_model.v index 4eb923cb1..56a733b75 100644 --- a/techlibs/ecp5/abc_model.v +++ b/techlibs/ecp5/abc_model.v @@ -3,16 +3,3 @@ (* abc_box_id=2 *) module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y); endmodule - -module \$__ABC_DPR16X4_SEQ ( - input [3:0] DI, - input [3:0] WAD, - input WRE, - input WCK, - input [3:0] RAD, - output [3:0] DO -); - parameter WCKMUX = "WCK"; - parameter WREMUX = "WRE"; - parameter [63:0] INITVAL = 64'h0000000000000000; -endmodule From 455da572723e4f19ddc1d636b700a5fe1e975fbb Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 13:21:21 -0700 Subject: [PATCH 114/144] Fix spacing --- techlibs/ecp5/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index e2bf3c854..01b10f392 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -116,7 +116,7 @@ module TRELLIS_DPR16X4 ( input WCK, input [3:0] RAD, /* (* abc_arrival= *) */ - output [3:0] DO + output [3:0] DO ); parameter WCKMUX = "WCK"; parameter WREMUX = "WRE"; From 3c1c376fb126017b8c3fdc3811830da11a15b635 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 13:22:37 -0700 Subject: [PATCH 115/144] Revert to upstream --- passes/techmap/abc9.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 919c4ce53..0a5b07e6f 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1194,7 +1194,8 @@ 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; - for (auto cell : all_cells) { + for (auto cell : all_cells) + { clkdomain_t key; for (auto &conn : cell->connections()) @@ -1228,7 +1229,6 @@ struct Abc9Pass : public Pass { else continue; - unassigned_cells.erase(cell); expand_queue.insert(cell); expand_queue_up.insert(cell); From 48c424e45bceec55b71dd64c987b2c7eafe7a113 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 13:46:05 -0700 Subject: [PATCH 116/144] Cleanup --- passes/techmap/abc9.cc | 189 +++++++++++++---------------------------- 1 file changed, 59 insertions(+), 130 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 919c4ce53..968c68b70 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -76,8 +76,7 @@ inline std::string remap_name(RTLIL::IdString abc_name) return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); } -void handle_loops(RTLIL::Design *design, - const dict> &scc_break_inputs) +void handle_loops(RTLIL::Design *design) { Pass::call(design, "scc -set_attr abc_scc_id {}"); @@ -85,7 +84,7 @@ void handle_loops(RTLIL::Design *design, // cell in the component, and select (and mark) all its output // wires pool ids_seen; - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { auto it = cell->attributes.find(ID(abc_scc_id)); if (it != cell->attributes.end()) { auto r = ids_seen.insert(it->second); @@ -114,30 +113,6 @@ void handle_loops(RTLIL::Design *design, } cell->attributes.erase(it); } - - auto jt = scc_break_inputs.find(cell->type); - if (jt != scc_break_inputs.end()) - for (auto port_name : jt->second) { - RTLIL::SigSpec sig; - auto &rhs = cell->connections_.at(port_name); - for (auto b : rhs) { - Wire *w = b.wire; - if (!w) continue; - w->port_output = true; - w->set_bool_attribute(ID(abc_scc_break)); - w = module->wire(stringf("%s.abci", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); - w->port_input = true; - } - else { - log_assert(b.offset < GetSize(w)); - log_assert(w->port_input); - } - sig.append(RTLIL::SigBit(w, b.offset)); - } - rhs = sig; - } } module->fixup_ports(); @@ -269,11 +244,10 @@ struct abc_output_filter }; 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 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, - const dict> &scc_break_inputs + std::string wire_delay, const dict &box_lookup ) { module = current_module; @@ -309,8 +283,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri 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()); + 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) @@ -383,7 +357,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri fprintf(f, "%s\n", abc_script.c_str()); fclose(f); - if (/*dff_mode ||*/ !clk_str.empty()) + 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"); @@ -413,16 +387,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Selection& sel = design->selection_stack.back(); sel.select(module); - handle_loops(design, scc_break_inputs); + 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); -#if 0 - Pass::call(design, stringf("write_verilog -noexpr -norename %s/before.v", tempdir_name.c_str())); -#endif Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str())); std::string buffer; @@ -531,12 +502,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (int i = 0; i < GetSize(w); i++) output_bits.insert({wire, i}); } - - auto jt = w->attributes.find("\\init"); - if (jt != w->attributes.end()) { - auto r = remap_wire->attributes.insert(std::make_pair("\\init", jt->second)); - log_assert(r.second); - } } for (auto &it : module->connections_) { @@ -550,7 +515,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict abc_box; vector boxes; - for (auto cell : module->selected_cells()) { + for (const auto &it : module->cells_) { + auto cell = it.second; if (cell->type.in(ID($_AND_), ID($_NOT_))) { module->remove(cell); continue; @@ -570,23 +536,25 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict> bit2sinks; std::map cell_stats; - for (auto mapped_cell : mapped_mod->cells()) + for (auto c : mapped_mod->cells()) { - toposort.node(mapped_cell->name); + toposort.node(c->name); RTLIL::Cell *cell = nullptr; - if (mapped_cell->type == ID($_NOT_)) { - RTLIL::SigBit a_bit = mapped_cell->getPort(ID::A); - RTLIL::SigBit y_bit = mapped_cell->getPort(ID::Y); + 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) { - mapped_cell->setPort(ID::Y, module->addWire(NEW_ID)); + 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 { - RTLIL::Cell* driving_lut = nullptr; + 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, @@ -598,46 +566,46 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri 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); - driving_lut = mapped_mod->cell(driver_name); + driver_lut = mapped_mod->cell(driver_name); } - if (!driving_lut) { + 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", mapped_cell->name.c_str())), + 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)]++; - bit_users[a_bit].insert(mapped_cell->name); - bit_drivers[y_bit].insert(mapped_cell->name); } else - not2drivers[mapped_cell] = driving_lut; + not2drivers[c] = driver_lut; continue; } + else + log_abort(); if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; continue; } - cell_stats[mapped_cell->type]++; + cell_stats[c->type]++; RTLIL::Cell *existing_cell = nullptr; - if (mapped_cell->type == ID($lut)) { - if (GetSize(mapped_cell->getPort(ID::A)) == 1 && mapped_cell->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(mapped_cell->getPort(ID::A).as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(mapped_cell->getPort(ID::Y).as_wire()->name)); + 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) mapped_cell->attributes[ID(abcgroup)] = map_autoidx; + if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; log_abort(); continue; } - cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); + cell = module->addCell(remap_name(c->name), c->type); } else { - existing_cell = module->cell(mapped_cell->name); + existing_cell = module->cell(c->name); log_assert(existing_cell); - cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); + cell = module->addCell(remap_name(c->name), c->type); module->swap_names(cell, existing_cell); } @@ -647,11 +615,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->attributes = existing_cell->attributes; } else { - cell->parameters = mapped_cell->parameters; - cell->attributes = mapped_cell->attributes; + cell->parameters = c->parameters; + cell->attributes = c->attributes; } - - for (auto &conn : mapped_cell->connections()) { + for (auto &conn : c->connections()) { RTLIL::SigSpec newsig; for (auto c : conn.second.chunks()) { if (c.width == 0) @@ -667,11 +634,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto i : newsig) bit2sinks[i].push_back(cell); for (auto i : conn.second) - bit_users[i].insert(mapped_cell->name); + bit_users[i].insert(c->name); } if (cell->output(conn.first)) for (auto i : conn.second) - bit_drivers[i].insert(mapped_cell->name); + bit_drivers[i].insert(c->name); } } @@ -697,27 +664,29 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } for (auto &it : cell_stats) - log("ABC RESULTS: %15s cells: %8d\n", log_id(it.first), it.second); + 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_name : mapped_mod->ports) { - RTLIL::Wire *port = mapped_mod->wire(port_name); - log_assert(port); - RTLIL::Wire *wire = module->wire(port->name); + for (auto &it : mapped_mod->wires_) { + RTLIL::Wire *w = it.second; + if (!w->port_input && !w->port_output) + continue; + RTLIL::Wire *wire = module->wire(w->name); log_assert(wire); - RTLIL::Wire *remap_wire = module->wire(remap_name(port->name)); + RTLIL::Wire *remap_wire = module->wire(remap_name(w->name)); RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire)); log_assert(GetSize(signal) >= GetSize(remap_wire)); + log_assert(w->port_input || w->port_output); RTLIL::SigSig conn; - if (port->port_input) { + if (w->port_input) { conn.first = remap_wire; conn.second = signal; in_wires++; module->connect(conn); } - if (port->port_output) { + if (w->port_output) { conn.first = signal; conn.second = remap_wire; out_wires++; @@ -730,21 +699,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto driver_cell : bit_drivers.at(it.first)) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); -#if 0 - toposort.analyze_loops = true; -#endif bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); -#if 0 - unsigned i = 0; - for (auto &it : toposort.loops) { - log(" loop %d\n", i++); - for (auto cell_name : it) { - auto cell = mapped_mod->cell(cell_name); - log_assert(cell); - log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str()); - } - } -#endif log_assert(no_loops); for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { @@ -1045,7 +1000,7 @@ struct Abc9Pass : public Pass { fast_mode = true; continue; } - //if (arg == "-retime") { + //if (arg == "-dff") { // dff_mode = true; // continue; //} @@ -1085,11 +1040,7 @@ struct Abc9Pass : public Pass { } extra_args(args, argidx, design); - if (lut_costs.empty() && lut_file.empty()) - log_cmd_error("abc9 must be called with '-lut' or '-luts'\n"); - dict box_lookup; - dict> scc_break_inputs; for (auto m : design->modules()) { auto it = m->attributes.find(ID(abc_box_id)); if (it == m->attributes.end()) @@ -1107,17 +1058,13 @@ struct Abc9Pass : public Pass { for (auto p : m->ports) { auto w = m->wire(p); log_assert(w); - if (w->port_input) { - if (w->attributes.count(ID(abc_scc_break))) - scc_break_inputs[m->name].insert(p); - if (w->attributes.count(ID(abc_carry))) { + if (w->attributes.count(ID(abc_carry))) { + if (w->port_input) { if (carry_in) log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m)); carry_in = w; } - } - if (w->port_output) { - if (w->attributes.count(ID(abc_carry))) { + else if (w->port_output) { if (carry_out) log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m)); carry_out = w; @@ -1167,14 +1114,9 @@ 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); - - abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, false, clk_str, keepff, + 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, scc_break_inputs); - design->selection_stack.pop_back(); + box_file, lut_file, wire_delay, box_lookup); continue; } @@ -1194,7 +1136,8 @@ 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; - for (auto cell : all_cells) { + for (auto cell : all_cells) + { clkdomain_t key; for (auto &conn : cell->connections()) @@ -1228,7 +1171,6 @@ struct Abc9Pass : public Pass { else continue; - unassigned_cells.erase(cell); expand_queue.insert(cell); expand_queue_up.insert(cell); @@ -1313,29 +1255,16 @@ struct Abc9Pass : public Pass { std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)), std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first))); - design->selection_stack.emplace_back(false); - for (auto &it : assigned_cells) { - // FIXME: abc9_module calls below can delete cells, - // leaving a dangling pointer here... 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)); - - pool assigned_names; - for (auto i : it.second) - assigned_names.insert(i->name); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.selected_members[mod->name] = std::move(assigned_names); - 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, scc_break_inputs); + box_file, lut_file, wire_delay, box_lookup); assign_map.set(mod); } - - design->selection_stack.pop_back(); } assign_map.clear(); From a45c09c8d1320d311fbda8d615d39117acb8f70b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 15:31:55 -0700 Subject: [PATCH 117/144] Account for D port being a constant --- passes/pmgen/xilinx_srl.pmg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/pmgen/xilinx_srl.pmg b/passes/pmgen/xilinx_srl.pmg index 45d44247a..b18119b87 100644 --- a/passes/pmgen/xilinx_srl.pmg +++ b/passes/pmgen/xilinx_srl.pmg @@ -105,7 +105,7 @@ endcode match next select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1) select !next->has_keep_attr() - select !port(next, \D)[0].wire->get_bool_attribute(\keep) + select port(next, \D)[0].wire && !port(next, \D)[0].wire->get_bool_attribute(\keep) select nusers(port(next, \Q)) == 2 index next->type === first->type index port(next, \Q) === port(first, \D) @@ -132,7 +132,7 @@ match next semioptional select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1) select !next->has_keep_attr() - select !port(next, \D)[0].wire->get_bool_attribute(\keep) + select port(next, \D)[0].wire && !port(next, \D)[0].wire->get_bool_attribute(\keep) select nusers(port(next, \Q)) == 2 index next->type === chain.back()->type index port(next, \Q) === port(chain.back(), \D) @@ -201,7 +201,7 @@ endcode match first select first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, $dff, $dffe) select !first->has_keep_attr() - select !port(first, \Q)[0].wire->get_bool_attribute(\keep) + select port(first, \Q)[0].wire && !port(first, \Q)[0].wire->get_bool_attribute(\keep) slice idx GetSize(port(first, \Q)) select nusers(port(first, \Q)[idx]) <= 2 index port(first, \Q)[idx] === port(shiftx, \A)[shiftx_width-1] @@ -272,7 +272,7 @@ match next semioptional select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, $dff, $dffe) select !next->has_keep_attr() - select !port(next, \D)[0].wire->get_bool_attribute(\keep) + select port(next, \D)[0].wire && !port(next, \D)[0].wire->get_bool_attribute(\keep) slice idx GetSize(port(next, \Q)) select nusers(port(next, \Q)[idx]) <= 3 index next->type === chain.back().first->type From e4f89e01b5710eb9e2e6675a1df13a5a2637b206 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 17:21:12 -0700 Subject: [PATCH 118/144] Specify ice40 family to cells_sim.v using define --- techlibs/ice40/synth_ice40.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index c6de81bd9..2f77c03db 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -238,7 +238,14 @@ struct SynthIce40Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -icells -lib +/ice40/cells_sim.v"); + std::string define; + if (device_opt == "lp") + define = "-D ICE40_LX"; + else if (device_opt == "u") + define = "-D ICE40_U"; + else + define = "-D ICE40_HX"; + run("read_verilog -icells " + define + " -lib +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); run("proc"); } From 2421cb3fed1a990219227ed3cf0632eb221e9698 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 17:21:37 -0700 Subject: [PATCH 119/144] Add arrival times for HX devices --- techlibs/ice40/cells_sim.v | 135 +++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 21 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 02726605f..261d99c9b 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -2,6 +2,10 @@ `define SB_DFF_REG reg Q = 0 // `define SB_DFF_REG reg Q +`define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif +`define ABC_ARRIVAL_LX(TIME) `ifdef ICE40_LX (* abc_arrival=TIME *) `endif +`define ABC_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc_arrival=TIME *) `endif + // SiliconBlue IO Cells module SB_IO ( @@ -169,20 +173,34 @@ module \$__ICE40_CARRY_WRAPPER ( ); endmodule +// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // Positive Edge SiliconBlue FF Cells -module SB_DFF (output `SB_DFF_REG, input C, D); +module SB_DFF ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, D +); always @(posedge C) Q <= D; endmodule -module SB_DFFE (output `SB_DFF_REG, input C, E, D); +module SB_DFFE ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, D +); always @(posedge C) if (E) Q <= D; endmodule -module SB_DFFSR (output `SB_DFF_REG, input C, R, D); +module SB_DFFSR ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, R, D +); always @(posedge C) if (R) Q <= 0; @@ -190,7 +208,11 @@ module SB_DFFSR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFR (output `SB_DFF_REG, input C, R, D); +module SB_DFFR ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, R, D +); always @(posedge C, posedge R) if (R) Q <= 0; @@ -198,7 +220,11 @@ module SB_DFFR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFSS (output `SB_DFF_REG, input C, S, D); +module SB_DFFSS ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, S, D +); always @(posedge C) if (S) Q <= 1; @@ -206,7 +232,11 @@ module SB_DFFSS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFS (output `SB_DFF_REG, input C, S, D); +module SB_DFFS ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, S, D +); always @(posedge C, posedge S) if (S) Q <= 1; @@ -214,7 +244,11 @@ module SB_DFFS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFESR ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, R, D +); always @(posedge C) if (E) begin if (R) @@ -224,7 +258,11 @@ module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D); end endmodule -module SB_DFFER (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFER ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, R, D +); always @(posedge C, posedge R) if (R) Q <= 0; @@ -232,7 +270,11 @@ module SB_DFFER (output `SB_DFF_REG, input C, E, R, D); Q <= D; endmodule -module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFESS ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, S, D +); always @(posedge C) if (E) begin if (S) @@ -242,7 +284,11 @@ module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D); end endmodule -module SB_DFFES (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFES ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, S, D +); always @(posedge C, posedge S) if (S) Q <= 1; @@ -252,18 +298,30 @@ endmodule // Negative Edge SiliconBlue FF Cells -module SB_DFFN (output `SB_DFF_REG, input C, D); +module SB_DFFN ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, D +); always @(negedge C) Q <= D; endmodule -module SB_DFFNE (output `SB_DFF_REG, input C, E, D); +module SB_DFFNE ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, D +); always @(negedge C) if (E) Q <= D; endmodule -module SB_DFFNSR (output `SB_DFF_REG, input C, R, D); +module SB_DFFNSR ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, R, D +); always @(negedge C) if (R) Q <= 0; @@ -271,7 +329,11 @@ module SB_DFFNSR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFNR (output `SB_DFF_REG, input C, R, D); +module SB_DFFNR ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, R, D +); always @(negedge C, posedge R) if (R) Q <= 0; @@ -279,7 +341,11 @@ module SB_DFFNR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFNSS (output `SB_DFF_REG, input C, S, D); +module SB_DFFNSS ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, S, D +); always @(negedge C) if (S) Q <= 1; @@ -287,7 +353,11 @@ module SB_DFFNSS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFNS (output `SB_DFF_REG, input C, S, D); +module SB_DFFNS ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, S, D +); always @(negedge C, posedge S) if (S) Q <= 1; @@ -295,7 +365,11 @@ module SB_DFFNS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFNESR ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, R, D +); always @(negedge C) if (E) begin if (R) @@ -305,7 +379,11 @@ module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D); end endmodule -module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFNER ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, R, D +); always @(negedge C, posedge R) if (R) Q <= 0; @@ -313,7 +391,11 @@ module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D); Q <= D; endmodule -module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFNESS ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, S, D +); always @(negedge C) if (E) begin if (S) @@ -323,7 +405,11 @@ module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D); end endmodule -module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFNES ( + `ABC_ARRIVAL_HX(540) + output `SB_DFF_REG, + input C, E, S, D +); always @(negedge C, posedge S) if (S) Q <= 1; @@ -334,6 +420,7 @@ endmodule // SiliconBlue RAM Cells module SB_RAM40_4K ( + `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, @@ -502,6 +589,7 @@ module SB_RAM40_4K ( endmodule module SB_RAM40_4KNR ( + `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, @@ -567,6 +655,7 @@ module SB_RAM40_4KNR ( endmodule module SB_RAM40_4KNW ( + `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, @@ -632,6 +721,7 @@ module SB_RAM40_4KNW ( endmodule module SB_RAM40_4KNRNW ( + `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, @@ -700,7 +790,10 @@ endmodule module ICESTORM_LC ( input I0, I1, I2, I3, CIN, CLK, CEN, SR, - output LO, O, COUT + output LO, + `ABC_ARRIVAL_HX(540) + output O, + output COUT ); parameter [15:0] LUT_INIT = 0; From 082a01954b95f50cb0ab1b2a1105c06391c0b1b4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 17:30:54 -0700 Subject: [PATCH 120/144] Revert "Output "h" extension only if boxes" This reverts commit 399ac760ff2bf4a7d438ed388820e7bfb511de6b. --- backends/aiger/xaiger.cc | 60 +++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index b66706ffa..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,6 +575,24 @@ struct XAigerWriter f << "c"; + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + 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(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()); + auto write_buffer_float = [](std::stringstream &buffer, float f32) { buffer.write(reinterpret_cast(&f32), sizeof(f32)); }; @@ -588,24 +606,6 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty()) { - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - 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(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()); - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -669,18 +669,12 @@ struct XAigerWriter write_h_buffer(box_count++); } - f << "h"; - std::string buffer_str = h_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 r_buffer; auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); write_r_buffer(0); f << "r"; - buffer_str = r_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); + 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()); @@ -733,14 +727,16 @@ struct XAigerWriter log_pop(); } } - else { - log_debug("piNum = %d\n", GetSize(input_bits)); - log_debug("poNum = %d\n", GetSize(output_bits)); - } + + f << "h"; + std::string buffer_str = h_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()); f << "i"; - std::string buffer_str = i_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); + buffer_str = i_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()); //f << "o"; From 3247442bf9b1f5b672a360b1fc55af9170d000c5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 17:34:00 -0700 Subject: [PATCH 121/144] Revert "Revert "Fix omode which inserts an output if none exists (otherwise abc9 breaks)"" This reverts commit 8f0c1232d7c511a6473f4581e4c27a90088cedb7. --- backends/aiger/xaiger.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..8c8ff2f7e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -504,16 +504,16 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } + if (output_bits.empty()) { + output_bits.insert(State::S0); + omode = true; + } + for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - aig_o++; - aig_outputs.push_back(0); - omode = true; - } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -575,6 +575,7 @@ struct XAigerWriter f << "c"; + log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -796,11 +797,11 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); + if (omode) + output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); - if (omode && output_bits.empty()) - f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) From bf046ba09c9f694517a73af28133917e76d4924a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 18:34:32 -0700 Subject: [PATCH 122/144] Add ice40_opt test --- tests/ice40/ice40_opt.ys | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/ice40/ice40_opt.ys diff --git a/tests/ice40/ice40_opt.ys b/tests/ice40/ice40_opt.ys new file mode 100644 index 000000000..18e0d2b8a --- /dev/null +++ b/tests/ice40/ice40_opt.ys @@ -0,0 +1,24 @@ +read_verilog -icells -formal < Date: Wed, 28 Aug 2019 18:44:57 -0700 Subject: [PATCH 123/144] Add SB_CARRY to ice40_opt test --- tests/ice40/ice40_opt.ys | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/ice40/ice40_opt.ys b/tests/ice40/ice40_opt.ys index 18e0d2b8a..b17c69c91 100644 --- a/tests/ice40/ice40_opt.ys +++ b/tests/ice40/ice40_opt.ys @@ -1,5 +1,5 @@ read_verilog -icells -formal < Date: Wed, 28 Aug 2019 18:45:09 -0700 Subject: [PATCH 124/144] Do not overwrite LUT param --- techlibs/ice40/ice40_opt.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 58f106f7c..ea56d3f4d 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -125,7 +125,6 @@ static void run_ice40_opts(Module *module) cell->unsetPort("\\I3"); cell->unsetPort("\\CO"); cell->unsetPort("\\O"); - cell->setParam("\\LUT", RTLIL::Const::from_string("0110100110010110")); cell->setParam("\\WIDTH", 4); } continue; From e3709e5ee6b28c1156b4768373e244c32c7c5aba Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 18:51:14 -0700 Subject: [PATCH 125/144] LX -> LP --- techlibs/ice40/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 34134d02a..fe80c998d 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -3,7 +3,7 @@ // `define SB_DFF_REG reg Q `define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif -`define ABC_ARRIVAL_LX(TIME) `ifdef ICE40_LX (* abc_arrival=TIME *) `endif +`define ABC_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc_arrival=TIME *) `endif `define ABC_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc_arrival=TIME *) `endif // SiliconBlue IO Cells From 927f1e3754987ab794566a521c7a1149d4fbf6a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 18:56:25 -0700 Subject: [PATCH 126/144] Add LP timings --- techlibs/ice40/cells_sim.v | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index fe80c998d..b86ec3ea5 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -174,11 +174,13 @@ module \$__ICE40_CARRY_WRAPPER ( endmodule // Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 +// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 // Positive Edge SiliconBlue FF Cells module SB_DFF ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, D ); @@ -188,6 +190,7 @@ endmodule module SB_DFFE ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, D ); @@ -198,6 +201,7 @@ endmodule module SB_DFFSR ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, R, D ); @@ -210,6 +214,7 @@ endmodule module SB_DFFR ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, R, D ); @@ -222,6 +227,7 @@ endmodule module SB_DFFSS ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, S, D ); @@ -234,6 +240,7 @@ endmodule module SB_DFFS ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, S, D ); @@ -246,6 +253,7 @@ endmodule module SB_DFFESR ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, R, D ); @@ -260,6 +268,7 @@ endmodule module SB_DFFER ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, R, D ); @@ -272,6 +281,7 @@ endmodule module SB_DFFESS ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, S, D ); @@ -286,6 +296,7 @@ endmodule module SB_DFFES ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, S, D ); @@ -300,6 +311,7 @@ endmodule module SB_DFFN ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, D ); @@ -309,6 +321,7 @@ endmodule module SB_DFFNE ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, D ); @@ -319,6 +332,7 @@ endmodule module SB_DFFNSR ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, R, D ); @@ -331,6 +345,7 @@ endmodule module SB_DFFNR ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, R, D ); @@ -343,6 +358,7 @@ endmodule module SB_DFFNSS ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, S, D ); @@ -355,6 +371,7 @@ endmodule module SB_DFFNS ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, S, D ); @@ -367,6 +384,7 @@ endmodule module SB_DFFNESR ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, R, D ); @@ -381,6 +399,7 @@ endmodule module SB_DFFNER ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, R, D ); @@ -393,6 +412,7 @@ endmodule module SB_DFFNESS ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, S, D ); @@ -407,6 +427,7 @@ endmodule module SB_DFFNES ( `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output `SB_DFF_REG, input C, E, S, D ); @@ -421,6 +442,7 @@ endmodule module SB_RAM40_4K ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, @@ -590,6 +612,7 @@ endmodule module SB_RAM40_4KNR ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, @@ -656,6 +679,7 @@ endmodule module SB_RAM40_4KNW ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, @@ -722,6 +746,7 @@ endmodule module SB_RAM40_4KNRNW ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, @@ -792,6 +817,7 @@ module ICESTORM_LC ( input I0, I1, I2, I3, CIN, CLK, CEN, SR, output LO, `ABC_ARRIVAL_HX(540) + `ABC_ARRIVAL_LP(795) output O, output COUT ); From 0f4e9f6bc5a5a564b2ddccb0fbebdfa5735aeefd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 18:57:34 -0700 Subject: [PATCH 127/144] Round not floor --- techlibs/ice40/cells_sim.v | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index b86ec3ea5..f5fe800f7 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -180,7 +180,7 @@ endmodule module SB_DFF ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, D ); @@ -190,7 +190,7 @@ endmodule module SB_DFFE ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, D ); @@ -201,7 +201,7 @@ endmodule module SB_DFFSR ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, R, D ); @@ -214,7 +214,7 @@ endmodule module SB_DFFR ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, R, D ); @@ -227,7 +227,7 @@ endmodule module SB_DFFSS ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, S, D ); @@ -240,7 +240,7 @@ endmodule module SB_DFFS ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, S, D ); @@ -253,7 +253,7 @@ endmodule module SB_DFFESR ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, R, D ); @@ -268,7 +268,7 @@ endmodule module SB_DFFER ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, R, D ); @@ -281,7 +281,7 @@ endmodule module SB_DFFESS ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, S, D ); @@ -296,7 +296,7 @@ endmodule module SB_DFFES ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, S, D ); @@ -311,7 +311,7 @@ endmodule module SB_DFFN ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, D ); @@ -321,7 +321,7 @@ endmodule module SB_DFFNE ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, D ); @@ -332,7 +332,7 @@ endmodule module SB_DFFNSR ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, R, D ); @@ -345,7 +345,7 @@ endmodule module SB_DFFNR ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, R, D ); @@ -358,7 +358,7 @@ endmodule module SB_DFFNSS ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, S, D ); @@ -371,7 +371,7 @@ endmodule module SB_DFFNS ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, S, D ); @@ -384,7 +384,7 @@ endmodule module SB_DFFNESR ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, R, D ); @@ -399,7 +399,7 @@ endmodule module SB_DFFNER ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, R, D ); @@ -412,7 +412,7 @@ endmodule module SB_DFFNESS ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, S, D ); @@ -427,7 +427,7 @@ endmodule module SB_DFFNES ( `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output `SB_DFF_REG, input C, E, S, D ); @@ -817,7 +817,7 @@ module ICESTORM_LC ( input I0, I1, I2, I3, CIN, CLK, CEN, SR, output LO, `ABC_ARRIVAL_HX(540) - `ABC_ARRIVAL_LP(795) + `ABC_ARRIVAL_LP(796) output O, output COUT ); From 4bda902f1b9dccb5603c2beebd71392cbfe34eb9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:02:54 -0700 Subject: [PATCH 128/144] LX -> LP --- techlibs/ice40/synth_ice40.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 2f77c03db..a3890268a 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -240,7 +240,7 @@ struct SynthIce40Pass : public ScriptPass { std::string define; if (device_opt == "lp") - define = "-D ICE40_LX"; + define = "-D ICE40_LP"; else if (device_opt == "u") define = "-D ICE40_U"; else From efa4ee5c0e6201f357d7c02a7deeb1ba1c23c368 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:03:29 -0700 Subject: [PATCH 129/144] Add arrival times for U --- techlibs/ice40/cells_sim.v | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f5fe800f7..116188acb 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -175,12 +175,14 @@ endmodule // Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 +// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 // Positive Edge SiliconBlue FF Cells module SB_DFF ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, D ); @@ -191,6 +193,7 @@ endmodule module SB_DFFE ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, D ); @@ -202,6 +205,7 @@ endmodule module SB_DFFSR ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, R, D ); @@ -215,6 +219,7 @@ endmodule module SB_DFFR ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, R, D ); @@ -228,6 +233,7 @@ endmodule module SB_DFFSS ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, S, D ); @@ -241,6 +247,7 @@ endmodule module SB_DFFS ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, S, D ); @@ -254,6 +261,7 @@ endmodule module SB_DFFESR ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, R, D ); @@ -269,6 +277,7 @@ endmodule module SB_DFFER ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, R, D ); @@ -282,6 +291,7 @@ endmodule module SB_DFFESS ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, S, D ); @@ -297,6 +307,7 @@ endmodule module SB_DFFES ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, S, D ); @@ -312,6 +323,7 @@ endmodule module SB_DFFN ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, D ); @@ -322,6 +334,7 @@ endmodule module SB_DFFNE ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, D ); @@ -333,6 +346,7 @@ endmodule module SB_DFFNSR ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, R, D ); @@ -346,6 +360,7 @@ endmodule module SB_DFFNR ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, R, D ); @@ -359,6 +374,7 @@ endmodule module SB_DFFNSS ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, S, D ); @@ -372,6 +388,7 @@ endmodule module SB_DFFNS ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, S, D ); @@ -385,6 +402,7 @@ endmodule module SB_DFFNESR ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, R, D ); @@ -400,6 +418,7 @@ endmodule module SB_DFFNER ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, R, D ); @@ -413,6 +432,7 @@ endmodule module SB_DFFNESS ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, S, D ); @@ -428,6 +448,7 @@ endmodule module SB_DFFNES ( `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output `SB_DFF_REG, input C, E, S, D ); @@ -443,6 +464,7 @@ endmodule module SB_RAM40_4K ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, @@ -613,6 +635,7 @@ endmodule module SB_RAM40_4KNR ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, @@ -680,6 +703,7 @@ endmodule module SB_RAM40_4KNW ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, @@ -747,6 +771,7 @@ endmodule module SB_RAM40_4KNRNW ( `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, @@ -818,6 +843,7 @@ module ICESTORM_LC ( output LO, `ABC_ARRIVAL_HX(540) `ABC_ARRIVAL_LP(796) + `ABC_ARRIVAL_U(1391) output O, output COUT ); From 309684af16c763f7874beb605d0834c64975d004 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:07:28 -0700 Subject: [PATCH 130/144] Add arrival for SB_MAC16.O --- techlibs/ice40/cells_sim.v | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 116188acb..f4cc342eb 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1445,6 +1445,7 @@ module SB_MAC16 ( input ADDSUBTOP, ADDSUBBOT, input OHOLDTOP, OHOLDBOT, input CI, ACCUMCI, SIGNEXTIN, + `ABC_ARRIVAL_U(1984) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L587 output [31:0] O, output CO, ACCUMCO, SIGNEXTOUT ); From e8e38308689a760b69bd2910a36701b19f64656d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:09:29 -0700 Subject: [PATCH 131/144] Comment out SB_MAC16 arrival time for now, need to handle all its modes --- techlibs/ice40/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f4cc342eb..8e5e0358e 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1445,7 +1445,7 @@ module SB_MAC16 ( input ADDSUBTOP, ADDSUBBOT, input OHOLDTOP, OHOLDBOT, input CI, ACCUMCI, SIGNEXTIN, - `ABC_ARRIVAL_U(1984) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L587 + //`ABC_ARRIVAL_U(1984) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 output [31:0] O, output CO, ACCUMCO, SIGNEXTOUT ); From c4e53108230c246ecf1b014b11c240b71ed39a8a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 20:58:55 -0700 Subject: [PATCH 132/144] Use a dummy box file if none specified --- passes/techmap/abc9.cc | 11 ++++++++--- techlibs/common/Makefile.inc | 1 + techlibs/common/dummy.box | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 techlibs/common/dummy.box diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 968c68b70..11fe9c4a5 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1027,9 +1027,6 @@ struct Abc9Pass : public Pass { } if (arg == "-box" && argidx+1 < args.size()) { box_file = args[++argidx]; - rewrite_filename(box_file); - if (!box_file.empty() && !is_absolute_path(box_file)) - box_file = std::string(pwd) + "/" + box_file; continue; } if (arg == "-W" && argidx+1 < args.size()) { @@ -1040,6 +1037,14 @@ struct Abc9Pass : public Pass { } 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 = std::string(pwd) + "/" + box_file; + dict box_lookup; for (auto m : design->modules()) { auto it = m->attributes.find(ID(abc_box_id)); diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 0e05620bc..de94798af 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -28,3 +28,4 @@ $(eval $(call add_share_file,share,techlibs/common/dff2ff.v)) $(eval $(call add_share_file,share,techlibs/common/gate2lut.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2lut.v)) $(eval $(call add_share_file,share,techlibs/common/cells.lib)) +$(eval $(call add_share_file,share,techlibs/common/dummy.box)) diff --git a/techlibs/common/dummy.box b/techlibs/common/dummy.box new file mode 100644 index 000000000..0c18070a0 --- /dev/null +++ b/techlibs/common/dummy.box @@ -0,0 +1 @@ +(dummy) 1 0 0 0 From f33abd4eab08c0557a561b0fd4f16fc3d86433ab Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 16:44:11 -0700 Subject: [PATCH 133/144] Remove trailing space --- techlibs/xilinx/cells_sim.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index b4657daca..6e8729256 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -269,7 +269,7 @@ endmodule module FDCE ( (* abc_arrival=303 *) output reg Q, - (* clkbuf_sink *) + (* clkbuf_sink *) input C, input CE, D, CLR ); @@ -289,7 +289,7 @@ endmodule module FDPE ( (* abc_arrival=303 *) output reg Q, - (* clkbuf_sink *) + (* clkbuf_sink *) input C, input CE, D, PRE ); From e9bb252e77ba979a4c7041e6a221862a6464bf99 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 20:15:09 -0700 Subject: [PATCH 134/144] Recognise built-in types (e.g. $_DFF_*) --- backends/aiger/xaiger.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8c8ff2f7e..fa6ba0aca 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -263,12 +263,12 @@ struct XAigerWriter } } else { - bool cell_known = inst_module; + bool cell_known = inst_module || cell->known(); for (const auto &c : cell->connections()) { if (c.second.is_fully_const()) continue; auto port_wire = inst_module ? inst_module->wire(c.first) : nullptr; - auto is_input = !cell_known || port_wire->port_input; - auto is_output = !cell_known || port_wire->port_output; + auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first); + auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first); if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); From 4290548de35beba766bd7e0684e19de83a0cb2fa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 20:31:53 -0700 Subject: [PATCH 135/144] Make abc9 test a bit more interesting --- tests/various/abc9.v | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/various/abc9.v b/tests/various/abc9.v index a08b613a8..30ebd4e26 100644 --- a/tests/various/abc9.v +++ b/tests/various/abc9.v @@ -5,5 +5,7 @@ always @* endmodule module abc9_test028(input i, output o); -unknown u(~i, o); +wire w; +unknown u(~i, w); +unknown2 u2(w, o); endmodule From 696f854801619644e42f437894847ace96594a6b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 2 Sep 2019 12:15:11 -0700 Subject: [PATCH 136/144] Rename box --- techlibs/ecp5/abc_5g.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ecp5/abc_5g.box b/techlibs/ecp5/abc_5g.box index 66ebe196a..a336b4a85 100644 --- a/techlibs/ecp5/abc_5g.box +++ b/techlibs/ecp5/abc_5g.box @@ -18,7 +18,7 @@ CCU2C 1 1 9 3 # Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram) # Outputs: DO0, DO1, DO2, DO3 # name ID w/b ins outs -$__ABC_RAM16X2_COMB 2 0 8 4 +$__ABC_DPR16X4_COMB 2 0 8 4 #A0 A1 A2 A3 RAD0 RAD1 RAD2 RAD3 0 0 0 0 141 379 275 379 From 3459d283492769263e73a0e35d0e5d253c0bbec7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 2 Sep 2019 12:22:15 -0700 Subject: [PATCH 137/144] Add comments --- techlibs/xilinx/abc_xc7.box | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 554cc0cf0..20da3b8a0 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -15,7 +15,10 @@ F7MUX 1 1 3 1 MUXF8 2 1 3 1 104 94 273 -# Box containing MUXF7.[AB] + MUXF8 +# Box containing MUXF7.[AB] + MUXF8, +# Necessary to make these an atomic unit so that +# ABC cannot optimise just one of the MUXF7 away +# and expect to save on its delay # Inputs: I0 I1 I2 I3 S0 S1 # Outputs: O $__MUXF78 3 1 6 1 @@ -40,6 +43,11 @@ CARRY4 4 1 10 8 # SLICEM/A6LUT # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} +# Necessary since RAMD* and SRL* have both combinatorial (i.e. +# same-cycle read operation) and sequential (write operation +# is only committed on the next clock edge). +# To model the combinatorial path, such cells have to be split +# into comb and seq parts, with this box modelling only the former. # Inputs: A S0 S1 S2 S3 S4 S5 # Outputs: Y $__ABC_LUT6 2000 0 7 1 From 25e5fbac9096a872f7be1a481e6798103f40ccf5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 2 Sep 2019 22:56:38 +0200 Subject: [PATCH 138/144] Properly construct $live and $fair cells from "if (...) assume/assert (s_eventually ...)" Fixes https://github.com/YosysHQ/SymbiYosys/issues/59 Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 86dd80c65..52fcf3ee7 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1530,10 +1530,16 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector x_bit; - x_bit.push_back(RTLIL::State::Sx); + AstNode *check_defval; + if (type == AST_LIVE || type == AST_FAIR) { + check_defval = new AstNode(AST_REDUCE_BOOL, children[0]->clone()); + } else { + std::vector x_bit; + x_bit.push_back(RTLIL::State::Sx); + check_defval = mkconst_bits(x_bit, false); + } - AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false)); + AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), check_defval); assign_check->children[0]->str = id_check; assign_check->children[0]->was_checked = true; @@ -1546,9 +1552,13 @@ skip_dynamic_range_lvalue_expansion:; default_signals->children.push_back(assign_en); current_top_block->children.insert(current_top_block->children.begin(), default_signals); - assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone())); - assign_check->children[0]->str = id_check; - assign_check->children[0]->was_checked = true; + if (type == AST_LIVE || type == AST_FAIR) { + assign_check = nullptr; + } else { + assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone())); + assign_check->children[0]->str = id_check; + assign_check->children[0]->was_checked = true; + } if (current_always == nullptr || current_always->type != AST_INITIAL) { assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1)); @@ -1560,7 +1570,8 @@ skip_dynamic_range_lvalue_expansion:; assign_en->children[0]->was_checked = true; newNode = new AstNode(AST_BLOCK); - newNode->children.push_back(assign_check); + if (assign_check != nullptr) + newNode->children.push_back(assign_check); newNode->children.push_back(assign_en); AstNode *assertnode = new AstNode(type); From aa1491add3722e4cfae35755cc4cecfd3e5a6c82 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 4 Sep 2019 15:47:36 -0700 Subject: [PATCH 139/144] Resolve TODO with pin assignments for SRL* --- techlibs/xilinx/abc_map.v | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/abc_map.v b/techlibs/xilinx/abc_map.v index c3701b1a8..0c85d6656 100644 --- a/techlibs/xilinx/abc_map.v +++ b/techlibs/xilinx/abc_map.v @@ -101,8 +101,7 @@ module SRL16E ( .Q(\$Q ), .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D) ); - // TODO: Check if SRL uses fast inputs or slow inputs - \$__ABC_LUT6 q (.A(\$Q ), .S({A0, A1, A2, A3, 1'b0, 1'b0}), .Y(Q)); + \$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q)); endmodule module SRLC32E ( @@ -120,6 +119,5 @@ module SRLC32E ( .Q(\$Q ), .Q31(Q31), .A(A), .CE(CE), .CLK(CLK), .D(D) ); - // TODO: Check if SRL uses fast inputs or slow inputs - \$__ABC_LUT6 q (.A(\$Q ), .S({A, 1'b0}), .Y(Q)); + \$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q)); endmodule From a9af28694ce5fbcf4cdfd0c3cb440c08681f8f16 Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 5 Sep 2019 00:30:29 +0100 Subject: [PATCH 140/144] Use $(shell :; ...) in Makefile to force shell Did you think that `$(shell command -v ...)` would actually get run by the shell? Foolish mortal; GNU Make is obviously far more wise than thee, as it optimizes it to a direct -- and hence broken (since `command` is a shell builtin) -- exec. This horrifying contortion ensures that an actual shell runs the command and fixes the behaviour. @Shizmob found the source of this misbehaviour; turns out gmake has a hard-coded, incomplete list of shell builtins: https://github.com/mirror/make/blob/715c787dc69bac37827a7d6ea6d40a86c55b5583/src/job.c#L2691 This contains `command`, but the whole function is full of horrible heuristic garbage so who knows. I'm so sorry. --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index bb26eabed..8e01ac137 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ ifeq ($(OS), Darwin) PLUGIN_LDFLAGS += -undefined dynamic_lookup # homebrew search paths -ifneq ($(shell command -v brew),) +ifneq ($(shell :; command -v brew),) BREW_PREFIX := $(shell brew --prefix)/opt $(info $$BREW_PREFIX is [${BREW_PREFIX}]) ifeq ($(ENABLE_PYOSYS),1) @@ -102,8 +102,8 @@ PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH) export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) # macports search paths -else ifneq ($(shell command -v port),) -PORT_PREFIX := $(patsubst %/bin/port,%,$(shell command -v port)) +else ifneq ($(shell :; command -v port),) +PORT_PREFIX := $(patsubst %/bin/port,%,$(shell :; command -v port)) CXXFLAGS += -I$(PORT_PREFIX)/include LDFLAGS += -L$(PORT_PREFIX)/lib PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) From 694a8f75cf7a8bcf86a421ca6c9fe3560b1e2a0f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 27 Aug 2019 00:55:43 +0200 Subject: [PATCH 141/144] Add flatten handling of pre-existing wires as created by interfaces, fixes #1145 Signed-off-by: Clifford Wolf --- passes/techmap/techmap.cc | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index c4496f76f..cb01cadb1 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -211,14 +211,26 @@ struct TechmapWorker positional_ports[stringf("$%d", it.second->port_id)] = it.first; IdString w_name = it.second->name; apply_prefix(cell->name, w_name); - RTLIL::Wire *w = module->addWire(w_name, it.second); - w->port_input = false; - w->port_output = false; - w->port_id = 0; - if (it.second->get_bool_attribute(ID(_techmap_special_))) - w->attributes.clear(); - if (w->attributes.count(ID(src))) - w->add_strpool_attribute(ID(src), extra_src_attrs); + RTLIL::Wire *w = module->wire(w_name); + if (w != nullptr) { + if (!flatten_mode) + log_error("Signal %s.%s conflicts with %s.%s (via %s.%s).\n", log_id(module), log_id(w), + log_id(tpl), log_id(it.second), log_id(module), log_id(cell)); + if (GetSize(w) < GetSize(it.second)) { + log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w), + log_id(tpl), log_id(it.second), log_id(module), log_id(cell)); + w->width = GetSize(it.second); + } + } else { + w = module->addWire(w_name, it.second); + w->port_input = false; + w->port_output = false; + w->port_id = 0; + if (it.second->get_bool_attribute(ID(_techmap_special_))) + w->attributes.clear(); + if (w->attributes.count(ID(src))) + w->add_strpool_attribute(ID(src), extra_src_attrs); + } design->select(module, w); } From 30f1ac7ce9c44ac5cbd4ad7e389264246a1e3306 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 5 Sep 2019 13:51:53 +0200 Subject: [PATCH 142/144] Rename conflicting wires on flatten/techmap, add "hierconn" attribute, fixes #1220 Signed-off-by: Clifford Wolf --- README.md | 3 +++ passes/techmap/techmap.cc | 32 ++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e0a95a9d5..a39737c08 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,9 @@ Verilog Attributes and non-standard features that represent module parameters or localparams (when the HDL front-end is run in ``-pwires`` mode). +- Wires marked with the ``hierconn`` attribute are connected to wires with the + same name when they are imported from sub-modules by ``flatten``. + - The ``clkbuf_driver`` attribute can be set on an output port of a blackbox module to mark it as a clock buffer output, and thus prevent ``clkbufmap`` from inserting another clock buffer on a net driven by such output. diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index cb01cadb1..5ce1bf7d6 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -205,6 +205,7 @@ struct TechmapWorker } std::map positional_ports; + dict temp_renamed_wires; for (auto &it : tpl->wires_) { if (it.second->port_id > 0) @@ -213,15 +214,20 @@ struct TechmapWorker apply_prefix(cell->name, w_name); RTLIL::Wire *w = module->wire(w_name); if (w != nullptr) { - if (!flatten_mode) - log_error("Signal %s.%s conflicts with %s.%s (via %s.%s).\n", log_id(module), log_id(w), - log_id(tpl), log_id(it.second), log_id(module), log_id(cell)); - if (GetSize(w) < GetSize(it.second)) { - log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w), - log_id(tpl), log_id(it.second), log_id(module), log_id(cell)); - w->width = GetSize(it.second); + if (!flatten_mode || !w->get_bool_attribute(ID(hierconn))) { + temp_renamed_wires[w] = w->name; + module->rename(w, NEW_ID); + w = nullptr; + } else { + w->attributes.erase(ID(hierconn)); + if (GetSize(w) < GetSize(it.second)) { + log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w), + log_id(tpl), log_id(it.second), log_id(module), log_id(cell)); + w->width = GetSize(it.second); + } } - } else { + } + if (w == nullptr) { w = module->addWire(w_name, it.second); w->port_input = false; w->port_output = false; @@ -392,6 +398,16 @@ struct TechmapWorker } module->remove(cell); + + for (auto &it : temp_renamed_wires) + { + Wire *w = it.first; + IdString name = it.second; + IdString altname = module->uniquify(name); + Wire *other_w = module->wire(name); + module->rename(other_w, altname); + module->rename(w, name); + } } bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, From 71d355560e718147ac9ab769363c6a2b069fd209 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 5 Sep 2019 17:20:29 +0200 Subject: [PATCH 143/144] Update README.md Signed-off-by: Clifford Wolf --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a39737c08..894b152ce 100644 --- a/README.md +++ b/README.md @@ -333,7 +333,8 @@ Verilog Attributes and non-standard features is run in ``-pwires`` mode). - Wires marked with the ``hierconn`` attribute are connected to wires with the - same name when they are imported from sub-modules by ``flatten``. + same name (format ``cell_name.identifier``) when they are imported from + sub-modules by ``flatten``. - The ``clkbuf_driver`` attribute can be set on an output port of a blackbox module to mark it as a clock buffer output, and thus prevent ``clkbufmap`` From 58ec1df4c26599338f2f45941ed8ca402abfe607 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 5 Sep 2019 19:05:13 +0200 Subject: [PATCH 144/144] Bump version Signed-off-by: Clifford Wolf --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8e01ac137..5e5c4e66e 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+36 +YOSYS_VER := 0.9+231 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o