aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2020-01-06 09:44:00 -0800
committerEddie Hung <eddie@fpgeh.com>2020-01-06 09:44:00 -0800
commit020606f81c39df234d7a3f5e3e605e5f27422d87 (patch)
tree8334168ea6ad76983226fa3bbc631ff151d4fedd
parent36d79c80d05f93cd4cb565fe7a92d7cb88683852 (diff)
parentb5f60e055d07579a2d4f23fc053ca030f103f377 (diff)
downloadyosys-020606f81c39df234d7a3f5e3e605e5f27422d87.tar.gz
yosys-020606f81c39df234d7a3f5e3e605e5f27422d87.tar.bz2
yosys-020606f81c39df234d7a3f5e3e605e5f27422d87.zip
Merge remote-tracking branch 'origin/eddie/abc9_refactor' into xaig_arrival_required
-rw-r--r--CHANGELOG2
-rw-r--r--README.md3
-rw-r--r--backends/aiger/xaiger.cc636
-rw-r--r--frontends/aiger/aigerparse.cc358
-rw-r--r--frontends/aiger/aigerparse.h2
-rw-r--r--kernel/rtlil.cc29
-rw-r--r--passes/cmds/scc.cc6
-rw-r--r--passes/techmap/Makefile.inc2
-rw-r--r--passes/techmap/abc.cc28
-rw-r--r--passes/techmap/abc9.cc1235
-rw-r--r--passes/techmap/abc9_map.cc881
-rw-r--r--passes/techmap/abc9_ops.cc449
-rw-r--r--passes/techmap/iopadmap.cc3
-rwxr-xr-xtechlibs/achronix/synth_achronix.cc6
-rw-r--r--techlibs/anlogic/Makefile.inc6
-rw-r--r--techlibs/anlogic/cells_map.v16
-rw-r--r--techlibs/anlogic/lutram_init_16x4.vh (renamed from techlibs/anlogic/dram_init_16x4.vh)0
-rw-r--r--techlibs/anlogic/lutrams.txt (renamed from techlibs/anlogic/drams.txt)0
-rw-r--r--techlibs/anlogic/lutrams_map.v (renamed from techlibs/anlogic/drams_map.v)2
-rw-r--r--techlibs/anlogic/synth_anlogic.cc28
-rw-r--r--techlibs/coolrunner2/synth_coolrunner2.cc4
-rw-r--r--techlibs/easic/synth_easic.cc4
-rw-r--r--techlibs/ecp5/Makefile.inc4
-rw-r--r--techlibs/ecp5/abc9_5g.box41
-rw-r--r--techlibs/ecp5/abc9_map.v19
-rw-r--r--techlibs/ecp5/abc9_model.v2
-rw-r--r--techlibs/ecp5/abc9_unmap.v4
-rw-r--r--techlibs/ecp5/brams.txt (renamed from techlibs/ecp5/bram.txt)0
-rw-r--r--techlibs/ecp5/cells_sim.v12
-rw-r--r--techlibs/ecp5/lutrams.txt (renamed from techlibs/ecp5/lutram.txt)0
-rw-r--r--techlibs/ecp5/synth_ecp5.cc10
-rw-r--r--techlibs/efinix/Makefile.inc2
-rw-r--r--techlibs/efinix/brams.txt (renamed from techlibs/efinix/bram.txt)0
-rw-r--r--techlibs/efinix/synth_efinix.cc26
-rw-r--r--techlibs/gowin/Makefile.inc6
-rw-r--r--techlibs/gowin/brams.txt (renamed from techlibs/gowin/bram.txt)0
-rw-r--r--techlibs/gowin/lutrams.txt (renamed from techlibs/gowin/dram.txt)0
-rw-r--r--techlibs/gowin/lutrams_map.v (renamed from techlibs/gowin/drams_map.v)0
-rw-r--r--techlibs/gowin/synth_gowin.cc53
-rw-r--r--techlibs/greenpak4/synth_greenpak4.cc4
-rw-r--r--techlibs/ice40/abc9_hx.box24
-rw-r--r--techlibs/ice40/abc9_lp.box24
-rw-r--r--techlibs/ice40/abc9_u.box25
-rw-r--r--techlibs/ice40/synth_ice40.cc4
-rw-r--r--techlibs/intel/synth_intel.cc14
-rw-r--r--techlibs/sf2/synth_sf2.cc4
-rw-r--r--techlibs/xilinx/abc9_map.v478
-rw-r--r--techlibs/xilinx/abc9_model.v19
-rw-r--r--techlibs/xilinx/abc9_unmap.v9
-rw-r--r--techlibs/xilinx/abc9_xc7.box799
-rw-r--r--techlibs/xilinx/cells_sim.v127
-rw-r--r--techlibs/xilinx/synth_xilinx.cc69
-rw-r--r--tests/arch/anlogic/counter.ys2
-rw-r--r--tests/arch/ecp5/bug1598.ys16
-rw-r--r--tests/arch/ecp5/counter.ys2
-rw-r--r--tests/arch/ecp5/macc.ys4
-rw-r--r--tests/arch/ecp5/mul.ys4
-rw-r--r--tests/arch/ecp5/mux.ys6
-rw-r--r--tests/arch/efinix/counter.ys2
-rw-r--r--tests/arch/gowin/counter.ys2
-rw-r--r--tests/arch/ice40/bug1598.ys16
-rw-r--r--tests/arch/ice40/counter.ys2
-rw-r--r--tests/arch/ice40/mul.ys2
-rw-r--r--tests/arch/ice40/rom.v3
-rw-r--r--tests/arch/xilinx/abc9_dff.ys32
-rw-r--r--tests/arch/xilinx/abc9_map.ys91
-rw-r--r--tests/arch/xilinx/add_sub.ys2
-rw-r--r--tests/arch/xilinx/adffs.ys8
-rw-r--r--tests/arch/xilinx/attributes_test.ys12
-rw-r--r--tests/arch/xilinx/blockram.ys24
-rw-r--r--tests/arch/xilinx/bug1460.ys2
-rw-r--r--tests/arch/xilinx/bug1598.ys16
-rw-r--r--tests/arch/xilinx/bug1605.ys19
-rw-r--r--tests/arch/xilinx/counter.ys2
-rw-r--r--tests/arch/xilinx/dffs.ys4
-rw-r--r--tests/arch/xilinx/dsp_cascade.ys8
-rw-r--r--tests/arch/xilinx/dsp_fastfir.ys2
-rw-r--r--tests/arch/xilinx/fsm.ys2
-rw-r--r--tests/arch/xilinx/latches.ys6
-rw-r--r--tests/arch/xilinx/logic.ys2
-rw-r--r--tests/arch/xilinx/lutram.ys14
-rw-r--r--tests/arch/xilinx/macc.ys8
-rw-r--r--tests/arch/xilinx/mul.ys4
-rw-r--r--tests/arch/xilinx/mul_unsigned.ys4
-rw-r--r--tests/arch/xilinx/mux.ys8
-rw-r--r--tests/arch/xilinx/shifter.ys2
-rw-r--r--tests/arch/xilinx/tribuf.ys7
-rw-r--r--tests/simple_abc9/abc9.v27
-rwxr-xr-xtests/simple_abc9/run-test.sh6
-rw-r--r--tests/various/abc9.v7
-rw-r--r--tests/various/abc9.ys16
91 files changed, 3416 insertions, 2459 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 01ae17c2b..481ba266e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -57,6 +57,8 @@ Yosys 0.9 .. Yosys 0.9-dev
always_latch and always_ff)
- Added "xilinx_dffopt" pass
- Added "scratchpad" pass
+ - Added "abc9 -dff"
+ - Added "synth_xilinx -dff"
Yosys 0.8 .. Yosys 0.9
----------------------
diff --git a/README.md b/README.md
index 0250c7846..aab1c7d6b 100644
--- a/README.md
+++ b/README.md
@@ -378,6 +378,9 @@ Verilog Attributes and non-standard features
for example, to specify the clk-to-Q delay of a flip-flop for consideration
during techmapping.
+- The module attribute ``abc9_flop`` is a boolean marking the module as a
+ whitebox that describes the synchronous behaviour of a flip-flop.
+
- The frontend sets attributes ``always_comb``, ``always_latch`` and
``always_ff`` on processes derived from SystemVerilog style always blocks
according to the type of the always. These are checked for correctness in
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index db38f2017..5aea70f3b 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -82,6 +82,7 @@ struct XAigerWriter
dict<SigBit, SigBit> not_map, alias_map;
dict<SigBit, pair<SigBit, SigBit>> and_map;
vector<SigBit> ci_bits, co_bits;
+ dict<SigBit, Cell*> ff_bits;
dict<SigBit, float> arrival_times;
vector<pair<int, int>> aig_gates;
@@ -92,7 +93,7 @@ struct XAigerWriter
dict<SigBit, int> ordered_outputs;
vector<Cell*> box_list;
- bool omode = false;
+ dict<IdString, std::vector<IdString>> box_ports;
int mkgate(int a0, int a1)
{
@@ -136,11 +137,10 @@ struct XAigerWriter
return a;
}
- XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module)
+ XAigerWriter(Module *module) : module(module), sigmap(module)
{
pool<SigBit> undriven_bits;
pool<SigBit> unused_bits;
- pool<SigBit> keep_bits;
// promote public wires
for (auto wire : module->wires())
@@ -152,55 +152,54 @@ struct XAigerWriter
if (wire->port_input)
sigmap.add(wire);
+ // promote keep wires
for (auto wire : module->wires())
- {
- bool keep = wire->attributes.count("\\keep");
+ if (wire->get_bool_attribute(ID::keep))
+ sigmap.add(wire);
+ // First, collect all the ports in port_id order
+ // since module->wires() could be sorted
+ // alphabetically
+ for (auto port : module->ports) {
+ auto wire = module->wire(port);
+ log_assert(wire);
for (int i = 0; i < GetSize(wire); i++)
{
SigBit wirebit(wire, i);
SigBit bit = sigmap(wirebit);
- if (bit.wire) {
- undriven_bits.insert(bit);
- unused_bits.insert(bit);
+ if (bit.wire == nullptr) {
+ if (wire->port_output) {
+ aig_map[wirebit] = (bit == State::S1) ? 1 : 0;
+ output_bits.insert(wirebit);
+ }
+ continue;
}
- if (keep)
- keep_bits.insert(wirebit);
+ if (wire->port_input)
+ input_bits.insert(bit);
- if (wire->port_input || keep) {
+ if (wire->port_output) {
if (bit != wirebit)
- alias_map[bit] = wirebit;
- input_bits.insert(wirebit);
- }
-
- if (wire->port_output || keep) {
- if (bit != RTLIL::Sx) {
- if (bit != wirebit)
- alias_map[wirebit] = bit;
- output_bits.insert(wirebit);
- }
- else
- log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit));
+ alias_map[wirebit] = bit;
+ output_bits.insert(wirebit);
}
}
}
- for (auto bit : input_bits)
- undriven_bits.erase(sigmap(bit));
- for (auto bit : output_bits)
- if (!bit.wire->port_input)
- unused_bits.erase(bit);
+ for (auto wire : module->wires())
+ for (int i = 0; i < GetSize(wire); i++)
+ {
+ SigBit wirebit(wire, i);
+ SigBit bit = sigmap(wirebit);
- // TODO: Speed up toposort -- ultimately we care about
- // box ordering, but not individual AIG cells
- dict<SigBit, pool<IdString>> bit_drivers, bit_users;
- TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
- bool abc9_box_seen = false;
- std::vector<int> arrivals;
+ if (bit.wire) {
+ undriven_bits.insert(bit);
+ unused_bits.insert(bit);
+ }
+ }
- for (auto cell : module->selected_cells()) {
+ for (auto cell : module->cells()) {
if (cell->type == "$_NOT_")
{
SigBit A = sigmap(cell->getPort("\\A").as_bit());
@@ -208,11 +207,6 @@ 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);
- }
continue;
}
@@ -225,277 +219,215 @@ 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);
- }
continue;
}
- log_assert(!holes_mode);
+ 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;
+ }
RTLIL::Module* inst_module = module->design->module(cell->type);
- if (inst_module && inst_module->attributes.count("\\abc9_box_id")) {
- abc9_box_seen = true;
-
- 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 (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;
+ if (!inst_module->get_bool_attribute("\\abc9_flop"))
+ continue;
+ }
- if (port_wire->port_output)
+ 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();
+ }
+ if (arrival)
for (auto bit : sigmap(conn.second))
- bit_drivers[bit].insert(cell->name);
+ arrival_times[bit] = arrival;
}
}
}
- else {
- 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 = (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));
-
- if (is_input) {
- for (auto b : c.second) {
- Wire *w = b.wire;
- if (!w) continue;
- if (!w->port_output || !cell_known) {
- SigBit I = sigmap(b);
- if (I != b)
- alias_map[b] = I;
- output_bits.insert(b);
- unused_bits.erase(b);
-
- if (!cell_known)
- keep_bits.insert(b);
- }
- }
- }
- if (is_output) {
- arrivals.clear();
- if (port_wire) {
- auto it = port_wire->attributes.find("\\abc9_arrival");
- if (it != port_wire->attributes.end()) {
- if (it->second.flags == 0)
- arrivals.push_back(it->second.as_int());
- else
- for (const auto &tok : split_tokens(it->second.decode_string()))
- arrivals.push_back(atoi(tok.c_str()));
- }
- }
- log_assert(GetSize(arrivals) <= 1 || GetSize(arrivals) == GetSize(c.second));
- auto it = arrivals.begin();
- for (auto b : c.second) {
- Wire *w = b.wire;
- if (!w) continue;
- input_bits.insert(b);
- SigBit O = sigmap(b);
- if (O != b)
- alias_map[O] = b;
- undriven_bits.erase(O);
-
- if (!arrivals.empty()) {
- if (arrivals.size() == 1)
- arrival_times[b] = *it;
- else
- arrival_times[b] = *it++;
- }
+ 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 = (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));
+
+ if (is_input)
+ for (auto b : c.second) {
+ Wire *w = b.wire;
+ if (!w) continue;
+ if (!w->port_output || !cell_known) {
+ SigBit I = sigmap(b);
+ if (I != b)
+ alias_map[b] = I;
+ output_bits.insert(b);
}
}
- }
}
//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;
+ for (auto cell : box_list) {
+ log_assert(cell);
- bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */);
+ 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
- // NB: Assume box_module->ports are sorted alphabetically
- // (as RTLIL::Module::fixup_ports() would do)
+ 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) {
- RTLIL::Wire* w = box_module->wire(port_name);
+ 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.bits()) {
- 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(b);
+ 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()) {
- ci_bits.emplace_back(b);
- SigBit O = sigmap(b);
- if (O != b)
- alias_map[O] = b;
- undriven_bits.erase(O);
- input_bits.erase(b);
- }
- }
+ 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);
}
- box_list.emplace_back(cell);
}
- // TODO: Free memory from toposort, bit_drivers, bit_users
- }
-
- for (auto bit : input_bits) {
- if (!output_bits.count(bit))
- continue;
- RTLIL::Wire *wire = bit.wire;
- // If encountering an inout port, or a keep-ed wire, then create a new wire
- // with $inout.out suffix, make it a PO driven by the existing inout, and
- // inherit existing inout's drivers
- if ((wire->port_input && wire->port_output && !undriven_bits.count(bit))
- || keep_bits.count(bit)) {
- RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str());
- RTLIL::Wire *new_wire = module->wire(wire_name);
- if (!new_wire)
- new_wire = module->addWire(wire_name, GetSize(wire));
- SigBit new_bit(new_wire, bit.offset);
- module->connect(new_bit, bit);
- if (not_map.count(bit)) {
- auto a = not_map.at(bit);
- not_map[new_bit] = a;
+ 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)));
+ 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);
+ }
}
- else if (and_map.count(bit)) {
- auto a = and_map.at(bit);
- and_map[new_bit] = a;
+ 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);
+ }
}
- else if (alias_map.count(bit)) {
- auto a = alias_map.at(bit);
- alias_map[new_bit] = a;
+ }
+
+ // Connect <cell>.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);
}
- else
- alias_map[new_bit] = bit;
- output_bits.erase(bit);
- output_bits.insert(new_bit);
}
}
+ for (auto bit : input_bits)
+ undriven_bits.erase(bit);
+ for (auto bit : output_bits)
+ unused_bits.erase(sigmap(bit));
for (auto bit : unused_bits)
undriven_bits.erase(bit);
- if (!undriven_bits.empty() && !holes_mode) {
- undriven_bits.sort();
- 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);
- }
- log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module));
- }
-
- 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();
+ // Make all undriven bits a primary input
+ for (auto bit : undriven_bits) {
+ input_bits.insert(bit);
+ undriven_bits.erase(bit);
}
- not_map.sort();
- and_map.sort();
-
aig_map[State::S0] = 0;
aig_map[State::S1] = 1;
- for (auto bit : input_bits) {
+ // pool<> iterates in LIFO order...
+ for (int i = input_bits.size()-1; i >= 0; i--) {
+ const auto &bit = *input_bits.element(i);
aig_m++, aig_i++;
log_assert(!aig_map.count(bit));
aig_map[bit] = 2*aig_m;
}
- for (auto bit : ci_bits) {
+ for (const auto &i : ff_bits) {
+ const Cell *cell = i.second;
+ const SigBit &q = sigmap(cell->getPort("\\Q"));
aig_m++, aig_i++;
- aig_map[bit] = 2*aig_m;
+ log_assert(!aig_map.count(q));
+ aig_map[q] = 2*aig_m;
+ }
+
+ 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;
+ }
}
for (auto bit : co_bits) {
@@ -503,15 +435,18 @@ struct XAigerWriter
aig_outputs.push_back(bit2aig(bit));
}
- if (output_bits.empty()) {
- output_bits.insert(State::S0);
- omode = true;
- }
-
- for (auto bit : output_bits) {
+ // pool<> iterates in LIFO order...
+ for (int i = output_bits.size()-1; i >= 0; i--) {
+ const auto &bit = *output_bits.element(i);
ordered_outputs[bit] = aig_o++;
aig_outputs.push_back(bit2aig(bit));
}
+
+ for (auto &i : ff_bits) {
+ const SigBit &d = i.first;
+ aig_o++;
+ aig_outputs.push_back(aig_map.at(d));
+ }
}
void write_aiger(std::ostream &f, bool ascii_mode)
@@ -573,7 +508,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<const char*>(&i32_be), sizeof(i32_be));
@@ -581,14 +515,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(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("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());
@@ -604,75 +538,34 @@ struct XAigerWriter
//for (auto bit : output_bits)
// write_o_buffer(0);
- if (!box_list.empty()) {
- RTLIL::Module *holes_module = module->design->addModule("$__holes__");
+ 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<IdString, Cell*> cell_cache;
- int port_id = 1;
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);
- IdString derived_name = box_module->derive(module->design, cell->parameters);
- box_module = module->design->module(derived_name);
- if (box_module->has_processes())
- log_error("ABC9 box '%s' contains processes!\n", box_module->name.c_str());
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 && !holes_cell && 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;
- }
-
- // NB: Assume box_module->ports are sorted alphabetically
- // (as RTLIL::Module::fixup_ports() would do)
- for (const auto &port_name : box_module->ports) {
+ 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("%s.%s", cell->name.c_str(), log_id(w->name)));
- else
- holes_wire = holes_module->addWire(stringf("%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 "<cell>.abc9_ff.Q" that is used below
+ if (box_module->get_bool_attribute("\\abc9_flop"))
+ box_inputs++;
+
write_h_buffer(box_inputs);
write_h_buffer(box_outputs);
write_h_buffer(box_module->attributes.at("\\abc9_box_id").as_int());
@@ -681,57 +574,58 @@ struct XAigerWriter
std::stringstream r_buffer;
auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1);
- write_r_buffer(0);
+ log_debug("flopNum = %d\n", GetSize(ff_bits));
+ write_r_buffer(ff_bits.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 (const auto &i : ff_bits) {
+ const SigBit &d = i.first;
+ const Cell *cell = i.second;
+
+ int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
+ log_assert(mergeability > 0);
+ write_r_buffer(mergeability);
+
+ Const init = cell->attributes.at(ID(abc9_init));
+ log_assert(GetSize(init) == 1);
+ if (init == State::S1)
+ write_s_buffer(1);
+ else if (init == State::S0)
+ write_s_buffer(0);
+ else {
+ log_assert(init == State::Sx);
+ write_s_buffer(0);
+ }
+
+ write_i_buffer(arrival_times.at(d, 0));
+ //write_o_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<const char*>(&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);
-
- Pass::call(holes_module->design, "flatten -wb");
-
- // 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(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");
+ f << "s";
+ buffer_str = s_buffer.str();
+ buffer_size_be = to_big_endian(buffer_str.size());
+ f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
+ f.write(buffer_str.data(), buffer_str.size());
+ if (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*/);
- 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<const char*>(&buffer_size_be), sizeof(buffer_size_be));
f.write(buffer_str.data(), buffer_str.size());
-
- log_pop();
}
}
@@ -753,6 +647,11 @@ struct XAigerWriter
//f.write(buffer_str.data(), buffer_str.size());
f << stringf("Generated by %s\n", yosys_version_str);
+
+ module->design->scratchpad_set_int("write_xaiger.num_ands", and_map.size());
+ module->design->scratchpad_set_int("write_xaiger.num_wires", aig_map.size());
+ module->design->scratchpad_set_int("write_xaiger.num_inputs", input_bits.size());
+ module->design->scratchpad_set_int("write_xaiger.num_outputs", output_bits.size());
}
void write_map(std::ostream &f, bool verbose_map)
@@ -779,7 +678,8 @@ struct XAigerWriter
if (output_bits.count(b)) {
int o = ordered_outputs.at(b);
- output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), i, log_id(wire));
+ int init = 2;
+ output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init);
continue;
}
@@ -803,8 +703,6 @@ 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());
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index cf060193d..f030933ec 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -255,7 +255,7 @@ end_of_header:
else
log_abort();
- RTLIL::Wire* n0 = module->wire("\\__0__");
+ RTLIL::Wire* n0 = module->wire("$0");
if (n0)
module->connect(n0, State::S0);
@@ -316,14 +316,14 @@ static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned litera
{
const unsigned variable = literal >> 1;
const bool invert = literal & 1;
- RTLIL::IdString wire_name(stringf("\\__%d%s__", variable, invert ? "b" : ""));
+ RTLIL::IdString wire_name(stringf("$%d%s", variable, invert ? "b" : ""));
RTLIL::Wire *wire = module->wire(wire_name);
if (wire) return wire;
log_debug2("Creating %s\n", wire_name.c_str());
wire = module->addWire(wire_name);
wire->port_input = wire->port_output = false;
if (!invert) return wire;
- RTLIL::IdString wire_inv_name(stringf("\\__%d__", variable));
+ RTLIL::IdString wire_inv_name(stringf("$%d", variable));
RTLIL::Wire *wire_inv = module->wire(wire_inv_name);
if (wire_inv) {
if (module->cell(wire_inv_name)) return wire;
@@ -335,12 +335,12 @@ static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned litera
}
log_debug2("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
- module->addNotGate(stringf("\\__%d__$not", variable), wire_inv, wire);
+ module->addNotGate(stringf("$%d$not", variable), wire_inv, wire);
return wire;
}
-void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
+void AigerReader::parse_xaiger()
{
std::string header;
f >> header;
@@ -372,108 +372,117 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
else
log_abort();
- RTLIL::Wire* n0 = module->wire("\\__0__");
+ RTLIL::Wire* n0 = module->wire("$0");
if (n0)
module->connect(n0, State::S0);
+ int c = f.get();
+ if (c != 'c')
+ log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c);
+ if (f.peek() == '\n')
+ f.get();
+
+ dict<int,IdString> box_lookup;
+ for (auto m : design->modules()) {
+ auto it = m->attributes.find(ID(abc9_box_id));
+ if (it == m->attributes.end())
+ continue;
+ if (m->name.begins_with("$paramod"))
+ continue;
+ auto id = it->second.as_int();
+ auto r = box_lookup.insert(std::make_pair(id, m->name));
+ if (!r.second)
+ log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
+ log_id(m), id, log_id(r.first->second));
+ log_assert(r.second);
+ }
+
// Parse footer (symbol table, comments, etc.)
std::string s;
- bool comment_seen = false;
- for (int c = f.peek(); c != EOF; c = f.peek()) {
- if (comment_seen || c == 'c') {
- if (!comment_seen) {
- f.ignore(1);
- c = f.peek();
- comment_seen = true;
- }
- if (c == '\n')
- break;
- f.ignore(1);
- // XAIGER extensions
- if (c == 'm') {
- uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
- uint32_t lutNum = parse_xaiger_literal(f);
- uint32_t lutSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
- log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize);
- ConstEvalAig ce(module);
- for (unsigned i = 0; i < lutNum; ++i) {
- uint32_t rootNodeID = parse_xaiger_literal(f);
- uint32_t cutLeavesM = parse_xaiger_literal(f);
- log_debug2("rootNodeID=%d cutLeavesM=%d\n", rootNodeID, cutLeavesM);
- RTLIL::Wire *output_sig = module->wire(stringf("\\__%d__", rootNodeID));
- uint32_t nodeID;
- RTLIL::SigSpec input_sig;
- for (unsigned j = 0; j < cutLeavesM; ++j) {
- nodeID = parse_xaiger_literal(f);
- log_debug2("\t%u\n", nodeID);
- RTLIL::Wire *wire = module->wire(stringf("\\__%d__", nodeID));
- log_assert(wire);
- input_sig.append(wire);
- }
- // TODO: Compute LUT mask from AIG in less than O(2 ** input_sig.size())
- ce.clear();
- ce.compute_deps(output_sig, input_sig.to_sigbit_pool());
- RTLIL::Const lut_mask(RTLIL::State::Sx, 1 << input_sig.size());
- for (int j = 0; j < (1 << cutLeavesM); ++j) {
- int gray = j ^ (j >> 1);
- ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)});
- RTLIL::SigBit o(output_sig);
- bool success YS_ATTRIBUTE(unused) = ce.eval(o);
- log_assert(success);
- log_assert(o.wire == nullptr);
- lut_mask[gray] = o.data;
- }
- RTLIL::Cell *output_cell = module->cell(stringf("\\__%d__$and", rootNodeID));
- log_assert(output_cell);
- module->remove(output_cell);
- module->addLut(stringf("\\__%d__$lut", rootNodeID), input_sig, output_sig, std::move(lut_mask));
+ for (int c = f.get(); c != EOF; c = f.get()) {
+ // XAIGER extensions
+ if (c == 'm') {
+ uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
+ uint32_t lutNum = parse_xaiger_literal(f);
+ uint32_t lutSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
+ log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize);
+ ConstEvalAig ce(module);
+ for (unsigned i = 0; i < lutNum; ++i) {
+ uint32_t rootNodeID = parse_xaiger_literal(f);
+ uint32_t cutLeavesM = parse_xaiger_literal(f);
+ log_debug2("rootNodeID=%d cutLeavesM=%d\n", rootNodeID, cutLeavesM);
+ RTLIL::Wire *output_sig = module->wire(stringf("$%d", rootNodeID));
+ uint32_t nodeID;
+ RTLIL::SigSpec input_sig;
+ for (unsigned j = 0; j < cutLeavesM; ++j) {
+ nodeID = parse_xaiger_literal(f);
+ log_debug2("\t%u\n", nodeID);
+ RTLIL::Wire *wire = module->wire(stringf("$%d", nodeID));
+ log_assert(wire);
+ input_sig.append(wire);
}
- }
- else if (c == 'r') {
- uint32_t dataSize YS_ATTRIBUTE(unused) = 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));
- }
- else if (c == 'n') {
- parse_xaiger_literal(f);
- f >> s;
- log_debug("n: '%s'\n", s.c_str());
- }
- else if (c == 'h') {
- f.ignore(sizeof(uint32_t));
- uint32_t version YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
- log_assert(version == 1);
- uint32_t ciNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
- log_debug("ciNum = %u\n", ciNum);
- uint32_t coNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
- log_debug("coNum = %u\n", coNum);
- piNum = parse_xaiger_literal(f);
- log_debug("piNum = %u\n", piNum);
- uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
- log_debug("poNum = %u\n", poNum);
- uint32_t boxNum = parse_xaiger_literal(f);
- 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);
- log_assert(boxUniqueId > 0);
- uint32_t oldBoxNum = parse_xaiger_literal(f);
- RTLIL::Cell* cell = module->addCell(stringf("$__box%u__", oldBoxNum), box_lookup.at(boxUniqueId));
- boxes.emplace_back(cell);
+ // TODO: Compute LUT mask from AIG in less than O(2 ** input_sig.size())
+ ce.clear();
+ ce.compute_deps(output_sig, input_sig.to_sigbit_pool());
+ RTLIL::Const lut_mask(RTLIL::State::Sx, 1 << input_sig.size());
+ for (int j = 0; j < (1 << cutLeavesM); ++j) {
+ int gray = j ^ (j >> 1);
+ ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)});
+ RTLIL::SigBit o(output_sig);
+ bool success YS_ATTRIBUTE(unused) = ce.eval(o);
+ log_assert(success);
+ log_assert(o.wire == nullptr);
+ lut_mask[gray] = o.data;
}
+ RTLIL::Cell *output_cell = module->cell(stringf("$%d$and", rootNodeID));
+ log_assert(output_cell);
+ module->remove(output_cell);
+ module->addLut(stringf("$%d$lut", rootNodeID), input_sig, output_sig, std::move(lut_mask));
}
- else if (c == 'a' || c == 'i' || c == 'o') {
- uint32_t dataSize = parse_xaiger_literal(f);
- f.ignore(dataSize);
- }
- else {
- break;
+ }
+ else if (c == 'r') {
+ uint32_t dataSize YS_ATTRIBUTE(unused) = 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));
+ }
+ else if (c == 'n') {
+ parse_xaiger_literal(f);
+ f >> s;
+ log_debug("n: '%s'\n", s.c_str());
+ }
+ else if (c == 'h') {
+ f.ignore(sizeof(uint32_t));
+ uint32_t version YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
+ log_assert(version == 1);
+ uint32_t ciNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
+ log_debug("ciNum = %u\n", ciNum);
+ uint32_t coNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
+ log_debug("coNum = %u\n", coNum);
+ piNum = parse_xaiger_literal(f);
+ log_debug("piNum = %u\n", piNum);
+ uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
+ log_debug("poNum = %u\n", poNum);
+ uint32_t boxNum = parse_xaiger_literal(f);
+ 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);
+ log_assert(boxUniqueId > 0);
+ uint32_t oldBoxNum = parse_xaiger_literal(f);
+ RTLIL::Cell* cell = module->addCell(stringf("$box%u", oldBoxNum), box_lookup.at(boxUniqueId));
+ boxes.emplace_back(cell);
}
}
- else
- log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c);
+ else if (c == 'a' || c == 'i' || c == 'o' || c == 's') {
+ uint32_t dataSize = parse_xaiger_literal(f);
+ f.ignore(dataSize);
+ log_debug("ignoring '%c'\n", c);
+ }
+ else {
+ break;
+ }
}
post_process();
@@ -550,7 +559,7 @@ void AigerReader::parse_aiger_ascii()
log_debug2("%d is an output\n", l1);
const unsigned variable = l1 >> 1;
const bool invert = l1 & 1;
- RTLIL::IdString wire_name(stringf("\\__%d%s__", variable, invert ? "b" : "")); // FIXME: is "b" the right suffix?
+ RTLIL::IdString wire_name(stringf("$%d%s", variable, invert ? "b" : "")); // FIXME: is "b" the right suffix?
RTLIL::Wire *wire = module->wire(wire_name);
if (!wire)
wire = createWireIfNotExists(module, l1);
@@ -616,11 +625,12 @@ void AigerReader::parse_aiger_binary()
std::string line;
// Parse inputs
+ int digits = ceil(log10(I));
for (unsigned i = 1; i <= I; ++i) {
log_debug2("%d is an input\n", i);
- RTLIL::Wire *wire = createWireIfNotExists(module, i << 1);
+ RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, i));
wire->port_input = true;
- log_assert(!wire->port_output);
+ module->connect(createWireIfNotExists(module, i << 1), wire);
inputs.push_back(wire);
}
@@ -670,23 +680,15 @@ void AigerReader::parse_aiger_binary()
}
// Parse outputs
+ digits = ceil(log10(O));
for (unsigned i = 0; i < O; ++i, ++line_count) {
if (!(f >> l1))
log_error("Line %u cannot be interpreted as an output!\n", line_count);
log_debug2("%d is an output\n", l1);
- const unsigned variable = l1 >> 1;
- const bool invert = l1 & 1;
- RTLIL::IdString wire_name(stringf("\\__%d%s__", variable, invert ? "b" : "")); // FIXME: is "_b" the right suffix?
- RTLIL::Wire *wire = module->wire(wire_name);
- if (!wire)
- wire = createWireIfNotExists(module, l1);
- else if (wire->port_input || wire->port_output) {
- RTLIL::Wire *new_wire = module->addWire(NEW_ID);
- module->connect(new_wire, wire);
- wire = new_wire;
- }
+ RTLIL::Wire *wire = module->addWire(stringf("$o%0*d", digits, i));
wire->port_output = true;
+ module->connect(wire, createWireIfNotExists(module, l1));
outputs.push_back(wire);
}
std::getline(f, line); // Ignore up to start of next line
@@ -733,56 +735,37 @@ void AigerReader::parse_aiger_binary()
void AigerReader::post_process()
{
- pool<IdString> seen_boxes;
- unsigned ci_count = 0, co_count = 0;
+ dict<IdString, std::vector<IdString>> box_ports;
+ 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);
- if (seen_boxes.insert(cell->type).second) {
- auto it = box_module->attributes.find("\\abc9_carry");
- 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("'abc9_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));
- carry_in = box_module->wire(carry_in_name);
- if (!carry_in || !carry_in->port_input)
- log_error("'abc9_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));
- carry_out = box_module->wire(carry_out_name);
- if (!carry_out || !carry_out->port_output)
- log_error("'abc9_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());
-
- auto &ports = box_module->ports;
- for (auto jt = ports.begin(); jt != ports.end(); ) {
- RTLIL::Wire* w = box_module->wire(*jt);
- log_assert(w);
- if (w == carry_in || w == carry_out) {
- jt = ports.erase(jt);
- continue;
- }
- if (w->port_id > carry_in->port_id)
- --w->port_id;
- if (w->port_id > carry_out->port_id)
- --w->port_id;
- log_assert(w->port_input || w->port_output);
- log_assert(ports[w->port_id-1] == w->name);
- ++jt;
+ 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)
+ carry_in = port_name;
+ if (w->port_output)
+ carry_out = port_name;
}
- ports.push_back(carry_in->name);
- carry_in->port_id = ports.size();
- ports.push_back(carry_out->name);
- carry_out->port_id = ports.size();
+ else
+ r.first->second.push_back(port_name);
+ }
+ if (carry_in != IdString()) {
+ log_assert(carry_out != IdString());
+ r.first->second.push_back(carry_in);
+ r.first->second.push_back(carry_out);
}
}
- // NB: Assume box_module->ports are sorted alphabetically
- // (as RTLIL::Module::fixup_ports() would do)
- for (auto port_name : box_module->ports) {
+ for (auto port_name : box_ports.at(cell->type)) {
RTLIL::Wire* port = box_module->wire(port_name);
log_assert(port);
RTLIL::SigSpec rhs;
@@ -804,9 +787,32 @@ void AigerReader::post_process()
}
rhs.append(wire);
}
-
cell->setPort(port_name, rhs);
}
+
+ if (box_module->attributes.count("\\abc9_flop")) {
+ log_assert(co_count < outputs.size());
+ Wire *wire = outputs[co_count++];
+ log_assert(wire);
+ log_assert(wire->port_output);
+ wire->port_output = false;
+
+ 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;
+
+ auto ff = module->addCell(NEW_ID, "$__ABC9_FF_");
+ ff->setPort("\\D", d);
+ ff->setPort("\\Q", q);
+ flop_count++;
+ continue;
+ }
}
dict<RTLIL::IdString, int> wideports_cache;
@@ -868,16 +874,7 @@ void AigerReader::post_process()
// simply connect the latter to the former
RTLIL::Wire* existing = module->wire(escaped_s);
if (!existing) {
- if (escaped_s.ends_with("$inout.out")) {
- wire->port_output = false;
- RTLIL::Wire *in_wire = module->wire(escaped_s.substr(1, escaped_s.size()-11));
- log_assert(in_wire);
- log_assert(in_wire->port_input && !in_wire->port_output);
- in_wire->port_output = true;
- module->connect(in_wire, wire);
- }
- else
- module->rename(wire, escaped_s);
+ module->rename(wire, escaped_s);
}
else {
wire->port_output = false;
@@ -889,19 +886,9 @@ void AigerReader::post_process()
std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index);
RTLIL::Wire* existing = module->wire(indexed_name);
if (!existing) {
- if (escaped_s.ends_with("$inout.out")) {
- wire->port_output = false;
- RTLIL::Wire *in_wire = module->wire(stringf("%s[%d]", escaped_s.substr(1, escaped_s.size()-11).c_str(), index));
- log_assert(in_wire);
- log_assert(in_wire->port_input && !in_wire->port_output);
- in_wire->port_output = true;
- module->connect(in_wire, wire);
- }
- else {
- module->rename(wire, indexed_name);
- if (wideports)
- wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index);
- }
+ module->rename(wire, indexed_name);
+ if (wideports)
+ wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index);
}
else {
module->connect(wire, existing);
@@ -909,9 +896,13 @@ 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));
+ RTLIL::Cell* cell = module->cell(stringf("$box%d", variable));
if (cell) { // ABC could have optimised this box away
module->rename(cell, escaped_s);
for (const auto &i : cell->connections()) {
@@ -968,15 +959,10 @@ void AigerReader::post_process()
if (other_wire) {
other_wire->port_input = false;
other_wire->port_output = false;
- }
- if (wire->port_input) {
- if (other_wire)
+ if (wire->port_input)
module->connect(other_wire, SigSpec(wire, i));
- }
- else {
- // Since we skip POs that are connected to Sx,
- // re-connect them here
- module->connect(SigSpec(wire, i), other_wire ? other_wire : SigSpec(RTLIL::Sx));
+ else
+ module->connect(SigSpec(wire, i), other_wire);
}
}
}
diff --git a/frontends/aiger/aigerparse.h b/frontends/aiger/aigerparse.h
index 583c9d0f9..de3c3efbc 100644
--- a/frontends/aiger/aigerparse.h
+++ b/frontends/aiger/aigerparse.h
@@ -47,7 +47,7 @@ struct AigerReader
AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports);
void parse_aiger();
- void parse_xaiger(const dict<int,IdString> &box_lookup);
+ void parse_xaiger();
void parse_aiger_ascii();
void parse_aiger_binary();
void post_process();
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 7c73f94c8..ab4f4f377 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1893,10 +1893,6 @@ DEF_METHOD(And, max(sig_a.size(), sig_b.size()), ID($and))
DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), ID($or))
DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), ID($xor))
DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), ID($xnor))
-DEF_METHOD(Shl, sig_a.size(), ID($shl))
-DEF_METHOD(Shr, sig_a.size(), ID($shr))
-DEF_METHOD(Sshl, sig_a.size(), ID($sshl))
-DEF_METHOD(Sshr, sig_a.size(), ID($sshr))
DEF_METHOD(Shift, sig_a.size(), ID($shift))
DEF_METHOD(Shiftx, sig_a.size(), ID($shiftx))
DEF_METHOD(Lt, 1, ID($lt))
@@ -1916,6 +1912,31 @@ DEF_METHOD(LogicAnd, 1, ID($logic_and))
DEF_METHOD(LogicOr, 1, ID($logic_or))
#undef DEF_METHOD
+#define DEF_METHOD(_func, _y_size, _type) \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
+ RTLIL::Cell *cell = addCell(name, _type); \
+ cell->parameters[ID(A_SIGNED)] = is_signed; \
+ cell->parameters[ID(B_SIGNED)] = false; \
+ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
+ cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
+ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->setPort(ID::A, sig_a); \
+ cell->setPort(ID::B, sig_b); \
+ cell->setPort(ID::Y, sig_y); \
+ cell->set_src_attribute(src); \
+ return cell; \
+ } \
+ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \
+ RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
+ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
+ return sig_y; \
+ }
+DEF_METHOD(Shl, sig_a.size(), ID($shl))
+DEF_METHOD(Shr, sig_a.size(), ID($shr))
+DEF_METHOD(Sshl, sig_a.size(), ID($sshl))
+DEF_METHOD(Sshr, sig_a.size(), ID($sshr))
+#undef DEF_METHOD
+
#define DEF_METHOD(_func, _type, _pmux) \
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc
index 99f4fbae8..dd26f8258 100644
--- a/passes/cmds/scc.cc
+++ b/passes/cmds/scc.cc
@@ -301,10 +301,10 @@ struct SccPass : public Pass {
RTLIL::Selection newSelection(false);
int scc_counter = 0;
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
+ for (auto mod : design->modules())
+ if (!mod->get_blackbox_attribute() && design->selected(mod))
{
- SccWorker worker(design, mod_it.second, nofeedbackMode, allCellTypes, maxDepth);
+ SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth);
if (!setAttr.empty())
{
diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc
index cd357d72a..734d6c10f 100644
--- a/passes/techmap/Makefile.inc
+++ b/passes/techmap/Makefile.inc
@@ -8,6 +8,8 @@ OBJS += passes/techmap/libparse.o
ifeq ($(ENABLE_ABC),1)
OBJS += passes/techmap/abc.o
OBJS += passes/techmap/abc9.o
+OBJS += passes/techmap/abc9_map.o
+OBJS += passes/techmap/abc9_ops.o
ifneq ($(ABCEXTERNAL),)
passes/techmap/abc.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"'
passes/techmap/abc9.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"'
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index b29480e26..7ea1138e3 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -29,17 +29,17 @@
// Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558-562, doi:10.1145/368996.369025
// http://en.wikipedia.org/wiki/Topological_sorting
-#define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put"
-#define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p"
-#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; dch -f; if; mfs2"
-#define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; dch -f; cover {I} {P}"
-#define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put"
-
-#define ABC_FAST_COMMAND_LIB "strash; dretime; retime {D}; map {D}"
-#define ABC_FAST_COMMAND_CTR "strash; dretime; retime {D}; map {D}; buffer; upsize {D}; dnsize {D}; stime -p"
-#define ABC_FAST_COMMAND_LUT "strash; dretime; retime {D}; if"
-#define ABC_FAST_COMMAND_SOP "strash; dretime; retime {D}; cover -I {I} -P {P}"
-#define ABC_FAST_COMMAND_DFL "strash; dretime; retime {D}; map"
+#define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put"
+#define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p"
+#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; strash; dch -f; if; mfs2"
+#define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; strash; dch -f; cover {I} {P}"
+#define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put"
+
+#define ABC_FAST_COMMAND_LIB "strash; dretime; map {D}"
+#define ABC_FAST_COMMAND_CTR "strash; dretime; map {D}; buffer; upsize {D}; dnsize {D}; stime -p"
+#define ABC_FAST_COMMAND_LUT "strash; dretime; if"
+#define ABC_FAST_COMMAND_SOP "strash; dretime; cover -I {I} -P {P}"
+#define ABC_FAST_COMMAND_DFL "strash; dretime; map"
#include "kernel/register.h"
#include "kernel/sigtools.h"
@@ -747,6 +747,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
else
abc_script += fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL;
+ if (script_file.empty() && !delay_target.empty())
+ for (size_t pos = abc_script.find("dretime;"); pos != std::string::npos; pos = abc_script.find("dretime;", pos+1))
+ abc_script = abc_script.substr(0, pos) + "dretime; retime -o {D};" + abc_script.substr(pos+8);
+
for (size_t pos = abc_script.find("{D}"); pos != std::string::npos; pos = abc_script.find("{D}", pos))
abc_script = abc_script.substr(0, pos) + delay_target + abc_script.substr(pos+3);
@@ -1767,7 +1771,7 @@ struct AbcPass : public Pass {
extra_args(args, argidx, design);
if (!lut_costs.empty() && !liberty_file.empty())
- log_cmd_error("Got -lut and -liberty! This two options are exclusive.\n");
+ log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n");
if (!constr_file.empty() && liberty_file.empty())
log_cmd_error("Got -constr but no -liberty!\n");
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index d03e5da8e..d51ed3352 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -2,7 +2,7 @@
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- * 2019 Eddie Hung <eddie@fpgeh.com>
+ * (C) 2019 Eddie Hung <eddie@fpgeh.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,802 +18,21 @@
*
*/
-// [[CITE]] ABC
-// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification
-// http://www.eecs.berkeley.edu/~alanmi/abc/
-
-#if 0
-// Based on &flow3 - better QoR but more experimental
-#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \
- "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\
- "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\
- "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\
- "&mfs; &ps -l"
-#else
-#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l"
-#endif
-
-
-#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}"
-
#include "kernel/register.h"
-#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
-#include "kernel/cost.h"
+#include "kernel/rtlil.h"
#include "kernel/log.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <cerrno>
-#include <sstream>
-#include <climits>
-
-#ifndef _WIN32
-# include <unistd.h>
-# include <dirent.h>
-#endif
-
-#include "frontends/aiger/aigerparse.h"
-#include "kernel/utils.h"
-
-#ifdef YOSYS_LINK_ABC
-extern "C" int Abc_RealMain(int argc, char *argv[]);
-#endif
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-bool markgroups;
-int map_autoidx;
-SigMap assign_map;
-RTLIL::Module *module;
-
-bool clk_polarity, en_polarity;
-RTLIL::SigSpec clk_sig, en_sig;
-
-inline std::string remap_name(RTLIL::IdString abc9_name)
-{
- return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1);
-}
-
-void handle_loops(RTLIL::Design *design)
-{
- Pass::call(design, "scc -set_attr abc9_scc_id {}");
-
- // For every unique SCC found, (arbitrarily) find the first
- // cell in the component, and select (and mark) all its output
- // wires
- pool<RTLIL::Const> ids_seen;
- for (auto cell : module->cells()) {
- auto it = cell->attributes.find(ID(abc9_scc_id));
- if (it != cell->attributes.end()) {
- auto r = ids_seen.insert(it->second);
- if (r.second) {
- for (auto &c : cell->connections_) {
- if (c.second.is_fully_const()) continue;
- if (cell->output(c.first)) {
- SigBit b = c.second.as_bit();
- Wire *w = b.wire;
- if (w->port_input) {
- // In this case, hopefully the loop break has been already created
- // Get the non-prefixed wire
- Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str()));
- log_assert(wo != nullptr);
- log_assert(wo->port_output);
- log_assert(b.offset < GetSize(wo));
- c.second = RTLIL::SigBit(wo, b.offset);
- }
- else {
- // Create a new output/input loop break
- w->port_input = true;
- w = module->wire(stringf("%s.abco", w->name.c_str()));
- if (!w) {
- w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire));
- w->port_output = true;
- }
- else {
- log_assert(w->port_input);
- log_assert(b.offset < GetSize(w));
- }
- w->set_bool_attribute(ID(abc9_scc_break));
- c.second = RTLIL::SigBit(w, b.offset);
- }
- }
- }
- }
- cell->attributes.erase(it);
- }
- }
-
- module->fixup_ports();
-}
-
-std::string add_echos_to_abc9_cmd(std::string str)
-{
- std::string new_str, token;
- for (size_t i = 0; i < str.size(); i++) {
- token += str[i];
- if (str[i] == ';') {
- while (i+1 < str.size() && str[i+1] == ' ')
- i++;
- new_str += "echo + " + token + " " + token + " ";
- token.clear();
- }
- }
-
- if (!token.empty()) {
- if (!new_str.empty())
- new_str += "echo + " + token + "; ";
- new_str += token;
- }
-
- return new_str;
-}
+#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate
+ // to one LUT6 (instead of a LUT5 + LUT2)
-std::string fold_abc9_cmd(std::string str)
+struct Abc9Pass : public ScriptPass
{
- std::string token, new_str = " ";
- int char_counter = 10;
-
- for (size_t i = 0; i <= str.size(); i++) {
- if (i < str.size())
- token += str[i];
- if (i == str.size() || str[i] == ';') {
- if (char_counter + token.size() > 75)
- new_str += "\n ", char_counter = 14;
- new_str += token, char_counter += token.size();
- token.clear();
- }
- }
-
- return new_str;
-}
-
-std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir)
-{
- if (show_tempdir)
- return text;
-
- while (1) {
- size_t pos = text.find(tempdir_name);
- if (pos == std::string::npos)
- break;
- text = text.substr(0, pos) + "<abc-temp-dir>" + text.substr(pos + GetSize(tempdir_name));
- }
-
- std::string selfdir_name = proc_self_dirname();
- if (selfdir_name != "/") {
- while (1) {
- size_t pos = text.find(selfdir_name);
- if (pos == std::string::npos)
- break;
- text = text.substr(0, pos) + "<yosys-exe-dir>/" + text.substr(pos + GetSize(selfdir_name));
- }
- }
-
- return text;
-}
-
-struct abc9_output_filter
-{
- bool got_cr;
- int escape_seq_state;
- std::string linebuf;
- std::string tempdir_name;
- bool show_tempdir;
-
- abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir)
- {
- got_cr = false;
- escape_seq_state = 0;
- }
-
- void next_char(char ch)
- {
- if (escape_seq_state == 0 && ch == '\033') {
- escape_seq_state = 1;
- return;
- }
- if (escape_seq_state == 1) {
- escape_seq_state = ch == '[' ? 2 : 0;
- return;
- }
- if (escape_seq_state == 2) {
- if ((ch < '0' || '9' < ch) && ch != ';')
- escape_seq_state = 0;
- return;
- }
- escape_seq_state = 0;
- if (ch == '\r') {
- got_cr = true;
- return;
- }
- if (ch == '\n') {
- log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str());
- got_cr = false, linebuf.clear();
- return;
- }
- if (got_cr)
- got_cr = false, linebuf.clear();
- linebuf += ch;
- }
-
- void next_line(const std::string &line)
- {
- //int pi, po;
- //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) {
- // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n",
- // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???",
- // po, po_map.count(po) ? po_map.at(po).c_str() : "???");
- // return;
- //}
-
- for (char ch : line)
- next_char(ch);
- }
-};
-
-void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file,
- bool cleanup, vector<int> 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<int,IdString> &box_lookup, bool nomfs
-)
-{
- module = current_module;
- map_autoidx = autoidx++;
-
- if (clk_str != "$")
- {
- clk_polarity = true;
- clk_sig = RTLIL::SigSpec();
-
- en_polarity = true;
- en_sig = RTLIL::SigSpec();
- }
-
- if (!clk_str.empty() && clk_str != "$")
- {
- if (clk_str.find(',') != std::string::npos) {
- int pos = clk_str.find(',');
- std::string en_str = clk_str.substr(pos+1);
- clk_str = clk_str.substr(0, pos);
- if (en_str[0] == '!') {
- en_polarity = false;
- en_str = en_str.substr(1);
- }
- if (module->wires_.count(RTLIL::escape_id(en_str)) != 0)
- en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0));
- }
- if (clk_str[0] == '!') {
- clk_polarity = false;
- clk_str = clk_str.substr(1);
- }
- if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0)
- clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0));
- }
-
- if (dff_mode && clk_sig.empty())
- log_cmd_error("Clock domain %s not found.\n", clk_str.c_str());
-
- std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
- if (!cleanup)
- tempdir_name[0] = tempdir_name[4] = '_';
- tempdir_name = make_temp_dir(tempdir_name);
- log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n",
- module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str());
-
- std::string abc9_script;
-
- if (!lut_costs.empty()) {
- abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str());
- if (!box_file.empty())
- abc9_script += stringf("read_box -v %s; ", box_file.c_str());
- }
- else
- if (!lut_file.empty()) {
- abc9_script += stringf("read_lut %s; ", lut_file.c_str());
- if (!box_file.empty())
- abc9_script += stringf("read_box -v %s; ", box_file.c_str());
- }
- else
- log_abort();
-
- abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str());
-
- if (!script_file.empty()) {
- if (script_file[0] == '+') {
- for (size_t i = 1; i < script_file.size(); i++)
- if (script_file[i] == '\'')
- abc9_script += "'\\''";
- else if (script_file[i] == ',')
- abc9_script += " ";
- else
- abc9_script += script_file[i];
- } else
- abc9_script += stringf("source %s", script_file.c_str());
- } else if (!lut_costs.empty() || !lut_file.empty()) {
- //bool all_luts_cost_same = true;
- //for (int this_cost : lut_costs)
- // if (this_cost != lut_costs.front())
- // all_luts_cost_same = false;
- abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT;
- //if (all_luts_cost_same && !fast_mode)
- // abc9_script += "; lutpack {S}";
- } else
- log_abort();
-
- //if (script_file.empty() && !delay_target.empty())
- // for (size_t pos = abc9_script.find("dretime;"); pos != std::string::npos; pos = abc9_script.find("dretime;", pos+1))
- // abc9_script = abc9_script.substr(0, pos) + "dretime; retime -o {D};" + abc9_script.substr(pos+8);
-
- for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos))
- abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3);
-
- //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos))
- // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3);
-
- for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos))
- abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3);
-
- if (nomfs)
- for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos))
- abc9_script = abc9_script.erase(pos, strlen("&mfs"));
-
- abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str());
- abc9_script = add_echos_to_abc9_cmd(abc9_script);
-
- for (size_t i = 0; i+1 < abc9_script.size(); i++)
- if (abc9_script[i] == ';' && abc9_script[i+1] == ' ')
- abc9_script[i+1] = '\n';
-
- FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt");
- fprintf(f, "%s\n", abc9_script.c_str());
- fclose(f);
-
- if (dff_mode || !clk_str.empty())
- {
- if (clk_sig.size() == 0)
- log("No%s clock domain found. Not extracting any FF cells.\n", clk_str.empty() ? "" : " matching");
- else {
- log("Found%s %s clock domain: %s", clk_str.empty() ? "" : " matching", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig));
- if (en_sig.size() != 0)
- log(", enabled by %s%s", en_polarity ? "" : "!", log_signal(en_sig));
- log("\n");
- }
- }
-
- bool count_output = false;
- for (auto port_name : module->ports) {
- RTLIL::Wire *port_wire = module->wire(port_name);
- log_assert(port_wire);
- if (port_wire->port_output) {
- count_output = true;
- break;
- }
- }
-
- log_push();
-
- if (count_output)
- {
- design->selection_stack.emplace_back(false);
- RTLIL::Selection& sel = design->selection_stack.back();
- sel.select(module);
-
- handle_loops(design);
-
- Pass::call(design, "aigmap");
-
- //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n",
- // count_gates, GetSize(signal_list), count_input, count_output);
-
- Pass::call(design, stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
-
- std::string buffer;
- std::ifstream ifs;
-#if 0
- buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig");
- ifs.open(buffer);
- if (ifs.fail())
- log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
- buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
- log_assert(!design->module(ID($__abc9__)));
- {
- AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
- reader.parse_xaiger();
- }
- ifs.close();
- Pass::call(design, stringf("write_verilog -noexpr -norename"));
- design->remove(design->module(ID($__abc9__)));
-#endif
-
- design->selection_stack.pop_back();
-
- log_header(design, "Executing ABC9.\n");
-
- if (!lut_costs.empty()) {
- buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str());
- f = fopen(buffer.c_str(), "wt");
- if (f == NULL)
- log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
- for (int i = 0; i < GetSize(lut_costs); i++)
- fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i));
- fclose(f);
- }
-
- buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str());
- log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str());
-
-#ifndef YOSYS_LINK_ABC
- abc9_output_filter filt(tempdir_name, show_tempdir);
- int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1));
-#else
- // These needs to be mutable, supposedly due to getopt
- char *abc9_argv[5];
- string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str());
- abc9_argv[0] = strdup(exe_file.c_str());
- abc9_argv[1] = strdup("-s");
- abc9_argv[2] = strdup("-f");
- abc9_argv[3] = strdup(tmp_script_name.c_str());
- abc9_argv[4] = 0;
- int ret = Abc_RealMain(4, abc9_argv);
- free(abc9_argv[0]);
- free(abc9_argv[1]);
- free(abc9_argv[2]);
- free(abc9_argv[3]);
-#endif
- if (ret != 0)
- log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret);
-
- buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig");
- ifs.open(buffer, std::ifstream::binary);
- if (ifs.fail())
- log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
-
- buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
- log_assert(!design->module(ID($__abc9__)));
-
- AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
- reader.parse_xaiger(box_lookup);
- ifs.close();
-
-#if 0
- Pass::call(design, stringf("write_verilog -noexpr -norename"));
-#endif
-
- log_header(design, "Re-integrating ABC9 results.\n");
- RTLIL::Module *mapped_mod = design->module(ID($__abc9__));
- if (mapped_mod == NULL)
- log_error("ABC output file does not contain a module `$__abc9__'.\n");
-
- pool<RTLIL::SigBit> output_bits;
- for (auto &it : mapped_mod->wires_) {
- RTLIL::Wire *w = it.second;
- RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w));
- if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx;
- if (w->port_output) {
- RTLIL::Wire *wire = module->wire(w->name);
- log_assert(wire);
- for (int i = 0; i < GetSize(w); i++)
- output_bits.insert({wire, i});
- }
- }
-
- for (auto &it : module->connections_) {
- auto &signal = it.first;
- auto bits = signal.bits();
- for (auto &b : bits)
- if (output_bits.count(b))
- b = module->addWire(NEW_ID);
- signal = std::move(bits);
- }
-
- dict<IdString, bool> abc9_box;
- vector<RTLIL::Cell*> boxes;
- for (const auto &it : module->cells_) {
- auto cell = it.second;
- if (cell->type.in(ID($_AND_), ID($_NOT_))) {
- module->remove(cell);
- continue;
- }
- auto jt = abc9_box.find(cell->type);
- if (jt == abc9_box.end()) {
- RTLIL::Module* box_module = design->module(cell->type);
- jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first;
- }
- if (jt->second)
- boxes.emplace_back(cell);
- }
-
- dict<SigBit, pool<IdString>> bit_drivers, bit_users;
- TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
- dict<RTLIL::Cell*,RTLIL::Cell*> not2drivers;
- dict<SigBit, std::vector<RTLIL::Cell*>> bit2sinks;
-
- std::map<IdString, int> cell_stats;
- for (auto c : mapped_mod->cells())
- {
- toposort.node(c->name);
-
- RTLIL::Cell *cell = nullptr;
- if (c->type == ID($_NOT_)) {
- RTLIL::SigBit a_bit = c->getPort(ID::A);
- RTLIL::SigBit y_bit = c->getPort(ID::Y);
- bit_users[a_bit].insert(c->name);
- bit_drivers[y_bit].insert(c->name);
-
- if (!a_bit.wire) {
- c->setPort(ID::Y, module->addWire(NEW_ID));
- RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name));
- log_assert(wire);
- module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1);
- }
- else if (!lut_costs.empty() || !lut_file.empty()) {
- RTLIL::Cell* driver_lut = nullptr;
- // ABC can return NOT gates that drive POs
- if (!a_bit.wire->port_input) {
- // If it's not a NOT gate that that comes from a PI directly,
- // find the driver LUT and clone that to guarantee that we won't
- // increase the max logic depth
- // (TODO: Optimise by not cloning unless will increase depth)
- RTLIL::IdString driver_name;
- if (GetSize(a_bit.wire) == 1)
- driver_name = stringf("%s$lut", a_bit.wire->name.c_str());
- else
- driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset);
- driver_lut = mapped_mod->cell(driver_name);
- }
-
- if (!driver_lut) {
- // If a driver couldn't be found (could be from PI or box CI)
- // then implement using a LUT
- cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())),
- RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset),
- RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset),
- RTLIL::Const::from_string("01"));
- bit2sinks[cell->getPort(ID::A)].push_back(cell);
- cell_stats[ID($lut)]++;
- }
- else
- not2drivers[c] = driver_lut;
- continue;
- }
- else
- log_abort();
- if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
- continue;
- }
- cell_stats[c->type]++;
-
- RTLIL::Cell *existing_cell = nullptr;
- if (c->type == ID($lut)) {
- if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) {
- SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name));
- SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name));
- module->connect(my_y, my_a);
- if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx;
- log_abort();
- continue;
- }
- cell = module->addCell(remap_name(c->name), c->type);
- }
- else {
- existing_cell = module->cell(c->name);
- log_assert(existing_cell);
- cell = module->addCell(remap_name(c->name), c->type);
- }
-
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
- if (existing_cell) {
- cell->parameters = existing_cell->parameters;
- cell->attributes = existing_cell->attributes;
- }
- else {
- cell->parameters = c->parameters;
- cell->attributes = c->attributes;
- }
- for (auto &conn : c->connections()) {
- RTLIL::SigSpec newsig;
- for (auto c : conn.second.chunks()) {
- if (c.width == 0)
- continue;
- //log_assert(c.width == 1);
- if (c.wire)
- c.wire = module->wires_.at(remap_name(c.wire->name));
- newsig.append(c);
- }
- cell->setPort(conn.first, newsig);
-
- if (cell->input(conn.first)) {
- for (auto i : newsig)
- bit2sinks[i].push_back(cell);
- for (auto i : conn.second)
- bit_users[i].insert(c->name);
- }
- if (cell->output(conn.first))
- for (auto i : conn.second)
- bit_drivers[i].insert(c->name);
- }
- }
-
- for (auto existing_cell : boxes) {
- Cell *cell = module->cell(remap_name(existing_cell->name));
- if (cell) {
- for (auto &conn : existing_cell->connections()) {
- if (!conn.second.is_wire())
- continue;
- Wire *wire = conn.second.as_wire();
- if (!wire->get_bool_attribute(ID(abc9_padding)))
- continue;
- cell->unsetPort(conn.first);
- log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second));
- }
- module->swap_names(cell, existing_cell);
- }
- module->remove(existing_cell);
- }
-
- // Copy connections (and rename) from mapped_mod to module
- for (auto conn : mapped_mod->connections()) {
- if (!conn.first.is_fully_const()) {
- auto chunks = conn.first.chunks();
- for (auto &c : chunks)
- c.wire = module->wires_.at(remap_name(c.wire->name));
- conn.first = std::move(chunks);
- }
- if (!conn.second.is_fully_const()) {
- auto chunks = conn.second.chunks();
- for (auto &c : chunks)
- if (c.wire)
- c.wire = module->wires_.at(remap_name(c.wire->name));
- conn.second = std::move(chunks);
- }
- module->connect(conn);
- }
-
- for (auto &it : cell_stats)
- log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second);
- int in_wires = 0, out_wires = 0;
-
- // Stitch in mapped_mod's inputs/outputs into module
- for (auto port : mapped_mod->ports) {
- RTLIL::Wire *w = mapped_mod->wire(port);
- RTLIL::Wire *wire = module->wire(port);
- log_assert(wire);
- RTLIL::Wire *remap_wire = module->wire(remap_name(port));
- RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire));
- log_assert(GetSize(signal) >= GetSize(remap_wire));
-
- RTLIL::SigSig conn;
- if (w->port_output) {
- conn.first = signal;
- conn.second = remap_wire;
- out_wires++;
- module->connect(conn);
- }
- else if (w->port_input) {
- conn.first = remap_wire;
- conn.second = signal;
- in_wires++;
- module->connect(conn);
- }
- }
-
- for (auto &it : bit_users)
- if (bit_drivers.count(it.first))
- for (auto driver_cell : bit_drivers.at(it.first))
- for (auto user_cell : it.second)
- toposort.edge(driver_cell, user_cell);
- bool no_loops YS_ATTRIBUTE(unused) = toposort.sort();
- log_assert(no_loops);
+ Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { }
- for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) {
- RTLIL::Cell *not_cell = mapped_mod->cell(*ii);
- log_assert(not_cell);
- if (not_cell->type != ID($_NOT_))
- continue;
- auto it = not2drivers.find(not_cell);
- if (it == not2drivers.end())
- continue;
- RTLIL::Cell *driver_lut = it->second;
- RTLIL::SigBit a_bit = not_cell->getPort(ID::A);
- RTLIL::SigBit y_bit = not_cell->getPort(ID::Y);
- RTLIL::Const driver_mask;
-
- a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name));
- y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name));
-
- auto jt = bit2sinks.find(a_bit);
- if (jt == bit2sinks.end())
- goto clone_lut;
-
- for (auto sink_cell : jt->second)
- if (sink_cell->type != ID($lut))
- goto clone_lut;
-
- // Push downstream LUTs past inverter
- for (auto sink_cell : jt->second) {
- SigSpec A = sink_cell->getPort(ID::A);
- RTLIL::Const mask = sink_cell->getParam(ID(LUT));
- int index = 0;
- for (; index < GetSize(A); index++)
- if (A[index] == a_bit)
- break;
- log_assert(index < GetSize(A));
- int i = 0;
- while (i < GetSize(mask)) {
- for (int j = 0; j < (1 << index); j++)
- std::swap(mask[i+j], mask[i+j+(1 << index)]);
- i += 1 << (index+1);
- }
- A[index] = y_bit;
- sink_cell->setPort(ID::A, A);
- sink_cell->setParam(ID(LUT), mask);
- }
-
- // Since we have rewritten all sinks (which we know
- // to be only LUTs) to be after the inverter, we can
- // go ahead and clone the LUT with the expectation
- // that the original driving LUT will become dangling
- // and get cleaned away
-clone_lut:
- driver_mask = driver_lut->getParam(ID(LUT));
- for (auto &b : driver_mask.bits) {
- if (b == RTLIL::State::S0) b = RTLIL::State::S1;
- else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
- }
- auto cell = module->addLut(NEW_ID,
- driver_lut->getPort(ID::A),
- y_bit,
- driver_mask);
- for (auto &bit : cell->connections_.at(ID::A)) {
- bit.wire = module->wires_.at(remap_name(bit.wire->name));
- bit2sinks[bit].push_back(cell);
- }
- }
-
- // Now 'unexpose' those wires by undoing
- // the expose operation -- remove them from PO/PI
- // and re-connecting them back together
- for (auto wire : module->wires()) {
- auto it = wire->attributes.find(ID(abc9_scc_break));
- if (it != wire->attributes.end()) {
- wire->attributes.erase(it);
- log_assert(wire->port_output);
- wire->port_output = false;
- std::string name = wire->name.str();
- RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5));
- log_assert(i_wire);
- log_assert(i_wire->port_input);
- i_wire->port_input = false;
- module->connect(i_wire, wire);
- }
- }
- module->fixup_ports();
-
- //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
- log("ABC RESULTS: input signals: %8d\n", in_wires);
- log("ABC RESULTS: output signals: %8d\n", out_wires);
-
- design->remove(mapped_mod);
- }
- else
- {
- log("Don't call ABC as there is nothing to map.\n");
- }
-
- if (cleanup)
- {
- log("Removing temp directory.\n");
- remove_directory(tempdir_name);
- }
-
- log_pop();
-}
-
-struct Abc9Pass : public Pass {
- Abc9Pass() : Pass("abc9", "use ABC9 for technology mapping") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
@@ -842,24 +61,25 @@ struct Abc9Pass : public Pass {
log(" if no -script parameter is given, the following scripts are used:\n");
log("\n");
log(" for -lut/-luts (only one LUT size):\n");
- log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
+ // FIXME
+ //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
log("\n");
log(" for -lut/-luts (different LUT sizes):\n");
- log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());
+ // FIXME
+ //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());
log("\n");
log(" -fast\n");
log(" use different default scripts that are slightly faster (at the cost\n");
log(" of output quality):\n");
log("\n");
log(" for -lut/-luts:\n");
- log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
+ // FIXME
+ //log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
log("\n");
log(" -D <picoseconds>\n");
log(" set delay target. the string {D} in the default scripts above is\n");
log(" replaced by this option when used, and an empty string otherwise\n");
log(" (indicating best possible delay).\n");
-// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n");
-// log(" default scripts above.\n");
log("\n");
// log(" -S <num>\n");
// log(" maximum number of LUT inputs shared.\n");
@@ -881,19 +101,10 @@ struct Abc9Pass : public Pass {
log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
log(" 2, 3, .. inputs.\n");
log("\n");
-// log(" -dff\n");
-// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n");
-// log(" clock domains are automatically partitioned in clock domains and each\n");
-// log(" domain is passed through ABC independently.\n");
-// log("\n");
-// log(" -clk [!]<clock-signal-name>[,[!]<enable-signal-name>]\n");
-// log(" use only the specified clock domain. this is like -dff, but only FF\n");
-// log(" cells that belong to the specified clock domain are used.\n");
-// log("\n");
-// log(" -keepff\n");
-// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n");
-// log(" them, for example for equivalence checking.)\n");
-// log("\n");
+ log(" -dff\n");
+ log(" also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n");
+ log(" domains are marked as such and automatically partitioned by ABC.\n");
+ log("\n");
log(" -nocleanup\n");
log(" when this option is used, the temporary files created by this pass\n");
log(" are not removed. this is useful for debugging.\n");
@@ -914,230 +125,85 @@ struct Abc9Pass : public Pass {
log("internally. This is not going to \"run ABC on your design\". It will instead run\n");
log("ABC on logic snippets extracted from your design. You will not get any useful\n");
log("output when passing an ABC script that writes a file. Instead write your full\n");
- log("design as BLIF file with write_blif and then load that into ABC externally if\n");
- log("you want to use ABC to convert your design into another format.\n");
+ log("design as an XAIGER file with `write_xaiger' and then load that into ABC\n");
+ log("externally if you want to use ABC to convert your design into another format.\n");
log("\n");
log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n");
log("\n");
+ help_script();
+ log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
- {
- log_header(design, "Executing ABC9 pass (technology mapping using ABC9).\n");
- log_push();
- assign_map.clear();
+ std::stringstream map_cmd;
+ bool dff_mode, cleanup;
-#ifdef ABCEXTERNAL
- std::string exe_file = ABCEXTERNAL;
-#else
- std::string exe_file = proc_self_dirname() + "yosys-abc";
-#endif
- std::string script_file, clk_str, box_file, lut_file;
- std::string delay_target, lutin_shared = "-S 1", wire_delay;
- bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true;
- bool show_tempdir = false;
- bool nomfs = false;
- vector<int> lut_costs;
- markgroups = false;
-
-#if 0
- cleanup = false;
- show_tempdir = true;
-#endif
+ void clear_flags() YS_OVERRIDE
+ {
+ map_cmd.str("");
+ map_cmd << "abc9_map";
+ dff_mode = false;
+ cleanup = true;
+ }
-#ifdef _WIN32
-#ifndef ABCEXTERNAL
- if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe"))
- exe_file = proc_self_dirname() + "..\\yosys-abc";
-#endif
-#endif
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ std::string run_from, run_to;
+ clear_flags();
size_t argidx;
- char pwd [PATH_MAX];
- if (!getcwd(pwd, sizeof(pwd))) {
- log_cmd_error("getcwd failed: %s\n", strerror(errno));
- log_abort();
- }
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
- if (arg == "-exe" && argidx+1 < args.size()) {
- exe_file = args[++argidx];
- continue;
- }
- if (arg == "-script" && argidx+1 < args.size()) {
- script_file = args[++argidx];
- rewrite_filename(script_file);
- if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')
- script_file = std::string(pwd) + "/" + script_file;
- continue;
- }
- if (arg == "-D" && argidx+1 < args.size()) {
- delay_target = "-D " + args[++argidx];
+ if ((arg == "-exe" || arg == "-script" || arg == "-D" ||
+ /* arg == "-S" || */ arg == "-lut" || arg == "-luts" ||
+ arg == "-box" || arg == "-W") &&
+ argidx+1 < args.size()) {
+ map_cmd << " " << arg << " " << args[++argidx];
continue;
}
- //if (arg == "-S" && argidx+1 < args.size()) {
- // lutin_shared = "-S " + args[++argidx];
- // continue;
- //}
- if (arg == "-lut" && argidx+1 < args.size()) {
- string arg = args[++argidx];
- if (arg.find_first_not_of("0123456789:") == std::string::npos) {
- size_t pos = arg.find_first_of(':');
- int lut_mode = 0, lut_mode2 = 0;
- if (pos != string::npos) {
- lut_mode = atoi(arg.substr(0, pos).c_str());
- lut_mode2 = atoi(arg.substr(pos+1).c_str());
- } else {
- lut_mode = atoi(arg.c_str());
- lut_mode2 = lut_mode;
- }
- lut_costs.clear();
- for (int i = 0; i < lut_mode; i++)
- lut_costs.push_back(1);
- for (int i = lut_mode; i < lut_mode2; i++)
- lut_costs.push_back(2 << (i - lut_mode));
- }
- else {
- lut_file = arg;
- rewrite_filename(lut_file);
- if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+')
- lut_file = std::string(pwd) + "/" + lut_file;
- }
+ if (arg == "-fast" || /* arg == "-dff" || */
+ /* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-markgroups" ||
+ arg == "-nomfs") {
+ map_cmd << " " << arg;
continue;
}
- if (arg == "-luts" && argidx+1 < args.size()) {
- lut_costs.clear();
- for (auto &tok : split_tokens(args[++argidx], ",")) {
- auto parts = split_tokens(tok, ":");
- if (GetSize(parts) == 0 && !lut_costs.empty())
- lut_costs.push_back(lut_costs.back());
- else if (GetSize(parts) == 1)
- lut_costs.push_back(atoi(parts.at(0).c_str()));
- else if (GetSize(parts) == 2)
- while (GetSize(lut_costs) < atoi(parts.at(0).c_str()))
- lut_costs.push_back(atoi(parts.at(1).c_str()));
- else
- log_cmd_error("Invalid -luts syntax.\n");
- }
+ if (arg == "-dff") {
+ dff_mode = true;
continue;
}
- if (arg == "-fast") {
- fast_mode = true;
- continue;
- }
- //if (arg == "-dff") {
- // dff_mode = true;
- // continue;
- //}
- //if (arg == "-clk" && argidx+1 < args.size()) {
- // clk_str = args[++argidx];
- // dff_mode = true;
- // continue;
- //}
- //if (arg == "-keepff") {
- // keepff = true;
- // continue;
- //}
if (arg == "-nocleanup") {
cleanup = false;
continue;
}
- if (arg == "-showtmp") {
- show_tempdir = true;
- continue;
- }
- if (arg == "-markgroups") {
- markgroups = true;
- continue;
- }
- if (arg == "-box" && argidx+1 < args.size()) {
- box_file = args[++argidx];
- continue;
- }
- if (arg == "-W" && argidx+1 < args.size()) {
- wire_delay = "-W " + args[++argidx];
- continue;
- }
- if (arg == "-nomfs") {
- nomfs = true;
- continue;
- }
break;
}
extra_args(args, argidx, design);
- // ABC expects a box file for XAIG
- if (box_file.empty())
- box_file = "+/dummy.box";
-
- rewrite_filename(box_file);
- if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+')
- box_file = std::string(pwd) + "/" + box_file;
-
- dict<int,IdString> box_lookup;
- for (auto m : design->modules()) {
- auto it = m->attributes.find(ID(abc9_box_id));
- if (it == m->attributes.end())
- continue;
- if (m->name.begins_with("$paramod"))
- continue;
- auto id = it->second.as_int();
- auto r = box_lookup.insert(std::make_pair(id, m->name));
- if (!r.second)
- log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
- log_id(m), id, log_id(r.first->second));
- log_assert(r.second);
+ log_header(design, "Executing ABC9 pass.\n");
- RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr;
- for (auto p : m->ports) {
- auto w = m->wire(p);
- log_assert(w);
- if (w->attributes.count(ID(abc9_carry))) {
- if (w->port_input) {
- if (carry_in)
- log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m));
- carry_in = w;
- }
- else if (w->port_output) {
- if (carry_out)
- log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m));
- carry_out = w;
- }
- }
- }
- if (carry_in || carry_out) {
- if (carry_in && !carry_out)
- log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m));
- if (!carry_in && carry_out)
- log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m));
- // Make carry_in the last PI, and carry_out the last PO
- // since ABC requires it this way
- auto &ports = m->ports;
- for (auto it = ports.begin(); it != ports.end(); ) {
- RTLIL::Wire* w = m->wire(*it);
- log_assert(w);
- if (w == carry_in || w == carry_out) {
- it = ports.erase(it);
- continue;
- }
- if (w->port_id > carry_in->port_id)
- --w->port_id;
- if (w->port_id > carry_out->port_id)
- --w->port_id;
- log_assert(w->port_input || w->port_output);
- log_assert(ports[w->port_id-1] == w->name);
- ++it;
- }
- ports.push_back(carry_in->name);
- carry_in->port_id = ports.size();
- ports.push_back(carry_out->name);
- carry_out->port_id = ports.size();
- }
- }
+ run_script(design, run_from, run_to);
+ }
- for (auto mod : design->selected_modules())
- {
- if (mod->attributes.count(ID(abc9_box_id)))
+ void script() YS_OVERRIDE
+ {
+ run("scc -set_attr abc9_scc_id {}");
+ if (help_mode)
+ run("abc9_ops -break_scc -prep_holes [-dff]", "(option for -dff)");
+ else
+ run("abc9_ops -break_scc -prep_holes" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)");
+ run("select -set abc9_holes A:abc9_holes");
+ run("flatten -wb @abc9_holes");
+ run("techmap @abc9_holes");
+ run("aigmap");
+ if (dff_mode)
+ run("abc9_ops -prep_dff");
+ run("opt -purge @abc9_holes");
+ run("wbflip @abc9_holes");
+
+ auto selected_modules = active_design->selected_modules();
+ active_design->selection_stack.emplace_back(false);
+
+ for (auto mod : selected_modules) {
+ if (mod->get_blackbox_attribute())
continue;
if (mod->processes.size() > 0) {
@@ -1145,165 +211,30 @@ struct Abc9Pass : public Pass {
continue;
}
- assign_map.set(mod);
-
- if (!dff_mode || !clk_str.empty()) {
- abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
- delay_target, lutin_shared, fast_mode, show_tempdir,
- box_file, lut_file, wire_delay, box_lookup, nomfs);
- continue;
- }
-
- CellTypes ct(design);
-
- std::vector<RTLIL::Cell*> all_cells = mod->selected_cells();
- std::set<RTLIL::Cell*> unassigned_cells(all_cells.begin(), all_cells.end());
+ active_design->selection().select(mod);
- std::set<RTLIL::Cell*> expand_queue, next_expand_queue;
- std::set<RTLIL::Cell*> expand_queue_up, next_expand_queue_up;
- std::set<RTLIL::Cell*> expand_queue_down, next_expand_queue_down;
+ std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
+ if (!cleanup)
+ tempdir_name[0] = tempdir_name[4] = '_';
+ tempdir_name = make_temp_dir(tempdir_name);
- typedef tuple<bool, RTLIL::SigSpec, bool, RTLIL::SigSpec> clkdomain_t;
- std::map<clkdomain_t, std::vector<RTLIL::Cell*>> assigned_cells;
- std::map<RTLIL::Cell*, clkdomain_t> assigned_cells_reverse;
+ run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()),
+ "write_xaiger -map <abc-temp-dir>/input.sym <abc-temp-dir>/input.xaig");
+ run(stringf("%s -tempdir %s", map_cmd.str().c_str(), tempdir_name.c_str()),
+ "abc9_map [options] -tempdir <abc-temp-dir>");
- std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down;
- std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down;
-
- for (auto cell : all_cells)
+ if (cleanup)
{
- clkdomain_t key;
-
- for (auto &conn : cell->connections())
- for (auto bit : conn.second) {
- bit = assign_map(bit);
- if (bit.wire != nullptr) {
- cell_to_bit[cell].insert(bit);
- bit_to_cell[bit].insert(cell);
- if (ct.cell_input(cell->type, conn.first)) {
- cell_to_bit_up[cell].insert(bit);
- bit_to_cell_down[bit].insert(cell);
- }
- if (ct.cell_output(cell->type, conn.first)) {
- cell_to_bit_down[cell].insert(bit);
- bit_to_cell_up[bit].insert(cell);
- }
- }
- }
-
- if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
- {
- key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec());
- }
- else
- if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
- {
- bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
- bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
- key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E))));
- }
- else
- continue;
-
- unassigned_cells.erase(cell);
- expand_queue.insert(cell);
- expand_queue_up.insert(cell);
- expand_queue_down.insert(cell);
-
- assigned_cells[key].push_back(cell);
- assigned_cells_reverse[cell] = key;
+ log("Removing temp directory.\n");
+ remove_directory(tempdir_name);
}
- while (!expand_queue_up.empty() || !expand_queue_down.empty())
- {
- if (!expand_queue_up.empty())
- {
- RTLIL::Cell *cell = *expand_queue_up.begin();
- clkdomain_t key = assigned_cells_reverse.at(cell);
- expand_queue_up.erase(cell);
-
- for (auto bit : cell_to_bit_up[cell])
- for (auto c : bit_to_cell_up[bit])
- if (unassigned_cells.count(c)) {
- unassigned_cells.erase(c);
- next_expand_queue_up.insert(c);
- assigned_cells[key].push_back(c);
- assigned_cells_reverse[c] = key;
- expand_queue.insert(c);
- }
- }
-
- if (!expand_queue_down.empty())
- {
- RTLIL::Cell *cell = *expand_queue_down.begin();
- clkdomain_t key = assigned_cells_reverse.at(cell);
- expand_queue_down.erase(cell);
-
- for (auto bit : cell_to_bit_down[cell])
- for (auto c : bit_to_cell_down[bit])
- if (unassigned_cells.count(c)) {
- unassigned_cells.erase(c);
- next_expand_queue_up.insert(c);
- assigned_cells[key].push_back(c);
- assigned_cells_reverse[c] = key;
- expand_queue.insert(c);
- }
- }
-
- if (expand_queue_up.empty() && expand_queue_down.empty()) {
- expand_queue_up.swap(next_expand_queue_up);
- expand_queue_down.swap(next_expand_queue_down);
- }
- }
-
- while (!expand_queue.empty())
- {
- RTLIL::Cell *cell = *expand_queue.begin();
- clkdomain_t key = assigned_cells_reverse.at(cell);
- expand_queue.erase(cell);
-
- for (auto bit : cell_to_bit.at(cell)) {
- for (auto c : bit_to_cell[bit])
- if (unassigned_cells.count(c)) {
- unassigned_cells.erase(c);
- next_expand_queue.insert(c);
- assigned_cells[key].push_back(c);
- assigned_cells_reverse[c] = key;
- }
- bit_to_cell[bit].clear();
- }
-
- if (expand_queue.empty())
- expand_queue.swap(next_expand_queue);
- }
-
- clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec());
- for (auto cell : unassigned_cells) {
- assigned_cells[key].push_back(cell);
- assigned_cells_reverse[cell] = key;
- }
-
- log_header(design, "Summary of detected clock domains:\n");
- for (auto &it : assigned_cells)
- log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second),
- std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)),
- std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first)));
-
- for (auto &it : assigned_cells) {
- clk_polarity = std::get<0>(it.first);
- clk_sig = assign_map(std::get<1>(it.first));
- en_polarity = std::get<2>(it.first);
- en_sig = assign_map(std::get<3>(it.first));
- abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$",
- keepff, delay_target, lutin_shared, fast_mode, show_tempdir,
- box_file, lut_file, wire_delay, box_lookup, nomfs);
- assign_map.set(mod);
- }
+ active_design->selection().selected_modules.clear();
}
- assign_map.clear();
+ active_design->selection_stack.pop_back();
- log_pop();
+ run("abc9_ops -unbreak_scc");
}
} Abc9Pass;
diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc
new file mode 100644
index 000000000..e061cadeb
--- /dev/null
+++ b/passes/techmap/abc9_map.cc
@@ -0,0 +1,881 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ * 2019 Eddie Hung <eddie@fpgeh.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+// [[CITE]] ABC
+// Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification
+// http://www.eecs.berkeley.edu/~alanmi/abc/
+
+#if 0
+// Based on &flow3 - better QoR but more experimental
+#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \
+ "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\
+ "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\
+ "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\
+ "&mfs; &ps -l"
+#else
+#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l"
+#endif
+
+
+#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}"
+
+#include "kernel/register.h"
+#include "kernel/sigtools.h"
+#include "kernel/celltypes.h"
+#include "kernel/cost.h"
+#include "kernel/log.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <cerrno>
+#include <sstream>
+#include <climits>
+
+#ifndef _WIN32
+# include <unistd.h>
+# include <dirent.h>
+#endif
+
+#include "frontends/aiger/aigerparse.h"
+#include "kernel/utils.h"
+
+#ifdef YOSYS_LINK_ABC
+extern "C" int Abc_RealMain(int argc, char *argv[]);
+#endif
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+bool markgroups;
+int map_autoidx;
+
+inline std::string remap_name(RTLIL::IdString abc9_name)
+{
+ return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1);
+}
+
+std::string add_echos_to_abc9_cmd(std::string str)
+{
+ std::string new_str, token;
+ for (size_t i = 0; i < str.size(); i++) {
+ token += str[i];
+ if (str[i] == ';') {
+ while (i+1 < str.size() && str[i+1] == ' ')
+ i++;
+ new_str += "echo + " + token + " " + token + " ";
+ token.clear();
+ }
+ }
+
+ if (!token.empty()) {
+ if (!new_str.empty())
+ new_str += "echo + " + token + "; ";
+ new_str += token;
+ }
+
+ return new_str;
+}
+
+std::string fold_abc9_cmd(std::string str)
+{
+ std::string token, new_str = " ";
+ int char_counter = 10;
+
+ for (size_t i = 0; i <= str.size(); i++) {
+ if (i < str.size())
+ token += str[i];
+ if (i == str.size() || str[i] == ';') {
+ if (char_counter + token.size() > 75)
+ new_str += "\n ", char_counter = 14;
+ new_str += token, char_counter += token.size();
+ token.clear();
+ }
+ }
+
+ return new_str;
+}
+
+std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir)
+{
+ if (show_tempdir)
+ return text;
+
+ while (1) {
+ size_t pos = text.find(tempdir_name);
+ if (pos == std::string::npos)
+ break;
+ text = text.substr(0, pos) + "<abc-temp-dir>" + text.substr(pos + GetSize(tempdir_name));
+ }
+
+ std::string selfdir_name = proc_self_dirname();
+ if (selfdir_name != "/") {
+ while (1) {
+ size_t pos = text.find(selfdir_name);
+ if (pos == std::string::npos)
+ break;
+ text = text.substr(0, pos) + "<yosys-exe-dir>/" + text.substr(pos + GetSize(selfdir_name));
+ }
+ }
+
+ return text;
+}
+
+struct abc9_output_filter
+{
+ bool got_cr;
+ int escape_seq_state;
+ std::string linebuf;
+ std::string tempdir_name;
+ bool show_tempdir;
+
+ abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir)
+ {
+ got_cr = false;
+ escape_seq_state = 0;
+ }
+
+ void next_char(char ch)
+ {
+ if (escape_seq_state == 0 && ch == '\033') {
+ escape_seq_state = 1;
+ return;
+ }
+ if (escape_seq_state == 1) {
+ escape_seq_state = ch == '[' ? 2 : 0;
+ return;
+ }
+ if (escape_seq_state == 2) {
+ if ((ch < '0' || '9' < ch) && ch != ';')
+ escape_seq_state = 0;
+ return;
+ }
+ escape_seq_state = 0;
+ if (ch == '\r') {
+ got_cr = true;
+ return;
+ }
+ if (ch == '\n') {
+ log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir).c_str());
+ got_cr = false, linebuf.clear();
+ return;
+ }
+ if (got_cr)
+ got_cr = false, linebuf.clear();
+ linebuf += ch;
+ }
+
+ void next_line(const std::string &line)
+ {
+ //int pi, po;
+ //if (sscanf(line.c_str(), "Start-point = pi%d. End-point = po%d.", &pi, &po) == 2) {
+ // log("ABC: Start-point = pi%d (%s). End-point = po%d (%s).\n",
+ // pi, pi_map.count(pi) ? pi_map.at(pi).c_str() : "???",
+ // po, po_map.count(po) ? po_map.at(po).c_str() : "???");
+ // return;
+ //}
+
+ for (char ch : line)
+ next_char(ch);
+ }
+};
+
+void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file,
+ vector<int> lut_costs, 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, bool nomfs, std::string tempdir_name
+)
+{
+ map_autoidx = autoidx++;
+
+ //FIXME:
+ //log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n",
+ // module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str());
+
+ std::string abc9_script;
+
+ if (!lut_costs.empty()) {
+ abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str());
+ if (!box_file.empty())
+ abc9_script += stringf("read_box %s; ", box_file.c_str());
+ }
+ else
+ if (!lut_file.empty()) {
+ abc9_script += stringf("read_lut %s; ", lut_file.c_str());
+ if (!box_file.empty())
+ abc9_script += stringf("read_box %s; ", box_file.c_str());
+ }
+ else
+ log_abort();
+
+ abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str());
+
+ if (!script_file.empty()) {
+ if (script_file[0] == '+') {
+ for (size_t i = 1; i < script_file.size(); i++)
+ if (script_file[i] == '\'')
+ abc9_script += "'\\''";
+ else if (script_file[i] == ',')
+ abc9_script += " ";
+ else
+ abc9_script += script_file[i];
+ } else
+ abc9_script += stringf("source %s", script_file.c_str());
+ } else if (!lut_costs.empty() || !lut_file.empty()) {
+ abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT;
+ } else
+ log_abort();
+
+ for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos))
+ abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3);
+
+ //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos))
+ // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3);
+
+ for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos))
+ abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3);
+
+ if (nomfs)
+ for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos))
+ abc9_script = abc9_script.erase(pos, strlen("&mfs"));
+
+ abc9_script += stringf("; &write -n %s/output.aig", tempdir_name.c_str());
+ abc9_script = add_echos_to_abc9_cmd(abc9_script);
+
+ for (size_t i = 0; i+1 < abc9_script.size(); i++)
+ if (abc9_script[i] == ';' && abc9_script[i+1] == ' ')
+ abc9_script[i+1] = '\n';
+
+ FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt");
+ fprintf(f, "%s\n", abc9_script.c_str());
+ fclose(f);
+
+ int count_outputs = design->scratchpad_get_int("write_xaiger.num_outputs");
+ log("Extracted %d AND gates and %d wires to a netlist network with %d inputs and %d outputs.\n",
+ design->scratchpad_get_int("write_xaiger.num_ands"),
+ design->scratchpad_get_int("write_xaiger.num_wires"),
+ design->scratchpad_get_int("write_xaiger.num_inputs"),
+ count_outputs);
+
+ if (count_outputs > 0) {
+ std::string buffer;
+ std::ifstream ifs;
+#if 0
+ buffer = stringf("%s/%s", tempdir_name.c_str(), "input.xaig");
+ ifs.open(buffer);
+ if (ifs.fail())
+ log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
+ buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
+ log_assert(!design->module(ID($__abc9__)));
+ {
+ AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
+ reader.parse_xaiger();
+ }
+ ifs.close();
+ Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected"));
+ design->remove(design->module(ID($__abc9__)));
+#endif
+
+ log_header(design, "Executing ABC9.\n");
+
+ if (!lut_costs.empty()) {
+ buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str());
+ f = fopen(buffer.c_str(), "wt");
+ if (f == NULL)
+ log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
+ for (int i = 0; i < GetSize(lut_costs); i++)
+ fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i));
+ fclose(f);
+ }
+
+ buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str());
+ log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str());
+
+#ifndef YOSYS_LINK_ABC
+ abc9_output_filter filt(tempdir_name, show_tempdir);
+ int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1));
+#else
+ // These needs to be mutable, supposedly due to getopt
+ char *abc9_argv[5];
+ string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str());
+ abc9_argv[0] = strdup(exe_file.c_str());
+ abc9_argv[1] = strdup("-s");
+ abc9_argv[2] = strdup("-f");
+ abc9_argv[3] = strdup(tmp_script_name.c_str());
+ abc9_argv[4] = 0;
+ int ret = Abc_RealMain(4, abc9_argv);
+ free(abc9_argv[0]);
+ free(abc9_argv[1]);
+ free(abc9_argv[2]);
+ free(abc9_argv[3]);
+#endif
+ if (ret != 0)
+ log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret);
+
+ buffer = stringf("%s/%s", tempdir_name.c_str(), "output.aig");
+ ifs.open(buffer, std::ifstream::binary);
+ if (ifs.fail())
+ log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
+
+ buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
+ log_assert(!design->module(ID($__abc9__)));
+
+ AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
+ reader.parse_xaiger();
+ ifs.close();
+
+#if 0
+ Pass::call_on_module(design, design->module(ID($__abc9__)), stringf("write_verilog -noexpr -norename -selected"));
+#endif
+
+ log_header(design, "Re-integrating ABC9 results.\n");
+ RTLIL::Module *mapped_mod = design->module(ID($__abc9__));
+ if (mapped_mod == NULL)
+ log_error("ABC output file does not contain a module `$__abc9__'.\n");
+
+ for (auto &it : mapped_mod->wires_) {
+ RTLIL::Wire *w = it.second;
+ RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w));
+ if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx;
+ }
+
+ for (auto it = module->cells_.begin(); it != module->cells_.end(); )
+ if (it->second->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
+ it = module->cells_.erase(it);
+ else
+ ++it;
+
+ dict<SigBit, pool<IdString>> bit_drivers, bit_users;
+ TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
+ dict<RTLIL::Cell*,RTLIL::Cell*> not2drivers;
+ dict<SigBit, std::vector<RTLIL::Cell*>> bit2sinks;
+
+ std::map<IdString, int> cell_stats;
+ for (auto mapped_cell : mapped_mod->cells())
+ {
+ toposort.node(mapped_cell->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);
+ bit_users[a_bit].insert(mapped_cell->name);
+ bit_drivers[y_bit].insert(mapped_cell->name);
+
+ if (!a_bit.wire) {
+ 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);
+ }
+ else if (!lut_costs.empty() || !lut_file.empty()) {
+ RTLIL::Cell* driver_lut = nullptr;
+ // ABC can return NOT gates that drive POs
+ if (!a_bit.wire->port_input) {
+ // If it's not a NOT gate that that comes from a PI directly,
+ // find the driver LUT and clone that to guarantee that we won't
+ // increase the max logic depth
+ // (TODO: Optimise by not cloning unless will increase depth)
+ RTLIL::IdString driver_name;
+ if (GetSize(a_bit.wire) == 1)
+ driver_name = stringf("%s$lut", a_bit.wire->name.c_str());
+ else
+ driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset);
+ driver_lut = mapped_mod->cell(driver_name);
+ }
+
+ if (!driver_lut) {
+ // If a driver couldn't be found (could be from PI or box CI)
+ // then implement using a LUT
+ cell = module->addLut(remap_name(stringf("%s$lut", 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)]++;
+ }
+ else
+ not2drivers[mapped_cell] = driver_lut;
+ continue;
+ }
+ else
+ log_abort();
+ if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ continue;
+ }
+ cell_stats[mapped_cell->type]++;
+
+ RTLIL::Cell *existing_cell = nullptr;
+ if (mapped_cell->type.in(ID($lut), ID($__ABC9_FF_))) {
+ if (mapped_cell->type == ID($lut) &&
+ 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) mapped_cell->attributes[ID(abcgroup)] = map_autoidx;
+ log_abort();
+ continue;
+ }
+ cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
+ }
+ else {
+ existing_cell = module->cell(mapped_cell->name);
+ log_assert(existing_cell);
+ cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
+ }
+
+ if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (existing_cell) {
+ cell->parameters = existing_cell->parameters;
+ cell->attributes = existing_cell->attributes;
+ if (cell->attributes.erase("\\abc9_box_seq")) {
+ module->swap_names(cell, existing_cell);
+ module->remove(existing_cell);
+ }
+ }
+ else {
+ cell->parameters = mapped_cell->parameters;
+ cell->attributes = mapped_cell->attributes;
+ }
+
+ RTLIL::Module* box_module = design->module(mapped_cell->type);
+ auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop");
+ for (auto &conn : mapped_cell->connections()) {
+ RTLIL::SigSpec newsig;
+ for (auto c : conn.second.chunks()) {
+ if (c.width == 0)
+ continue;
+ //log_assert(c.width == 1);
+ if (c.wire)
+ c.wire = module->wires_.at(remap_name(c.wire->name));
+ newsig.append(c);
+ }
+ cell->setPort(conn.first, newsig);
+
+ if (!abc9_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);
+ }
+ }
+ }
+
+ // Copy connections (and rename) from mapped_mod to module
+ for (auto conn : mapped_mod->connections()) {
+ if (!conn.first.is_fully_const()) {
+ auto chunks = conn.first.chunks();
+ for (auto &c : chunks)
+ c.wire = module->wires_.at(remap_name(c.wire->name));
+ conn.first = std::move(chunks);
+ }
+ if (!conn.second.is_fully_const()) {
+ auto chunks = conn.second.chunks();
+ for (auto &c : chunks)
+ if (c.wire)
+ c.wire = module->wires_.at(remap_name(c.wire->name));
+ conn.second = std::move(chunks);
+ }
+ module->connect(conn);
+ }
+
+ for (auto &it : cell_stats)
+ log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second);
+ int in_wires = 0, out_wires = 0;
+
+ // Stitch in mapped_mod's inputs/outputs into module
+ for (auto port : mapped_mod->ports) {
+ RTLIL::Wire *w = mapped_mod->wire(port);
+ RTLIL::Wire *wire = module->wire(port);
+ log_assert(wire);
+ RTLIL::Wire *remap_wire = module->wire(remap_name(port));
+ RTLIL::SigSpec signal = RTLIL::SigSpec(wire, 0, GetSize(remap_wire));
+ log_assert(GetSize(signal) >= GetSize(remap_wire));
+
+ RTLIL::SigSig conn;
+ if (w->port_output) {
+ conn.first = signal;
+ conn.second = remap_wire;
+ out_wires++;
+ module->connect(conn);
+ }
+ else if (w->port_input) {
+ conn.first = remap_wire;
+ conn.second = signal;
+ in_wires++;
+ module->connect(conn);
+ }
+ }
+
+ for (auto &it : bit_users)
+ if (bit_drivers.count(it.first))
+ for (auto driver_cell : bit_drivers.at(it.first))
+ for (auto user_cell : it.second)
+ toposort.edge(driver_cell, user_cell);
+ bool no_loops YS_ATTRIBUTE(unused) = toposort.sort();
+ log_assert(no_loops);
+
+ for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) {
+ RTLIL::Cell *not_cell = mapped_mod->cell(*ii);
+ log_assert(not_cell);
+ if (not_cell->type != ID($_NOT_))
+ continue;
+ auto it = not2drivers.find(not_cell);
+ if (it == not2drivers.end())
+ continue;
+ RTLIL::Cell *driver_lut = it->second;
+ RTLIL::SigBit a_bit = not_cell->getPort(ID::A);
+ RTLIL::SigBit y_bit = not_cell->getPort(ID::Y);
+ RTLIL::Const driver_mask;
+
+ a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name));
+ y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name));
+
+ auto jt = bit2sinks.find(a_bit);
+ if (jt == bit2sinks.end())
+ goto clone_lut;
+
+ for (auto sink_cell : jt->second)
+ if (sink_cell->type != ID($lut))
+ goto clone_lut;
+
+ // Push downstream LUTs past inverter
+ for (auto sink_cell : jt->second) {
+ SigSpec A = sink_cell->getPort(ID::A);
+ RTLIL::Const mask = sink_cell->getParam(ID(LUT));
+ int index = 0;
+ for (; index < GetSize(A); index++)
+ if (A[index] == a_bit)
+ break;
+ log_assert(index < GetSize(A));
+ int i = 0;
+ while (i < GetSize(mask)) {
+ for (int j = 0; j < (1 << index); j++)
+ std::swap(mask[i+j], mask[i+j+(1 << index)]);
+ i += 1 << (index+1);
+ }
+ A[index] = y_bit;
+ sink_cell->setPort(ID::A, A);
+ sink_cell->setParam(ID(LUT), mask);
+ }
+
+ // Since we have rewritten all sinks (which we know
+ // to be only LUTs) to be after the inverter, we can
+ // go ahead and clone the LUT with the expectation
+ // that the original driving LUT will become dangling
+ // and get cleaned away
+clone_lut:
+ driver_mask = driver_lut->getParam(ID(LUT));
+ for (auto &b : driver_mask.bits) {
+ if (b == RTLIL::State::S0) b = RTLIL::State::S1;
+ else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
+ }
+ auto cell = module->addLut(NEW_ID,
+ driver_lut->getPort(ID::A),
+ y_bit,
+ driver_mask);
+ for (auto &bit : cell->connections_.at(ID::A)) {
+ bit.wire = module->wires_.at(remap_name(bit.wire->name));
+ bit2sinks[bit].push_back(cell);
+ }
+ }
+
+ //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
+ log("ABC RESULTS: input signals: %8d\n", in_wires);
+ log("ABC RESULTS: output signals: %8d\n", out_wires);
+
+ design->remove(mapped_mod);
+ }
+ //else
+ //{
+ // log("Don't call ABC as there is nothing to map.\n");
+ //}
+}
+
+struct Abc9MapPass : public Pass {
+ Abc9MapPass() : Pass("abc9_map", "use ABC9 for technology mapping") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" abc9_map [options] [selection]\n");
+ log("\n");
+ log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n");
+ log("library to a target architecture.\n");
+ log("\n");
+ log(" -exe <command>\n");
+#ifdef ABCEXTERNAL
+ log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
+#else
+ log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+#endif
+ log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
+ log("\n");
+ log(" -script <file>\n");
+ log(" use the specified ABC script file instead of the default script.\n");
+ log("\n");
+ log(" if <file> starts with a plus sign (+), then the rest of the filename\n");
+ log(" string is interpreted as the command string to be passed to ABC. The\n");
+ log(" leading plus sign is removed and all commas (,) in the string are\n");
+ log(" replaced with blanks before the string is passed to ABC.\n");
+ log("\n");
+ log(" if no -script parameter is given, the following scripts are used:\n");
+ log("\n");
+ log(" for -lut/-luts (only one LUT size):\n");
+ log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
+ log("\n");
+ log(" for -lut/-luts (different LUT sizes):\n");
+ log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());
+ log("\n");
+ log(" -fast\n");
+ log(" use different default scripts that are slightly faster (at the cost\n");
+ log(" of output quality):\n");
+ log("\n");
+ log(" for -lut/-luts:\n");
+ log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
+ log("\n");
+ log(" -D <picoseconds>\n");
+ log(" set delay target. the string {D} in the default scripts above is\n");
+ log(" replaced by this option when used, and an empty string otherwise\n");
+ log(" (indicating best possible delay).\n");
+// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n");
+// log(" default scripts above.\n");
+ log("\n");
+// log(" -S <num>\n");
+// log(" maximum number of LUT inputs shared.\n");
+// log(" (replaces {S} in the default scripts above, default: -S 1)\n");
+// log("\n");
+ log(" -lut <width>\n");
+ log(" generate netlist using luts of (max) the specified width.\n");
+ log("\n");
+ log(" -lut <w1>:<w2>\n");
+ log(" generate netlist using luts of (max) the specified width <w2>. All\n");
+ log(" luts with width <= <w1> have constant cost. for luts larger than <w1>\n");
+ log(" the area cost doubles with each additional input bit. the delay cost\n");
+ log(" is still constant for all lut widths.\n");
+ log("\n");
+ log(" -lut <file>\n");
+ log(" pass this file with lut library to ABC.\n");
+ log("\n");
+ log(" -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..\n");
+ log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
+ log(" 2, 3, .. inputs.\n");
+ log("\n");
+// log(" -dff\n");
+// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n");
+// log(" clock domains are automatically partitioned in clock domains and each\n");
+// log(" domain is passed through ABC independently.\n");
+// log("\n");
+// log(" -clk [!]<clock-signal-name>[,[!]<enable-signal-name>]\n");
+// log(" use only the specified clock domain. this is like -dff, but only FF\n");
+// log(" cells that belong to the specified clock domain are used.\n");
+// log("\n");
+// log(" -keepff\n");
+// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n");
+// log(" them, for example for equivalence checking.)\n");
+// log("\n");
+ log(" -showtmp\n");
+ log(" print the temp dir name in log. usually this is suppressed so that the\n");
+ log(" command output is identical across runs.\n");
+ log("\n");
+ log(" -markgroups\n");
+ log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n");
+ log(" this attribute is a unique integer for each ABC process started. This\n");
+ log(" is useful for debugging the partitioning of clock domains.\n");
+ log("\n");
+ log(" -box <file>\n");
+ log(" pass this file with box library to ABC. Use with -lut.\n");
+ log("\n");
+ log(" -tempdir <dir>\n");
+ log(" use this as the temp dir.\n");
+ log("\n");
+ log("Note that this is a logic optimization pass within Yosys that is calling ABC\n");
+ log("internally. This is not going to \"run ABC on your design\". It will instead run\n");
+ log("ABC on logic snippets extracted from your design. You will not get any useful\n");
+ log("output when passing an ABC script that writes a file. Instead write your full\n");
+ log("design as BLIF file with write_blif and then load that into ABC externally if\n");
+ log("you want to use ABC to convert your design into another format.\n");
+ log("\n");
+ log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ log_header(design, "Executing ABC9_MAP pass (technology mapping using ABC9).\n");
+
+#ifdef ABCEXTERNAL
+ std::string exe_file = ABCEXTERNAL;
+#else
+ std::string exe_file = proc_self_dirname() + "yosys-abc";
+#endif
+ std::string script_file, clk_str, box_file, lut_file;
+ std::string delay_target, lutin_shared = "-S 1", wire_delay;
+ std::string tempdir_name;
+ bool fast_mode = false;
+ bool show_tempdir = false;
+ bool nomfs = false;
+ vector<int> lut_costs;
+ markgroups = false;
+
+#if 0
+ cleanup = false;
+ show_tempdir = true;
+#endif
+
+#ifdef _WIN32
+#ifndef ABCEXTERNAL
+ if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe"))
+ exe_file = proc_self_dirname() + "..\\yosys-abc";
+#endif
+#endif
+
+ size_t argidx;
+ char pwd [PATH_MAX];
+ if (!getcwd(pwd, sizeof(pwd))) {
+ log_cmd_error("getcwd failed: %s\n", strerror(errno));
+ log_abort();
+ }
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ std::string arg = args[argidx];
+ if (arg == "-exe" && argidx+1 < args.size()) {
+ exe_file = args[++argidx];
+ continue;
+ }
+ if (arg == "-script" && argidx+1 < args.size()) {
+ script_file = args[++argidx];
+ rewrite_filename(script_file);
+ if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')
+ script_file = std::string(pwd) + "/" + script_file;
+ continue;
+ }
+ if (arg == "-D" && argidx+1 < args.size()) {
+ delay_target = "-D " + args[++argidx];
+ continue;
+ }
+ //if (arg == "-S" && argidx+1 < args.size()) {
+ // lutin_shared = "-S " + args[++argidx];
+ // continue;
+ //}
+ if (arg == "-lut" && argidx+1 < args.size()) {
+ string arg = args[++argidx];
+ if (arg.find_first_not_of("0123456789:") == std::string::npos) {
+ size_t pos = arg.find_first_of(':');
+ int lut_mode = 0, lut_mode2 = 0;
+ if (pos != string::npos) {
+ lut_mode = atoi(arg.substr(0, pos).c_str());
+ lut_mode2 = atoi(arg.substr(pos+1).c_str());
+ } else {
+ lut_mode = atoi(arg.c_str());
+ lut_mode2 = lut_mode;
+ }
+ lut_costs.clear();
+ for (int i = 0; i < lut_mode; i++)
+ lut_costs.push_back(1);
+ for (int i = lut_mode; i < lut_mode2; i++)
+ lut_costs.push_back(2 << (i - lut_mode));
+ }
+ else {
+ lut_file = arg;
+ rewrite_filename(lut_file);
+ if (!lut_file.empty() && !is_absolute_path(lut_file) && lut_file[0] != '+')
+ lut_file = std::string(pwd) + "/" + lut_file;
+ }
+ continue;
+ }
+ if (arg == "-luts" && argidx+1 < args.size()) {
+ lut_costs.clear();
+ for (auto &tok : split_tokens(args[++argidx], ",")) {
+ auto parts = split_tokens(tok, ":");
+ if (GetSize(parts) == 0 && !lut_costs.empty())
+ lut_costs.push_back(lut_costs.back());
+ else if (GetSize(parts) == 1)
+ lut_costs.push_back(atoi(parts.at(0).c_str()));
+ else if (GetSize(parts) == 2)
+ while (GetSize(lut_costs) < atoi(parts.at(0).c_str()))
+ lut_costs.push_back(atoi(parts.at(1).c_str()));
+ else
+ log_cmd_error("Invalid -luts syntax.\n");
+ }
+ continue;
+ }
+ if (arg == "-fast") {
+ fast_mode = true;
+ continue;
+ }
+ if (arg == "-showtmp") {
+ show_tempdir = true;
+ continue;
+ }
+ if (arg == "-markgroups") {
+ markgroups = true;
+ continue;
+ }
+ if (arg == "-box" && argidx+1 < args.size()) {
+ box_file = args[++argidx];
+ continue;
+ }
+ if (arg == "-W" && argidx+1 < args.size()) {
+ wire_delay = "-W " + args[++argidx];
+ continue;
+ }
+ if (arg == "-nomfs") {
+ nomfs = true;
+ continue;
+ }
+ if (arg == "-tempdir" && argidx+1 < args.size()) {
+ tempdir_name = args[++argidx];
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ // ABC expects a box file for XAIG
+ if (box_file.empty())
+ box_file = "+/dummy.box";
+
+ rewrite_filename(box_file);
+ if (!box_file.empty() && !is_absolute_path(box_file) && box_file[0] != '+')
+ box_file = std::string(pwd) + "/" + box_file;
+
+ if (tempdir_name.empty())
+ log_cmd_error("abc9_map '-tempdir' option is mandatory.\n");
+
+
+ for (auto mod : design->selected_modules())
+ {
+ if (mod->processes.size() > 0) {
+ log("Skipping module %s as it contains processes.\n", log_id(mod));
+ continue;
+ }
+
+ abc9_module(design, mod, script_file, exe_file, lut_costs,
+ delay_target, lutin_shared, fast_mode, show_tempdir,
+ box_file, lut_file, wire_delay, nomfs, tempdir_name);
+ }
+ }
+} Abc9MapPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
new file mode 100644
index 000000000..730431ebf
--- /dev/null
+++ b/passes/techmap/abc9_ops.cc
@@ -0,0 +1,449 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ * 2019 Eddie Hung <eddie@fpgeh.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/sigtools.h"
+#include "kernel/utils.h"
+#include "kernel/celltypes.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+void break_scc(RTLIL::Module *module)
+{
+ // For every unique SCC found, (arbitrarily) find the first
+ // cell in the component, and convert all wires driven by
+ // its output ports into a new PO, and drive its previous
+ // sinks with a new PI
+ pool<RTLIL::Const> ids_seen;
+ for (auto cell : module->selected_cells()) {
+ auto it = cell->attributes.find(ID(abc9_scc_id));
+ if (it == cell->attributes.end())
+ continue;
+ auto r = ids_seen.insert(it->second);
+ cell->attributes.erase(it);
+ if (!r.second)
+ continue;
+ for (auto &c : cell->connections_) {
+ if (c.second.is_fully_const()) continue;
+ if (cell->output(c.first)) {
+ SigBit b = c.second.as_bit();
+ Wire *w = b.wire;
+ if (w->port_input) {
+ // In this case, hopefully the loop break has been already created
+ // Get the non-prefixed wire
+ Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str()));
+ log_assert(wo != nullptr);
+ log_assert(wo->port_output);
+ log_assert(b.offset < GetSize(wo));
+ c.second = RTLIL::SigBit(wo, b.offset);
+ }
+ else {
+ // Create a new output/input loop break
+ w->port_input = true;
+ w = module->wire(stringf("%s.abco", w->name.c_str()));
+ if (!w) {
+ w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire));
+ w->port_output = true;
+ }
+ else {
+ log_assert(w->port_input);
+ log_assert(b.offset < GetSize(w));
+ }
+ w->set_bool_attribute(ID(abc9_scc_break));
+ c.second = RTLIL::SigBit(w, b.offset);
+ }
+ }
+ }
+ }
+
+ module->fixup_ports();
+}
+
+void unbreak_scc(RTLIL::Module *module)
+{
+ // Now 'unexpose' those wires by undoing
+ // the expose operation -- remove them from PO/PI
+ // and re-connecting them back together
+ for (auto wire : module->wires()) {
+ auto it = wire->attributes.find(ID(abc9_scc_break));
+ if (it != wire->attributes.end()) {
+ wire->attributes.erase(it);
+ log_assert(wire->port_output);
+ wire->port_output = false;
+ std::string name = wire->name.str();
+ RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5));
+ log_assert(i_wire);
+ log_assert(i_wire->port_input);
+ i_wire->port_input = false;
+ module->connect(i_wire, wire);
+ }
+ }
+ module->fixup_ports();
+}
+
+void prep_dff(RTLIL::Module *module)
+{
+ auto design = module->design;
+ log_assert(design);
+
+ SigMap assign_map(module);
+
+ typedef SigSpec clkdomain_t;
+ dict<clkdomain_t, int> clk_to_mergeability;
+
+ for (auto cell : module->selected_cells()) {
+ if (cell->type != "$__ABC9_FF_")
+ continue;
+
+ Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str()));
+ if (abc9_clock_wire == NULL)
+ log_error("'%s.clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
+ SigSpec abc9_clock = assign_map(abc9_clock_wire);
+
+ clkdomain_t key(abc9_clock);
+
+ auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
+ auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second));
+ log_assert(r2.second);
+
+ Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str()));
+ if (abc9_init_wire == NULL)
+ log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
+ log_assert(GetSize(abc9_init_wire) == 1);
+ SigSpec abc9_init = assign_map(abc9_init_wire);
+ if (!abc9_init.is_fully_const())
+ log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
+ r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const()));
+ log_assert(r2.second);
+ }
+
+ RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str()));
+ if (holes_module) {
+ dict<SigSig, SigSig> 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 <port> = DFF.Q;" with "assign <port> = 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 "<cell>.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 "<cell>.$abc9_currQ"
+ // 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);
+ }
+ else
+ ++it;
+ }
+
+ for (auto &conn : holes_module->connections_) {
+ auto it = replace.find(conn);
+ if (it != replace.end())
+ conn = it->second;
+ }
+ }
+}
+
+void prep_holes(RTLIL::Module *module, bool dff)
+{
+ auto design = module->design;
+ log_assert(design);
+
+ SigMap sigmap(module);
+
+ dict<SigBit, pool<IdString>> bit_drivers, bit_users;
+ TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
+ bool abc9_box_seen = false;
+
+ for (auto cell : module->selected_cells()) {
+ if (cell->type == "$__ABC9_FF_")
+ continue;
+
+ auto inst_module = module->design->module(cell->type);
+ bool abc9_box = inst_module && inst_module->attributes.count("\\abc9_box_id");
+ bool abc9_flop = false;
+ if (abc9_box) {
+ abc9_flop = inst_module->get_bool_attribute("\\abc9_flop");
+ if (abc9_flop && !dff)
+ continue;
+ abc9_box_seen = abc9_box;
+ }
+ else if (!yosys_celltypes.cell_known(cell->type))
+ continue;
+
+ for (auto conn : cell->connections()) {
+ if (cell->input(conn.first))
+ for (auto bit : sigmap(conn.second))
+ bit_users[bit].insert(cell->name);
+
+ if (cell->output(conn.first) && !abc9_flop)
+ for (auto bit : sigmap(conn.second))
+ bit_drivers[bit].insert(cell->name);
+ }
+
+ toposort.node(cell->name);
+ }
+
+ if (!abc9_box_seen)
+ return;
+
+ 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);
+
+ vector<Cell*> box_list;
+ for (auto cell_name : toposort.sorted) {
+ RTLIL::Cell *cell = module->cell(cell_name);
+ log_assert(cell);
+
+ RTLIL::Module* box_module = design->module(cell->type);
+ if (!box_module || !box_module->attributes.count("\\abc9_box_id"))
+ continue;
+ cell->attributes["\\abc9_box_seq"] = box_list.size();
+ box_list.emplace_back(cell);
+ }
+ log_assert(!box_list.empty());
+
+ RTLIL::Module *holes_module = design->addModule(stringf("%s$holes", module->name.c_str()));
+ log_assert(holes_module);
+ holes_module->set_bool_attribute("\\abc9_holes");
+
+ dict<IdString, Cell*> cell_cache;
+ dict<IdString, std::vector<IdString>> box_ports;
+
+ int port_id = 1;
+ for (auto cell : box_list) {
+ RTLIL::Module* orig_box_module = design->module(cell->type);
+ log_assert(orig_box_module);
+ IdString derived_name = orig_box_module->derive(design, cell->parameters);
+ RTLIL::Module* box_module = design->module(derived_name);
+ if (box_module->has_processes())
+ Pass::call_on_module(design, box_module, "proc");
+
+ int box_inputs = 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;
+ }
+
+ auto r2 = box_ports.insert(cell->type);
+ if (r2.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
+ r2.first->second.push_back(port_name);
+ }
+
+ 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()) {
+ r2.first->second.push_back(carry_in);
+ r2.first->second.push_back(carry_out);
+ }
+ }
+
+ for (const 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)
+ 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)
+ 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 "<cell>.$abc9_currQ" 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()));
+ holes_module->connect(w, holes_wire);
+ }
+ }
+}
+
+struct Abc9OpsPass : public Pass {
+ Abc9OpsPass() : Pass("abc9_ops", "helper functions for ABC9") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" abc9_ops [options] [selection]\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ log_header(design, "Executing ABC9_OPS pass (helper functions for ABC9).\n");
+
+ bool break_scc_mode = false;
+ bool unbreak_scc_mode = false;
+ bool prep_dff_mode = false;
+ bool prep_holes_mode = false;
+ bool dff_mode = false;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ std::string arg = args[argidx];
+ if (arg == "-break_scc") {
+ break_scc_mode = true;
+ continue;
+ }
+ if (arg == "-unbreak_scc") {
+ unbreak_scc_mode = true;
+ continue;
+ }
+ if (arg == "-prep_dff") {
+ prep_dff_mode = true;
+ continue;
+ }
+ if (arg == "-prep_holes") {
+ prep_holes_mode = true;
+ continue;
+ }
+ if (arg == "-dff") {
+ dff_mode = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ for (auto mod : design->selected_modules()) {
+ if (mod->get_blackbox_attribute())
+ continue;
+ if (mod->get_bool_attribute("\\abc9_holes"))
+ continue;
+
+ if (mod->processes.size() > 0) {
+ log("Skipping module %s as it contains processes.\n", log_id(mod));
+ continue;
+ }
+
+ if (break_scc_mode)
+ break_scc(mod);
+ if (unbreak_scc_mode)
+ unbreak_scc(mod);
+ if (prep_dff_mode)
+ prep_dff(mod);
+ if (prep_holes_mode)
+ prep_holes(mod, dff_mode);
+ }
+ }
+} Abc9OpsPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index 47da98b06..531ac2b99 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -234,6 +234,9 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
Cell *tbuf_cell = nullptr;
+ if (skip_wire_bits.count(wire_bit))
+ continue;
+
if (tbuf_bits.count(wire_bit))
tbuf_cell = tbuf_bits.at(wire_bit);
diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc
index 626860d9c..1dc6bdb2f 100755
--- a/techlibs/achronix/synth_achronix.cc
+++ b/techlibs/achronix/synth_achronix.cc
@@ -52,7 +52,7 @@ struct SynthAchronixPass : public ScriptPass {
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -152,12 +152,12 @@ struct SynthAchronixPass : public ScriptPass {
run("clean -purge");
run("setundef -undriven -zero");
if (retime || help_mode)
- run("abc -markgroups -dff", "(only if -retime)");
+ run("abc -markgroups -dff -D 1", "(only if -retime)");
}
if (check_label("map_luts"))
{
- run("abc -lut 4" + string(retime ? " -dff" : ""));
+ run("abc -lut 4" + string(retime ? " -dff -D 1" : ""));
run("clean");
}
diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc
index 9426b5ca5..2d8d65e2e 100644
--- a/techlibs/anlogic/Makefile.inc
+++ b/techlibs/anlogic/Makefile.inc
@@ -7,6 +7,6 @@ $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/eagle_bb.v))
-$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/drams.txt))
-$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/drams_map.v))
-$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/dram_init_16x4.vh))
+$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams.txt))
+$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams_map.v))
+$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutram_init_16x4.vh))
diff --git a/techlibs/anlogic/cells_map.v b/techlibs/anlogic/cells_map.v
index cfc743a4b..8ac087d9d 100644
--- a/techlibs/anlogic/cells_map.v
+++ b/techlibs/anlogic/cells_map.v
@@ -6,14 +6,14 @@ module \$_DFFE_NP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REG
module \$_DFFE_PN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule
module \$_DFFE_PP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule
-module \$_DFF_NN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_NN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_NP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_NP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_PN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) , .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_PN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_PP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule
-module \$_DFF_PP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_NN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_NN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_NP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_NP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_PN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) , .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_PN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_PP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule
+module \$_DFF_PP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule
module \$_DLATCH_N_ (E, D, Q);
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
diff --git a/techlibs/anlogic/dram_init_16x4.vh b/techlibs/anlogic/lutram_init_16x4.vh
index 32fb1578c..32fb1578c 100644
--- a/techlibs/anlogic/dram_init_16x4.vh
+++ b/techlibs/anlogic/lutram_init_16x4.vh
diff --git a/techlibs/anlogic/drams.txt b/techlibs/anlogic/lutrams.txt
index 4e903c0a2..4e903c0a2 100644
--- a/techlibs/anlogic/drams.txt
+++ b/techlibs/anlogic/lutrams.txt
diff --git a/techlibs/anlogic/drams_map.v b/techlibs/anlogic/lutrams_map.v
index 084e2a25f..5a464cafc 100644
--- a/techlibs/anlogic/drams_map.v
+++ b/techlibs/anlogic/lutrams_map.v
@@ -10,7 +10,7 @@ module \$__ANLOGIC_DRAM16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
input B1EN;
EG_LOGIC_DRAM16X4 #(
- `include "dram_init_16x4.vh"
+ `include "lutram_init_16x4.vh"
) _TECHMAP_REPLACE_ (
.di(B1DATA),
.waddr(B1ADDR),
diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc
index b87fc8566..aaa6bda4a 100644
--- a/techlibs/anlogic/synth_anlogic.cc
+++ b/techlibs/anlogic/synth_anlogic.cc
@@ -58,7 +58,10 @@ struct SynthAnlogicPass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
+ log("\n");
+ log(" -nolutram\n");
+ log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -67,7 +70,7 @@ struct SynthAnlogicPass : public ScriptPass
}
string top_opt, edif_file, json_file;
- bool flatten, retime;
+ bool flatten, retime, nolutram;
void clear_flags() YS_OVERRIDE
{
@@ -76,6 +79,7 @@ struct SynthAnlogicPass : public ScriptPass
json_file = "";
flatten = true;
retime = false;
+ nolutram = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -110,6 +114,10 @@ struct SynthAnlogicPass : public ScriptPass
flatten = false;
continue;
}
+ if (args[argidx] == "-nolutram") {
+ nolutram = true;
+ continue;
+ }
if (args[argidx] == "-retime") {
retime = true;
continue;
@@ -150,21 +158,25 @@ struct SynthAnlogicPass : public ScriptPass
run("synth -run coarse");
}
- if (check_label("dram"))
+ if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
{
- run("memory_bram -rules +/anlogic/drams.txt");
- run("techmap -map +/anlogic/drams_map.v");
+ run("memory_bram -rules +/anlogic/lutrams.txt");
+ run("techmap -map +/anlogic/lutrams_map.v");
run("setundef -zero -params t:EG_LOGIC_DRAM16X4");
}
- if (check_label("fine"))
+ if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine");
+ }
+
+ if (check_label("map_gates"))
+ {
run("techmap -map +/techmap.v -map +/anlogic/arith_map.v");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_ffs"))
@@ -187,7 +199,7 @@ struct SynthAnlogicPass : public ScriptPass
run("techmap -map +/anlogic/cells_map.v");
run("clean");
}
-
+
if (check_label("map_anlogic"))
{
run("anlogic_fixcarry");
diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc
index 014c68622..388e2b792 100644
--- a/techlibs/coolrunner2/synth_coolrunner2.cc
+++ b/techlibs/coolrunner2/synth_coolrunner2.cc
@@ -55,7 +55,7 @@ struct SynthCoolrunner2Pass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -161,7 +161,7 @@ struct SynthCoolrunner2Pass : public ScriptPass
if (check_label("map_pla"))
{
- run("abc -sop -I 40 -P 56");
+ run("abc -sop -I 40 -P 56" + string(retime ? " -dff -D 1" : ""));
run("clean");
}
diff --git a/techlibs/easic/synth_easic.cc b/techlibs/easic/synth_easic.cc
index dd9e3dab7..b4a3a1ac9 100644
--- a/techlibs/easic/synth_easic.cc
+++ b/techlibs/easic/synth_easic.cc
@@ -56,7 +56,7 @@ struct SynthEasicPass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -158,7 +158,7 @@ struct SynthEasicPass : public ScriptPass
run("techmap");
run("opt -fast");
if (retime || help_mode) {
- run("abc -dff", " (only if -retime)");
+ run("abc -dff -D 1", " (only if -retime)");
run("opt_clean", "(only if -retime)");
}
}
diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc
index 46463f510..2c33f23b9 100644
--- a/techlibs/ecp5/Makefile.inc
+++ b/techlibs/ecp5/Makefile.inc
@@ -8,9 +8,9 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_bb.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutrams_map.v))
-$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutram.txt))
+$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutrams.txt))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams_map.v))
-$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt))
+$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams.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/dsp_map.v))
diff --git a/techlibs/ecp5/abc9_5g.box b/techlibs/ecp5/abc9_5g.box
index 2bc945a54..f153a665e 100644
--- a/techlibs/ecp5/abc9_5g.box
+++ b/techlibs/ecp5/abc9_5g.box
@@ -1,43 +1,36 @@
-# NB: Inputs/Outputs must be ordered alphabetically
-# (with exceptions for carry in/out)
+# NB: Box inputs/outputs must each be in the same order
+# as their corresponding module definition
+# (with exceptions detailed below)
# Box 1 : CCU2C (2xCARRY + 2xLUT4)
-# Outputs: S0, S1, COUT
-# (NB: carry chain input/output must be last
-# input/output and bus has been moved
-# there overriding the otherwise
+# (Exception: carry chain input/output must be the
+# last input and output and the entire bus has been
+# moved there overriding the otherwise
# alphabetical ordering)
# name ID w/b ins outs
CCU2C 1 1 9 3
-
-#A0 A1 B0 B1 C0 C1 D0 D1 CIN
-379 - 379 - 275 - 141 - 257
-630 379 630 379 526 275 392 141 273
-516 516 516 516 412 412 278 278 43
+#A0 B0 C0 D0 A1 B1 C1 D1 CIN
+379 379 275 141 - - - - 257 # S0
+630 630 526 392 379 379 275 141 273 # S1
+516 516 412 278 516 516 412 278 43 # COUT
# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram)
-# Outputs: DO0, DO1, DO2, DO3
# name ID w/b ins outs
$__ABC9_DPR16X4_COMB 2 0 8 4
-
-#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
+#$DO0 $DO1 $DO2 $DO3 RAD0 RAD1 RAD2 RAD3
+0 0 0 0 141 379 275 379 # DO0
+0 0 0 0 141 379 275 379 # DO1
+0 0 0 0 141 379 275 379 # DO2
+0 0 0 0 141 379 275 379 # DO3
# Box 3 : PFUMX (MUX2)
-# Outputs: Z
# name ID w/b ins outs
PFUMX 3 1 3 1
-
#ALUT BLUT C0
-98 98 151
+98 98 151 # Z
# Box 4 : L6MUX21 (MUX2)
-# Outputs: Z
# name ID w/b ins outs
L6MUX21 4 1 3 1
-
#D0 D1 SD
-140 141 148
+140 141 148 # Z
diff --git a/techlibs/ecp5/abc9_map.v b/techlibs/ecp5/abc9_map.v
index d8d70f9f6..113a35b91 100644
--- a/techlibs/ecp5/abc9_map.v
+++ b/techlibs/ecp5/abc9_map.v
@@ -1,24 +1,27 @@
// ---------------------------------------
+// Attach a (combinatorial) black-box onto the output
+// of this LUTRAM primitive to capture its
+// asynchronous read behaviour
module TRELLIS_DPR16X4 (
- input [3:0] DI,
- input [3:0] WAD,
- input WRE,
- input WCK,
- input [3:0] RAD,
+ (* techmap_autopurge *) input [3:0] DI,
+ (* techmap_autopurge *) input [3:0] WAD,
+ (* techmap_autopurge *) input WRE,
+ (* techmap_autopurge *) input WCK,
+ (* techmap_autopurge *) input [3:0] RAD,
output [3:0] DO
);
parameter WCKMUX = "WCK";
parameter WREMUX = "WRE";
parameter [63:0] INITVAL = 64'h0000000000000000;
- wire [3:0] \$DO ;
+ wire [3:0] $DO;
TRELLIS_DPR16X4 #(
.WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL)
) _TECHMAP_REPLACE_ (
.DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK),
- .RAD(RAD), .DO(\$DO )
+ .RAD(RAD), .DO($DO)
);
- \$__ABC9_DPR16X4_COMB do (.A(\$DO ), .S(RAD), .Y(DO));
+ $__ABC9_DPR16X4_COMB do (.$DO($DO), .RAD(RAD), .DO(DO));
endmodule
diff --git a/techlibs/ecp5/abc9_model.v b/techlibs/ecp5/abc9_model.v
index 1dc8b5617..81e5cd070 100644
--- a/techlibs/ecp5/abc9_model.v
+++ b/techlibs/ecp5/abc9_model.v
@@ -1,5 +1,5 @@
// ---------------------------------------
(* abc9_box_id=2 *)
-module \$__ABC9_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
+module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO);
endmodule
diff --git a/techlibs/ecp5/abc9_unmap.v b/techlibs/ecp5/abc9_unmap.v
index 9ae143c46..cbdffdaf1 100644
--- a/techlibs/ecp5/abc9_unmap.v
+++ b/techlibs/ecp5/abc9_unmap.v
@@ -1,5 +1,5 @@
// ---------------------------------------
-module \$__ABC9_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
- assign Y = A;
+module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO);
+ assign DO = $DO;
endmodule
diff --git a/techlibs/ecp5/bram.txt b/techlibs/ecp5/brams.txt
index 777ccaa2e..777ccaa2e 100644
--- a/techlibs/ecp5/bram.txt
+++ b/techlibs/ecp5/brams.txt
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index f467218cc..0d3ec4e5b 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -1,5 +1,6 @@
// ---------------------------------------
+(* lib_whitebox *)
module LUT4(input A, B, C, D, output Z);
parameter [15:0] INIT = 16'h0000;
wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0];
@@ -31,13 +32,8 @@ module CCU2C(
// First half
wire LUT4_0, LUT2_0;
-`ifdef _ABC
- assign LUT4_0 = INIT0[{D0, C0, B0, A0}];
- assign LUT2_0 = INIT0[{2'b00, B0, A0}];
-`else
LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0));
LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0));
-`endif
wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN;
assign S0 = LUT4_0 ^ gated_cin_0;
@@ -46,13 +42,8 @@ module CCU2C(
// Second half
wire LUT4_1, LUT2_1;
-`ifdef _ABC
- assign LUT4_1 = INIT1[{D1, C1, B1, A1}];
- assign LUT2_1 = INIT1[{2'b00, B1, A1}];
-`else
LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1));
LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1));
-`endif
wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0;
assign S1 = LUT4_1 ^ gated_cin_1;
@@ -209,6 +200,7 @@ endmodule
// ---------------------------------------
+(* lib_whitebox *)
module LUT2(input A, B, output Z);
parameter [3:0] INIT = 4'h0;
wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0];
diff --git a/techlibs/ecp5/lutram.txt b/techlibs/ecp5/lutrams.txt
index b94357429..b94357429 100644
--- a/techlibs/ecp5/lutram.txt
+++ b/techlibs/ecp5/lutrams.txt
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index b71bb2395..d616391b2 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -62,7 +62,7 @@ struct SynthEcp5Pass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log(" -noccu2\n");
log(" do not use CCU2 cells in output netlist\n");
@@ -230,7 +230,7 @@ struct SynthEcp5Pass : public ScriptPass
{
if (check_label("begin"))
{
- run("read_verilog -D_ABC -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
+ run("read_verilog -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
@@ -266,13 +266,13 @@ struct SynthEcp5Pass : public ScriptPass
if (!nobram && check_label("map_bram", "(skip if -nobram)"))
{
- run("memory_bram -rules +/ecp5/bram.txt");
+ run("memory_bram -rules +/ecp5/brams.txt");
run("techmap -map +/ecp5/brams_map.v");
}
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
{
- run("memory_bram -rules +/ecp5/lutram.txt");
+ run("memory_bram -rules +/ecp5/lutrams.txt");
run("techmap -map +/ecp5/lutrams_map.v");
}
@@ -290,7 +290,7 @@ struct SynthEcp5Pass : public ScriptPass
else
run("techmap -map +/techmap.v -map +/ecp5/arith_map.v");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_ffs"))
diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc
index 5013f7fc1..69665982c 100644
--- a/techlibs/efinix/Makefile.inc
+++ b/techlibs/efinix/Makefile.inc
@@ -7,4 +7,4 @@ $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v))
-$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt))
+$(eval $(call add_share_file,share/efinix,techlibs/efinix/brams.txt))
diff --git a/techlibs/efinix/bram.txt b/techlibs/efinix/brams.txt
index 0b3fd9308..0b3fd9308 100644
--- a/techlibs/efinix/bram.txt
+++ b/techlibs/efinix/brams.txt
diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc
index 26a8d4eda..0efd91708 100644
--- a/techlibs/efinix/synth_efinix.cc
+++ b/techlibs/efinix/synth_efinix.cc
@@ -58,7 +58,10 @@ struct SynthEfinixPass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
+ log("\n");
+ log(" -nobram\n");
+ log(" do not use EFX_RAM_5K cells in output netlist\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -67,7 +70,7 @@ struct SynthEfinixPass : public ScriptPass
}
string top_opt, edif_file, json_file;
- bool flatten, retime;
+ bool flatten, retime, nobram;
void clear_flags() YS_OVERRIDE
{
@@ -76,6 +79,7 @@ struct SynthEfinixPass : public ScriptPass
json_file = "";
flatten = true;
retime = false;
+ nobram = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -114,6 +118,10 @@ struct SynthEfinixPass : public ScriptPass
retime = true;
continue;
}
+ if (args[argidx] == "-nobram") {
+ nobram = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -150,21 +158,25 @@ struct SynthEfinixPass : public ScriptPass
run("synth -run coarse");
}
- if (check_label("map_bram", "(skip if -nobram)"))
+ if (!nobram || check_label("map_bram", "(skip if -nobram)"))
{
- run("memory_bram -rules +/efinix/bram.txt");
+ run("memory_bram -rules +/efinix/brams.txt");
run("techmap -map +/efinix/brams_map.v");
run("setundef -zero -params t:EFX_RAM_5K");
}
- if (check_label("fine"))
+ if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine");
+ }
+
+ if (check_label("map_gates"))
+ {
run("techmap -map +/techmap.v -map +/efinix/arith_map.v");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_ffs"))
@@ -194,7 +206,7 @@ struct SynthEfinixPass : public ScriptPass
run("efinix_fixcarry");
run("clean");
}
-
+
if (check_label("check"))
{
run("hierarchy -check");
diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc
index d2853704b..fe5d9d6e6 100644
--- a/techlibs/gowin/Makefile.inc
+++ b/techlibs/gowin/Makefile.inc
@@ -7,9 +7,9 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_sim.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v))
-$(eval $(call add_share_file,share/gowin,techlibs/gowin/bram.txt))
-$(eval $(call add_share_file,share/gowin,techlibs/gowin/drams_map.v))
-$(eval $(call add_share_file,share/gowin,techlibs/gowin/dram.txt))
+$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt))
+$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v))
+$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt))
diff --git a/techlibs/gowin/bram.txt b/techlibs/gowin/brams.txt
index e406f9c51..e406f9c51 100644
--- a/techlibs/gowin/bram.txt
+++ b/techlibs/gowin/brams.txt
diff --git a/techlibs/gowin/dram.txt b/techlibs/gowin/lutrams.txt
index 9db530251..9db530251 100644
--- a/techlibs/gowin/dram.txt
+++ b/techlibs/gowin/lutrams.txt
diff --git a/techlibs/gowin/drams_map.v b/techlibs/gowin/lutrams_map.v
index a50ab365a..a50ab365a 100644
--- a/techlibs/gowin/drams_map.v
+++ b/techlibs/gowin/lutrams_map.v
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc
index 6cf058f29..c5b41b503 100644
--- a/techlibs/gowin/synth_gowin.cc
+++ b/techlibs/gowin/synth_gowin.cc
@@ -55,23 +55,23 @@ struct SynthGowinPass : public ScriptPass
log(" -nobram\n");
log(" do not use BRAM cells in output netlist\n");
log("\n");
- log(" -nodram\n");
+ log(" -nolutram\n");
log(" do not use distributed RAM cells in output netlist\n");
log("\n");
log(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log(" -nowidelut\n");
log(" do not use muxes to implement LUTs larger than LUT4s\n");
log("\n");
log(" -noiopads\n");
log(" do not emit IOB at top level ports\n");
- log("\n");
- log(" -abc9\n");
- log(" use new ABC9 flow (EXPERIMENTAL)\n");
+ //log("\n");
+ //log(" -abc9\n");
+ //log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -80,7 +80,7 @@ struct SynthGowinPass : public ScriptPass
}
string top_opt, vout_file;
- bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9, noiopads;
+ bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads;
void clear_flags() YS_OVERRIDE
{
@@ -90,7 +90,7 @@ struct SynthGowinPass : public ScriptPass
flatten = true;
nobram = false;
nodffe = false;
- nodram = false;
+ nolutram = false;
nowidelut = false;
abc9 = false;
noiopads = false;
@@ -128,8 +128,8 @@ struct SynthGowinPass : public ScriptPass
nobram = true;
continue;
}
- if (args[argidx] == "-nodram") {
- nodram = true;
+ if (args[argidx] == "-nolutram" || /*deprecated*/args[argidx] == "-nodram") {
+ nolutram = true;
continue;
}
if (args[argidx] == "-nodffe") {
@@ -144,10 +144,10 @@ struct SynthGowinPass : public ScriptPass
nowidelut = true;
continue;
}
- if (args[argidx] == "-abc9") {
- abc9 = true;
- continue;
- }
+ //if (args[argidx] == "-abc9") {
+ // abc9 = true;
+ // continue;
+ //}
if (args[argidx] == "-noiopads") {
noiopads = true;
continue;
@@ -188,28 +188,32 @@ struct SynthGowinPass : public ScriptPass
run("synth -run coarse");
}
- if (!nobram && check_label("bram", "(skip if -nobram)"))
+ if (!nobram && check_label("map_bram", "(skip if -nobram)"))
{
- run("memory_bram -rules +/gowin/bram.txt");
+ run("memory_bram -rules +/gowin/brams.txt");
run("techmap -map +/gowin/brams_map.v -map +/gowin/cells_sim.v");
}
- if (!nodram && check_label("dram", "(skip if -nodram)"))
+ if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
{
- run("memory_bram -rules +/gowin/dram.txt");
- run("techmap -map +/gowin/drams_map.v");
+ run("memory_bram -rules +/gowin/lutrams.txt");
+ run("techmap -map +/gowin/lutrams_map.v");
run("determine_init");
}
- if (check_label("fine"))
+ if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine");
+ }
+
+ if (check_label("map_gates"))
+ {
run("techmap -map +/techmap.v -map +/gowin/arith_map.v");
run("techmap -map +/techmap.v");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
run("splitnets");
}
@@ -227,13 +231,13 @@ struct SynthGowinPass : public ScriptPass
if (check_label("map_luts"))
{
- if (nowidelut && abc9) {
+ /*if (nowidelut && abc9) {
run("abc9 -lut 4");
- } else if (nowidelut && !abc9) {
+ } else*/ if (nowidelut && !abc9) {
run("abc -lut 4");
- } else if (!nowidelut && abc9) {
+ } else /*if (!nowidelut && abc9) {
run("abc9 -lut 4:8");
- } else if (!nowidelut && !abc9) {
+ } else*/ if (!nowidelut && !abc9) {
run("abc -lut 4:8");
}
run("clean");
@@ -248,7 +252,6 @@ struct SynthGowinPass : public ScriptPass
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O "
"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)");
run("clean");
-
}
if (check_label("check"))
diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc
index eeb001b46..e1fbe6b69 100644
--- a/techlibs/greenpak4/synth_greenpak4.cc
+++ b/techlibs/greenpak4/synth_greenpak4.cc
@@ -59,7 +59,7 @@ struct SynthGreenPAK4Pass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -165,7 +165,7 @@ struct SynthGreenPAK4Pass : public ScriptPass
run("dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib");
run("opt -fast");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_luts"))
diff --git a/techlibs/ice40/abc9_hx.box b/techlibs/ice40/abc9_hx.box
index 3ea70bc91..31e743669 100644
--- a/techlibs/ice40/abc9_hx.box
+++ b/techlibs/ice40/abc9_hx.box
@@ -1,13 +1,17 @@
# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt
-# NB: Inputs/Outputs must be ordered alphabetically
-# (with exceptions for carry in/out)
+# NB: Box inputs/outputs must each be in the same order
+# as their corresponding module definition
+# (with exceptions detailed below)
-# Inputs: A B I0 I3 CI
-# Outputs: O CO
-# (NB: carry chain input/output must be last
-# input/output and have been moved there
-# overriding the alphabetical ordering)
-$__ICE40_CARRY_WRAPPER 1 1 5 2
-400 379 449 316 316
-259 231 - - 126
+# Box 1 : $__ICE40_CARRY_WRAPPER (private cell used to preserve
+# SB_LUT4+SB_CARRY)
+# (Exception: carry chain input/output must be the
+# last input and output and the entire bus has been
+# moved there overriding the otherwise
+# alphabetical ordering)
+# name ID w/b ins outs
+$__ICE40_CARRY_WRAPPER 1 1 5 2
+#A B I0 I3 CI
+400 379 449 316 316 # O
+259 231 - - 126 # CO
diff --git a/techlibs/ice40/abc9_lp.box b/techlibs/ice40/abc9_lp.box
index 473e92fe9..71986a67b 100644
--- a/techlibs/ice40/abc9_lp.box
+++ b/techlibs/ice40/abc9_lp.box
@@ -1,13 +1,17 @@
# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt
-# NB: Inputs/Outputs must be ordered alphabetically
-# (with exceptions for carry in/out)
+# NB: Box inputs/outputs must each be in the same order
+# as their corresponding module definition
+# (with exceptions detailed below)
-# Inputs: A B I0 I3 CI
-# Outputs: O CO
-# (NB: carry chain input/output must be last
-# input/output and have been moved there
-# overriding the alphabetical ordering)
-$__ICE40_CARRY_WRAPPER 1 1 5 2
-589 558 661 465 465
-675 609 - - 186
+# Box 1 : $__ICE40_CARRY_WRAPPER (private cell used to preserve
+# SB_LUT4+SB_CARRY)
+# (Exception: carry chain input/output must be the
+# last input and output and the entire bus has been
+# moved there overriding the otherwise
+# alphabetical ordering)
+# name ID w/b ins outs
+$__ICE40_CARRY_WRAPPER 1 1 5 2
+#A B I0 I3 CI
+589 558 661 465 465 # O
+675 609 - - 186 # CO
diff --git a/techlibs/ice40/abc9_u.box b/techlibs/ice40/abc9_u.box
index f00e247b8..48a51463e 100644
--- a/techlibs/ice40/abc9_u.box
+++ b/techlibs/ice40/abc9_u.box
@@ -1,13 +1,18 @@
# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt
-# NB: Inputs/Outputs must be ordered alphabetically
-# (with exceptions for carry in/out)
+# NB: Box inputs/outputs must each be in the same order
+# as their corresponding module definition
+# (with exceptions detailed below)
-# Inputs: A B I0 I3 CI
-# Outputs: O CO
-# (NB: carry chain input/output must be last
-# input/output and have been moved there
-# overriding the alphabetical ordering)
-$__ICE40_CARRY_WRAPPER 1 1 5 2
-1231 1205 1285 874 874
-675 609 - - 278
+# Box 1 : $__ICE40_CARRY_WRAPPER (private cell used to preserve
+# SB_LUT4+SB_CARRY)
+# Outputs: O, CO
+# (Exception: carry chain input/output must be the
+# last input and output and the entire bus has been
+# moved there overriding the otherwise
+# alphabetical ordering)
+# name ID w/b ins outs
+$__ICE40_CARRY_WRAPPER 1 1 5 2
+#A B I0 I3 CI
+1231 1205 1285 874 874 # O
+675 609 - - 278 # CO
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index ed7a16c08..463c2063a 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -65,7 +65,7 @@ struct SynthIce40Pass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log(" -nocarry\n");
log(" do not use SB_CARRY cells in output netlist\n");
@@ -316,7 +316,7 @@ struct SynthIce40Pass : public ScriptPass
run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
}
if (retime || help_mode)
- run(abc + " -dff", "(only if -retime)");
+ run(abc + " -dff -D 1", "(only if -retime)");
run("ice40_opt");
}
diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc
index c8c690e45..2ebb8bf50 100644
--- a/techlibs/intel/synth_intel.cc
+++ b/techlibs/intel/synth_intel.cc
@@ -71,7 +71,7 @@ struct SynthIntelPass : public ScriptPass {
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -187,10 +187,10 @@ struct SynthIntelPass : public ScriptPass {
}
if (!nobram && check_label("map_bram", "(skip if -nobram)")) {
- if (family_opt == "cycloneiv" ||
- family_opt == "cycloneive" ||
- family_opt == "max10" ||
- help_mode) {
+ if (family_opt == "cycloneiv" ||
+ family_opt == "cycloneive" ||
+ family_opt == "max10" ||
+ help_mode) {
run("memory_bram -rules +/intel/common/brams_m9k.txt", "(if applicable for family)");
run("techmap -map +/intel/common/brams_map_m9k.v", "(if applicable for family)");
} else {
@@ -210,7 +210,7 @@ struct SynthIntelPass : public ScriptPass {
run("clean -purge");
run("setundef -undriven -zero");
if (retime || help_mode)
- run("abc -markgroups -dff", "(only if -retime)");
+ run("abc -markgroups -dff -D 1", "(only if -retime)");
}
if (check_label("map_luts")) {
@@ -224,7 +224,7 @@ struct SynthIntelPass : public ScriptPass {
if (check_label("map_cells")) {
if (iopads || help_mode)
run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I", "(if -iopads)");
- run(stringf("techmap -map +/intel/%s/cells_map.v", family_opt.c_str()));
+ run(stringf("techmap -map +/intel/%s/cells_map.v", family_opt.c_str()));
run("dffinit -highlow -ff dffeas q power_up");
run("clean -purge");
}
diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc
index 0924df7a6..543dfdb9e 100644
--- a/techlibs/sf2/synth_sf2.cc
+++ b/techlibs/sf2/synth_sf2.cc
@@ -67,7 +67,7 @@ struct SynthSf2Pass : public ScriptPass
log(" insert direct PAD->global_net buffers\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
@@ -181,7 +181,7 @@ struct SynthSf2Pass : public ScriptPass
run("opt -undriven -fine");
run("techmap -map +/techmap.v -map +/sf2/arith_map.v");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_ffs"))
diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v
index 7b9427b2f..af58e217c 100644
--- a/techlibs/xilinx/abc9_map.v
+++ b/techlibs/xilinx/abc9_map.v
@@ -18,8 +18,366 @@
*
*/
-// ============================================================================
+// The following techmapping rules are intended to be run (with -max_iter 1)
+// before invoking the `abc9` pass in order to transform the design into
+// a format that it understands.
+`ifdef DFF_MODE
+// For example, (complex) flip-flops are expected to be described as an
+// combinatorial box (containing all control logic such as clock enable
+// or synchronous resets) followed by a basic D-Q flop.
+// Yosys will automatically analyse the simulation model (described in
+// cells_sim.v) and detach any $_DFF_P_ or $_DFF_N_ cells present in
+// order to extract the combinatorial control logic left behind.
+// Specifically, a simulation model similar to the one below:
+//
+// ++===================================++
+// || Sim model ||
+// || /\/\/\/\ ||
+// D -->>-----< > +------+ ||
+// R -->>-----< Comb. > |$_DFF_| ||
+// CE -->>-----< logic >-----| [NP]_|---+---->>-- Q
+// || +--< > +------+ | ||
+// || | \/\/\/\/ | ||
+// || | | ||
+// || +----------------------------+ ||
+// || ||
+// ++===================================++
+//
+// is transformed into:
+//
+// ++==================++
+// || Comb box ||
+// || ||
+// || /\/\/\/\ ||
+// D -->>-----< > ||
+// R -->>-----< Comb. > || +-----------+
+// CE -->>-----< logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q
+// abc9_ff.Q +-->>-----< > || +-----------+ |
+// | || \/\/\/\/ || |
+// | || || |
+// | ++==================++ |
+// | |
+// +-----------------------------------------------+
+//
+// The purpose of the following FD* rules are to wrap the flop with:
+// (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9
+// the connectivity of its basic D-Q flop
+// (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to
+// capture asynchronous behaviour
+// (c) a special abc9_ff.clock wire to capture its clock domain and polarity
+// (indicated to `abc9' so that it only performs sequential synthesis
+// (with reachability analysis) correctly on one domain at a time)
+// (d) a special abc9_ff.init wire to encode the flop's initial state
+// NOTE: in order to perform sequential synthesis, `abc9' also requires
+// that the initial value of all flops be zero
+// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
+// into the (combinatorial) FD* cell to facilitate clock-enable behaviour
+
+module FDRE (output 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 QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDSE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_S_INVERTED(IS_R_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDRE #(
+ .INIT(1'b0),
+ .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)
+ );
+ end
+ endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+module FDRE_1 (output Q, input C, CE, D, R);
+ parameter [0:0] INIT = 1'b0;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDSE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDRE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .R(R)
+ );
+ end
+ endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+
+module FDSE (output 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;
+ parameter [0:0] IS_S_INVERTED = 1'b0;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDRE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_R_INVERTED(IS_S_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDSE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_S_INVERTED(IS_S_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
+ );
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+module FDSE_1 (output Q, input C, CE, D, S);
+ parameter [0:0] INIT = 1'b1;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDRE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDSE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
+ );
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+
+module FDCE (output 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 QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDPE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_PRE_INVERTED(IS_CLR_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ // Since this is an async flop, async behaviour is dealt with here
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDCE #(
+ .INIT(1'b0),
+ .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)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ // Since this is an async flop, async behaviour is dealt with here
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+module FDCE_1 (output Q, input C, CE, D, CLR);
+ parameter [0:0] INIT = 1'b0;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDPE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDCE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+
+module FDPE (output 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;
+ parameter [0:0] IS_PRE_INVERTED = 1'b0;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDCE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_CLR_INVERTED(IS_PRE_INVERTED),
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDPE #(
+ .INIT(1'b0),
+ .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)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+module FDPE_1 (output Q, input C, CE, D, PRE);
+ parameter [0:0] INIT = 1'b1;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDCE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDPE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+`endif
+
+// Attach a (combinatorial) black-box onto the output
+// of thes LUTRAM primitives to capture their
+// asynchronous read behaviour
module RAM32X1D (
output DPO, SPO,
(* techmap_autopurge *) input D,
@@ -30,17 +388,17 @@ module RAM32X1D (
);
parameter INIT = 32'h0;
parameter IS_WCLK_INVERTED = 1'b0;
- wire \$DPO , \$SPO ;
+ wire $DPO, $SPO;
RAM32X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .DPO(\$DPO ), .SPO(\$SPO ),
+ .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)
);
- \$__ABC9_LUT6 spo (.A(\$SPO ), .S({1'b1, A4, A3, A2, A1, A0}), .Y(SPO));
- \$__ABC9_LUT6 dpo (.A(\$DPO ), .S({1'b1, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
+ $__ABC9_LUT6 spo (.A($SPO), .S({1'b1, A4, A3, A2, A1, A0}), .Y(SPO));
+ $__ABC9_LUT6 dpo (.A($DPO), .S({1'b1, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
endmodule
module RAM64X1D (
@@ -53,17 +411,17 @@ module RAM64X1D (
);
parameter INIT = 64'h0;
parameter IS_WCLK_INVERTED = 1'b0;
- wire \$DPO , \$SPO ;
+ wire $DPO, $SPO;
RAM64X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .DPO(\$DPO ), .SPO(\$SPO ),
+ .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)
);
- \$__ABC9_LUT6 spo (.A(\$SPO ), .S({A5, A4, A3, A2, A1, A0}), .Y(SPO));
- \$__ABC9_LUT6 dpo (.A(\$DPO ), .S({DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
+ $__ABC9_LUT6 spo (.A($SPO), .S({A5, A4, A3, A2, A1, A0}), .Y(SPO));
+ $__ABC9_LUT6 dpo (.A($DPO), .S({DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
endmodule
module RAM128X1D (
@@ -75,17 +433,17 @@ module RAM128X1D (
);
parameter INIT = 128'h0;
parameter IS_WCLK_INVERTED = 1'b0;
- wire \$DPO , \$SPO ;
+ wire $DPO, $SPO;
RAM128X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .DPO(\$DPO ), .SPO(\$SPO ),
+ .DPO($DPO), .SPO($SPO),
.D(D), .WCLK(WCLK), .WE(WE),
.A(A),
.DPRA(DPRA)
);
- \$__ABC9_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO));
- \$__ABC9_LUT7 dpo (.A(\$DPO ), .S(DPRA), .Y(DPO));
+ $__ABC9_LUT7 spo (.A($SPO), .S(A), .Y(SPO));
+ $__ABC9_LUT7 dpo (.A($DPO), .S(DPRA), .Y(DPO));
endmodule
module RAM32M (
@@ -109,24 +467,24 @@ module RAM32M (
parameter [63:0] INIT_C = 64'h0000000000000000;
parameter [63:0] INIT_D = 64'h0000000000000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
- wire [1:0] \$DOA , \$DOB , \$DOC , \$DOD ;
+ wire [1:0] $DOA, $DOB, $DOC, $DOD;
RAM32M #(
.INIT_A(INIT_A), .INIT_B(INIT_B), .INIT_C(INIT_C), .INIT_D(INIT_D),
.IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .DOA(\$DOA ), .DOB(\$DOB ), .DOC(\$DOC ), .DOD(\$DOD ),
+ .DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
.WCLK(WCLK), .WE(WE),
.ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
.DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
);
- \$__ABC9_LUT6 doa0 (.A(\$DOA [0]), .S({1'b1, ADDRA}), .Y(DOA[0]));
- \$__ABC9_LUT6 doa1 (.A(\$DOA [1]), .S({1'b1, ADDRA}), .Y(DOA[1]));
- \$__ABC9_LUT6 dob0 (.A(\$DOB [0]), .S({1'b1, ADDRB}), .Y(DOB[0]));
- \$__ABC9_LUT6 dob1 (.A(\$DOB [1]), .S({1'b1, ADDRB}), .Y(DOB[1]));
- \$__ABC9_LUT6 doc0 (.A(\$DOC [0]), .S({1'b1, ADDRC}), .Y(DOC[0]));
- \$__ABC9_LUT6 doc1 (.A(\$DOC [1]), .S({1'b1, ADDRC}), .Y(DOC[1]));
- \$__ABC9_LUT6 dod0 (.A(\$DOD [0]), .S({1'b1, ADDRD}), .Y(DOD[0]));
- \$__ABC9_LUT6 dod1 (.A(\$DOD [1]), .S({1'b1, ADDRD}), .Y(DOD[1]));
+ $__ABC9_LUT6 doa0 (.A($DOA[0]), .S({1'b1, ADDRA}), .Y(DOA[0]));
+ $__ABC9_LUT6 doa1 (.A($DOA[1]), .S({1'b1, ADDRA}), .Y(DOA[1]));
+ $__ABC9_LUT6 dob0 (.A($DOB[0]), .S({1'b1, ADDRB}), .Y(DOB[0]));
+ $__ABC9_LUT6 dob1 (.A($DOB[1]), .S({1'b1, ADDRB}), .Y(DOB[1]));
+ $__ABC9_LUT6 doc0 (.A($DOC[0]), .S({1'b1, ADDRC}), .Y(DOC[0]));
+ $__ABC9_LUT6 doc1 (.A($DOC[1]), .S({1'b1, ADDRC}), .Y(DOC[1]));
+ $__ABC9_LUT6 dod0 (.A($DOD[0]), .S({1'b1, ADDRD}), .Y(DOD[0]));
+ $__ABC9_LUT6 dod1 (.A($DOD[1]), .S({1'b1, ADDRD}), .Y(DOD[1]));
endmodule
module RAM64M (
@@ -150,20 +508,20 @@ module RAM64M (
parameter [63:0] INIT_C = 64'h0000000000000000;
parameter [63:0] INIT_D = 64'h0000000000000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
- wire \$DOA , \$DOB , \$DOC , \$DOD ;
+ wire $DOA, $DOB, $DOC, $DOD;
RAM64M #(
.INIT_A(INIT_A), .INIT_B(INIT_B), .INIT_C(INIT_C), .INIT_D(INIT_D),
.IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .DOA(\$DOA ), .DOB(\$DOB ), .DOC(\$DOC ), .DOD(\$DOD ),
+ .DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
.WCLK(WCLK), .WE(WE),
.ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
.DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
);
- \$__ABC9_LUT6 doa (.A(\$DOA ), .S(ADDRA), .Y(DOA));
- \$__ABC9_LUT6 dob (.A(\$DOB ), .S(ADDRB), .Y(DOB));
- \$__ABC9_LUT6 doc (.A(\$DOC ), .S(ADDRC), .Y(DOC));
- \$__ABC9_LUT6 dod (.A(\$DOD ), .S(ADDRD), .Y(DOD));
+ $__ABC9_LUT6 doa (.A($DOA), .S(ADDRA), .Y(DOA));
+ $__ABC9_LUT6 dob (.A($DOB), .S(ADDRB), .Y(DOB));
+ $__ABC9_LUT6 doc (.A($DOC), .S(ADDRC), .Y(DOC));
+ $__ABC9_LUT6 dod (.A($DOD), .S(ADDRD), .Y(DOD));
endmodule
module SRL16E (
@@ -172,14 +530,14 @@ module SRL16E (
);
parameter [15:0] INIT = 16'h0000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
- wire \$Q ;
+ wire $Q;
SRL16E #(
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .Q(\$Q ),
+ .Q($Q),
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
);
- \$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
+ $__ABC9_LUT6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
endmodule
module SRLC32E (
@@ -190,14 +548,14 @@ module SRLC32E (
);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
- wire \$Q ;
+ wire $Q;
SRLC32E #(
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
) _TECHMAP_REPLACE_ (
- .Q(\$Q ), .Q31(Q31),
+ .Q($Q), .Q31(Q31),
.A(A), .CE(CE), .CLK(CLK), .D(D)
);
- \$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q));
+ $__ABC9_LUT6 q (.A($Q), .S({1'b1, A}), .Y(Q));
endmodule
module DSP48E1 (
@@ -386,15 +744,15 @@ __CELL__ #(
if (AREG == 0 && MREG == 0 && PREG == 0)
assign iA = A, pA = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
+ $__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
if (BREG == 0 && MREG == 0 && PREG == 0)
assign iB = B, pB = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
+ $__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
if (CREG == 0 && PREG == 0)
assign iC = C, pC = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
+ $__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
if (DREG == 0)
assign iD = D;
else if (techmap_guard)
@@ -405,27 +763,27 @@ __CELL__ #(
assign pAD = 1'bx;
if (PREG == 0) begin
if (MREG == 1)
- \$__ABC9_REG rM (.Q(pM));
+ $__ABC9_REG rM (.Q(pM));
else
assign pM = 1'bx;
assign pP = 1'bx;
end else begin
assign pM = 1'bx;
- \$__ABC9_REG rP (.Q(pP));
+ $__ABC9_REG rP (.Q(pP));
end
if (MREG == 0 && PREG == 0)
assign mP = oP, mPCOUT = oPCOUT;
else
assign mP = 1'bx, mPCOUT = 1'bx;
- \$__ABC9_DSP48E1_MULT_P_MUX muxP (
+ $__ABC9_DSP48E1_MULT_P_MUX muxP (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
);
- \$__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
+ $__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
);
- `DSP48E1_INST(\$__ABC9_DSP48E1_MULT )
+ `DSP48E1_INST($__ABC9_DSP48E1_MULT )
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
// Disconnect the A-input if MREG is enabled, since
@@ -433,26 +791,26 @@ __CELL__ #(
if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
assign iA = A, pA = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
+ $__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
if (BREG == 0 && MREG == 0 && PREG == 0)
assign iB = B, pB = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
+ $__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
if (CREG == 0 && PREG == 0)
assign iC = C, pC = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
+ $__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
if (DREG == 0 && ADREG == 0)
assign iD = D, pD = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
+ $__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
if (PREG == 0) begin
if (MREG == 1) begin
assign pAD = 1'bx;
- \$__ABC9_REG rM (.Q(pM));
+ $__ABC9_REG rM (.Q(pM));
end else begin
if (ADREG == 1)
- \$__ABC9_REG rAD (.Q(pAD));
+ $__ABC9_REG rAD (.Q(pAD));
else
assign pAD = 1'bx;
assign pM = 1'bx;
@@ -460,21 +818,21 @@ __CELL__ #(
assign pP = 1'bx;
end else begin
assign pAD = 1'bx, pM = 1'bx;
- \$__ABC9_REG rP (.Q(pP));
+ $__ABC9_REG rP (.Q(pP));
end
if (MREG == 0 && PREG == 0)
assign mP = oP, mPCOUT = oPCOUT;
else
assign mP = 1'bx, mPCOUT = 1'bx;
- \$__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP (
+ $__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
);
- \$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
+ $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
);
- `DSP48E1_INST(\$__ABC9_DSP48E1_MULT_DPORT )
+ `DSP48E1_INST($__ABC9_DSP48E1_MULT_DPORT )
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
// Disconnect the A-input if MREG is enabled, since
@@ -482,15 +840,15 @@ __CELL__ #(
if (AREG == 0 && PREG == 0)
assign iA = A, pA = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
+ $__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
if (BREG == 0 && PREG == 0)
assign iB = B, pB = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
+ $__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
if (CREG == 0 && PREG == 0)
assign iC = C, pC = 1'bx;
else
- \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
+ $__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
if (DREG == 1 && techmap_guard)
$error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
assign pD = 1'bx;
@@ -501,7 +859,7 @@ __CELL__ #(
$error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
assign pM = 1'bx;
if (PREG == 1)
- \$__ABC9_REG rP (.Q(pP));
+ $__ABC9_REG rP (.Q(pP));
else
assign pP = 1'bx;
@@ -509,14 +867,14 @@ __CELL__ #(
assign mP = oP, mPCOUT = oPCOUT;
else
assign mP = 1'bx, mPCOUT = 1'bx;
- \$__ABC9_DSP48E1_P_MUX muxP (
+ $__ABC9_DSP48E1_P_MUX muxP (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
);
- \$__ABC9_DSP48E1_PCOUT_MUX muxPCOUT (
+ $__ABC9_DSP48E1_PCOUT_MUX muxPCOUT (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
);
- `DSP48E1_INST(\$__ABC9_DSP48E1 )
+ `DSP48E1_INST($__ABC9_DSP48E1 )
end
else
$error("Invalid DSP48E1 configuration");
diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v
index 8c8e1556c..11250123d 100644
--- a/techlibs/xilinx/abc9_model.v
+++ b/techlibs/xilinx/abc9_model.v
@@ -30,7 +30,22 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
: (S0 ? I1 : I0);
endmodule
-// Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}
+module \$__ABC9_FF_ (input D, output Q);
+endmodule
+
+// Box to emulate async behaviour of FDC*
+(* abc9_box_id = 1000, lib_whitebox *)
+module \$__ABC9_ASYNC0 (input A, S, output Y);
+ assign Y = S ? 1'b0 : A;
+endmodule
+
+// Box to emulate async behaviour of FDP*
+(* abc9_box_id = 1001, lib_whitebox *)
+module \$__ABC9_ASYNC1 (input A, S, output Y);
+ assign Y = S ? 1'b0 : A;
+endmodule
+
+// Box to emulate comb/seq behaviour of RAM{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).
@@ -39,7 +54,7 @@ endmodule
(* abc9_box_id=2000 *)
module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);
endmodule
-// Box to emulate comb/seq behaviour of RAMD128
+// Box to emulate comb/seq behaviour of RAM128
(* abc9_box_id=2001 *)
module \$__ABC9_LUT7 (input A, input [6:0] S, output Y);
endmodule
diff --git a/techlibs/xilinx/abc9_unmap.v b/techlibs/xilinx/abc9_unmap.v
index ad6469702..46526007d 100644
--- a/techlibs/xilinx/abc9_unmap.v
+++ b/techlibs/xilinx/abc9_unmap.v
@@ -20,6 +20,15 @@
// ============================================================================
+(* techmap_celltype = "$__ABC9_ASYNC0 $__ABC9_ASYNC1" *)
+module \$__ABC9_ASYNC01 (input A, S, output Y);
+ assign Y = A;
+endmodule
+
+module \$__ABC9_FF_ (input D, output Q);
+ assign Q = D;
+endmodule
+
module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);
assign Y = A;
endmodule
diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box
index c6df54667..1dff88509 100644
--- a/techlibs/xilinx/abc9_xc7.box
+++ b/techlibs/xilinx/abc9_xc7.box
@@ -1,64 +1,142 @@
# 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)
+# NB: Box inputs/outputs must each be in the same order
+# as their corresponding module definition
+# (with exceptions detailed below)
-# Average across F7[AB]MUX
-# Inputs: I0 I1 S0
-# Outputs: O
-MUXF7 1 1 3 1
-204 208 286
+# Box 1 : MUXF7
+# Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L451-L453
+# name ID w/b ins outs
+MUXF7 1 1 3 1
+#I0 I1 S0
+204 208 286 # O
-# Inputs: I0 I1 S0
-# Outputs: O
-MUXF8 2 1 3 1
-104 94 273
+# Box 2 : MUXF8
+# Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L462-L464
+# name ID w/b ins outs
+MUXF8 2 1 3 1
+#I0 I1 S0
+104 94 273 # O
-# 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
-$__XILINX_MUXF78 3 1 6 1
-294 297 311 317 390 273
+# Box 3 : $__MUXF78
+# (private cell used to preserve 2xMUXF7 + 1xMUXF8
+# an atomic unit so that ABC cannot optimise just
+# one of the MUXF7 away and expect to save on its
+# delay, since MUXF8 is only reachable through an
+# MUXF7)
+# name ID w/b ins outs
+$__MUXF78 3 1 6 1
+#I0 I1 I2 I3 S0 S1
+294 297 311 317 390 273 # O
-# CARRY4 + CARRY4_[ABCD]X
-# Inputs: CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 CI
-# Outputs: O0 O1 O2 O3 CO0 CO1 CO2 CO3
-# (NB: carry chain input/output must be last
-# input/output and the entire bus has been
+# Box 4 : CARRY4 + CARRY4_[ABCD]X
+# (Exception: carry chain input/output must be the
+# last input and output and the entire bus has been
# moved there overriding the otherwise
# alphabetical ordering)
-CARRY4 4 1 10 8
-482 - - - - 223 - - - 222
-598 407 - - - 400 205 - - 334
-584 556 537 - - 523 558 226 - 239
-642 615 596 438 - 582 618 330 227 313
-536 379 - - - 340 - - - 271
-494 465 445 - - 433 469 - - 157
-592 540 520 356 - 512 548 292 - 228
-580 526 507 398 385 508 528 378 380 114
+# Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L11-L46
+# name ID w/b ins outs
+CARRY4 4 1 10 8
+#CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 CI
+482 - - - - 223 - - - 222 # O0
+598 407 - - - 400 205 - - 334 # O1
+584 556 537 - - 523 558 226 - 239 # O2
+642 615 596 438 - 582 618 330 227 313 # O3
+536 379 - - - 340 - - - 271 # CO0
+494 465 445 - - 433 469 - - 157 # CO1
+592 540 520 356 - 512 548 292 - 228 # CO2
+580 526 507 398 385 508 528 378 380 114 # CO3
+# Box 1000 : $__ABC9_ASYNC0
+# (private cell to emulate async behaviour of FDC*)
+# name ID w/b ins outs
+$__ABC9_ASYNC0 1000 1 2 1
+#A S
+0 764 # Y
+
+# Box 1001 : $__ABC9_ASYNC1
+# (private cell to emulate async behaviour of FDP*)
+# name ID w/b ins outs
+$__ABC9_ASYNC1 1001 1 2 1
+#A S
+0 764 # Y
+
+# Flop boxes:
+# * Max delays from 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
+# * Exception: $abc9_currQ is a special input (located last) necessary for clock-enable functionality
+
+# Box 1100 : FDRE
+# name ID w/b ins outs
+FDRE 1100 1 5 1
+#C CE D R $abc9_currQ
+#0 109 -46 404 0
+0 109 0 404 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1101 : FDRE_1
+# name ID w/b ins outs
+FDRE_1 1101 1 5 1
+#C CE D R $abc9_currQ
+#0 109 -46 404 0
+0 109 0 404 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1102 : FDSE
+# name ID w/b ins outs
+FDSE 1102 1 5 1
+#C CE D R $abc9_currQ
+#0 109 -46 404 0
+0 109 0 404 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1103 : FDSE_1
+# name ID w/b ins outs
+FDSE_1 1103 1 5 1
+#C CE D R $abc9_currQ
+#0 109 -46 404 0
+0 109 0 404 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1104 : FDCE
+# name ID w/b ins outs
+FDCE 1104 1 5 1
+#C CE CLR D $abc9_currQ
+#0 109 764 -46 0
+0 109 764 0 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1105 : FDCE_1
+# name ID w/b ins outs
+FDCE_1 1105 1 5 1
+#C CE CLR D $abc9_currQ
+#0 109 764 -46 0
+0 109 764 0 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1106 : FDPE
+# name ID w/b ins outs
+FDPE 1106 1 5 1
+#C CE D PRE $abc9_currQ
+#0 109 -46 764 0
+0 109 0 764 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 1107 : FDPE_1
+# name ID w/b ins outs
+FDPE_1 1107 1 5 1
+#C CE D PRE $abc9_currQ
+#0 109 -46 764 0
+0 109 0 764 0 # Q (-46ps Tsu clamped to 0)
+
+# Box 2000 : $__ABC9_LUT6
+# (private cell to emulate async behaviour of LUTRAMs)
# 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
-$__ABC9_LUT6 2000 0 7 1
-0 642 631 472 407 238 127
+# name ID w/b ins outs
+$__ABC9_LUT6 2000 0 7 1
+#A S0 S1 S2 S3 S4 S5
+0 642 631 472 407 238 127 # Y
-# SLICEM/A6LUT + F7BMUX
-# Box to emulate comb/seq behaviour of RAMD128
-# Inputs: A S0 S1 S2 S3 S4 S5 S6
-# Outputs: DPO SPO
+# Box 2001 : $__ABC9_LUT6
+# (private cell to emulate async behaviour of LUITRAMs)
+# name ID w/b ins outs
$__ABC9_LUT7 2001 0 8 1
-0 1047 1036 877 812 643 532 478
+#A S0 S1 S2 S3 S4 S5 S6
+0 1047 1036 877 812 643 532 478 # Y
# Boxes used to represent the comb/seq behaviour of DSP48E1
# With abc9_map.v responsible for disconnecting inputs to
@@ -70,308 +148,323 @@ $__ABC9_LUT7 2001 0 8 1
# the mux at zero time, the combinatorial delay through
# these muxes thus represents the clock-to-q delay at
# P/PCOUT.
-$__ABC9_DSP48E1_MULT_P_MUX 2100 0 103 48
-# A AD B C D I M P Pq
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-$__ABC9_DSP48E1_MULT_PCOUT_MUX 2101 0 103 48
-# A AD B C D I M P Pq
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-$__ABC9_DSP48E1_MULT_DPORT_P_MUX 2102 0 103 48
-# A AD B C D I M P Pq
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX 2103 0 103 48
-# A AD B C D I M P Pq
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-$__ABC9_DSP48E1_P_MUX 2104 0 103 48
-# A AD B C D I M P Pq
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
-$__ABC9_DSP48E1_PCOUT_MUX 2105 0 103 48
-# A AD B C D I M P Pq
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
-$__ABC9_DSP48E1_MULT 3000 0 263 154
+# Box 2100 : $__ABC9_DSP48E1_MULT_P_MUX
+# name ID w/b ins outs
+$__ABC9_DSP48E1_MULT_P_MUX 2100 0 103 48
+#A AD B C D I0 I47 M P0 P47 Pq
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329 # O0
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+2952 - 2813 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329 # O47
+# Box 2101 : $__ABC9_DSP48E1_MULT_PCOUT_MUX
+# name ID w/b ins outs
+$__ABC9_DSP48E1_MULT_PCOUT_MUX 2101 0 103 48
+#A AD B C D I0 I47 M P0 P47 Pq
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435 # O0
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+3098 - 2960 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435 # O47
+# Box 2102 : $__ABC9_DSP48E1_MULT_DPORT_P_MUX
+# name ID w/b ins outs
+$__ABC9_DSP48E1_MULT_DPORT_P_MUX 2102 0 103 48
+#A AD B C D I0 I47 M P0 P47 Pq
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329 # O0
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+3935 2958 2813 1687 3908 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1671 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329 # O47
+# Box 2103 : $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX
+# name ID w/b ins outs
+$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX 2103 0 103 48
+#A AD B C D I0 I47 M P0 P47 Pq
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435 # O
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+4083 2859 2960 1835 4056 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435 # O47
+# Box 2104 : $__ABC9_DSP48E1_P_MUX
+# name ID w/b ins outs
+$__ABC9_DSP48E1_P_MUX 2104 0 103 48
+#A AD B C D I0 I47 M P0 P47 Pq
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329 # O0
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329
+1632 - 1616 1687 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 329 # O47
+# Box 2105 : $__ABC9_DSP48E1_PCOUT_MUX
+# name ID w/b ins outs
+$__ABC9_DSP48E1_PCOUT_MUX 2105 0 103 48
+#A AD B C D I0 I47 M P0 P47 Pq
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435 # O0
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435
+1780 - 1765 1835 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1819 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 435 # O47
+
+# Box 3000 : $__ABC9_DSP48E1_MULT
+# name ID w/b ins outs
+$__ABC9_DSP48E1_MULT 3000 0 263 154
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 - - 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 - - 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 - - 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 -
@@ -635,7 +728,9 @@ $__ABC9_DSP48E1_MULT 3000 0 263 154
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-$__ABC9_DSP48E1_MULT_DPORT 3001 0 263 154
+# Box 3001 : $__ABC9_DSP48E1_MULT_DPORT
+# name ID w/b ins outs
+$__ABC9_DSP48E1_MULT_DPORT 3001 0 263 154
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 - - 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 - - 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 - - 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 -
@@ -899,7 +994,9 @@ $__ABC9_DSP48E1_MULT_DPORT 3001 0 263 154
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-$__ABC9_DSP48E1 3002 0 263 154
+# Box 3002 : $__ABC9_DSP48E1
+# name ID w/b ins outs
+$__ABC9_DSP48E1 3002 0 263 154
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 - - 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 - - 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 - - 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 -
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index ed602fa6e..e9741555c 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -325,6 +325,7 @@ endmodule
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250
+(* abc9_box_id=1100, lib_whitebox, abc9_flop *)
module FDRE (
(* abc9_arrival=303 *)
output reg Q,
@@ -348,6 +349,20 @@ module FDRE (
endcase endgenerate
endmodule
+(* abc9_box_id=1101, lib_whitebox, abc9_flop *)
+module FDRE_1 (
+ (* abc9_arrival=303 *)
+ output reg Q,
+ (* clkbuf_sink *)
+ input C,
+ input 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
+
+(* abc9_box_id=1102, lib_whitebox, abc9_flop *)
module FDSE (
(* abc9_arrival=303 *)
output reg Q,
@@ -371,6 +386,19 @@ module FDSE (
endcase endgenerate
endmodule
+(* abc9_box_id=1103, lib_whitebox, abc9_flop *)
+module FDSE_1 (
+ (* abc9_arrival=303 *)
+ output reg Q,
+ (* clkbuf_sink *)
+ input C,
+ input 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 FDRSE (
output reg Q,
(* clkbuf_sink *)
@@ -406,6 +434,7 @@ module FDRSE (
Q <= d;
endmodule
+(* abc9_box_id=1104, lib_whitebox, abc9_flop *)
module FDCE (
(* abc9_arrival=303 *)
output reg Q,
@@ -413,10 +442,10 @@ module FDCE (
(* invertible_pin = "IS_C_INVERTED" *)
input C,
input CE,
- (* invertible_pin = "IS_D_INVERTED" *)
- input D,
(* invertible_pin = "IS_CLR_INVERTED" *)
- input CLR
+ input CLR,
+ (* invertible_pin = "IS_D_INVERTED" *)
+ input D
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
@@ -431,6 +460,20 @@ module FDCE (
endcase endgenerate
endmodule
+(* abc9_box_id=1105, lib_whitebox, abc9_flop *)
+module FDCE_1 (
+ (* abc9_arrival=303 *)
+ output reg Q,
+ (* clkbuf_sink *)
+ input C,
+ input 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
+
+(* abc9_box_id=1106, lib_whitebox, abc9_flop *)
module FDPE (
(* abc9_arrival=303 *)
output reg Q,
@@ -456,6 +499,19 @@ module FDPE (
endcase endgenerate
endmodule
+(* abc9_box_id=1107, lib_whitebox, abc9_flop *)
+module FDPE_1 (
+ (* abc9_arrival=303 *)
+ output reg Q,
+ (* clkbuf_sink *)
+ input C,
+ input 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;
+endmodule
+
module FDCPE (
output wire Q,
(* clkbuf_sink *)
@@ -501,54 +557,6 @@ module FDCPE (
assign Q = qs ? qp : qc;
endmodule
-module FDRE_1 (
- (* abc9_arrival=303 *)
- output reg Q,
- (* clkbuf_sink *)
- input C,
- input 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 (
- (* abc9_arrival=303 *)
- output reg Q,
- (* clkbuf_sink *)
- input C,
- input 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 (
- (* abc9_arrival=303 *)
- output reg Q,
- (* clkbuf_sink *)
- input C,
- input 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 (
- (* abc9_arrival=303 *)
- output reg Q,
- (* clkbuf_sink *)
- input C,
- input 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;
-endmodule
-
module LDCE (
output reg Q,
(* invertible_pin = "IS_CLR_INVERTED" *)
@@ -1648,7 +1656,7 @@ module SRL16 (
endmodule
module SRL16E (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
(* abc9_arrival=1472 *)
output Q,
input A0, A1, A2, A3, CE,
@@ -1712,9 +1720,10 @@ module SRLC16E (
endmodule
module SRLC32E (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
(* abc9_arrival=1472 *)
output Q,
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904
(* abc9_arrival=1114 *)
output Q31,
input [4:0] A,
@@ -2356,7 +2365,7 @@ module DSP48E1 (
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
initial begin
-`ifdef __ICARUS__
+`ifndef YOSYS
if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");
if (SEL_MASK != "MASK") $fatal(1, "Unsupported SEL_MASK value");
if (SEL_PATTERN != "PATTERN") $fatal(1, "Unsupported SEL_PATTERN value");
@@ -2519,12 +2528,12 @@ module DSP48E1 (
case (OPMODEr[1:0])
2'b00: X = 48'b0;
2'b01: begin X = $signed(Mrx);
-`ifdef __ICARUS__
+`ifndef YOSYS
if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
`endif
end
2'b10: begin X = P;
-`ifdef __ICARUS__
+`ifndef YOSYS
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[1:0] is 2'b10");
`endif
end
@@ -2536,7 +2545,7 @@ module DSP48E1 (
case (OPMODEr[3:2])
2'b00: Y = 48'b0;
2'b01: begin Y = 48'b0; // FIXME: more accurate partial product modelling?
-`ifdef __ICARUS__
+`ifndef YOSYS
if (OPMODEr[1:0] != 2'b01) $fatal(1, "OPMODEr[1:0] must be 2'b01 when OPMODEr[3:2] is 2'b01");
`endif
end
@@ -2550,13 +2559,13 @@ module DSP48E1 (
3'b000: Z = 48'b0;
3'b001: Z = PCIN;
3'b010: begin Z = P;
-`ifdef __ICARUS__
+`ifndef YOSYS
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010");
`endif
end
3'b011: Z = Cr;
3'b100: begin Z = P;
-`ifdef __ICARUS__
+`ifndef YOSYS
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
if (OPMODEr[3:0] != 4'b1000) $fatal(1, "OPMODEr[3:0] must be 4'b1000 when OPMODEr[6:4] i0s 3'b100");
`endif
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index a19046911..51d2cbbd2 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -64,7 +64,7 @@ struct SynthXilinxPass : public ScriptPass
log(" (this feature is experimental and incomplete)\n");
log("\n");
log(" -ise\n");
- log(" generate an output netlist suitable for ISE (enables -iopad)\n");
+ log(" generate an output netlist suitable for ISE\n");
log("\n");
log(" -nobram\n");
log(" do not use block RAM cells in output netlist\n");
@@ -84,11 +84,9 @@ struct SynthXilinxPass : public ScriptPass
log(" -nodsp\n");
log(" do not use DSP48E1s to implement multipliers and associated logic\n");
log("\n");
- log(" -iopad\n");
- log(" enable I/O buffer insertion (selected automatically by -ise)\n");
- log("\n");
log(" -noiopad\n");
- log(" disable I/O buffer insertion (only useful with -ise)\n");
+ log(" disable I/O buffer insertion (useful for hierarchical or \n");
+ log(" out-of-context flows)\n");
log("\n");
log(" -noclkbuf\n");
log(" disable automatic clock buffer insertion\n");
@@ -109,8 +107,12 @@ struct SynthXilinxPass : public ScriptPass
log(" -flatten\n");
log(" flatten design before synthesis\n");
log("\n");
+ log(" -dff\n");
+ log(" run 'abc'/'abc9' with -dff option\n");
+ log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-D 1' option to enable flip-flop retiming.\n");
+ log(" implies -dff.\n");
log("\n");
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
@@ -122,7 +124,8 @@ struct SynthXilinxPass : public ScriptPass
}
std::string top_opt, edif_file, blif_file, family;
- bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram, abc9;
+ bool flatten, retime, vpr, ise, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram;
+ bool abc9, dff_mode;
bool flatten_before_abc;
int widemux;
@@ -136,7 +139,6 @@ struct SynthXilinxPass : public ScriptPass
retime = false;
vpr = false;
ise = false;
- iopad = false;
noiopad = false;
noclkbuf = false;
nocarry = false;
@@ -148,6 +150,7 @@ struct SynthXilinxPass : public ScriptPass
nodsp = false;
uram = false;
abc9 = false;
+ dff_mode = false;
flatten_before_abc = false;
widemux = 0;
}
@@ -193,6 +196,7 @@ struct SynthXilinxPass : public ScriptPass
continue;
}
if (args[argidx] == "-retime") {
+ dff_mode = true;
retime = true;
continue;
}
@@ -213,7 +217,6 @@ struct SynthXilinxPass : public ScriptPass
continue;
}
if (args[argidx] == "-iopad") {
- iopad = true;
continue;
}
if (args[argidx] == "-noiopad") {
@@ -256,6 +259,10 @@ struct SynthXilinxPass : public ScriptPass
uram = true;
continue;
}
+ if (args[argidx] == "-dff") {
+ dff_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -282,7 +289,6 @@ struct SynthXilinxPass : public ScriptPass
void script() YS_OVERRIDE
{
- bool do_iopad = iopad || (ise && !noiopad);
std::string ff_map_file;
if (help_mode)
ff_map_file = "+/xilinx/{family}_ff_map.v";
@@ -292,10 +298,11 @@ struct SynthXilinxPass : public ScriptPass
ff_map_file = "+/xilinx/xc7_ff_map.v";
if (check_label("begin")) {
+ std::string read_args;
if (vpr)
- run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
- else
- run("read_verilog -lib +/xilinx/cells_sim.v");
+ read_args += " -D_EXPLICIT_CARRY";
+ read_args += " -lib +/xilinx/cells_sim.v";
+ run("read_verilog" + read_args);
run("read_verilog -lib +/xilinx/cells_xtra.v");
@@ -517,8 +524,8 @@ struct SynthXilinxPass : public ScriptPass
if (check_label("map_cells")) {
// Needs to be done before logic optimization, so that inverters (OE vs T) are handled.
- if (help_mode || do_iopad)
- run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
+ if (help_mode || !noiopad)
+ run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(only if not '-noiopad')");
std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
if (widemux > 0)
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
@@ -537,12 +544,15 @@ struct SynthXilinxPass : public ScriptPass
if (flatten_before_abc)
run("flatten");
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] [-D 1]", "(option for 'nowidelut', '-dff', '-retime')");
else if (abc9) {
if (family != "xc7")
log_warning("'synth_xilinx -abc9' not currently supported for the '%s' family, "
"will use timing for 'xc7' instead.\n", family.c_str());
- run("techmap -map +/xilinx/abc9_map.v -max_iter 1");
+ std::string techmap_args = "-map +/xilinx/abc9_map.v -max_iter 1";
+ if (dff_mode)
+ techmap_args += " -D DFF_MODE";
+ run("techmap " + techmap_args);
run("read_verilog -icells -lib +/xilinx/abc9_model.v");
std::string abc9_opts = " -box +/xilinx/abc9_xc7.box";
abc9_opts += stringf(" -W %d", XC7_WIRE_DELAY);
@@ -551,13 +561,22 @@ struct SynthXilinxPass : public ScriptPass
abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut";
else
abc9_opts += " -lut +/xilinx/abc9_xc7.lut";
+ if (dff_mode)
+ abc9_opts += " -dff";
run("abc9" + abc9_opts);
+ run("techmap -map +/xilinx/abc9_unmap.v");
}
else {
+ std::string abc_opts;
if (nowidelut)
- run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
+ abc_opts += " -luts 2:2,3,6:5";
else
- run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
+ abc_opts += " -luts 2:2,3,6:5,10,20";
+ if (dff_mode)
+ abc_opts += " -dff";
+ if (retime)
+ abc_opts += " -D 1";
+ run("abc" + abc_opts);
}
run("clean");
@@ -567,14 +586,11 @@ struct SynthXilinxPass : public ScriptPass
run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
if (help_mode)
- techmap_args += " [-map " + ff_map_file + "]";
- else if (abc9)
- techmap_args += " -map +/xilinx/abc9_unmap.v";
- else
- techmap_args += " -map " + ff_map_file;
- run("techmap " + techmap_args);
+ techmap_args += stringf("[-map %s]", ff_map_file.c_str());
+ else if (!abc9)
+ techmap_args += stringf(" -map %s", ff_map_file.c_str());
+ run("techmap " + techmap_args, "(only if '-abc9')");
run("xilinx_dffopt");
- run("clean");
}
if (check_label("finalize")) {
@@ -582,6 +598,7 @@ struct SynthXilinxPass : public ScriptPass
run("clkbufmap -buf BUFG O:I ", "(skip if '-noclkbuf')");
if (help_mode || ise)
run("extractinv -inv INV O:I", "(only if '-ise')");
+ run("clean");
}
if (check_label("check")) {
diff --git a/tests/arch/anlogic/counter.ys b/tests/arch/anlogic/counter.ys
index d363ec24e..a6eab248c 100644
--- a/tests/arch/anlogic/counter.ys
+++ b/tests/arch/anlogic/counter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
-equiv_opt -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
+equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/ecp5/bug1598.ys b/tests/arch/ecp5/bug1598.ys
new file mode 100644
index 000000000..1d1682fcd
--- /dev/null
+++ b/tests/arch/ecp5/bug1598.ys
@@ -0,0 +1,16 @@
+read_verilog <<EOT
+module led_blink (
+ input clk,
+ output ledc
+ );
+
+ reg [6:0] led_counter = 0;
+ always @( posedge clk ) begin
+ led_counter <= led_counter + 1;
+ end
+ assign ledc = !led_counter[ 6:3 ];
+
+endmodule
+EOT
+proc
+equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 -abc9
diff --git a/tests/arch/ecp5/counter.ys b/tests/arch/ecp5/counter.ys
index f9f60fbff..e46001ffe 100644
--- a/tests/arch/ecp5/counter.ys
+++ b/tests/arch/ecp5/counter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
-equiv_opt -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
+equiv_opt -assert -multiclock -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 4 t:CCU2C
diff --git a/tests/arch/ecp5/macc.ys b/tests/arch/ecp5/macc.ys
index 1863ea4d2..8da8d2f8e 100644
--- a/tests/arch/ecp5/macc.ys
+++ b/tests/arch/ecp5/macc.ys
@@ -3,8 +3,8 @@ hierarchy -top top
proc
# Blocked by issue #1358 (Missing ECP5 simulation models)
#equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
-equiv_opt -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
-design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+synth_ecp5
+#design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT18X18D
select -assert-count 4 t:CCU2C
diff --git a/tests/arch/ecp5/mul.ys b/tests/arch/ecp5/mul.ys
index 2105be52c..f887e9585 100644
--- a/tests/arch/ecp5/mul.ys
+++ b/tests/arch/ecp5/mul.ys
@@ -3,9 +3,9 @@ hierarchy -top top
proc
# Blocked by issue #1358 (Missing ECP5 simulation models)
#equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
-equiv_opt -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
+synth_ecp5
-design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+#design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT18X18D
select -assert-none t:MULT18X18D %% t:* %D
diff --git a/tests/arch/ecp5/mux.ys b/tests/arch/ecp5/mux.ys
index 92463aa32..22866832d 100644
--- a/tests/arch/ecp5/mux.ys
+++ b/tests/arch/ecp5/mux.ys
@@ -39,8 +39,8 @@ proc
equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
-select -assert-count 8 t:L6MUX21
-select -assert-count 26 t:LUT4
-select -assert-count 12 t:PFUMX
+select -assert-count 12 t:L6MUX21
+select -assert-count 34 t:LUT4
+select -assert-count 17 t:PFUMX
select -assert-none t:LUT4 t:L6MUX21 t:PFUMX %% t:* %D
diff --git a/tests/arch/efinix/counter.ys b/tests/arch/efinix/counter.ys
index d20b8ae27..f8fb29a87 100644
--- a/tests/arch/efinix/counter.ys
+++ b/tests/arch/efinix/counter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
-equiv_opt -map +/efinix/cells_sim.v synth_efinix # equivalency check
+equiv_opt -assert -multiclock -map +/efinix/cells_sim.v synth_efinix # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/gowin/counter.ys b/tests/arch/gowin/counter.ys
index 920479d44..bdbc7ee24 100644
--- a/tests/arch/gowin/counter.ys
+++ b/tests/arch/gowin/counter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
-equiv_opt -map +/gowin/cells_sim.v synth_gowin # equivalency check
+equiv_opt -assert -multiclock -map +/gowin/cells_sim.v synth_gowin # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/ice40/bug1598.ys b/tests/arch/ice40/bug1598.ys
new file mode 100644
index 000000000..8438cb979
--- /dev/null
+++ b/tests/arch/ice40/bug1598.ys
@@ -0,0 +1,16 @@
+read_verilog <<EOT
+module led_blink (
+ input clk,
+ output ledc
+ );
+
+ reg [6:0] led_counter = 0;
+ always @( posedge clk ) begin
+ led_counter <= led_counter + 1;
+ end
+ assign ledc = !led_counter[ 6:3 ];
+
+endmodule
+EOT
+proc
+equiv_opt -assert -map +/ice40/cells_sim.v synth_ice40 -abc9
diff --git a/tests/arch/ice40/counter.ys b/tests/arch/ice40/counter.ys
index f112eb97d..7bbc4f2c3 100644
--- a/tests/arch/ice40/counter.ys
+++ b/tests/arch/ice40/counter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
-equiv_opt -map +/ice40/cells_sim.v synth_ice40 # equivalency check
+equiv_opt -assert -multiclock -map +/ice40/cells_sim.v synth_ice40 # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 6 t:SB_CARRY
diff --git a/tests/arch/ice40/mul.ys b/tests/arch/ice40/mul.ys
index 9891b77d6..b8c3eb941 100644
--- a/tests/arch/ice40/mul.ys
+++ b/tests/arch/ice40/mul.ys
@@ -1,6 +1,6 @@
read_verilog ../common/mul.v
hierarchy -top top
-equiv_opt -assert -map +/ice40/cells_sim.v synth_ice40 -dsp # equivalency check
+equiv_opt -assert -multiclock -map +/ice40/cells_sim.v synth_ice40 -dsp # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:SB_MAC16
diff --git a/tests/arch/ice40/rom.v b/tests/arch/ice40/rom.v
index 0a0f41f37..71459fe38 100644
--- a/tests/arch/ice40/rom.v
+++ b/tests/arch/ice40/rom.v
@@ -2,7 +2,8 @@
Example from: https://www.latticesemi.com/-/media/LatticeSemi/Documents/UserManuals/EI/iCEcube201701UserGuide.ashx?document_id=52071 [p. 74].
*/
module top(data, addr);
-output [3:0] data;
+output [3:0] data; // Note: this prompts a Yosys warning, but
+ // vendor doc does not contain 'reg'
input [4:0] addr;
always @(addr) begin
case (addr)
diff --git a/tests/arch/xilinx/abc9_dff.ys b/tests/arch/xilinx/abc9_dff.ys
new file mode 100644
index 000000000..b457cefce
--- /dev/null
+++ b/tests/arch/xilinx/abc9_dff.ys
@@ -0,0 +1,32 @@
+read_verilog <<EOT
+module top(input C, D, output [7:0] Q);
+FDRE fd1(.C(C), .CE(1'b1), .D(D), .R(1'b1), .Q(Q[0]));
+FDSE fd2(.C(C), .CE(1'b1), .D(D), .S(1'b1), .Q(Q[1]));
+FDCE fd3(.C(C), .CE(1'b1), .D(D), .CLR(1'b1), .Q(Q[2]));
+FDPE fd4(.C(C), .CE(1'b1), .D(D), .PRE(1'b1), .Q(Q[3]));
+FDRE_1 fd5(.C(C), .CE(1'b1), .D(D), .R(1'b1), .Q(Q[4]));
+FDSE_1 fd6(.C(C), .CE(1'b1), .D(D), .S(1'b1), .Q(Q[5]));
+FDCE_1 fd7(.C(C), .CE(1'b1), .D(D), .CLR(1'b1), .Q(Q[6]));
+FDPE_1 fd8(.C(C), .CE(1'b1), .D(D), .PRE(1'b1), .Q(Q[7]));
+endmodule
+EOT
+equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
+design -load postopt
+select -assert-none t:FD*
+
+design -reset
+read_verilog <<EOT
+module top(input C, D, output [7:0] Q);
+FDRE fd1(.C(C), .CE(1'b0), .D(D), .R(1'b0), .Q(Q[0]));
+FDSE fd2(.C(C), .CE(1'b0), .D(D), .S(1'b0), .Q(Q[1]));
+FDCE fd3(.C(C), .CE(1'b0), .D(D), .CLR(1'b0), .Q(Q[2]));
+FDPE fd4(.C(C), .CE(1'b0), .D(D), .PRE(1'b0), .Q(Q[3]));
+FDRE_1 fd5(.C(C), .CE(1'b0), .D(D), .R(1'b0), .Q(Q[4]));
+FDSE_1 fd6(.C(C), .CE(1'b0), .D(D), .S(1'b0), .Q(Q[5]));
+FDCE_1 fd7(.C(C), .CE(1'b0), .D(D), .CLR(1'b0), .Q(Q[6]));
+FDPE_1 fd8(.C(C), .CE(1'b0), .D(D), .PRE(1'b0), .Q(Q[7]));
+endmodule
+EOT
+equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
+design -load postopt
+select -assert-none t:FD*
diff --git a/tests/arch/xilinx/abc9_map.ys b/tests/arch/xilinx/abc9_map.ys
new file mode 100644
index 000000000..4a7b9384a
--- /dev/null
+++ b/tests/arch/xilinx/abc9_map.ys
@@ -0,0 +1,91 @@
+read_verilog <<EOT
+module top(input C, CE, D, R, output [1:0] Q);
+FDRE #(.INIT(1'b1)) ff1 (.C(C), .CE(CE), .D(D), .R(R), .Q(Q[0]));
+FDRE_1 #(.INIT(1'b1)) ff2 (.C(C), .CE(CE), .D(D), .R(R), .Q(Q[1]));
+endmodule
+EOT
+design -save gold
+
+techmap -map +/xilinx/abc9_map.v -max_iter 1 -D DFF_MODE
+techmap -map +/xilinx/abc9_unmap.v
+select -assert-count 1 t:FDSE
+select -assert-count 1 t:FDSE_1
+techmap -autoproc -map +/xilinx/cells_sim.v
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+techmap -autoproc -map +/xilinx/cells_sim.v
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -seq 2 -verify -prove-asserts -show-ports miter
+
+design -reset
+read_verilog <<EOT
+module top(input C, CE, D, S, output [1:0] Q);
+FDSE #(.INIT(1'b1)) ff1 (.C(C), .CE(CE), .D(D), .S(S), .Q(Q[0]));
+FDSE_1 #(.INIT(1'b1)) ff2 (.C(C), .CE(CE), .D(D), .S(S), .Q(Q[1]));
+endmodule
+EOT
+design -save gold
+
+techmap -map +/xilinx/abc9_map.v -max_iter 1 -D DFF_MODE
+techmap -map +/xilinx/abc9_unmap.v
+select -assert-count 1 t:FDRE
+select -assert-count 1 t:FDRE_1
+techmap -autoproc -map +/xilinx/cells_sim.v
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+techmap -autoproc -map +/xilinx/cells_sim.v
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -seq 2 -set-init-zero -verify -prove-asserts -show-ports miter
+
+design -reset
+read_verilog <<EOT
+module top(input C, CE, D, PRE, output [1:0] Q);
+FDPE #(.INIT(1'b1)) ff1 (.C(C), .CE(CE), .D(D), .PRE(PRE), .Q(Q[0]));
+FDPE_1 #(.INIT(1'b1)) ff2 (.C(C), .CE(CE), .D(D), .PRE(PRE), .Q(Q[1]));
+endmodule
+EOT
+design -save gold
+
+techmap -map +/xilinx/abc9_map.v -max_iter 1 -D DFF_MODE
+techmap -map +/xilinx/abc9_unmap.v
+select -assert-count 1 t:FDCE
+select -assert-count 1 t:FDCE_1
+techmap -autoproc -map +/xilinx/cells_sim.v
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+techmap -autoproc -map +/xilinx/cells_sim.v
+clk2fflogic
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -seq 2 -set-init-zero -verify -prove-asserts -show-ports miter
+
+design -reset
+read_verilog <<EOT
+module top(input C, CE, D, CLR, output [1:0] Q);
+FDCE #(.INIT(1'b1)) ff1 (.C(C), .CE(CE), .D(D), .CLR(CLR), .Q(Q[0]));
+FDCE_1 #(.INIT(1'b1)) ff2 (.C(C), .CE(CE), .D(D), .CLR(CLR), .Q(Q[1]));
+endmodule
+EOT
+design -save gold
+
+techmap -map +/xilinx/abc9_map.v -max_iter 1 -D DFF_MODE
+techmap -map +/xilinx/abc9_unmap.v
+select -assert-count 1 t:FDPE
+techmap -autoproc -map +/xilinx/cells_sim.v
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+techmap -autoproc -map +/xilinx/cells_sim.v
+clk2fflogic
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -seq 2 -set-init-zero -verify -prove-asserts -show-ports miter
diff --git a/tests/arch/xilinx/add_sub.ys b/tests/arch/xilinx/add_sub.ys
index 9dbddce47..313948cc5 100644
--- a/tests/arch/xilinx/add_sub.ys
+++ b/tests/arch/xilinx/add_sub.ys
@@ -1,7 +1,7 @@
read_verilog ../common/add_sub.v
hierarchy -top top
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 14 t:LUT2
diff --git a/tests/arch/xilinx/adffs.ys b/tests/arch/xilinx/adffs.ys
index c0ff6a2e2..3328f9edc 100644
--- a/tests/arch/xilinx/adffs.ys
+++ b/tests/arch/xilinx/adffs.ys
@@ -3,7 +3,7 @@ design -save read
hierarchy -top adff
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd adff # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
@@ -15,7 +15,7 @@ select -assert-none t:BUFG t:FDCE %% t:* %D
design -load read
hierarchy -top adffn
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd adffn # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
@@ -28,7 +28,7 @@ select -assert-none t:BUFG t:FDCE t:INV %% t:* %D
design -load read
hierarchy -top dffs
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dffs # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
@@ -40,7 +40,7 @@ select -assert-none t:BUFG t:FDSE %% t:* %D
design -load read
hierarchy -top ndffnr
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd ndffnr # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
diff --git a/tests/arch/xilinx/attributes_test.ys b/tests/arch/xilinx/attributes_test.ys
index 4c881b280..7bdd94a63 100644
--- a/tests/arch/xilinx/attributes_test.ys
+++ b/tests/arch/xilinx/attributes_test.ys
@@ -1,7 +1,7 @@
# Check that blockram memory without parameters is not modified
read_verilog ../common/memory_attributes/attributes_test.v
hierarchy -top block_ram
-synth_xilinx -top block_ram
+synth_xilinx -top block_ram -noiopad
cd block_ram # Constrain all select calls below inside the top module
select -assert-count 1 t:RAMB18E1
@@ -9,7 +9,7 @@ select -assert-count 1 t:RAMB18E1
design -reset
read_verilog ../common/memory_attributes/attributes_test.v
hierarchy -top distributed_ram
-synth_xilinx -top distributed_ram
+synth_xilinx -top distributed_ram -noiopad
cd distributed_ram # Constrain all select calls below inside the top module
select -assert-count 8 t:RAM32X1D
@@ -18,7 +18,7 @@ design -reset
read_verilog ../common/memory_attributes/attributes_test.v
prep
setattr -mod -set ram_style "distributed" block_ram
-synth_xilinx -top block_ram
+synth_xilinx -top block_ram -noiopad
cd block_ram # Constrain all select calls below inside the top module
select -assert-count 32 t:RAM128X1D
@@ -27,7 +27,7 @@ design -reset
read_verilog ../common/memory_attributes/attributes_test.v
prep
setattr -mod -set logic_block 1 block_ram
-synth_xilinx -top block_ram
+synth_xilinx -top block_ram -noiopad
cd block_ram # Constrain all select calls below inside the top module
select -assert-count 0 t:RAMB18E1
select -assert-count 32 t:RAM128X1D
@@ -35,13 +35,13 @@ select -assert-count 32 t:RAM128X1D
# Set ram_style block to a distributed memory; will be implemented as blockram
design -reset
read_verilog ../common/memory_attributes/attributes_test.v
-synth_xilinx -top distributed_ram_manual
+synth_xilinx -top distributed_ram_manual -noiopad
cd distributed_ram_manual # Constrain all select calls below inside the top module
select -assert-count 1 t:RAMB18E1
# Set synthesis, ram_block block to a distributed memory; will be implemented as blockram
design -reset
read_verilog ../common/memory_attributes/attributes_test.v
-synth_xilinx -top distributed_ram_manual_syn
+synth_xilinx -top distributed_ram_manual_syn -noiopad
cd distributed_ram_manual_syn # Constrain all select calls below inside the top module
select -assert-count 1 t:RAMB18E1
diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys
index bb908cbbf..ed743cf44 100644
--- a/tests/arch/xilinx/blockram.ys
+++ b/tests/arch/xilinx/blockram.ys
@@ -3,28 +3,28 @@
# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
design -reset
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
design -reset
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
design -reset
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
@@ -32,7 +32,7 @@ select -assert-count 1 t:RAMB18E1
design -reset
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 0 t:RAMB18E1
select -assert-count 4 t:RAM128X1D
@@ -41,7 +41,7 @@ select -assert-count 4 t:RAM128X1D
design -reset
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB36E1
@@ -52,7 +52,7 @@ design -reset
read_verilog ../common/blockram.v
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
setattr -set ram_style "block" m:memory
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
@@ -60,7 +60,7 @@ design -reset
read_verilog ../common/blockram.v
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
setattr -set ram_block 1 m:memory
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
@@ -68,7 +68,7 @@ design -reset
read_verilog ../common/blockram.v
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
setattr -set ram_style "dont_infer_a_ram_pretty_please" m:memory
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 0 t:RAMB18E1
@@ -76,7 +76,7 @@ design -reset
read_verilog ../common/blockram.v
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
setattr -set logic_block 1 m:memory
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 0 t:RAMB18E1
@@ -84,7 +84,7 @@ design -reset
read_verilog ../common/blockram.v
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 8 -chparam DATA_WIDTH 1
setattr -set ram_style "block" m:memory
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
@@ -92,6 +92,6 @@ design -reset
read_verilog ../common/blockram.v
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 8 -chparam DATA_WIDTH 1
setattr -set ram_block 1 m:memory
-synth_xilinx -top sync_ram_sdp
+synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
diff --git a/tests/arch/xilinx/bug1460.ys b/tests/arch/xilinx/bug1460.ys
index 2018071cc..09935ccd8 100644
--- a/tests/arch/xilinx/bug1460.ys
+++ b/tests/arch/xilinx/bug1460.ys
@@ -28,7 +28,7 @@ module register_file(
endmodule
EOT
-synth_xilinx
+synth_xilinx -noiopad
cd register_file
select -assert-count 32 t:RAM32M
select -assert-none t:* t:BUFG %d t:RAM32M %d
diff --git a/tests/arch/xilinx/bug1598.ys b/tests/arch/xilinx/bug1598.ys
new file mode 100644
index 000000000..1175380b1
--- /dev/null
+++ b/tests/arch/xilinx/bug1598.ys
@@ -0,0 +1,16 @@
+read_verilog <<EOT
+module led_blink (
+ input clk,
+ output ledc
+ );
+
+ reg [6:0] led_counter = 0;
+ always @( posedge clk ) begin
+ led_counter <= led_counter + 1;
+ end
+ assign ledc = !led_counter[ 6:3 ];
+
+endmodule
+EOT
+proc
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -abc9
diff --git a/tests/arch/xilinx/bug1605.ys b/tests/arch/xilinx/bug1605.ys
new file mode 100644
index 000000000..4be659860
--- /dev/null
+++ b/tests/arch/xilinx/bug1605.ys
@@ -0,0 +1,19 @@
+read_verilog <<EOT
+module top(inout io);
+ wire in;
+ wire t;
+ wire o;
+
+ IOBUF IOBUF(
+ .I(in),
+ .T(t),
+ .IO(io),
+ .O(o)
+ );
+endmodule
+EOT
+
+synth_xilinx
+cd top
+select -assert-count 1 t:IOBUF
+select -assert-none t:* t:IOBUF %d
diff --git a/tests/arch/xilinx/counter.ys b/tests/arch/xilinx/counter.ys
index 604acdbfc..11c29922e 100644
--- a/tests/arch/xilinx/counter.ys
+++ b/tests/arch/xilinx/counter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/xilinx/dffs.ys b/tests/arch/xilinx/dffs.ys
index 0bba4858f..dc764b033 100644
--- a/tests/arch/xilinx/dffs.ys
+++ b/tests/arch/xilinx/dffs.ys
@@ -3,7 +3,7 @@ design -save read
hierarchy -top dff
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dff # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
@@ -15,7 +15,7 @@ select -assert-none t:BUFG t:FDRE %% t:* %D
design -load read
hierarchy -top dffe
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dffe # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
diff --git a/tests/arch/xilinx/dsp_cascade.ys b/tests/arch/xilinx/dsp_cascade.ys
index f9185551b..ca6b619b9 100644
--- a/tests/arch/xilinx/dsp_cascade.ys
+++ b/tests/arch/xilinx/dsp_cascade.ys
@@ -19,7 +19,7 @@ EOT
proc
design -save read
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad
design -load postopt
cd cascade
select -assert-count 3 t:DSP48E1
@@ -35,7 +35,7 @@ select -assert-none t:DSP48E1 t:BUFG %% t:* %D
select -assert-count 2 t:DSP48E1 %co:+[PCOUT] t:DSP48E1 %d %co:+[PCIN] w:* %d t:DSP48E1 %i
design -load read
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s -noiopad
design -load postopt
cd cascade
select -assert-count 3 t:DSP48A1
@@ -65,7 +65,7 @@ EOT
proc
design -save read
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad
design -load postopt
cd cascade
select -assert-count 2 t:DSP48E1
@@ -75,7 +75,7 @@ select -assert-none t:DSP48E1 t:BUFG %% t:* %D
select -assert-count 1 t:DSP48E1 %co:+[PCOUT] t:DSP48E1 %d %co:+[PCIN] w:* %d t:DSP48E1 %i
design -load read
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s -noiopad
design -load postopt
cd cascade
select -assert-count 2 t:DSP48A1
diff --git a/tests/arch/xilinx/dsp_fastfir.ys b/tests/arch/xilinx/dsp_fastfir.ys
index 0067a822b..57fe49bde 100644
--- a/tests/arch/xilinx/dsp_fastfir.ys
+++ b/tests/arch/xilinx/dsp_fastfir.ys
@@ -63,7 +63,7 @@ module fastfir_dynamictaps(i_clk, i_reset, i_tap_wr, i_tap, i_ce, i_sample, o_re
endmodule
EOT
-synth_xilinx
+synth_xilinx -noiopad
cd fastfir_dynamictaps
select -assert-count 2 t:DSP48E1
select -assert-none t:* t:DSP48E1 %d t:BUFG %d
diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys
index f03400fe7..3235d5af3 100644
--- a/tests/arch/xilinx/fsm.ys
+++ b/tests/arch/xilinx/fsm.ys
@@ -3,7 +3,7 @@ hierarchy -top fsm
proc
flatten
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
miter -equiv -make_assert -flatten gold gate miter
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
diff --git a/tests/arch/xilinx/latches.ys b/tests/arch/xilinx/latches.ys
index c87a8e38b..e226c2ec8 100644
--- a/tests/arch/xilinx/latches.ys
+++ b/tests/arch/xilinx/latches.ys
@@ -3,7 +3,7 @@ design -save read
hierarchy -top latchp
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd latchp # Constrain all select calls below inside the top module
select -assert-count 1 t:LDCE
@@ -14,7 +14,7 @@ select -assert-none t:LDCE %% t:* %D
design -load read
hierarchy -top latchn
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd latchn # Constrain all select calls below inside the top module
select -assert-count 1 t:LDCE
@@ -26,7 +26,7 @@ select -assert-none t:LDCE t:INV %% t:* %D
design -load read
hierarchy -top latchsr
proc
-equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd latchsr # Constrain all select calls below inside the top module
select -assert-count 1 t:LDCE
diff --git a/tests/arch/xilinx/logic.ys b/tests/arch/xilinx/logic.ys
index d5b5c1a37..61a9314cc 100644
--- a/tests/arch/xilinx/logic.ys
+++ b/tests/arch/xilinx/logic.ys
@@ -1,7 +1,7 @@
read_verilog ../common/logic.v
hierarchy -top top
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys
index 6c9d1eae1..3f127a77e 100644
--- a/tests/arch/xilinx/lutram.ys
+++ b/tests/arch/xilinx/lutram.ys
@@ -2,7 +2,7 @@
#hierarchy -top lutram_1w1r -chparam A_WIDTH 4
#proc
#memory -nomap
-#equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+#equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
#memory
#opt -full
#
@@ -22,7 +22,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r -chparam A_WIDTH 5
proc
memory -nomap
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
memory
opt -full
@@ -42,7 +42,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r
proc
memory -nomap
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
memory
opt -full
@@ -62,7 +62,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w3r
proc
memory -nomap
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
memory
opt -full
@@ -82,7 +82,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w3r -chparam A_WIDTH 6
proc
memory -nomap
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
memory
opt -full
@@ -102,7 +102,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r -chparam A_WIDTH 5 -chparam D_WIDTH 6
proc
memory -nomap
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
memory
opt -full
@@ -122,7 +122,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r -chparam A_WIDTH 6 -chparam D_WIDTH 6
proc
memory -nomap
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
memory
opt -full
diff --git a/tests/arch/xilinx/macc.ys b/tests/arch/xilinx/macc.ys
index 11e959976..bf2b36320 100644
--- a/tests/arch/xilinx/macc.ys
+++ b/tests/arch/xilinx/macc.ys
@@ -3,8 +3,8 @@ design -save read
hierarchy -top macc
proc
-#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx ### TODO
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad ### TODO
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
@@ -17,8 +17,8 @@ select -assert-none t:BUFG t:FDRE t:DSP48E1 %% t:* %D
design -load read
hierarchy -top macc2
proc
-#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx ### TODO
-equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx
+#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad ### TODO
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
diff --git a/tests/arch/xilinx/mul.ys b/tests/arch/xilinx/mul.ys
index 6cf994fbf..490846ff1 100644
--- a/tests/arch/xilinx/mul.ys
+++ b/tests/arch/xilinx/mul.ys
@@ -1,7 +1,7 @@
read_verilog ../common/mul.v
hierarchy -top top
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
@@ -13,7 +13,7 @@ design -reset
read_verilog ../common/mul.v
hierarchy -top top
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/xilinx/mul_unsigned.ys b/tests/arch/xilinx/mul_unsigned.ys
index c714680af..980263cbd 100644
--- a/tests/arch/xilinx/mul_unsigned.ys
+++ b/tests/arch/xilinx/mul_unsigned.ys
@@ -2,7 +2,7 @@ read_verilog mul_unsigned.v
hierarchy -top mul_unsigned
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mul_unsigned # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
@@ -16,7 +16,7 @@ read_verilog mul_unsigned.v
hierarchy -top mul_unsigned
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc6s -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mul_unsigned # Constrain all select calls below inside the top module
select -assert-count 1 t:BUFG
diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys
index 388272449..99817738d 100644
--- a/tests/arch/xilinx/mux.ys
+++ b/tests/arch/xilinx/mux.ys
@@ -3,7 +3,7 @@ design -save read
hierarchy -top mux2
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux2 # Constrain all select calls below inside the top module
select -assert-count 1 t:LUT3
@@ -14,7 +14,7 @@ select -assert-none t:LUT3 %% t:* %D
design -load read
hierarchy -top mux4
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux4 # Constrain all select calls below inside the top module
select -assert-count 1 t:LUT6
@@ -25,7 +25,7 @@ select -assert-none t:LUT6 %% t:* %D
design -load read
hierarchy -top mux8
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux8 # Constrain all select calls below inside the top module
select -assert-count 1 t:LUT3
@@ -37,7 +37,7 @@ select -assert-none t:LUT3 t:LUT6 %% t:* %D
design -load read
hierarchy -top mux16
proc
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
select -assert-min 5 t:LUT6
diff --git a/tests/arch/xilinx/shifter.ys b/tests/arch/xilinx/shifter.ys
index 455437f18..3652319a0 100644
--- a/tests/arch/xilinx/shifter.ys
+++ b/tests/arch/xilinx/shifter.ys
@@ -2,7 +2,7 @@ read_verilog ../common/shifter.v
hierarchy -top top
proc
flatten
-equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
diff --git a/tests/arch/xilinx/tribuf.ys b/tests/arch/xilinx/tribuf.ys
index 4697703ca..eaccab126 100644
--- a/tests/arch/xilinx/tribuf.ys
+++ b/tests/arch/xilinx/tribuf.ys
@@ -7,6 +7,7 @@ synth
equiv_opt -assert -map +/xilinx/cells_sim.v -map +/simcells.v synth_xilinx # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd tristate # Constrain all select calls below inside the top module
-# TODO :: Tristate logic not yet supported; see https://github.com/YosysHQ/yosys/issues/1225
-select -assert-count 1 t:$_TBUF_
-select -assert-none t:$_TBUF_ %% t:* %D
+select -assert-count 2 t:IBUF
+select -assert-count 1 t:INV
+select -assert-count 1 t:OBUFT
+select -assert-none t:IBUF t:INV t:OBUFT %% t:* %D
diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v
index de60619d1..8afd0ce96 100644
--- a/tests/simple_abc9/abc9.v
+++ b/tests/simple_abc9/abc9.v
@@ -264,3 +264,30 @@ always @*
if (en)
q <= d;
endmodule
+
+module abc9_test031(input clk1, clk2, d, output reg q1, q2);
+always @(posedge clk1) q1 <= d;
+always @(negedge clk2) q2 <= q1;
+endmodule
+
+module abc9_test032(input clk, d, r, output reg q);
+always @(posedge clk or posedge r)
+ if (r) q <= 1'b0;
+ else q <= d;
+endmodule
+
+module abc9_test033(input clk, d, r, output reg q);
+always @(negedge clk or posedge r)
+ if (r) q <= 1'b1;
+ else q <= d;
+endmodule
+
+module abc9_test034(input clk, d, output reg q1, q2);
+always @(posedge clk) q1 <= d;
+always @(posedge clk) q2 <= q1;
+endmodule
+
+module abc9_test035(input clk, d, output reg [1:0] q);
+always @(posedge clk) q[0] <= d;
+always @(negedge clk) q[1] <= q[0];
+endmodule
diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh
index 0d4262005..bc921daa9 100755
--- a/tests/simple_abc9/run-test.sh
+++ b/tests/simple_abc9/run-test.sh
@@ -20,10 +20,12 @@ fi
cp ../simple/*.v .
cp ../simple/*.sv .
DOLLAR='?'
-exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-n 300 -p '\
+exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-n 300 -p '\
hierarchy; \
synth -run coarse; \
opt -full; \
- techmap; abc9 -lut 4 -box ../abc.box; \
+ techmap; \
+ abc9 -lut 4 -box ../abc.box; \
+ clean; \
check -assert; \
select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'"
diff --git a/tests/various/abc9.v b/tests/various/abc9.v
index 30ebd4e26..f0b3f6837 100644
--- a/tests/various/abc9.v
+++ b/tests/various/abc9.v
@@ -9,3 +9,10 @@ wire w;
unknown u(~i, w);
unknown2 u2(w, o);
endmodule
+
+module abc9_test032(input clk, d, r, output reg q);
+initial q = 1'b0;
+always @(negedge clk or negedge r)
+ if (!r) q <= 1'b0;
+ else q <= d;
+endmodule
diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys
index 5c9a4075d..81d0afd1b 100644
--- a/tests/various/abc9.ys
+++ b/tests/various/abc9.ys
@@ -22,3 +22,19 @@ abc9 -lut 4
select -assert-count 1 t:$lut r:LUT=2'b01 r:WIDTH=1 %i %i
select -assert-count 1 t:unknown
select -assert-none t:$lut t:unknown %% t: %D
+
+design -load read
+hierarchy -top abc9_test032
+proc
+clk2fflogic
+design -save gold
+
+abc9 -lut 4
+check
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -seq 10 -verify -prove-asserts -show-ports miter