From b50de28c045e786f3140c95ab23cb2f426918093 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:00:49 -0800 Subject: Add abc9_ops -prep_holes --- backends/aiger/xaiger.cc | 140 +++-------------------------------------------- 1 file changed, 8 insertions(+), 132 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e7d767721..73af3bdfb 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -680,12 +680,11 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); log_assert(holes_module); dict cell_cache; - int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* orig_box_module = module->design->module(cell->type); @@ -696,85 +695,21 @@ struct XAigerWriter Pass::call_on_module(module->design, box_module, "proc"); int box_inputs = 0, box_outputs = 0; - auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); - Cell *holes_cell = r.first->second; - if (r.second && box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; - - // Since Module::derive() will create a new module, there - // is a chance that the ports will be alphabetically ordered - // again, which is a problem when carry-chains are involved. - // Inherit the port ordering from the original module here... - // (and set the port_id below, when iterating through those) - log_assert(GetSize(box_module->ports) == GetSize(orig_box_module->ports)); - box_module->ports = orig_box_module->ports; - } - // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) - int box_port_id = 1; for (const auto &port_name : box_module->ports) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); - if (r.second) - w->port_id = box_port_id++; - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; 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_sig.append(holes_wire); - } - if (w->port_output) { + box_inputs += GetSize(w); + 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("$abc%s.%s", cell->name.c_str(), log_id(w->name))); - else - holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_sig.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); - } - } - if (!port_sig.empty()) { - if (r.second) - holes_cell->setPort(w->name, port_sig); - else - holes_module->connect(holes_cell->getPort(w->name), port_sig); - } } // For flops only, create an extra 1-bit input that drives a new wire // called ".$abc9_currQ" that is used below - if (box_module->get_bool_attribute("\\abc9_flop")) { - log_assert(holes_cell); - + if (box_module->get_bool_attribute("\\abc9_flop")) box_inputs++; - Wire *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); - } - Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str())); - holes_module->connect(w, holes_wire); - } write_h_buffer(box_inputs); write_h_buffer(box_outputs); @@ -815,79 +750,20 @@ struct XAigerWriter 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(); - - // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger - // since boxes may contain parameters in which case `flatten` would have - // created a new $paramod ... - Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); - - dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); - else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".$abc9_currQ" - // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); - log_assert(currQ); - holes_module->connect(Q, currQ); - continue; - } - else if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - ++it; - } - - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; - } - - // 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; - module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - Pass::call(holes_design, "opt -purge"); + module->design->selection_stack.emplace_back(false); + module->design->selection().select(holes_module); std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); - delete holes_design; + + module->design->selection_stack.pop_back(); 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(); } } -- cgit v1.2.3 From e2bbe33a88c11b89e5a011c43d5a9c6b4623f9a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:24:29 -0800 Subject: Get rid of holes_mode --- backends/aiger/xaiger.cc | 105 ++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 70 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 73af3bdfb..877e0e58a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits, external_bits; + pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; @@ -136,7 +136,7 @@ struct XAigerWriter return a; } - XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) + XAigerWriter(Module *module) : module(module), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -166,9 +166,7 @@ struct XAigerWriter if (bit.wire == nullptr) { if (wire->port_output) { aig_map[wirebit] = (bit == State::S1) ? 1 : 0; - if (holes_mode) - output_bits.insert(wirebit); - //external_bits.insert(wirebit); + output_bits.insert(wirebit); } continue; } @@ -182,10 +180,7 @@ struct XAigerWriter if (wire->port_output) { if (bit != wirebit) alias_map[wirebit] = bit; - if (holes_mode) - output_bits.insert(wirebit); - else - external_bits.insert(wirebit); + output_bits.insert(wirebit); } if (wire->port_input && wire->port_output) @@ -207,11 +202,9 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } @@ -224,17 +217,13 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - if (!holes_mode) { - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); - } + toposort.node(cell->name); + bit_users[A].insert(cell->name); + bit_users[B].insert(cell->name); + bit_drivers[Y].insert(cell->name); continue; } - log_assert(!holes_mode); - if (cell->type == "$__ABC9_FF_") { SigBit D = sigmap(cell->getPort("\\D").as_bit()); @@ -298,7 +287,7 @@ struct XAigerWriter 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) { + if (is_input) for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; @@ -306,13 +295,19 @@ struct XAigerWriter SigBit I = sigmap(b); if (I != b) alias_map[b] = I; - if (holes_mode) - output_bits.insert(b); - else - external_bits.insert(b); + output_bits.insert(b); } } - } + + if (is_output) + for (auto b : c.second) { + Wire *w = b.wire; + if (!w) continue; + SigBit O = sigmap(b); + if (O != b) + alias_map[O] = b; + input_bits.insert(O); + } } //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); @@ -495,57 +490,27 @@ struct XAigerWriter // TODO: Free memory from toposort, bit_drivers, bit_users } - if (!holes_mode) - for (auto cell : module->cells()) - if (!module->selected(cell)) - for (auto &conn : cell->connections()) - if (cell->input(conn.first)) - for (auto wirebit : conn.second) - if (sigmap(wirebit).wire) - external_bits.insert(wirebit); - - // For all bits consumed outside of the selected cells, - // but driven from a selected cell, then add it as - // a primary output - for (auto wirebit : external_bits) { - SigBit bit = sigmap(wirebit); - if (!bit.wire) - continue; - if (!undriven_bits.count(bit)) { - if (bit != wirebit) - alias_map[wirebit] = bit; - output_bits.insert(wirebit); - } - } - for (auto bit : input_bits) - undriven_bits.erase(sigmap(bit)); + undriven_bits.erase(bit); for (auto bit : output_bits) unused_bits.erase(sigmap(bit)); for (auto bit : unused_bits) undriven_bits.erase(bit); - - // Make all undriven bits a primary input - if (!holes_mode) + if (!undriven_bits.empty()) { for (auto bit : undriven_bits) { + log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); - undriven_bits.erase(bit); } - - if (holes_mode) { - struct sort_by_port_id { - bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { - return a.wire->port_id < b.wire->port_id; - } - }; - input_bits.sort(sort_by_port_id()); - output_bits.sort(sort_by_port_id()); - } - else { - input_bits.sort(); - output_bits.sort(); + log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } + struct sort_by_port_id { + bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { + return a.wire->port_id < b.wire->port_id; + } + }; + input_bits.sort(sort_by_port_id()); + output_bits.sort(sort_by_port_id()); not_map.sort(); and_map.sort(); @@ -754,7 +719,7 @@ struct XAigerWriter module->design->selection().select(holes_module); std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); + XAigerWriter writer(holes_module); writer.write_aiger(a_buffer, false /*ascii_mode*/); module->design->selection_stack.pop_back(); -- cgit v1.2.3 From 65baefecd39b3be641b9a6be350d2ae83854cacc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:26:35 -0800 Subject: Rid unnecessary if --- backends/aiger/xaiger.cc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 877e0e58a..35fb8d5dc 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -714,22 +714,20 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - if (holes_module) { - module->design->selection_stack.emplace_back(false); - module->design->selection().select(holes_module); + module->design->selection_stack.emplace_back(false); + module->design->selection().select(holes_module); - std::stringstream a_buffer; - XAigerWriter writer(holes_module); - writer.write_aiger(a_buffer, false /*ascii_mode*/); + std::stringstream a_buffer; + XAigerWriter writer(holes_module); + writer.write_aiger(a_buffer, false /*ascii_mode*/); - module->design->selection_stack.pop_back(); + module->design->selection_stack.pop_back(); - 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()); - } + f << "a"; + buffer_str = a_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"; -- cgit v1.2.3 From 88334cab891d47778931c1ea0060fd107052e189 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 18:49:33 -0800 Subject: Cleanup --- backends/aiger/xaiger.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 35fb8d5dc..9e0a56963 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -645,19 +645,12 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - - dict cell_cache; - int box_count = 0; for (auto cell : box_list) { RTLIL::Module* orig_box_module = module->design->module(cell->type); log_assert(orig_box_module); IdString derived_name = orig_box_module->derive(module->design, cell->parameters); RTLIL::Module* box_module = module->design->module(derived_name); - if (box_module->has_processes()) - Pass::call_on_module(module->design, box_module, "proc"); int box_inputs = 0, box_outputs = 0; // NB: Assume box_module->ports are sorted alphabetically @@ -714,6 +707,9 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); + log_assert(holes_module); + module->design->selection_stack.emplace_back(false); module->design->selection().select(holes_module); -- cgit v1.2.3 From b42b64e8ed713b0e9810f18db7cafcf356e2b4f6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Dec 2019 19:23:54 -0800 Subject: Move Pass::call() out of abc9_ops into abc9 --- backends/aiger/xaiger.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 9e0a56963..830c86787 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -710,6 +710,10 @@ struct XAigerWriter RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); log_assert(holes_module); + 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"); + module->design->selection_stack.emplace_back(false); module->design->selection().select(holes_module); -- cgit v1.2.3 From e1f494ab1db523f90cf1e386ba133b1550dcb300 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 13:08:52 -0800 Subject: WIP --- backends/aiger/xaiger.cc | 164 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 141 insertions(+), 23 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 42a26cbf9..02ab47ac0 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -619,26 +619,90 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + log_assert(holes_module); + + dict cell_cache; + + int port_id = 1; int box_count = 0; for (auto cell : box_list) { RTLIL::Module* orig_box_module = module->design->module(cell->type); log_assert(orig_box_module); IdString derived_name = orig_box_module->derive(module->design, cell->parameters); RTLIL::Module* box_module = module->design->module(derived_name); + if (box_module->has_processes()) + Pass::call_on_module(module->design, box_module, "proc"); + + auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); + Cell *holes_cell = r.first->second; + if (r.second && box_module->get_bool_attribute("\\whitebox")) { + holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell->parameters = cell->parameters; + r.first->second = holes_cell; + } int box_inputs = 0, box_outputs = 0; for (auto port_name : box_ports.at(cell->type)) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_sig; + if (w->port_input) - box_inputs += GetSize(w); - if (w->port_output) + 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_sig.append(holes_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("$abc%s.%s", cell->name.c_str(), log_id(w->name))); + else + holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); + holes_wire->port_output = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_sig.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); + } + } + if (!port_sig.empty()) { + if (r.second) + holes_cell->setPort(w->name, port_sig); + else + holes_module->connect(holes_cell->getPort(w->name), port_sig); + } } - // For flops only, create an extra 1-bit input for abc9_ff.Q - if (box_module->get_bool_attribute("\\abc9_flop")) + // For flops only, create an extra 1-bit input that drives a new wire + // called ".abc9_ff.Q" that is used below + if (box_module->get_bool_attribute("\\abc9_flop")) { + log_assert(holes_cell); + box_inputs++; + Wire *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); + } + Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); + log_assert(w); + holes_module->connect(w, holes_wire); + } write_h_buffer(box_inputs); write_h_buffer(box_outputs); @@ -690,27 +754,81 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - - 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"); - - module->design->selection_stack.emplace_back(false); - module->design->selection().select(holes_module); - - std::stringstream a_buffer; - XAigerWriter writer(holes_module); - writer.write_aiger(a_buffer, false /*ascii_mode*/); + if (holes_module) { + log_push(); + + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); + + // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger + // since boxes may contain parameters in which case `flatten` would have + // created a new $paramod ... + Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); + + dict replace; + for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { + auto cell = it->second; + if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", + "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { + SigBit D = cell->getPort("\\D"); + SigBit Q = cell->getPort("\\Q"); + // Remove the DFF cell from what needs to be a combinatorial box + it = holes_module->cells_.erase(it); + Wire *port; + if (GetSize(Q.wire) == 1) + port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); + else + port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); + log_assert(port); + // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" + // in order to extract the combinatorial control logic that feeds the box + // (i.e. clock enable, synchronous reset, etc.) + replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); + // Since `flatten` above would have created wires named ".Q", + // extract the pre-techmap cell name + auto pos = Q.wire->name.str().rfind("."); + log_assert(pos != std::string::npos); + IdString driver = Q.wire->name.substr(0, pos); + // And drive the signal that was previously driven by "DFF.Q" (typically + // used to implement clock-enable functionality) with the ".abc9_ff.Q" + // wire (which itself is driven an input port) we inserted above + Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); + log_assert(currQ); + holes_module->connect(Q, currQ); + continue; + } + else if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + ++it; + } - module->design->selection_stack.pop_back(); + for (auto &conn : holes_module->connections_) { + auto it = replace.find(conn); + if (it != replace.end()) + conn = it->second; + } - f << "a"; - buffer_str = a_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()); + // 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; + module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "opt -purge"); + + std::stringstream a_buffer; + XAigerWriter writer(holes_module); + 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"; -- cgit v1.2.3 From bb70915fb8adcd7ede7719174dea3bc9c04e613e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 13:21:56 -0800 Subject: WIP --- backends/aiger/xaiger.cc | 75 ++++++------------------------------------------ 1 file changed, 8 insertions(+), 67 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 02ab47ac0..7e7a3a17e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -619,90 +619,30 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); log_assert(holes_module); dict cell_cache; - int port_id = 1; int box_count = 0; for (auto cell : box_list) { - RTLIL::Module* orig_box_module = module->design->module(cell->type); - log_assert(orig_box_module); - IdString derived_name = orig_box_module->derive(module->design, cell->parameters); - RTLIL::Module* box_module = module->design->module(derived_name); - if (box_module->has_processes()) - Pass::call_on_module(module->design, box_module, "proc"); - - auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); - Cell *holes_cell = r.first->second; - if (r.second && box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - r.first->second = holes_cell; - } + RTLIL::Module* box_module = module->design->module(cell->type); + log_assert(box_module); int box_inputs = 0, box_outputs = 0; - for (auto port_name : box_ports.at(cell->type)) { + for (auto port_name : box_module->ports) { RTLIL::Wire *w = box_module->wire(port_name); log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_sig; - 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_sig.append(holes_wire); - } - if (w->port_output) { + box_inputs += GetSize(w); + 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("$abc%s.%s", cell->name.c_str(), log_id(w->name))); - else - holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_sig.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); - } - } - if (!port_sig.empty()) { - if (r.second) - holes_cell->setPort(w->name, port_sig); - else - holes_module->connect(holes_cell->getPort(w->name), port_sig); - } } // For flops only, create an extra 1-bit input that drives a new wire // called ".abc9_ff.Q" that is used below - if (box_module->get_bool_attribute("\\abc9_flop")) { - log_assert(holes_cell); - + if (box_module->get_bool_attribute("\\abc9_flop")) box_inputs++; - Wire *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); - } - Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - log_assert(w); - holes_module->connect(w, holes_wire); - } write_h_buffer(box_inputs); write_h_buffer(box_outputs); @@ -764,6 +704,7 @@ struct XAigerWriter // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger // since boxes may contain parameters in which case `flatten` would have // created a new $paramod ... + Pass::call_on_module(holes_module->design, holes_module, "wbflip"); Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); dict replace; -- cgit v1.2.3 From 559f3379e852f304a0255afcc37714b9d0da59d9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 14:37:58 -0800 Subject: Preserve topo ordering from -prep_holes to write_xaiger --- backends/aiger/xaiger.cc | 236 ++++++++++++++++------------------------------- 1 file changed, 77 insertions(+), 159 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7e7a3a17e..ff3de65cc 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -78,7 +78,7 @@ struct XAigerWriter Module *module; SigMap sigmap; - pool input_bits, output_bits, external_bits; + pool input_bits, output_bits; dict not_map, alias_map; dict> and_map; vector ci_bits, co_bits; @@ -199,12 +199,6 @@ struct XAigerWriter } } - // TODO: Speed up toposort -- ultimately we care about - // box ordering, but not individual AIG cells - dict> bit_drivers, bit_users; - TopoSort toposort; - bool abc9_box_seen = false; - for (auto cell : module->selected_cells()) { if (cell->type == "$_NOT_") { @@ -213,9 +207,6 @@ struct XAigerWriter unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_drivers[Y].insert(cell->name); continue; } @@ -228,10 +219,6 @@ struct XAigerWriter unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); - toposort.node(cell->name); - bit_users[A].insert(cell->name); - bit_users[B].insert(cell->name); - bit_drivers[Y].insert(cell->name); continue; } @@ -257,22 +244,17 @@ struct XAigerWriter if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) abc9_box = false; + if (abc9_box) { + int abc9_box_order = cell->attributes.at("\\abc9_box_order").as_int(); + if (GetSize(box_list) <= abc9_box_order) + box_list.resize(abc9_box_order+1); + box_list[abc9_box_order] = cell; + if (!abc9_flop) + continue; + } + for (const auto &conn : cell->connections()) { auto port_wire = inst_module->wire(conn.first); - - if (abc9_box) { - // Ignore inout for the sake of topographical ordering - if (port_wire->port_input && !port_wire->port_output) - 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); - - if (!abc9_flop) - continue; - } - if (port_wire->port_output) { int arrival = 0; auto it = port_wire->attributes.find("\\abc9_arrival"); @@ -286,12 +268,6 @@ struct XAigerWriter arrival_times[bit] = arrival; } } - - if (abc9_box) { - abc9_box_seen = true; - toposort.node(cell->name); - continue; - } } bool cell_known = inst_module || cell->known(); @@ -319,138 +295,56 @@ struct XAigerWriter //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } - if (abc9_box_seen) { - for (auto &it : bit_users) - if (bit_drivers.count(it.first)) - for (auto driver_cell : bit_drivers.at(it.first)) - for (auto user_cell : it.second) - toposort.edge(driver_cell, user_cell); - -#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 = module->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 cell_name : toposort.sorted) { - RTLIL::Cell *cell = module->cell(cell_name); - log_assert(cell); - - RTLIL::Module* box_module = module->design->module(cell->type); - if (!box_module || !box_module->attributes.count("\\abc9_box_id")) - continue; - - bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); - - auto r = box_ports.insert(cell->type); - if (r.second) { - // Make carry in the last PI, and carry out the last PO - // since ABC requires it this way - IdString carry_in, carry_out; - for (const auto &port_name : box_module->ports) { - auto w = box_module->wire(port_name); - log_assert(w); - if (w->get_bool_attribute("\\abc9_carry")) { - if (w->port_input) { - if (carry_in != IdString()) - log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module)); - carry_in = port_name; - } - if (w->port_output) { - if (carry_out != IdString()) - log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module)); - carry_out = port_name; - } - } - else - r.first->second.push_back(port_name); - } + for (auto cell : box_list) { + log_assert(cell); - if (carry_in != IdString() && carry_out == IdString()) - log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(box_module)); - if (carry_in == IdString() && carry_out != IdString()) - log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module)); - if (carry_in != IdString()) { - r.first->second.push_back(carry_in); - r.first->second.push_back(carry_out); - } - } + RTLIL::Module* box_module = module->design->module(cell->type); + log_assert(box_module); + log_assert(box_module->attributes.count("\\abc9_box_id")); - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires - for (auto port_name : r.first->second) { + auto r = box_ports.insert(cell->type); + if (r.second) { + // Make carry in the last PI, and carry out the last PO + // since ABC requires it this way + IdString carry_in, carry_out; + for (const auto &port_name : box_module->ports) { auto w = box_module->wire(port_name); log_assert(w); - auto it = cell->connections_.find(port_name); - if (w->port_input) { - RTLIL::SigSpec rhs; - if (it != cell->connections_.end()) { - if (GetSize(it->second) < GetSize(w)) - it->second.append(RTLIL::SigSpec(State::S0, GetSize(w)-GetSize(it->second))); - rhs = it->second; - } - else { - rhs = RTLIL::SigSpec(State::S0, GetSize(w)); - cell->setPort(port_name, rhs); + if (w->get_bool_attribute("\\abc9_carry")) { + if (w->port_input) { + if (carry_in != IdString()) + log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module)); + carry_in = port_name; } - - for (auto b : rhs) { - SigBit I = sigmap(b); - if (b == RTLIL::Sx) - b = State::S0; - else if (I != b) { - if (I == RTLIL::Sx) - alias_map[b] = State::S0; - else - alias_map[b] = I; - } - co_bits.emplace_back(b); - unused_bits.erase(I); + if (w->port_output) { + if (carry_out != IdString()) + log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module)); + carry_out = port_name; } } - if (w->port_output) { - RTLIL::SigSpec rhs; - auto it = cell->connections_.find(w->name); - if (it != cell->connections_.end()) { - if (GetSize(it->second) < GetSize(w)) - it->second.append(module->addWire(NEW_ID, GetSize(w)-GetSize(it->second))); - rhs = it->second; - } - else { - Wire *wire = module->addWire(NEW_ID, GetSize(w)); - if (blackbox) - wire->set_bool_attribute(ID(abc9_padding)); - rhs = wire; - cell->setPort(port_name, rhs); - } + else + r.first->second.push_back(port_name); + } - for (const auto &b : rhs.bits()) { - SigBit O = sigmap(b); - if (O != b) - alias_map[O] = b; - ci_bits.emplace_back(b); - undriven_bits.erase(O); - } - } + if (carry_in != IdString() && carry_out == IdString()) + log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(box_module)); + if (carry_in == IdString() && carry_out != IdString()) + log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module)); + if (carry_in != IdString()) { + r.first->second.push_back(carry_in); + r.first->second.push_back(carry_out); } + } - // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box - if (box_module->get_bool_attribute("\\abc9_flop")) { - SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); - if (rhs.empty()) - log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); + bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); + // Fully pad all unused input connections of this box cell with S0 + // Fully pad all undriven output connections of this box cell with anonymous wires + for (auto port_name : r.first->second) { + auto w = box_module->wire(port_name); + log_assert(w); + auto rhs = cell->getPort(port_name); + if (w->port_input) for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -464,12 +358,36 @@ struct XAigerWriter co_bits.emplace_back(b); unused_bits.erase(I); } - } - - box_list.emplace_back(cell); + if (w->port_output) + for (const auto &b : rhs.bits()) { + SigBit O = sigmap(b); + if (O != b) + alias_map[O] = b; + ci_bits.emplace_back(b); + undriven_bits.erase(O); + } } - // TODO: Free memory from toposort, bit_drivers, bit_users + // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box + if (box_module->get_bool_attribute("\\abc9_flop")) { + SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); + if (rhs.empty()) + log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); + + for (auto b : rhs) { + SigBit I = sigmap(b); + if (b == RTLIL::Sx) + b = State::S0; + else if (I != b) { + if (I == RTLIL::Sx) + alias_map[b] = State::S0; + else + alias_map[b] = I; + } + co_bits.emplace_back(b); + unused_bits.erase(I); + } + } } for (auto bit : input_bits) -- cgit v1.2.3 From a819656972dd44c479422fa688874926d6239a95 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 14:59:55 -0800 Subject: WIP --- backends/aiger/xaiger.cc | 56 ------------------------------------------------ 1 file changed, 56 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ff3de65cc..e9b4f07bf 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -336,8 +336,6 @@ struct XAigerWriter } } - bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */); - // Fully pad all unused input connections of this box cell with S0 // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { @@ -615,65 +613,11 @@ struct XAigerWriter if (holes_module) { log_push(); - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); - - // Cannot techmap/aigmap/check all lib_whitebox-es outside of write_xaiger - // since boxes may contain parameters in which case `flatten` would have - // created a new $paramod ... - Pass::call_on_module(holes_module->design, holes_module, "wbflip"); - Pass::call_on_module(holes_module->design, holes_module, "flatten -wb; techmap; aigmap"); - - dict replace; - for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { - auto cell = it->second; - if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { - SigBit D = cell->getPort("\\D"); - SigBit Q = cell->getPort("\\Q"); - // Remove the DFF cell from what needs to be a combinatorial box - it = holes_module->cells_.erase(it); - Wire *port; - if (GetSize(Q.wire) == 1) - port = holes_module->wire(stringf("$abc%s", Q.wire->name.c_str())); - else - port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); - log_assert(port); - // Prepare to replace "assign = DFF.Q;" with "assign = DFF.D;" - // in order to extract the combinatorial control logic that feeds the box - // (i.e. clock enable, synchronous reset, etc.) - replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); - // Since `flatten` above would have created wires named ".Q", - // extract the pre-techmap cell name - auto pos = Q.wire->name.str().rfind("."); - log_assert(pos != std::string::npos); - IdString driver = Q.wire->name.substr(0, pos); - // And drive the signal that was previously driven by "DFF.Q" (typically - // used to implement clock-enable functionality) with the ".abc9_ff.Q" - // wire (which itself is driven an input port) we inserted above - Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); - log_assert(currQ); - holes_module->connect(Q, currQ); - continue; - } - else if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - ++it; - } - - for (auto &conn : holes_module->connections_) { - auto it = replace.find(conn); - if (it != replace.end()) - conn = it->second; - } - // 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; module->design->modules_.erase(holes_module->name); holes_design->add(holes_module); - Pass::call(holes_design, "opt -purge"); std::stringstream a_buffer; XAigerWriter writer(holes_module); -- cgit v1.2.3 From 930f03e8830ed8a8023ff88207b97e757ae8496c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Jan 2020 15:38:18 -0800 Subject: Call -prep_holes before aigmap; fix topo ordering --- backends/aiger/xaiger.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e9b4f07bf..7ef744d04 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -199,7 +199,7 @@ struct XAigerWriter } } - for (auto cell : module->selected_cells()) { + for (auto cell : module->cells()) { if (cell->type == "$_NOT_") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); @@ -613,16 +613,9 @@ struct XAigerWriter if (holes_module) { log_push(); - // 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; - module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - std::stringstream a_buffer; XAigerWriter writer(holes_module); writer.write_aiger(a_buffer, false /*ascii_mode*/); - delete holes_design; f << "a"; std::string buffer_str = a_buffer.str(); -- cgit v1.2.3 From 6556a1347ab56b022a599835071c6b3059787462 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 4 Jan 2020 09:17:01 -0800 Subject: Fix when -dff not given --- backends/aiger/xaiger.cc | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7ef744d04..32b218a22 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -239,17 +239,13 @@ struct XAigerWriter RTLIL::Module* inst_module = module->design->module(cell->type); if (inst_module) { - bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); - bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); - if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) - abc9_box = false; - - if (abc9_box) { - int abc9_box_order = cell->attributes.at("\\abc9_box_order").as_int(); - if (GetSize(box_list) <= abc9_box_order) - box_list.resize(abc9_box_order+1); - box_list[abc9_box_order] = cell; - if (!abc9_flop) + auto it = cell->attributes.find("\\abc9_box_seq"); + if (it != cell->attributes.end()) { + int abc9_box_seq = it->second.as_int(); + if (GetSize(box_list) <= abc9_box_seq) + box_list.resize(abc9_box_seq+1); + box_list[abc9_box_seq] = cell; + if (!inst_module->get_bool_attribute("\\abc9_flop")) continue; } @@ -542,6 +538,8 @@ struct XAigerWriter int box_count = 0; for (auto cell : box_list) { + log_assert(cell); + RTLIL::Module* box_module = module->design->module(cell->type); log_assert(box_module); @@ -611,7 +609,7 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_push(); + log_module(holes_module); std::stringstream a_buffer; XAigerWriter writer(holes_module); @@ -622,8 +620,6 @@ struct XAigerWriter 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(); } } -- cgit v1.2.3 From b5f60e055d07579a2d4f23fc053ca030f103f377 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 5 Jan 2020 10:20:24 -0800 Subject: write_xaiger to pad, not abc9_ops -prep_holes --- backends/aiger/xaiger.cc | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 32b218a22..5aea70f3b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -332,13 +332,14 @@ struct XAigerWriter } } - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { auto w = box_module->wire(port_name); log_assert(w); - auto rhs = cell->getPort(port_name); - if (w->port_input) + + SigSpec rhs = cell->connections_.at(port_name, SigSpec()); + if (w->port_input) { + // Add padding to fill entire port + rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -352,14 +353,18 @@ struct XAigerWriter co_bits.emplace_back(b); unused_bits.erase(I); } - if (w->port_output) - for (const auto &b : rhs.bits()) { + } + if (w->port_output) { + // Add padding to fill entire port + rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); + for (const auto &b : rhs) { SigBit O = sigmap(b); if (O != b) alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); } + } } // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box @@ -418,8 +423,11 @@ struct XAigerWriter for (auto &bit : ci_bits) { aig_m++, aig_i++; - log_assert(!aig_map.count(bit)); - aig_map[bit] = 2*aig_m; + // State::Sx if padding + if (bit != State::Sx) { + log_assert(!aig_map.count(bit)); + aig_map[bit] = 2*aig_m; + } } for (auto bit : co_bits) { @@ -609,8 +617,6 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_module(holes_module); - std::stringstream a_buffer; XAigerWriter writer(holes_module); writer.write_aiger(a_buffer, false /*ascii_mode*/); -- cgit v1.2.3 From aa58472a292c2cd3c0f2ba669c9dcfd608d8dc5f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 13:34:45 -0800 Subject: Revert "write_xaiger to pad, not abc9_ops -prep_holes" This reverts commit b5f60e055d07579a2d4f23fc053ca030f103f377. --- backends/aiger/xaiger.cc | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c01adde3d..a9680525d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -318,14 +318,13 @@ struct XAigerWriter } } + // Fully pad all unused input connections of this box cell with S0 + // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { auto w = box_module->wire(port_name); log_assert(w); - - SigSpec rhs = cell->connections_.at(port_name, SigSpec()); - if (w->port_input) { - // Add padding to fill entire port - rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); + auto rhs = cell->getPort(port_name); + if (w->port_input) for (auto b : rhs) { SigBit I = sigmap(b); if (b == RTLIL::Sx) @@ -339,18 +338,14 @@ struct XAigerWriter co_bits.emplace_back(b); unused_bits.erase(I); } - } - if (w->port_output) { - // Add padding to fill entire port - rhs.append(SigSpec(State::Sx, GetSize(w)-GetSize(rhs))); - for (const auto &b : rhs) { + if (w->port_output) + for (const auto &b : rhs.bits()) { SigBit O = sigmap(b); if (O != b) alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); } - } } // Connect .abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box @@ -417,11 +412,8 @@ struct XAigerWriter for (auto &bit : ci_bits) { aig_m++, aig_i++; - // State::Sx if padding - if (bit != State::Sx) { - log_assert(!aig_map.count(bit)); - aig_map[bit] = 2*aig_m; - } + log_assert(!aig_map.count(bit)); + aig_map[bit] = 2*aig_m; } for (auto bit : co_bits) { @@ -609,6 +601,8 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { + log_module(holes_module); + std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); -- cgit v1.2.3 From 8d0cc654a4c6cad925d20557cf299e00e27d5726 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Jan 2020 15:14:38 -0800 Subject: Stray log_module --- backends/aiger/xaiger.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index a9680525d..beaed696d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -601,8 +601,6 @@ struct XAigerWriter f.write(buffer_str.data(), buffer_str.size()); if (holes_module) { - log_module(holes_module); - std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); -- cgit v1.2.3 From 295e241c074ae275e832fdde9fae6fd897170ac8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 11 Jan 2020 17:28:24 -0800 Subject: cleanup --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 212e1e561..93e0ebc8c 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -93,7 +93,6 @@ struct XAigerWriter dict ordered_outputs; vector box_list; - dict> box_ports; int mkgate(int a0, int a1) { @@ -277,6 +276,7 @@ struct XAigerWriter //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } + dict> box_ports; for (auto cell : box_list) { log_assert(cell); -- cgit v1.2.3 From 0d2c06ee47a5008ba79d14d52f72d9b08ac2c7fc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 09:50:50 -0800 Subject: write_xaiger: cache arrival times --- backends/aiger/xaiger.cc | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 93e0ebc8c..0c08645d0 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -184,6 +184,7 @@ struct XAigerWriter } } + dict> arrival_cache; for (auto cell : module->cells()) { if (cell->type == "$_NOT_") { @@ -230,24 +231,29 @@ struct XAigerWriter if (GetSize(box_list) <= abc9_box_seq) box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; + // Only flop boxes may have arrival times if (!inst_module->get_bool_attribute("\\abc9_flop")) continue; } + auto &cell_arrivals = arrival_cache[cell->type]; for (const auto &conn : cell->connections()) { - auto port_wire = inst_module->wire(conn.first); - if (port_wire->port_output) { - int arrival = 0; - auto it = port_wire->attributes.find("\\abc9_arrival"); - if (it != port_wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc9_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(); + auto r = cell_arrivals.insert(conn.first); + auto &arrival = r.first->second; + if (r.second) { + auto port_wire = inst_module->wire(conn.first); + if (port_wire->port_output) { + auto it = port_wire->attributes.find("\\abc9_arrival"); + if (it != port_wire->attributes.end()) { + if (it->second.flags != 0) + log_error("Attribute 'abc9_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(); + } } - if (arrival) - for (auto bit : sigmap(conn.second)) - arrival_times[bit] = arrival; } + if (arrival) + for (auto bit : sigmap(conn.second)) + arrival_times[bit] = arrival; } } -- cgit v1.2.3 From 9ec948f3965eef214bee3af778b67fdd6ee86929 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 19:07:55 -0800 Subject: write_xaiger: add support and test for (* keep *) on wires --- backends/aiger/xaiger.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0c08645d0..2a0f5c7e4 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -156,7 +156,6 @@ struct XAigerWriter if (wire->get_bool_attribute(ID::keep)) sigmap.add(wire); - for (auto wire : module->wires()) for (int i = 0; i < GetSize(wire); i++) { @@ -174,10 +173,11 @@ struct XAigerWriter undriven_bits.insert(bit); unused_bits.insert(bit); - if (wire->port_input) + bool keep = wire->get_bool_attribute(ID::keep); + if (wire->port_input || keep) input_bits.insert(bit); - if (wire->port_output) { + if (wire->port_output || keep) { if (bit != wirebit) alias_map[wirebit] = bit; output_bits.insert(wirebit); @@ -209,9 +209,9 @@ struct XAigerWriter } if (cell->type == "$__ABC9_FF_" && - // The presence of an abc9_mergeability attribute indicates - // that we do want to pass this flop to ABC - cell->attributes.count("\\abc9_mergeability")) + // The presence of an abc9_mergeability attribute indicates + // that we do want to pass this flop to ABC + cell->attributes.count("\\abc9_mergeability")) { SigBit D = sigmap(cell->getPort("\\D").as_bit()); SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); @@ -430,7 +430,17 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; - aig_outputs.push_back(bit2aig(bit)); + int aig; + if (input_bits.count(bit)) { + auto it = aig_map.find(bit); + int input_aig = it->second; + aig_map.erase(it); + aig = bit2aig(bit); + aig_map.at(bit) = input_aig; + } + else + aig = bit2aig(bit); + aig_outputs.push_back(aig); } for (auto &i : ff_bits) { -- cgit v1.2.3 From a6d4ea74634826741f09793c36d596f2fa239f62 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 19:21:11 -0800 Subject: abc9: respect (* keep *) on cells --- backends/aiger/xaiger.cc | 130 +++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 61 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2a0f5c7e4..ed0e48e01 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -186,74 +186,76 @@ struct XAigerWriter dict> arrival_cache; for (auto cell : module->cells()) { - if (cell->type == "$_NOT_") - { - SigBit A = sigmap(cell->getPort("\\A").as_bit()); - SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - unused_bits.erase(A); - undriven_bits.erase(Y); - not_map[Y] = A; - continue; - } - - if (cell->type == "$_AND_") - { - SigBit A = sigmap(cell->getPort("\\A").as_bit()); - SigBit B = sigmap(cell->getPort("\\B").as_bit()); - SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); - unused_bits.erase(A); - unused_bits.erase(B); - undriven_bits.erase(Y); - and_map[Y] = make_pair(A, B); - continue; - } + RTLIL::Module* inst_module = module->design->module(cell->type); + if (!cell->has_keep_attr()) { + if (cell->type == "$_NOT_") + { + SigBit A = sigmap(cell->getPort("\\A").as_bit()); + SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); + unused_bits.erase(A); + undriven_bits.erase(Y); + not_map[Y] = A; + continue; + } - if (cell->type == "$__ABC9_FF_" && - // The presence of an abc9_mergeability attribute indicates - // that we do want to pass this flop to ABC - cell->attributes.count("\\abc9_mergeability")) - { - 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; - auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); - log_assert(r.second); - continue; - } + if (cell->type == "$_AND_") + { + SigBit A = sigmap(cell->getPort("\\A").as_bit()); + SigBit B = sigmap(cell->getPort("\\B").as_bit()); + SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); + unused_bits.erase(A); + unused_bits.erase(B); + undriven_bits.erase(Y); + and_map[Y] = make_pair(A, B); + continue; + } - RTLIL::Module* inst_module = module->design->module(cell->type); - if (inst_module) { - auto it = cell->attributes.find("\\abc9_box_seq"); - if (it != cell->attributes.end()) { - int abc9_box_seq = it->second.as_int(); - if (GetSize(box_list) <= abc9_box_seq) - box_list.resize(abc9_box_seq+1); - box_list[abc9_box_seq] = cell; - // Only flop boxes may have arrival times - if (!inst_module->get_bool_attribute("\\abc9_flop")) - continue; + if (cell->type == "$__ABC9_FF_" && + // The presence of an abc9_mergeability attribute indicates + // that we do want to pass this flop to ABC + cell->attributes.count("\\abc9_mergeability")) + { + 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; + auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); + log_assert(r.second); + continue; } - auto &cell_arrivals = arrival_cache[cell->type]; - for (const auto &conn : cell->connections()) { - auto r = cell_arrivals.insert(conn.first); - auto &arrival = r.first->second; - if (r.second) { - auto port_wire = inst_module->wire(conn.first); - if (port_wire->port_output) { - auto it = port_wire->attributes.find("\\abc9_arrival"); - if (it != port_wire->attributes.end()) { - if (it->second.flags != 0) - log_error("Attribute 'abc9_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(); + if (inst_module) { + auto it = cell->attributes.find("\\abc9_box_seq"); + if (it != cell->attributes.end()) { + int abc9_box_seq = it->second.as_int(); + if (GetSize(box_list) <= abc9_box_seq) + box_list.resize(abc9_box_seq+1); + box_list[abc9_box_seq] = cell; + // Only flop boxes may have arrival times + if (!inst_module->get_bool_attribute("\\abc9_flop")) + continue; + } + + auto &cell_arrivals = arrival_cache[cell->type]; + for (const auto &conn : cell->connections()) { + auto r = cell_arrivals.insert(conn.first); + auto &arrival = r.first->second; + if (r.second) { + auto port_wire = inst_module->wire(conn.first); + if (port_wire->port_output) { + auto it = port_wire->attributes.find("\\abc9_arrival"); + if (it != port_wire->attributes.end()) { + if (it->second.flags != 0) + log_error("Attribute 'abc9_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(); + } } } + if (arrival) + for (auto bit : sigmap(conn.second)) + arrival_times[bit] = arrival; } - if (arrival) - for (auto bit : sigmap(conn.second)) - arrival_times[bit] = arrival; } } @@ -270,6 +272,9 @@ struct XAigerWriter for (auto b : c.second) { Wire *w = b.wire; if (!w) continue; + // Do not add as PO if bit is already a PI + if (input_bits.count(b)) + continue; if (!w->port_output || !cell_known) { SigBit I = sigmap(b); if (I != b) @@ -431,6 +436,9 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; int aig; + // For inout/keep bits only, the output bit + // should be driven by logic, not the PI, + // so temporarily swap that out if (input_bits.count(bit)) { auto it = aig_map.find(bit); int input_aig = it->second; -- cgit v1.2.3 From 2c65e1abacc4401c4fd3e9b48f52c4de120bc511 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 21:45:27 -0800 Subject: abc9: break SCC by setting (* keep *) on output wires --- backends/aiger/xaiger.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index ed0e48e01..8651f3a01 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -436,15 +436,22 @@ struct XAigerWriter for (const auto &bit : output_bits) { ordered_outputs[bit] = aig_o++; int aig; - // For inout/keep bits only, the output bit - // should be driven by logic, not the PI, - // so temporarily swap that out + // Unlike bit2aig() which checks aig_map first, for + // inout/keep bits, since aig_map will point to + // the PI, first attempt to find the NOT/AND driver + // before resorting to an aig_map lookup (which + // could be another PO) if (input_bits.count(bit)) { - auto it = aig_map.find(bit); - int input_aig = it->second; - aig_map.erase(it); - aig = bit2aig(bit); - aig_map.at(bit) = input_aig; + if (not_map.count(bit)) { + aig = bit2aig(not_map.at(bit)) ^ 1; + } else if (and_map.count(bit)) { + auto args = and_map.at(bit); + int a0 = bit2aig(args.first); + int a1 = bit2aig(args.second); + aig = mkgate(a0, a1); + } + else + aig = aig_map.at(bit); } else aig = bit2aig(bit); -- cgit v1.2.3 From eb7dd7d3741983fafe62b13c4a2d6a21ced06133 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Jan 2020 23:23:21 -0800 Subject: write_xaiger: fix case of PI and CI and (* keep *) --- backends/aiger/xaiger.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8651f3a01..822ba4dec 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -356,6 +356,11 @@ struct XAigerWriter alias_map[O] = b; ci_bits.emplace_back(b); undriven_bits.erase(O); + // If PI and CI, then must be a (* keep *) wire + if (input_bits.erase(O)) { + log_assert(output_bits.count(O)); + log_assert(O.wire->get_bool_attribute(ID::keep)); + } } } -- cgit v1.2.3 From 468386d67d902722562e9a0412a76fca79ec4fa2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 12:25:45 -0800 Subject: abc9_ops: -prep_holes -> -prep_xaiger, move padding to write_xaiger --- backends/aiger/xaiger.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 822ba4dec..2d908e33b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -329,12 +329,11 @@ struct XAigerWriter } } - // Fully pad all unused input connections of this box cell with S0 - // Fully pad all undriven output connections of this box cell with anonymous wires for (auto port_name : r.first->second) { auto w = box_module->wire(port_name); log_assert(w); - auto rhs = cell->getPort(port_name); + auto rhs = cell->connections_.at(port_name, SigSpec()); + rhs.append(Const(State::Sx, GetSize(w)-GetSize(rhs))); if (w->port_input) for (auto b : rhs) { SigBit I = sigmap(b); @@ -429,6 +428,10 @@ struct XAigerWriter for (auto &bit : ci_bits) { aig_m++, aig_i++; + // 1'bx may exist here due to a box output + // that has been padded to its full width + if (bit == State::Sx) + continue; log_assert(!aig_map.count(bit)); aig_map[bit] = 2*aig_m; } -- cgit v1.2.3 From 654247abe9078566f93960a135ce08b0cfc96442 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 12:40:36 -0800 Subject: abc9_ops/write_xaiger: update doc --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 2d908e33b..f9890a592 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -740,7 +740,8 @@ struct XAigerBackend : public Backend { log("Write the top module (according to the (* top *) attribute or if only one module\n"); log("is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_ABC9_FF_, or"); log("non (* abc9_box_id *) cells will be converted into psuedo-inputs and\n"); - log("pseudo-outputs.\n"); + log("pseudo-outputs. Whitebox contents will be taken from the '$holes'\n"); + log("module, if it exists.\n"); log("\n"); log(" -ascii\n"); log(" write ASCII version of AIGER format\n"); -- cgit v1.2.3 From 4656f202c6f05d126c1acc79fca675e467c80840 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 14:27:29 -0800 Subject: abc9_ops: -reintegrate to not trim box padding anymore --- backends/aiger/xaiger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f9890a592..4f466d568 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -349,7 +349,7 @@ struct XAigerWriter unused_bits.erase(I); } if (w->port_output) - for (const auto &b : rhs.bits()) { + for (const auto &b : rhs) { SigBit O = sigmap(b); if (O != b) alias_map[O] = b; -- cgit v1.2.3 From 1c41dc6b95c4c0261db96c15dd1b3cce8de6491f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Jan 2020 16:17:27 -0800 Subject: write_xaiger: do not export flop inputs as POs --- backends/aiger/xaiger.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 4f466d568..c3fc61e3b 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -226,6 +226,7 @@ struct XAigerWriter } if (inst_module) { + bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); auto it = cell->attributes.find("\\abc9_box_seq"); if (it != cell->attributes.end()) { int abc9_box_seq = it->second.as_int(); @@ -233,7 +234,7 @@ struct XAigerWriter box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; // Only flop boxes may have arrival times - if (!inst_module->get_bool_attribute("\\abc9_flop")) + if (!abc9_flop) continue; } @@ -256,6 +257,9 @@ struct XAigerWriter for (auto bit : sigmap(conn.second)) arrival_times[bit] = arrival; } + + if (abc9_flop) + continue; } } @@ -591,7 +595,7 @@ struct XAigerWriter // For flops only, create an extra 1-bit input that drives a new wire // called ".abc9_ff.Q" that is used below if (box_module->get_bool_attribute("\\abc9_flop")) - box_inputs++; + box_inputs++; std::get<0>(v) = box_inputs; std::get<1>(v) = box_outputs; -- cgit v1.2.3 From d6da9c0c0f3b59706f509b7fd96ea793491a2307 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 15 Jan 2020 11:25:20 -0800 Subject: write_xaiger: skip abc9_flop only if abc_box_seq present --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c3fc61e3b..a9b75ecc7 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -226,7 +226,7 @@ struct XAigerWriter } if (inst_module) { - bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); + bool abc9_flop = false; auto it = cell->attributes.find("\\abc9_box_seq"); if (it != cell->attributes.end()) { int abc9_box_seq = it->second.as_int(); @@ -234,6 +234,7 @@ struct XAigerWriter box_list.resize(abc9_box_seq+1); box_list[abc9_box_seq] = cell; // Only flop boxes may have arrival times + abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); if (!abc9_flop) continue; } -- cgit v1.2.3 From cd8f55a91100b8dcf8b4775803cbacf70f5a998c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Jan 2020 09:43:04 -0800 Subject: write_xaiger: fix for (* keep *) on flop output --- backends/aiger/xaiger.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index a9b75ecc7..b72dd6890 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -222,6 +222,8 @@ struct XAigerWriter alias_map[Q] = D; auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); log_assert(r.second); + if (input_bits.erase(Q)) + log_assert(Q.wire->attributes.count(ID::keep)); continue; } @@ -568,9 +570,6 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty() || !ff_bits.empty()) { - RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); - log_assert(holes_module); - dict> cell_cache; int box_count = 0; @@ -653,6 +652,7 @@ struct XAigerWriter f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str())); if (holes_module) { std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); -- cgit v1.2.3